From 4251daa76e0aae7330139978648fc04f5c7b8ccb Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Wed, 5 Apr 2017 14:52:25 -0700 Subject: [PATCH] Update Reference Source to .NET 4.7 --- .../SR.Designer.cs | 2 +- .../Core/Presentation/MorphHelpers.cs | 2 +- .../DynamicArgumentDesigner.xaml.cs | 2 +- .../SqlCommandAsyncResult.cs | 4 +- .../Internal/PropertyEditing/CategoryList.cs | 2 +- .../Framework/ValueEditors/ChoiceEditor.cs | 4 +- .../PropertyValueDialogHost.cs | 4 +- .../PropertyEditing/VisualTreeUtils.cs | 2 +- .../PropertyEditing/EditModeSwitchButton.cs | 2 +- .../Hosting/WindowHelperService.cs | 2 +- .../Model/ModelItemDictionaryImpl.cs | 4 +- .../Presentation/Model/ModelPropertyImpl.cs | 2 +- .../View/ExpressionTextBox.xaml.cs | 2 +- .../View/VariableDesigner.xaml.cs | 2 +- .../Xaml/ErrorTolerantObjectWriter.cs | 2 +- .../Activities/Debugger/StateManager.cs | 5 +- .../Debugger/Symbol/SymbolHelper.cs | 49 +- .../Activities/Runtime/ActivityExecutor.cs | 2 +- .../Activities/Runtime/ActivityInstanceMap.cs | 2 +- .../Activities/Statements/MethodExecutor.cs | 4 +- .../Activities/Statements/MethodResolver.cs | 2 +- .../System/Activities/WorkflowApplication.cs | 6 +- .../Activities/WorkflowPersistenceContext.cs | 2 +- .../DataAnnotationsResources.resx | 291 + ...mponentModel.DataAnnotations.Resources.txt | 16 + .../Configuration/BaseConfigurationRecord.cs | 33 +- .../Internal/InternalConfigHost.cs | 2 +- .../Configuration/MgmtConfigurationRecord.cs | 13 +- .../Win32/SafeHandles/NCryptSafeHandles.cs | 2 +- System.Core/System.Core.txt | 35 + .../Diagnostics/Eventing/EventDescriptor.cs | 4 +- .../Eventing/Reader/EventLogSession.cs | 2 +- .../Eventing/Reader/EventMetadata.cs | 2 +- .../Eventing/Reader/EventOpcode.cs | 2 +- .../Eventing/Reader/EventRecord.cs | 4 +- .../Eventing/Reader/ProviderMetadata.cs | 2 +- System.Core/System/IO/BufferedStream2.cs | 4 +- System.Core/System/IO/LogStream.cs | 2 +- .../IO/MemoryMappedFiles/MemoryMappedView.cs | 2 +- .../MemoryMappedViewAccessor.cs | 2 +- .../MemoryMappedViewStream.cs | 2 +- System.Core/System/IO/Pipes/PipeStream.cs | 6 +- System.Core/System/Linq/Enumerable.cs | 4 +- .../Parallel/Channels/AsynchronousChannel.cs | 2 +- .../Parallel/Channels/SynchronousChannel.cs | 2 +- .../Enumerables/AggregationMinMaxHelpers.cs | 2 +- .../Parallel/Enumerables/EmptyEnumerable.cs | 2 +- .../EnumerableWrapperWeakToStrong.cs | 2 +- .../Enumerables/OrderedParallelQuery.cs | 2 +- .../Enumerables/ParallelEnumerableWrapper.cs | 2 +- .../Parallel/Enumerables/ParallelQuery.cs | 2 +- .../Parallel/Enumerables/RangeEnumerable.cs | 2 +- .../Parallel/Enumerables/RepeatEnumerable.cs | 2 +- .../Linq/Parallel/Merging/ArrayMergeHelper.cs | 2 +- .../AsynchronousChannelMergeEnumerator.cs | 2 +- .../Parallel/Merging/DefaultMergeHelper.cs | 4 +- .../Linq/Parallel/Merging/MergeEnumerator.cs | 2 +- .../Linq/Parallel/Merging/MergeExecutor.cs | 2 +- .../Merging/OrderPreservingMergeHelper.cs | 2 +- .../OrderPreservingPipeliningMergeHelper.cs | 2 +- .../SynchronousChannelMergeEnumerator.cs | 2 +- .../Partitioning/HashRepartitionEnumerator.cs | 2 +- .../Partitioning/HashRepartitionStream.cs | 2 +- .../OrderedHashRepartitionEnumerator.cs | 2 +- .../OrderedHashRepartitionStream.cs | 2 +- .../Partitioning/PartitionedDataSource.cs | 2 +- .../Partitioning/PartitionedStream.cs | 2 +- .../UnorderedHashRepartitionStream.cs | 2 +- .../AssociativeAggregationOperator.cs | 2 +- .../Binary/ExceptQueryOperator.cs | 2 +- .../Binary/GroupJoinQueryOperator.cs | 2 +- .../Binary/HashJoinQueryOperatorEnumerator.cs | 2 +- .../Binary/IntersectQueryOperator.cs | 2 +- .../Binary/JoinQueryOperator.cs | 2 +- .../Binary/UnionQueryOperator.cs | 2 +- .../QueryOperators/Binary/ZipQueryOperator.cs | 2 +- .../QueryOperators/BinaryQueryOperator.cs | 2 +- .../Inlined/CountAggregationOperator.cs | 2 +- .../DecimalAverageAggregationOperator.cs | 2 +- .../DecimalMinMaxAggregationOperator.cs | 2 +- .../Inlined/DecimalSumAggregationOperator.cs | 2 +- .../DoubleAverageAggregationOperator.cs | 2 +- .../DoubleMinMaxAggregationOperator.cs | 2 +- .../Inlined/DoubleSumAggregationOperator.cs | 2 +- .../FloatAverageAggregationOperator.cs | 2 +- .../Inlined/FloatMinMaxAggregationOperator.cs | 2 +- .../Inlined/FloatSumAggregationOperator.cs | 2 +- .../Inlined/InlinedAggregationOperator.cs | 2 +- .../InlinedAggregationOperatorEnumerator.cs | 2 +- .../Inlined/IntAverageAggregationOperator.cs | 2 +- .../Inlined/IntMinMaxAggregationOperator.cs | 2 +- .../Inlined/IntSumAggregationOperator.cs | 2 +- .../Inlined/LongAverageAggregationOperator.cs | 2 +- .../Inlined/LongCountAggregationOperator.cs | 2 +- .../Inlined/LongMinMaxAggregationOperator.cs | 2 +- .../Inlined/LongSumAggregationOperator.cs | 2 +- ...llableDecimalAverageAggregationOperator.cs | 2 +- ...ullableDecimalMinMaxAggregationOperator.cs | 2 +- .../NullableDecimalSumAggregationOperator.cs | 2 +- ...ullableDoubleAverageAggregationOperator.cs | 2 +- ...NullableDoubleMinMaxAggregationOperator.cs | 2 +- .../NullableDoubleSumAggregationOperator.cs | 2 +- ...NullableFloatAverageAggregationOperator.cs | 2 +- .../NullableFloatMinMaxAggregationOperator.cs | 2 +- .../NullableFloatSumAggregationOperator.cs | 2 +- .../NullableIntAverageAggregationOperator.cs | 2 +- .../NullableIntMinMaxAggregationOperator.cs | 2 +- .../NullableIntSumAggregationOperator.cs | 2 +- .../NullableLongAverageAggregationOperator.cs | 2 +- .../NullableLongMinMaxAggregationOperator.cs | 2 +- .../NullableLongSumAggregationOperator.cs | 2 +- .../QueryOperators/ListQueryResults.cs | 2 +- .../Options/OrderingQueryOperator.cs | 2 +- .../Options/QueryExecutionOption.cs | 2 +- .../QueryOperators/PartitionedStreamMerger.cs | 2 +- .../PartitionerQueryOperator.cs | 2 +- .../QueryOperators/QueryOpeningEnumerator.cs | 2 +- .../Parallel/QueryOperators/QueryOperator.cs | 2 +- .../QueryOperators/QueryOperatorEnumerator.cs | 2 +- .../Parallel/QueryOperators/QueryResults.cs | 2 +- .../Parallel/QueryOperators/QuerySettings.cs | 2 +- .../QueryOperators/ScanQueryOperator.cs | 2 +- .../Unary/AnyAllSearchOperator.cs | 2 +- .../Unary/ConcatQueryOperator.cs | 2 +- .../Unary/ContainsSearchOperator.cs | 2 +- .../Unary/DefaultIfEmptyQueryOperator.cs | 2 +- .../Unary/DistinctQueryOperator.cs | 2 +- .../Unary/ElementAtQueryOperator.cs | 2 +- .../Unary/FirstQueryOperator.cs | 2 +- .../QueryOperators/Unary/ForAllOperator.cs | 2 +- .../Unary/GroupByQueryOperator.cs | 2 +- .../Unary/IndexedSelectQueryOperator.cs | 2 +- .../Unary/IndexedWhereQueryOperator.cs | 2 +- .../QueryOperators/Unary/LastQueryOperator.cs | 2 +- .../Unary/ReverseQueryOperator.cs | 2 +- .../Unary/SelectManyQueryOperator.cs | 2 +- .../Unary/SelectQueryOperator.cs | 2 +- .../Unary/SingleQueryOperator.cs | 2 +- .../QueryOperators/Unary/SortQueryOperator.cs | 2 +- .../Unary/TakeOrSkipQueryOperator.cs | 2 +- .../Unary/TakeOrSkipWhileQueryOperator.cs | 2 +- .../Unary/WhereQueryOperator.cs | 2 +- .../QueryOperators/UnaryQueryOperator.cs | 2 +- .../Parallel/Scheduling/CancellationState.cs | 2 +- .../OrderPreservingPipeliningSpoolingTask.cs | 2 +- .../Scheduling/OrderPreservingSpoolingTask.cs | 2 +- .../Parallel/Scheduling/QueryLifecycle.cs | 2 +- .../Linq/Parallel/Scheduling/QueryTask.cs | 4 +- .../Scheduling/QueryTaskGroupState.cs | 2 +- .../Linq/Parallel/Scheduling/Scheduling.cs | 2 +- .../Linq/Parallel/Scheduling/SpoolingTask.cs | 2 +- .../Parallel/Scheduling/SpoolingTaskBase.cs | 2 +- .../Parallel/Utils/CancellableEnumerable.cs | 2 +- .../Parallel/Utils/ExceptionAggregator.cs | 2 +- .../Linq/Parallel/Utils/ExchangeUtilities.cs | 2 +- .../Linq/Parallel/Utils/FixedMaxHeap.cs | 2 +- .../Linq/Parallel/Utils/GrowingArray.cs | 2 +- .../System/Linq/Parallel/Utils/HashLookup.cs | 2 +- .../System/Linq/Parallel/Utils/ListChunk.cs | 2 +- .../System/Linq/Parallel/Utils/Lookup.cs | 2 +- .../Linq/Parallel/Utils/PLINQETWProvider.cs | 2 +- .../System/Linq/Parallel/Utils/Pair.cs | 2 +- .../Linq/Parallel/Utils/PairComparer.cs | 2 +- .../Linq/Parallel/Utils/ReverseComparer.cs | 2 +- .../System/Linq/Parallel/Utils/Shared.cs | 2 +- .../System/Linq/Parallel/Utils/Sorting.cs | 2 +- .../Linq/Parallel/Utils/TraceHelpers.cs | 2 +- .../System/Linq/Parallel/Utils/Util.cs | 2 +- .../System/Linq/Parallel/Utils/Wrapper.cs | 2 +- .../Parallel/Utils/WrapperEqualityComparer.cs | 2 +- System.Core/System/Linq/ParallelEnumerable.cs | 2 +- System.Core/System/Linq/SequenceQuery.cs | 2 +- .../Security/Cryptography/BCryptNative.cs | 6 + .../Security/Cryptography/CngAlgorithm.cs | 26 + .../System/Security/Cryptography/CngKey.cs | 51 +- .../Security/Cryptography/CngKeyBlobFormat.cs | 26 + .../Security/Cryptography/ECDiffieHellman.cs | 86 + .../Cryptography/ECDiffieHellmanCng.cs | 78 +- .../ECDiffieHellmanCngPublicKey.cs | 101 +- .../Cryptography/ECDiffieHellmanPublicKey.cs | 25 +- .../System/Security/Cryptography/ECDsa.cs | 80 + .../System/Security/Cryptography/ECDsaCng.cs | 31 +- .../Security/Cryptography/NCryptNative.cs | 117 +- .../Cryptography/Rfc4050KeyFormatter.cs | 271 +- .../System/threading/Tasks/TaskExtensions.cs | 2 +- .../System/Data/DataRowComparer.cs | 2 +- .../System/Data/DataRowExtensions.cs | 2 +- .../System/Data/DataSetUtil.cs | 4 +- .../System/Data/DataTableExtensions.cs | 4 +- .../System/Data/EnumerableRowCollection.cs | 4 +- .../Data/EnumerableRowCollectionExtensions.cs | 4 +- .../System/Data/LinqDataView.cs | 4 +- .../Data/OrderedEnumerableRowCollection.cs | 4 +- .../System/Data/SortExpressionBuilder.cs | 4 +- .../System/Data/TypedTableBase.cs | 2 +- .../System/Data/TypedTableBaseExtensions.cs | 4 +- .../Design/AspNet/BuildProviderUtils.cs | 4 +- .../AspNet/EntityDesignerBuildProvider.cs | 4 +- .../Design/AspNet/EntityModelBuildProvider.cs | 4 +- .../AspNet/MappingModelBuildProvider.cs | 4 +- .../AspNet/StorageModelBuildProvider.cs | 4 +- .../Data/Entity/Design/Common/EDesignUtil.cs | 4 +- .../Design/Common/MetadataItemSerializer.cs | 4 +- .../Data/Entity/Design/Common/MetadataUtil.cs | 4 +- .../Common/OneToOneMappingSerializer.cs | 4 +- .../Design/Common/UniqueIdentifierService.cs | 4 +- .../Data/Entity/Design/EntityCodeGenerator.cs | 4 +- .../Data/Entity/Design/EntityDesignerUtils.cs | 4 +- .../Entity/Design/EntityFrameworkVersions.cs | 4 +- .../Design/EntityModelSchemaGenerator.cs | 4 +- .../Design/EntityStoreSchemaFilterEntry.cs | 4 +- .../Design/EntityStoreSchemaGenerator.cs | 4 +- .../EntityStoreSchemaGenerator.DbObjectKey.cs | 4 +- ...eSchemaGenerator.LoadMethodSessionState.cs | 4 +- .../EntityViewGenerationConstants.cs | 4 +- .../EntityViewGenerator.cs | 4 +- .../Entity/Design/MetadataExtensionMethods.cs | 2 +- .../Design/MetadataItemCollectionFactory.cs | 4 +- .../BidirectionalDictionary.cs | 4 +- .../EnglishPluralizationService.cs | 4 +- .../EntityDesignPluralizationHandler.cs | 4 +- .../PluralizationServiceUtil.cs | 4 +- ...toreSchemaGeneratorDatabaseSchemaLoader.cs | 4 +- .../SSDLGenerator/FunctionDetailsReader.cs | 4 +- .../RelationshipDetailsCollection.cs | 4 +- .../SSDLGenerator/RelationshipDetailsRow.cs | 4 +- .../SSDLGenerator/TableDetailsCollection.cs | 4 +- .../Design/SSDLGenerator/TableDetailsRow.cs | 4 +- .../EntityModel/EdmToObjectNamespaceMap.cs | 4 +- .../Emitters/AssociationTypeEmitter.cs | 4 +- .../EntityModel/Emitters/AttributeEmitter.cs | 4 +- .../Emitters/ClientApiGenerator.cs | 4 +- .../EntityModel/Emitters/CommentEmitter.cs | 4 +- .../Emitters/ComplexTypeEmitter.cs | 4 +- .../Data/EntityModel/Emitters/Emitter.cs | 4 +- .../Emitters/EntityContainerEmitter.cs | 4 +- .../EntityModel/Emitters/EntityTypeEmitter.cs | 4 +- .../System/Data/EntityModel/Emitters/FixUp.cs | 4 +- .../EntityModel/Emitters/FixUpCollection.cs | 4 +- .../Emitters/MetadataItemEmitter.cs | 4 +- .../EntityModel/Emitters/NamespaceEmitter.cs | 4 +- .../Emitters/NavigationPropertyEmitter.cs | 4 +- .../EntityModel/Emitters/PropertyEmitter.cs | 4 +- .../Emitters/PropertyEmitterBase.cs | 4 +- .../EntityModel/Emitters/SchemaTypeEmitter.cs | 4 +- .../Emitters/StructuredTypeEmitter.cs | 4 +- .../EntityModel/Emitters/TypeReference.cs | 4 +- .../System/Data/EntityModel/Emitters/Utils.cs | 4 +- .../Data/EntityModel/EntityClassGenerator.cs | 4 +- .../Data/EntityModel/LazyTextWriterCreator.cs | 4 +- .../EntityModel/PropertyGeneratedEventArgs.cs | 4 +- .../EntityModel/TypeGeneratedEventArgs.cs | 4 +- .../CommandTrees/AbstractExpressions.cs | 4 +- .../Data/Common/CommandTrees/Aggregates.cs | 4 +- .../CommandTrees/BasicCommandTreeVisitor.cs | 4 +- .../CommandTrees/BasicExpressionVisitor.cs | 4 +- .../Data/Common/CommandTrees/DbCommandTree.cs | 4 +- .../CommandTrees/DbDeleteCommandTree.cs | 4 +- .../CommandTrees/DbExpressionVisitor.cs | 4 +- .../DbExpressionVisitor_TResultType.cs | 4 +- .../CommandTrees/DbFunctionCommandTree.cs | 4 +- .../CommandTrees/DbInsertCommandTree.cs | 4 +- .../Data/Common/CommandTrees/DbLambda.cs | 4 +- .../CommandTrees/DbModificationClause.cs | 4 +- .../CommandTrees/DbModificationCommandTree.cs | 4 +- .../Common/CommandTrees/DbQueryCommandTree.cs | 4 +- .../Data/Common/CommandTrees/DbSetClause.cs | 4 +- .../CommandTrees/DbUpdateCommandTree.cs | 4 +- .../CommandTrees/DefaultExpressionVisitor.cs | 4 +- .../Common/CommandTrees/ExpressionBindings.cs | 4 +- .../ExpressionBuilder/DbExpressionBuilder.cs | 4 +- .../ExpressionBuilder/EdmFunctions.cs | 4 +- .../Internal/ArgumentValidation.cs | 4 +- .../Internal/EnumerableValidator.cs | 4 +- .../CommandTrees/ExpressionBuilder/Row.cs | 4 +- .../Spatial/SpatialEdmFunctions.cs | 2 +- .../Internal/DbExpressionRules.cs | 4 +- .../CommandTrees/Internal/ExpressionCopier.cs | 4 +- .../CommandTrees/Internal/ExpressionDumper.cs | 4 +- .../CommandTrees/Internal/ExpressionKeyGen.cs | 2 +- .../CommandTrees/Internal/ExpressionList.cs | 4 +- .../Internal/ExpressionPrinter.cs | 4 +- .../Internal/ParameterRetriever.cs | 4 +- .../Internal/PatternMatchRules.cs | 4 +- .../Common/CommandTrees/Internal/Validator.cs | 4 +- .../CommandTrees/Internal/ViewSimplifier.cs | 4 +- .../Internal/XmlExpressionDumper.cs | 4 +- .../CommandTrees/OperatorExpressions.cs | 4 +- .../CommandTrees/RelationalExpressions.cs | 4 +- .../Common/CommandTrees/ValueExpressions.cs | 4 +- .../System/Data/Common/DataRecord.cs | 6 +- .../System/Data/Common/DataRecordInfo.cs | 4 +- .../System/Data/Common/DbCommandDefinition.cs | 4 +- .../System/Data/Common/DbProviderManifest.cs | 4 +- .../System/Data/Common/DbProviderServices.cs | 4 +- .../Common/DbXmlEnabledProviderManifest.cs | 2 +- .../System/Data/Common/EntityRecordInfo.cs | 4 +- .../Data/Common/EntitySql/AST/AliasedExpr.cs | 4 +- .../Data/Common/EntitySql/AST/AstNode.cs | 4 +- .../Data/Common/EntitySql/AST/BuiltInExpr.cs | 4 +- .../Data/Common/EntitySql/AST/CaseExpr.cs | 4 +- .../Data/Common/EntitySql/AST/Command.cs | 4 +- .../Common/EntitySql/AST/ConstructorExpr.cs | 4 +- .../Common/EntitySql/AST/CreateRefExpr.cs | 4 +- .../Data/Common/EntitySql/AST/DotExpr.cs | 4 +- .../EntitySql/AST/FunctionDefinition.cs | 4 +- .../EntitySql/AST/GroupAggregateExpr.cs | 4 +- .../EntitySql/AST/GroupPartitionExpr.cs | 4 +- .../Data/Common/EntitySql/AST/Identifier.cs | 4 +- .../Data/Common/EntitySql/AST/Literal.cs | 4 +- .../Data/Common/EntitySql/AST/MethodExpr.cs | 4 +- .../Common/EntitySql/AST/NamespaceImport.cs | 4 +- .../Common/EntitySql/AST/NavigationExpr.cs | 4 +- .../Data/Common/EntitySql/AST/ParenExpr.cs | 4 +- .../Data/Common/EntitySql/AST/QueryExpr.cs | 4 +- .../Common/EntitySql/AST/QueryParameter.cs | 4 +- .../Common/EntitySql/AST/QueryStatement.cs | 4 +- .../Data/Common/EntitySql/AST/RefExpr.cs | 4 +- .../Common/EntitySql/AST/TypeDefinition.cs | 4 +- .../Data/Common/EntitySql/CqlErrorHelper.cs | 4 +- .../System/Data/Common/EntitySql/CqlLexer.cs | 4 +- .../Data/Common/EntitySql/CqlLexerHelpers.cs | 4 +- .../System/Data/Common/EntitySql/CqlParser.cs | 4 +- .../Data/Common/EntitySql/CqlParserHelpers.cs | 4 +- .../System/Data/Common/EntitySql/CqlQuery.cs | 4 +- .../Data/Common/EntitySql/EntitySqlParser.cs | 4 +- .../EntitySql/FunctionOverloadResolver.cs | 4 +- .../Data/Common/EntitySql/ParseResult.cs | 4 +- .../Data/Common/EntitySql/ParserOptions.cs | 4 +- .../Data/Common/EntitySql/SemanticAnalyzer.cs | 4 +- .../Data/Common/EntitySql/SemanticResolver.cs | 4 +- .../Data/Common/EntitySql/StaticContext.cs | 4 +- .../Data/Common/EntitySql/TypeResolver.cs | 4 +- .../System/Data/Common/EntityUtil.cs | 2 +- .../System/Data/Common/FieldMetadata.cs | 4 +- .../System/Data/Common/FieldNameLookup.cs | 4 +- .../System/Data/Common/Internal/DbTypeMap.cs | 2 +- .../Materialization/ColumnMapKeyBuilder.cs | 4 +- .../Materialization/CompensatingCollection.cs | 4 +- .../Internal/Materialization/Coordinator.cs | 4 +- .../Materialization/CoordinatorFactory.cs | 4 +- .../Materialization/CoordinatorScratchpad.cs | 4 +- .../Internal/Materialization/RecordState.cs | 2 +- .../Materialization/RecordStateFactory.cs | 2 +- .../Materialization/RecordStateScratchpad.cs | 2 +- .../Common/Internal/Materialization/Shaper.cs | 4 +- .../Internal/Materialization/ShaperFactory.cs | 4 +- .../Internal/Materialization/Translator.cs | 4 +- .../Common/Internal/Materialization/Util.cs | 2 +- .../Common/Internal/MultipartIdentifier.cs | 4 +- .../QueryCache/CompiledQueryCacheEntry.cs | 4 +- .../QueryCache/CompiledQueryCacheKey.cs | 4 +- .../Common/QueryCache/EntityClientCacheKey.cs | 4 +- .../QueryCache/EntitySqlQueryCacheKey.cs | 4 +- .../Common/QueryCache/LinqQueryCacheKey.cs | 2 +- .../Data/Common/QueryCache/QueryCacheEntry.cs | 4 +- .../Data/Common/QueryCache/QueryCacheKey.cs | 4 +- .../Common/QueryCache/QueryCacheManager.cs | 4 +- .../QueryCache/ShaperFactoryQueryCacheKey.cs | 4 +- .../Data/Common/Utils/AliasGenerator.cs | 4 +- .../Data/Common/Utils/Boolean/BoolExpr.cs | 4 +- .../Data/Common/Utils/Boolean/Clause.cs | 4 +- .../Common/Utils/Boolean/ConversionContext.cs | 4 +- .../Data/Common/Utils/Boolean/Converter.cs | 4 +- .../Common/Utils/Boolean/DomainConstraint.cs | 4 +- .../Common/Utils/Boolean/IdentifierService.cs | 4 +- .../Common/Utils/Boolean/KnowledgeBase.cs | 4 +- .../Data/Common/Utils/Boolean/Literal.cs | 4 +- .../Common/Utils/Boolean/NegationPusher.cs | 4 +- .../Data/Common/Utils/Boolean/Sentence.cs | 4 +- .../Data/Common/Utils/Boolean/Simplifier.cs | 4 +- .../Data/Common/Utils/Boolean/Solver.cs | 8 +- .../Data/Common/Utils/Boolean/Vertex.cs | 4 +- .../Data/Common/Utils/Boolean/Visitor.cs | 4 +- .../Common/Utils/ByValueEqualityComparer.cs | 4 +- .../System/Data/Common/Utils/CommandHelper.cs | 4 +- .../Utils/DisposableCollectionWrapper.cs | 4 +- .../System/Data/Common/Utils/Helpers.cs | 4 +- .../System/Data/Common/Utils/InternalBase.cs | 4 +- .../System/Data/Common/Utils/KeyToListMap.cs | 4 +- .../System/Data/Common/Utils/Memoizer.cs | 2 +- .../Data/Common/Utils/MetadataHelper.cs | 4 +- .../Utils/ModifiableIteratorCollection.cs | 4 +- .../System/Data/Common/Utils/Pair.cs | 4 +- .../System/Data/Common/Utils/Set.cs | 4 +- .../System/Data/Common/Utils/Singleton.cs | 2 +- .../System/Data/Common/Utils/StringUtil.cs | 4 +- .../Data/Common/Utils/ThreadSafeList.cs | 4 +- .../Common/Utils/TrailingSpaceComparer.cs | 4 +- .../System/Data/Common/Utils/TreePrinter.cs | 2 +- .../Data/EntityClient/DbConnectionOptions.cs | 4 +- .../DbParameterCollectionHelper.cs | 4 +- .../Data/EntityClient/DbParameterHelper.cs | 4 +- .../System/Data/EntityClient/EntityAdapter.cs | 4 +- .../System/Data/EntityClient/EntityCommand.cs | 4 +- .../EntityClient/EntityCommandDefinition.cs | 4 +- .../Data/EntityClient/EntityConnection.cs | 4 +- .../EntityConnectionStringBuilder.cs | 4 +- .../Data/EntityClient/EntityDataReader.cs | 4 +- .../Data/EntityClient/EntityParameter.cs | 4 +- .../EntityClient/EntityParameterCollection.cs | 4 +- .../EntityClient/EntityProviderFactory.cs | 4 +- .../EntityClient/EntityProviderServices.cs | 4 +- .../Data/EntityClient/EntityTransaction.cs | 4 +- .../System/Data/EntityClient/NameValuePair.cs | 4 +- .../Data/EntityCommandCompilationException.cs | 4 +- .../Data/EntityCommandExecutionException.cs | 4 +- .../System/Data/EntityException.cs | 4 +- System.Data.Entity/System/Data/EntityKey.cs | 4 +- .../BooleanFacetDescriptionElement.cs | 4 +- .../ByteFacetDescriptionElement.cs | 4 +- .../CollectionTypeElement.cs | 4 +- .../SchemaObjectModel/Documentation.cs | 4 +- .../SchemaObjectModel/EntityContainer.cs | 4 +- .../EntityContainerAssociationSet.cs | 4 +- .../EntityContainerAssociationSetEnd.cs | 4 +- .../EntityContainerEntitySet.cs | 4 +- .../EntityContainerEntitySetDefiningQuery.cs | 4 +- .../EntityContainerRelationshipSet.cs | 4 +- .../EntityContainerRelationshipSetEnd.cs | 4 +- .../SchemaObjectModel/EntityKeyElement.cs | 4 +- .../FacetDescriptionElement.cs | 4 +- .../FacetEnabledSchemaElement.cs | 4 +- .../FilteredSchemaElementLookUpTable.cs | 4 +- .../EntityModel/SchemaObjectModel/Function.cs | 4 +- .../SchemaObjectModel/FunctionCommandText.cs | 4 +- .../FunctionImportElement.cs | 2 +- .../IntegerFacetDescriptionElement.cs | 4 +- .../EntityModel/SchemaObjectModel/ItemType.cs | 4 +- .../SchemaObjectModel/KeyProperty.cs | 4 +- .../SchemaObjectModel/ModelFunction.cs | 4 +- .../ModelFunctionTypeElement.cs | 4 +- .../SchemaObjectModel/NavigationProperty.cs | 4 +- .../SchemaObjectModel/OnOperation.cs | 4 +- .../SchemaObjectModel/Parameter.cs | 4 +- .../SchemaObjectModel/PrimitiveSchema.cs | 4 +- .../EntityModel/SchemaObjectModel/Property.cs | 4 +- .../SchemaObjectModel/ReferenceSchema.cs | 4 +- .../SchemaObjectModel/ReferenceTypeElement.cs | 4 +- .../ReferentialConstraint.cs | 4 +- .../ReferentialConstraintRoleElement.cs | 4 +- .../SchemaObjectModel/Relationship.cs | 4 +- .../SchemaObjectModel/RelationshipEnd.cs | 4 +- .../RelationshipEndCollection.cs | 4 +- .../SchemaObjectModel/ReturnType.cs | 4 +- .../SchemaObjectModel/ReturnValue.cs | 4 +- .../SchemaObjectModel/RowTypeElement.cs | 4 +- .../RowTypePropertyElement.cs | 4 +- .../SchemaObjectModel/ScalarType.cs | 4 +- .../EntityModel/SchemaObjectModel/Schema.cs | 10 +- .../SchemaObjectModel/SchemaComplexType.cs | 4 +- .../SchemaObjectModel/SchemaElement.cs | 4 +- .../SchemaElementLookUpTable.cs | 4 +- .../SchemaElementLookUpTableEnumerator.cs | 4 +- .../SchemaObjectModel/SchemaEnumMember.cs | 4 +- .../SchemaObjectModel/SchemaEnumType.cs | 4 +- .../SchemaObjectModel/SchemaLookupTable.cs | 4 +- .../SchemaObjectModel/SchemaManager.cs | 4 +- .../SchemaObjectModel/SchemaType.cs | 4 +- .../SridFacetDescriptionElement.cs | 4 +- .../SchemaObjectModel/StructuredProperty.cs | 4 +- .../SchemaObjectModel/StructuredType.cs | 4 +- .../SchemaObjectModel/TextElement.cs | 4 +- .../SchemaObjectModel/TypeElement.cs | 4 +- .../SchemaObjectModel/TypeRefElement.cs | 4 +- .../SchemaObjectModel/TypeUsageBuilder.cs | 4 +- .../EntityModel/SchemaObjectModel/Utils.cs | 4 +- .../SchemaObjectModel/ValidationHelper.cs | 4 +- .../SchemaObjectModel/XmlSchemaResource.cs | 4 +- .../System/Data/EntitySqlException.cs | 4 +- .../System/Data/InternalMappingException.cs | 4 +- .../Data/InvalidCommandTreeException.cs | 4 +- .../Mapping/BaseMetadataMappingVisitor.cs | 4 +- .../DefaultObjectMappingItemCollection.cs | 4 +- .../Data/Mapping/EntityViewContainer.cs | 4 +- .../Mapping/EntityViewGenerationAttribute.cs | 4 +- ...onImportMapping.ReturnTypeRenameMapping.cs | 4 +- .../Data/Mapping/FunctionImportMapping.cs | 2 +- .../FunctionImportMappingComposable.cs | 2 +- .../FunctionImportMappingNonComposable.cs | 2 +- .../System/Data/Mapping/Mapping.cs | 4 +- .../Data/Mapping/MappingItemCollection.cs | 4 +- ...aMappingHasherVisitor.HashSourceBuilder.cs | 4 +- .../Mapping/MetadataMappingHasherVisitor.cs | 4 +- .../Mapping/ObjectAssociationEndMapping.cs | 4 +- .../Mapping/ObjectComplexPropertyMapping.cs | 4 +- .../Data/Mapping/ObjectMemberMapping.cs | 4 +- .../ObjectNavigationPropertyMapping.cs | 4 +- .../Data/Mapping/ObjectPropertyMapping.cs | 4 +- .../System/Data/Mapping/ObjectTypeMapping.cs | 4 +- .../Mapping/StorageAssociationSetMapping.cs | 4 +- .../Mapping/StorageAssociationTypeMapping.cs | 2 +- .../Mapping/StorageComplexPropertyMapping.cs | 4 +- .../Data/Mapping/StorageComplexTypeMapping.cs | 2 +- .../StorageConditionPropertyMapping.cs | 4 +- .../Data/Mapping/StorageEndPropertyMapping.cs | 4 +- .../Mapping/StorageEntityContainerMapping.cs | 4 +- .../Data/Mapping/StorageEntitySetMapping.cs | 4 +- .../Data/Mapping/StorageEntityTypeMapping.cs | 4 +- .../Data/Mapping/StorageMappingFragment.cs | 4 +- ...ageMappingItemCollection.ViewDictionary.cs | 4 +- .../Mapping/StorageMappingItemCollection.cs | 4 +- .../Data/Mapping/StorageMappingItemLoader.cs | 4 +- .../StorageModificationFunctionMapping.cs | 4 +- .../Data/Mapping/StoragePropertyMapping.cs | 4 +- .../Mapping/StorageScalarPropertyMapping.cs | 4 +- .../System/Data/Mapping/StorageSetMapping.cs | 4 +- .../System/Data/Mapping/StorageTypeMapping.cs | 4 +- .../Update/Internal/AssociationSetMetadata.cs | 4 +- .../Mapping/Update/Internal/ChangeNode.cs | 4 +- .../Mapping/Update/Internal/CompositeKey.cs | 4 +- .../Update/Internal/DynamicUpdateCommand.cs | 4 +- .../Update/Internal/ExtractedStateEntry.cs | 2 +- .../Update/Internal/ExtractorMetadata.cs | 4 +- .../Internal/FunctionMappingTranslator.cs | 4 +- .../Update/Internal/FunctionUpdateCommand.cs | 4 +- .../Data/Mapping/Update/Internal/Graph.cs | 4 +- .../Mapping/Update/Internal/KeyManager.cs | 4 +- .../Update/Internal/Propagator.Evaluator.cs | 4 +- .../Propagator.ExtentPlaceholderCreator.cs | 4 +- ...tor.JoinPropagator.JoinPredicateVisitor.cs | 4 +- ...JoinPropagator.SubstitutingCloneVisitor.cs | 4 +- .../Internal/Propagator.JoinPropagator.cs | 4 +- .../Mapping/Update/Internal/Propagator.cs | 4 +- .../Update/Internal/PropagatorResult.cs | 4 +- .../Update/Internal/RecordConverter.cs | 4 +- .../RelationshipConstraintValidator.cs | 4 +- .../Update/Internal/SourceInterpreter.cs | 4 +- .../Update/Internal/TableChangeProcessor.cs | 4 +- .../Update/Internal/UndirectedGraph.cs | 4 +- .../Mapping/Update/Internal/UpdateCommand.cs | 4 +- .../Update/Internal/UpdateCommandOrderer.cs | 4 +- .../Mapping/Update/Internal/UpdateCompiler.cs | 4 +- .../Internal/UpdateExpressionVisitor.cs | 4 +- .../Update/Internal/UpdateTranslator.cs | 4 +- .../Mapping/Update/Internal/ViewLoader.cs | 4 +- .../ViewGeneration/BasicViewGenerator.cs | 6 +- .../Mapping/ViewGeneration/CellCreator.cs | 4 +- .../Mapping/ViewGeneration/CellPartitioner.cs | 4 +- .../ViewGeneration/CellTreeSimplifier.cs | 6 +- .../ViewGeneration/ConfigViewGenerator.cs | 4 +- .../CqlGeneration/AliasedSlot.cs | 4 +- .../CqlGeneration/BooleanProjectedSlot.cs | 4 +- .../CqlGeneration/CaseCqlBlock.cs | 4 +- .../ViewGeneration/CqlGeneration/CqlBlock.cs | 4 +- .../CqlGeneration/CqlIdentifiers.cs | 4 +- .../ViewGeneration/CqlGeneration/CqlWriter.cs | 4 +- .../CqlGeneration/ExtentCqlBlock.cs | 4 +- .../CqlGeneration/JoinCqlBlock.cs | 4 +- .../ViewGeneration/CqlGeneration/SlotInfo.cs | 4 +- .../CqlGeneration/UnionCqlBlock.cs | 4 +- .../Mapping/ViewGeneration/CqlGenerator.cs | 4 +- .../ViewGeneration/DiscriminatorMap.cs | 4 +- .../Mapping/ViewGeneration/GeneratedView.cs | 4 +- .../QueryRewriting/FragmentQuery.cs | 4 +- .../QueryRewriting/FragmentQueryKB.cs | 4 +- .../QueryRewriting/FragmentQueryProcessor.cs | 4 +- .../QueryRewriting/QueryRewriter.cs | 4 +- .../QueryRewriting/RewritingPass.cs | 4 +- .../QueryRewriting/RewritingProcessor.cs | 4 +- .../QueryRewriting/RewritingSimplifier.cs | 4 +- .../QueryRewriting/RewritingValidator.cs | 4 +- .../QueryRewriting/RoleBoolean.cs | 4 +- .../ViewGeneration/QueryRewriting/Tile.cs | 4 +- .../Structures/BoolExpression.cs | 6 +- .../Structures/BoolExpressionVisitors.cs | 4 +- .../ViewGeneration/Structures/BoolLiteral.cs | 4 +- .../Structures/CaseStatement.cs | 4 +- .../Structures/CaseStatementProjectedSlot.cs | 4 +- .../Mapping/ViewGeneration/Structures/Cell.cs | 4 +- .../Structures/CellIdBoolean.cs | 4 +- .../ViewGeneration/Structures/CellLabel.cs | 4 +- .../ViewGeneration/Structures/CellQuery.cs | 4 +- .../ViewGeneration/Structures/CellTreeNode.cs | 4 +- .../Structures/CellTreeNodeVisitors.cs | 4 +- .../ViewGeneration/Structures/Constant.cs | 4 +- .../Structures/ConstantProjectedSlot.cs | 4 +- .../ViewGeneration/Structures/Domain.cs | 6 +- .../ViewGeneration/Structures/ErrorLog.cs | 4 +- .../Structures/LeafCellTreeNode.cs | 4 +- .../Structures/LeftCellWrapper.cs | 4 +- .../Structures/MemberDomainMap.cs | 4 +- .../ViewGeneration/Structures/MemberMaps.cs | 4 +- .../ViewGeneration/Structures/MemberPath.cs | 4 +- .../Structures/MemberProjectedSlot.cs | 4 +- .../Structures/MemberProjectionIndex.cs | 4 +- .../Structures/MemberRestriction.cs | 4 +- .../Structures/NegatedConstant.cs | 4 +- .../Structures/OpCellTreeNode.cs | 4 +- .../Structures/ProjectedSlot.cs | 4 +- .../Structures/QualifiedCellIdBoolean.cs | 4 +- .../Structures/ScalarConstant.cs | 4 +- .../Structures/ScalarRestriction.cs | 4 +- .../ViewGeneration/Structures/TypeConstant.cs | 4 +- .../Structures/TypeRestriction.cs | 4 +- .../Structures/WithStatement.cs | 4 +- .../ViewGeneration/Utils/ExceptionHelpers.cs | 4 +- .../ViewGeneration/Utils/ExternalCalls.cs | 4 +- .../Validation/BasicCellRelation.cs | 6 +- .../Validation/BasicKeyConstraint.cs | 4 +- .../ViewGeneration/Validation/CellRelation.cs | 4 +- .../Validation/ErrorPatternMatcher.cs | 4 +- .../ViewGeneration/Validation/ExtentKey.cs | 6 +- .../Validation/ForeignConstraint.cs | 4 +- .../Validation/KeyConstraint.cs | 4 +- .../Validation/SchemaConstraints.cs | 4 +- .../Validation/ViewCellRelation.cs | 6 +- .../ViewGeneration/Validation/ViewCellSlot.cs | 4 +- .../Validation/ViewKeyConstraint.cs | 4 +- .../Data/Mapping/ViewGeneration/Validator.cs | 4 +- .../Mapping/ViewGeneration/ViewGenResults.cs | 4 +- .../Mapping/ViewGeneration/ViewGenerator.cs | 6 +- .../Mapping/ViewGeneration/ViewgenContext.cs | 4 +- .../ViewGeneration/ViewgenGatekeeper.cs | 4 +- .../System/Data/Mapping/ViewValidator.cs | 4 +- .../System/Data/MappingException.cs | 4 +- .../System/Data/Metadata/AspProxy.cs | 4 +- .../Data/Metadata/CacheForPrimitiveTypes.cs | 4 +- .../System/Data/Metadata/ClrPerspective.cs | 4 +- .../System/Data/Metadata/Converter.cs | 4 +- .../Data/Metadata/CustomAssemblyResolver.cs | 4 +- .../Data/Metadata/DefaultAssemblyResolver.cs | 4 +- .../Data/Metadata/Edm/AssociationEndMember.cs | 4 +- .../Data/Metadata/Edm/AssociationSet.cs | 4 +- .../Data/Metadata/Edm/AssociationSetEnd.cs | 4 +- .../Data/Metadata/Edm/AssociationType.cs | 4 +- .../Data/Metadata/Edm/CollectionType.cs | 4 +- .../System/Data/Metadata/Edm/ComplexType.cs | 4 +- .../System/Data/Metadata/Edm/Documentation.cs | 4 +- .../System/Data/Metadata/Edm/EdmConstants.cs | 4 +- .../System/Data/Metadata/Edm/EdmFunction.cs | 4 +- .../System/Data/Metadata/Edm/EdmMember.cs | 4 +- .../System/Data/Metadata/Edm/EdmProperty.cs | 4 +- .../System/Data/Metadata/Edm/EdmType.cs | 4 +- .../Data/Metadata/Edm/EntityContainer.cs | 4 +- .../System/Data/Metadata/Edm/EntitySet.cs | 4 +- .../System/Data/Metadata/Edm/EntitySetBase.cs | 4 +- .../Metadata/Edm/EntitySetBaseCollection.cs | 4 +- .../System/Data/Metadata/Edm/EntityType.cs | 4 +- .../Data/Metadata/Edm/EntityTypeBase.cs | 6 +- .../System/Data/Metadata/Edm/EnumMember.cs | 4 +- .../System/Data/Metadata/Edm/EnumType.cs | 4 +- .../System/Data/Metadata/Edm/Facet.cs | 4 +- .../Data/Metadata/Edm/FacetDescription.cs | 4 +- .../Data/Metadata/Edm/FacetValueContainer.cs | 4 +- .../System/Data/Metadata/Edm/FacetValues.cs | 4 +- .../Edm/FilteredReadOnlyMetadataCollection.cs | 4 +- .../Data/Metadata/Edm/FunctionParameter.cs | 4 +- .../System/Data/Metadata/Edm/GlobalItem.cs | 4 +- .../Data/Metadata/Edm/ItemCollection.cs | 4 +- .../Metadata/Edm/LightweightCodeGenerator.cs | 4 +- .../Data/Metadata/Edm/MemberCollection.cs | 4 +- .../Data/Metadata/Edm/MetadataCollection.cs | 6 +- .../System/Data/Metadata/Edm/MetadataItem.cs | 4 +- .../Data/Metadata/Edm/MetadataItem_Static.cs | 4 +- .../Data/Metadata/Edm/MetadataProperty.cs | 4 +- .../Metadata/Edm/MetadataPropertyAttribute.cs | 4 +- .../Edm/MetadataPropertyCollection.cs | 4 +- .../Metadata/Edm/MetadataPropertyvalue.cs | 4 +- .../Data/Metadata/Edm/NavigationProperty.cs | 4 +- .../Edm/NavigationPropertyAccessor.cs | 4 +- .../System/Data/Metadata/Edm/PrimitiveType.cs | 4 +- .../Edm/Provider/ClrProviderManifest.cs | 4 +- .../Edm/Provider/EdmProviderManifest.cs | 4 +- .../EdmProviderManifestFunctionBuilder.cs | 4 +- .../EdmProviderManifestSpatialFunctions.cs | 2 +- .../Edm/ReadOnlyMetadataCollection.cs | 4 +- .../System/Data/Metadata/Edm/RefType.cs | 4 +- .../Metadata/Edm/ReferentialConstraint.cs | 4 +- .../Metadata/Edm/RelationshipEndMember.cs | 4 +- .../Data/Metadata/Edm/RelationshipSet.cs | 4 +- .../Data/Metadata/Edm/RelationshipType.cs | 4 +- .../System/Data/Metadata/Edm/RowType.cs | 4 +- .../System/Data/Metadata/Edm/SafeLink.cs | 4 +- .../Data/Metadata/Edm/SafeLinkCollection.cs | 4 +- .../System/Data/Metadata/Edm/SimpleType.cs | 4 +- .../Data/Metadata/Edm/StructuralType.cs | 4 +- .../System/Data/Metadata/Edm/TypeUsage.cs | 4 +- .../System/Data/Metadata/Edm/util.cs | 4 +- .../System/Data/Metadata/EdmError.cs | 4 +- .../EdmItemCollection.OcAssemblyCache.cs | 4 +- .../System/Data/Metadata/EdmItemCollection.cs | 4 +- .../System/Data/Metadata/EdmItemError.cs | 4 +- .../System/Data/Metadata/EdmSchemaError.cs | 4 +- .../System/Data/Metadata/EdmValidator.cs | 4 +- .../System/Data/Metadata/Helper.cs | 4 +- .../Data/Metadata/MappingMetadataHelper.cs | 4 +- .../Data/Metadata/MetadataArtifactLoader.cs | 4 +- .../MetadataArtifactLoaderComposite.cs | 4 +- .../MetadataArtifactLoaderCompositeFile.cs | 4 +- ...MetadataArtifactLoaderCompositeResource.cs | 4 +- .../Metadata/MetadataArtifactLoaderFile.cs | 4 +- .../MetadataArtifactLoaderResource.cs | 4 +- .../MetadataArtifactLoaderXmlReaderWrapper.cs | 4 +- .../System/Data/Metadata/MetadataCache.cs | 4 +- .../System/Data/Metadata/MetadataWorkspace.cs | 4 +- .../System/Data/Metadata/ModelPerspective.cs | 4 +- .../System/Data/Metadata/ObjectHelper.cs | 4 +- .../Data/Metadata/ObjectItemCollection.cs | 4 +- .../Metadata/ObjectLayer/AssemblyCache.cs | 4 +- .../ObjectLayer/AssemblyCacheEntry.cs | 4 +- .../ImmutableAssemblyCacheEntry.cs | 4 +- .../ObjectLayer/KnownAssembliesSet.cs | 4 +- .../ObjectLayer/KnownAssemblyEntry.cs | 4 +- .../Metadata/ObjectLayer/LoadMessageLogger.cs | 4 +- .../ObjectLayer/LockedAssemblyCache.cs | 4 +- .../ObjectLayer/MetadataAssemblyHelper.cs | 4 +- .../ObjectLayer/MutableAssemblyCacheEntry.cs | 4 +- .../ObjectLayer/ObjectItemAssemblyLoader.cs | 4 +- .../ObjectItemAttributeAssemblyLoader.cs | 4 +- .../ObjectItemCachedAssemblyLoader.cs | 4 +- .../ObjectItemConventionAssemblyLoader.cs | 4 +- .../ObjectItemLoadingSessionData.cs | 4 +- .../ObjectItemNoOpAssemblyLoader.cs | 4 +- .../System/Data/Metadata/Perspective.cs | 4 +- .../Metadata/StoreItemCollection.Loader.cs | 4 +- .../Data/Metadata/StoreItemCollection.cs | 4 +- .../System/Data/Metadata/TargetPerspective.cs | 4 +- .../System/Data/Metadata/TypeHelpers.cs | 4 +- .../System/Data/Metadata/TypeSemantics.cs | 4 +- .../System/Data/MetadataException.cs | 4 +- .../System/Data/ObjectNotFoundException.cs | 2 +- .../Data/Objects/AdditionalEntityFunctions.cs | 4 +- .../System/Data/Objects/CompiledQuery.cs | 4 +- .../Data/Objects/DataClasses/ComplexObject.cs | 4 +- .../EdmComplexPropertyAttribute.cs | 4 +- .../DataClasses/EdmComplexTypeAttribute.cs | 4 +- .../DataClasses/EdmEntityTypeAttribute.cs | 4 +- .../DataClasses/EdmEnumTypeAttribute.cs | 4 +- .../DataClasses/EdmFunctionAttribute.cs | 2 +- .../DataClasses/EdmPropertyAttribute.cs | 4 +- ...RelationshipNavigationPropertyAttribute.cs | 4 +- .../EdmRelationshipRoleAttribute.cs | 4 +- .../DataClasses/EdmScalarPropertyAttribute.cs | 4 +- .../Objects/DataClasses/EdmSchemaAttribute.cs | 4 +- .../Objects/DataClasses/EdmTypeAttribute.cs | 4 +- .../Objects/DataClasses/EntityCollection.cs | 4 +- .../Data/Objects/DataClasses/EntityObject.cs | 4 +- .../Objects/DataClasses/EntityReference.cs | 4 +- .../EntityReference_TResultType.cs | 4 +- .../Data/Objects/DataClasses/RelatedEnd.cs | 4 +- .../Objects/DataClasses/RelationshipFixer.cs | 4 +- .../DataClasses/RelationshipManager.cs | 4 +- .../DataClasses/RelationshipNavigation.cs | 4 +- .../Objects/DataClasses/StructuralObject.cs | 4 +- .../Data/Objects/DataRecordObjectView.cs | 12 +- .../Data/Objects/ELinq/BindingContext.cs | 2 +- .../Objects/ELinq/CompiledELinqQueryState.cs | 4 +- .../Data/Objects/ELinq/ELinqQueryState.cs | 4 +- .../Data/Objects/ELinq/ExpressionConverter.cs | 2 +- .../Objects/ELinq/ExpressionVisitorHelpers.cs | 2 +- .../System/Data/Objects/ELinq/Funcletizer.cs | 4 +- .../Data/Objects/ELinq/InitializerFacet.cs | 2 +- .../Objects/ELinq/LinqExpressionNormalizer.cs | 2 +- .../Objects/ELinq/MethodCallTranslator.cs | 2 +- .../Data/Objects/ELinq/ObjectQueryProvider.cs | 4 +- .../Data/Objects/ELinq/OrderByLifter.cs | 2 +- .../Data/Objects/ELinq/ReflectionUtil.cs | 2 +- .../ELinq/SpatialMethodCallTranslator.cs | 2 +- .../ELinq/SpatialPropertyTranslator.cs | 2 +- .../System/Data/Objects/ELinq/Translator.cs | 2 +- .../System/Data/Objects/ELinq/TypeSystem.cs | 2 +- .../System/Data/Objects/EntityEntry.cs | 4 +- .../System/Data/Objects/EntityFunctions.cs | 4 +- .../System/Data/Objects/FieldDescriptor.cs | 4 +- .../Objects/Internal/BaseEntityWrapper.cs | 4 +- .../Internal/ComplexTypeMaterializer.cs | 4 +- .../Objects/Internal/EntityProxyFactory.cs | 4 +- .../Objects/Internal/EntityProxyTypeInfo.cs | 4 +- .../Objects/Internal/EntitySqlQueryBuilder.cs | 2 +- .../Objects/Internal/EntitySqlQueryState.cs | 2 +- .../Data/Objects/Internal/EntityWrapper.cs | 4 +- .../Objects/Internal/EntityWrapperFactory.cs | 4 +- .../Data/Objects/Internal/LazyLoadBehavior.cs | 4 +- .../Internal/LightweightEntityWrapper.cs | 4 +- .../Objects/Internal/NullEntityWrapper.cs | 4 +- .../Internal/ObjectFullSpanRewriter.cs | 4 +- .../Internal/ObjectQueryExecutionPlan.cs | 2 +- .../Data/Objects/Internal/ObjectQueryState.cs | 2 +- .../Objects/Internal/ObjectSpanRewriter.cs | 4 +- .../Objects/Internal/TransactionManager.cs | 4 +- .../System/Data/Objects/ObjectContext.cs | 12 +- .../Objects/ObjectMaterializedEventArgs.cs | 4 +- .../System/Data/Objects/ObjectParameter.cs | 4 +- .../Data/Objects/ObjectParameterCollection.cs | 4 +- .../System/Data/Objects/ObjectQuery.cs | 4 +- .../ObjectQuery_EntitySqlExtensions.cs | 4 +- .../Data/Objects/ObjectQuery_TResultType.cs | 4 +- .../System/Data/Objects/ObjectResult.cs | 4 +- .../Data/Objects/ObjectResult_TResultType.cs | 4 +- .../System/Data/Objects/ObjectSet.cs | 4 +- .../System/Data/Objects/ObjectStateEntry.cs | 4 +- ...ObjectStateEntryBaseUpdatableDataRecord.cs | 4 +- .../Objects/ObjectStateEntryDbDataRecord.cs | 4 +- .../ObjectStateEntryDbUpdatableDataRecord.cs | 4 +- ...StateEntryOriginalDbUpdatableDataRecord.cs | 4 +- .../System/Data/Objects/ObjectStateManager.cs | 8 +- .../Objects/ObjectStateManagerMetadata.cs | 4 +- .../System/Data/Objects/ObjectView.cs | 4 +- .../Objects/ObjectViewEntityCollectionData.cs | 4 +- .../System/Data/Objects/ObjectViewFactory.cs | 4 +- .../System/Data/Objects/ObjectViewListener.cs | 4 +- .../Data/Objects/ObjectViewQueryResultData.cs | 4 +- .../Data/Objects/ProxyDataContractResolver.cs | 4 +- .../System/Data/Objects/RelationshipEntry.cs | 4 +- .../Data/Objects/RelationshipWrapper.cs | 4 +- .../System/Data/Objects/Span.cs | 4 +- .../System/Data/Objects/SpanIndex.cs | 4 +- .../Data/Objects/SqlClient/SqlFunctions.cs | 4 +- .../Objects/SqlClient/SqlSpatialFunctions.cs | 4 +- .../Data/OptimisticConcurrencyException.cs | 2 +- .../Data/PropertyConstraintException.cs | 4 +- .../Data/ProviderIncompatibleException.cs | 4 +- .../Data/Query/InternalTrees/AncillaryOps.cs | 4 +- .../Data/Query/InternalTrees/ColumnMap.cs | 4 +- .../Query/InternalTrees/ColumnMapCopier.cs | 4 +- .../Query/InternalTrees/ColumnMapFactory.cs | 4 +- .../Query/InternalTrees/ColumnMapVisitor.cs | 4 +- .../Data/Query/InternalTrees/Command.cs | 4 +- .../System/Data/Query/InternalTrees/Dump.cs | 4 +- .../InternalTrees/ExplicitDiscriminatorMap.cs | 4 +- .../Data/Query/InternalTrees/Metadata.cs | 4 +- .../Data/Query/InternalTrees/NodeCounter.cs | 4 +- .../Data/Query/InternalTrees/NodeInfo.cs | 4 +- .../System/Data/Query/InternalTrees/Nodes.cs | 4 +- .../Data/Query/InternalTrees/OpCopier.cs | 4 +- .../System/Data/Query/InternalTrees/Ops.cs | 4 +- .../Data/Query/InternalTrees/PhysicalOps.cs | 4 +- .../System/Data/Query/InternalTrees/RelOps.cs | 4 +- .../Query/InternalTrees/RelPropertyHelper.cs | 4 +- .../System/Data/Query/InternalTrees/Rule.cs | 4 +- .../Query/InternalTrees/RulePatternOps.cs | 4 +- .../Data/Query/InternalTrees/RuleProcessor.cs | 4 +- .../Data/Query/InternalTrees/ScalarOps.cs | 4 +- .../System/Data/Query/InternalTrees/Vars.cs | 4 +- .../Data/Query/InternalTrees/Visitors.cs | 4 +- .../Query/PlanCompiler/AggregatePushdown.cs | 4 +- .../Data/Query/PlanCompiler/CTreeGenerator.cs | 6 +- .../System/Data/Query/PlanCompiler/CodeGen.cs | 4 +- .../Query/PlanCompiler/ColumnMapProcessor.cs | 4 +- .../Query/PlanCompiler/ColumnMapTranslator.cs | 4 +- .../Data/Query/PlanCompiler/CommandPlan.cs | 4 +- .../Query/PlanCompiler/ConstraintManager.cs | 4 +- .../Data/Query/PlanCompiler/ITreeGenerator.cs | 4 +- .../Query/PlanCompiler/JoinElimination.cs | 4 +- .../Data/Query/PlanCompiler/JoinGraph.cs | 4 +- .../Data/Query/PlanCompiler/KeyPullup.cs | 4 +- .../Data/Query/PlanCompiler/NestPullup.cs | 6 +- .../PlanCompiler/NominalTypeEliminator.cs | 4 +- .../Data/Query/PlanCompiler/Normalizer.cs | 4 +- .../Data/Query/PlanCompiler/PlanCompiler.cs | 4 +- .../Query/PlanCompiler/PlanCompilerUtil.cs | 4 +- .../Data/Query/PlanCompiler/PreProcessor.cs | 4 +- .../Data/Query/PlanCompiler/Predicate.cs | 4 +- .../Query/PlanCompiler/ProjectionPruner.cs | 4 +- .../PlanCompiler/PropertyPushdownHelper.cs | 4 +- .../Data/Query/PlanCompiler/PropertyRef.cs | 4 +- .../PlanCompiler/ProviderCommandInfoUtils.cs | 4 +- .../Query/PlanCompiler/StructuredTypeInfo.cs | 4 +- .../PlanCompiler/SubqueryTrackingVisitor.cs | 4 +- .../Query/PlanCompiler/TransformationRules.cs | 4 +- .../Data/Query/PlanCompiler/TypeInfo.cs | 4 +- .../Data/Query/PlanCompiler/TypeUtils.cs | 4 +- .../System/Data/Query/PlanCompiler/VarInfo.cs | 4 +- .../Data/Query/PlanCompiler/VarRefManager.cs | 4 +- .../Data/Query/PlanCompiler/VarRemapper.cs | 4 +- .../Query/ResultAssembly/BridgeDataReader.cs | 4 +- .../Query/ResultAssembly/BridgeDataRecord.cs | 4 +- .../System/Data/Spatial/DbGeography.cs | 2 +- .../Data/Spatial/DbGeographyWellKnownValue.cs | 2 +- .../System/Data/Spatial/DbGeometry.cs | 2 +- .../Data/Spatial/DbGeometryWellKnownValue.cs | 2 +- .../System/Data/Spatial/DbSpatialServices.cs | 2 +- .../Data/Spatial/DefaultSpatialServices.cs | 2 +- .../System/Data/Spatial/ExtensionMethods.cs | 2 +- .../Spatial/Internal/SpatialExceptions.cs | 2 +- .../System/Data/Spatial/SpatialHelpers.cs | 2 +- .../System/Data/SqlClient/IDbSpatialValue.cs | 2 +- .../Data/SqlClient/SqlGen/DmlSqlGenerator.cs | 4 +- .../Data/SqlClient/SqlGen/JoinSymbol.cs | 4 +- .../Data/SqlClient/SqlGen/OptionalColumn.cs | 2 +- .../SqlGen/Sql8ConformanceChecker.cs | 4 +- .../SqlGen/Sql8ExpressionRewriter.cs | 4 +- .../Data/SqlClient/SqlGen/SqlBuilder.cs | 4 +- .../SqlGen/SqlFunctionCallHandler.cs | 4 +- .../Data/SqlClient/SqlGen/SqlGenerator.cs | 6 +- .../SqlGen/SqlSelectClauseBuilder.cs | 2 +- .../SqlClient/SqlGen/SqlSelectStatement.cs | 4 +- .../System/Data/SqlClient/SqlGen/SqlWriter.cs | 4 +- .../System/Data/SqlClient/SqlGen/Symbol.cs | 4 +- .../Data/SqlClient/SqlGen/SymbolPair.cs | 4 +- .../Data/SqlClient/SqlGen/SymbolTable.cs | 4 +- .../SqlClient/SqlGen/SymbolUsageManager.cs | 2 +- .../System/Data/SqlClient/SqlGen/TopClause.cs | 4 +- .../Data/SqlClient/SqlProviderManifest.cs | 4 +- .../Data/SqlClient/SqlProviderServices.cs | 4 +- .../Data/SqlClient/SqlProviderUtilities.cs | 4 +- .../Data/SqlClient/SqlSpatialDataReader.cs | 2 +- .../SqlClient/SqlSpatialServices.Generated.cs | 2 +- .../Data/SqlClient/SqlSpatialServices.cs | 2 +- .../System/Data/SqlClient/SqlTypesAssembly.cs | 2 +- .../System/Data/SqlClient/SqlVersion.cs | 4 +- .../System/Data/UpdateException.cs | 4 +- System.Data.Entity/Util/AppSettings.cs | 2 +- System.Data.Linq/ChangeConflicts.cs | 4 +- System.Data.Linq/ChangeDirector.cs | 22 +- System.Data.Linq/ChangeProcessor.cs | 4 +- System.Data.Linq/ChangeTracker.cs | 2 +- System.Data.Linq/CompiledQuery.cs | 32 +- System.Data.Linq/DataContext.cs | 20 +- System.Data.Linq/DataShape.cs | 8 +- System.Data.Linq/DbConvert.cs | 4 +- System.Data.Linq/Mapping/MetaModel.cs | 2 +- System.Data.Linq/Provider/IProvider.cs | 28 +- .../SqlClient/Common/SqlVisitor.cs | 2 +- .../SqlClient/Query/Funcletizer.cs | 2 +- .../SqlClient/Query/QueryConverter.cs | 2 +- System.Data.Linq/SqlClient/Query/SqlBinder.cs | 2 +- .../SqlClient/Query/SqlComparer.cs | 2 +- .../SqlClient/Query/SqlDeflator.cs | 2 +- .../SqlClient/Query/SqlFlattener.cs | 2 +- .../SqlClient/Query/SqlMethodCallConverter.cs | 6 +- .../SqlClient/Reader/ObjectReaderCompiler.cs | 28 +- System.Data.Linq/SqlClient/SqlMethods.cs | 16 +- System.Data.Linq/SqlClient/SqlProvider.cs | 4 +- .../SqlClient/SqlTypeSystemProvider.cs | 2 +- System.Data.Linq/Types.cs | 18 +- System.Data.Linq/misc/SecurityUtils.cs | 6 +- .../System/Xml/Xsl/IlGen/GenerateHelper.cs | 2 +- .../Xml/Xsl/IlGen/IteratorDescriptor.cs | 2 +- .../System/Xml/Xsl/IlGen/OptimizerPatterns.cs | 2 +- .../System/Xml/Xsl/IlGen/StaticDataManager.cs | 4 +- .../System/Xml/Xsl/IlGen/TailCallAnalyzer.cs | 2 +- .../System/Xml/Xsl/IlGen/XmlILAnnotation.cs | 2 +- .../Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs | 2 +- .../System/Xml/Xsl/IlGen/XmlILModule.cs | 4 +- .../Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs | 2 +- .../System/Xml/Xsl/IlGen/XmlIlTypeHelper.cs | 2 +- .../System/Xml/Xsl/IlGen/XmlIlVisitor.cs | 2 +- System.Data.SqlXml/System/Xml/Xsl/ListBase.cs | 2 +- System.Data.SqlXml/System/Xml/Xsl/Pair.cs | 2 +- .../System/Xml/Xsl/QIL/QilBinary.cs | 2 +- .../System/Xml/Xsl/QIL/QilChoice.cs | 2 +- .../System/Xml/Xsl/QIL/QilCloneVisitor.cs | 2 +- .../System/Xml/Xsl/QIL/QilDataSource.cs | 2 +- .../System/Xml/Xsl/QIL/QilExpression.cs | 2 +- .../System/Xml/Xsl/QIL/QilFactory.cs | 2 +- .../System/Xml/Xsl/QIL/QilFunction.cs | 2 +- .../System/Xml/Xsl/QIL/QilInvoke.cs | 2 +- .../System/Xml/Xsl/QIL/QilInvokeEarlyBound.cs | 2 +- .../System/Xml/Xsl/QIL/QilInvokeLateBound.cs | 2 +- .../System/Xml/Xsl/QIL/QilIterator.cs | 2 +- .../System/Xml/Xsl/QIL/QilList.cs | 2 +- .../System/Xml/Xsl/QIL/QilLiteral.cs | 2 +- .../System/Xml/Xsl/QIL/QilLoop.cs | 2 +- .../System/Xml/Xsl/QIL/QilName.cs | 2 +- .../System/Xml/Xsl/QIL/QilNode.cs | 2 +- .../System/Xml/Xsl/QIL/QilParameter.cs | 2 +- .../System/Xml/Xsl/QIL/QilPatternFactory.cs | 2 +- .../System/Xml/Xsl/QIL/QilPatternVisitor.cs | 2 +- .../System/Xml/Xsl/QIL/QilReference.cs | 2 +- .../System/Xml/Xsl/QIL/QilReplaceVisitor.cs | 2 +- .../System/Xml/Xsl/QIL/QilScopedVisitor.cs | 2 +- .../System/Xml/Xsl/QIL/QilSortKey.cs | 2 +- .../System/Xml/Xsl/QIL/QilStrConcat.cs | 2 +- .../System/Xml/Xsl/QIL/QilTargetType.cs | 2 +- .../System/Xml/Xsl/QIL/QilTernary.cs | 2 +- .../System/Xml/Xsl/QIL/QilTypeChecker.cs | 2 +- .../System/Xml/Xsl/QIL/QilUnary.cs | 2 +- .../Xml/Xsl/QIL/QilValidationVisitor.cs | 2 +- .../System/Xml/Xsl/QIL/QilVisitor.cs | 2 +- .../System/Xml/Xsl/QIL/QilXmlReader.cs | 2 +- .../System/Xml/Xsl/QIL/QilXmlWriter.cs | 2 +- .../System/Xml/Xsl/QIL/SubstitutionList.cs | 2 +- .../System/Xml/Xsl/QIL/WhitespaceRule.cs | 4 +- .../System/Xml/Xsl/QueryReaderSettings.cs | 2 +- .../Xml/Xsl/Runtime/ContentIterators.cs | 2 +- .../Xml/Xsl/Runtime/DecimalFormatter.cs | 2 +- .../Xml/Xsl/Runtime/DocumentOrderComparer.cs | 2 +- .../Xml/Xsl/Runtime/DodSequenceMerge.cs | 2 +- .../System/Xml/Xsl/Runtime/EarlyBoundInfo.cs | 4 +- .../System/Xml/Xsl/Runtime/NumberFormatter.cs | 2 +- .../System/Xml/Xsl/Runtime/RtfNavigator.cs | 2 +- .../System/Xml/Xsl/Runtime/SetIterators.cs | 2 +- .../Xml/Xsl/Runtime/SiblingIterators.cs | 2 +- .../System/Xml/Xsl/Runtime/StringConcat.cs | 2 +- .../System/Xml/Xsl/Runtime/TreeIterators.cs | 2 +- .../Xml/Xsl/Runtime/WhitespaceRuleLookup.cs | 2 +- .../Xml/Xsl/Runtime/WhitespaceRuleReader.cs | 2 +- .../System/Xml/Xsl/Runtime/XmlAggregates.cs | 2 +- .../Xml/Xsl/Runtime/XmlAttributeCache.cs | 2 +- .../System/Xml/Xsl/Runtime/XmlCollation.cs | 2 +- .../Xml/Xsl/Runtime/XmlExtensionFunction.cs | 2 +- .../System/Xml/Xsl/Runtime/XmlILIndex.cs | 2 +- .../Xml/Xsl/Runtime/XmlILStorageConverter.cs | 2 +- .../System/Xml/Xsl/Runtime/XmlIterators.cs | 2 +- .../Xml/Xsl/Runtime/XmlNavigatorFilter.cs | 2 +- .../Xml/Xsl/Runtime/XmlNavigatorStack.cs | 2 +- .../System/Xml/Xsl/Runtime/XmlQueryContext.cs | 2 +- .../System/Xml/Xsl/Runtime/XmlQueryOutput.cs | 2 +- .../System/Xml/Xsl/Runtime/XmlQueryRuntime.cs | 2 +- .../Xml/Xsl/Runtime/XmlQuerySequence.cs | 2 +- .../Xml/Xsl/Runtime/XmlQueryStaticData.cs | 2 +- .../Xml/Xsl/Runtime/XmlRawWriterWrapper.cs | 2 +- .../Xml/Xsl/Runtime/XmlSequenceWriter.cs | 2 +- .../System/Xml/Xsl/Runtime/XmlSortKey.cs | 2 +- .../Xml/Xsl/Runtime/XmlSortKeyAccumulator.cs | 2 +- .../System/Xml/Xsl/Runtime/XslNumber.cs | 2 +- .../System/Xml/Xsl/Runtime/XsltConvert.cs | 2 +- .../System/Xml/Xsl/Runtime/XsltFunctions.cs | 2 +- .../System/Xml/Xsl/Runtime/XsltLibrary.cs | 2 +- .../System/Xml/Xsl/SourceLineInfo.cs | 2 +- .../System/Xml/Xsl/XPath/XPathBuilder.cs | 2 +- .../Xml/Xsl/XPath/XPathCompileException.cs | 2 +- .../System/Xml/Xsl/XPath/XPathParser.cs | 2 +- .../System/Xml/Xsl/XPath/XPathQilFactory.cs | 2 +- .../System/Xml/Xsl/XPath/XPathScanner.cs | 2 +- .../System/Xml/Xsl/XPathConvert.cs | 2 +- .../System/Xml/Xsl/XmlILCommand.cs | 4 +- .../System/Xml/Xsl/XmlIlGenerator.cs | 4 +- .../System/Xml/Xsl/XmlQualifiedNameTest.cs | 2 +- .../System/Xml/Xsl/XmlQueryCardinality.cs | 2 +- .../System/Xml/Xsl/XmlQueryType.cs | 4 +- .../System/Xml/Xsl/XmlQueryTypeFactory.cs | 4 +- .../System/Xml/Xsl/XslException.cs | 2 +- .../System/Xml/Xsl/Xslt/Compiler.cs | 2 +- .../Xml/Xsl/Xslt/CompilerScopeManager.cs | 2 +- .../System/Xml/Xsl/Xslt/Focus.cs | 2 +- .../System/Xml/Xsl/Xslt/InvokeGenerator.cs | 2 +- .../System/Xml/Xsl/Xslt/KeyMatchBuilder.cs | 2 +- .../System/Xml/Xsl/Xslt/Keywords.cs | 2 +- .../System/Xml/Xsl/Xslt/MatcherBuilder.cs | 2 +- .../System/Xml/Xsl/Xslt/OutputScopeManager.cs | 2 +- .../System/Xml/Xsl/Xslt/QilGenerator.cs | 2 +- .../System/Xml/Xsl/Xslt/QilGeneratorEnv.cs | 2 +- .../System/Xml/Xsl/Xslt/QilStrConcatenator.cs | 2 +- .../System/Xml/Xsl/Xslt/Scripts.cs | 4 +- .../System/Xml/Xsl/Xslt/Stylesheet.cs | 2 +- .../Xml/Xsl/Xslt/XPathPatternBuilder.cs | 2 +- .../System/Xml/Xsl/Xslt/XPathPatternParser.cs | 2 +- .../System/Xml/Xsl/Xslt/XslAst.cs | 2 +- .../System/Xml/Xsl/Xslt/XslAstAnalyzer.cs | 4 +- .../System/Xml/Xsl/Xslt/XslVisitor.cs | 2 +- .../System/Xml/Xsl/Xslt/XsltInput.cs | 2 +- .../System/Xml/Xsl/Xslt/XsltLoader.cs | 2 +- .../System/Xml/Xsl/Xslt/XsltQilFactory.cs | 2 +- .../System/Xml/Xsl/XsltOld/Action.cs | 2 +- .../System/Xml/Xsl/XsltOld/ActionFrame.cs | 2 +- .../Xml/Xsl/XsltOld/ApplyImportsAction.cs | 2 +- .../Xml/Xsl/XsltOld/ApplyTemplatesAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/AttributeAction.cs | 2 +- .../Xml/Xsl/XsltOld/AttributeSetAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/Avt.cs | 2 +- .../System/Xml/Xsl/XsltOld/AvtEvent.cs | 2 +- .../System/Xml/Xsl/XsltOld/BeginEvent.cs | 2 +- .../System/Xml/Xsl/XsltOld/BuilderInfo.cs | 2 +- .../Xml/Xsl/XsltOld/CallTemplateAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/ChooseAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/CommentAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/CompiledAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/Compiler.cs | 2 +- .../System/Xml/Xsl/XsltOld/ContainerAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/CopyAction.cs | 2 +- .../Xml/Xsl/XsltOld/CopyAttributesAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/CopyCodeAction.cs | 2 +- .../Xml/Xsl/XsltOld/CopyNamespacesAction.cs | 2 +- .../Xml/Xsl/XsltOld/CopyNodesetAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/CopyOfAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/DbgCompiler.cs | 2 +- .../System/Xml/Xsl/XsltOld/DocumentScope.cs | 2 +- .../System/Xml/Xsl/XsltOld/ElementAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/EndEvent.cs | 2 +- .../System/Xml/Xsl/XsltOld/Event.cs | 2 +- .../System/Xml/Xsl/XsltOld/ForeachAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/HtmlProps.cs | 2 +- .../System/Xml/Xsl/XsltOld/IfAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/InputScope.cs | 2 +- .../Xml/Xsl/XsltOld/InputScopeManager.cs | 2 +- .../System/Xml/Xsl/XsltOld/MessageAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/NamespaceDecl.cs | 2 +- .../System/Xml/Xsl/XsltOld/NamespaceEvent.cs | 2 +- .../System/Xml/Xsl/XsltOld/NavigatorInput.cs | 2 +- .../System/Xml/Xsl/XsltOld/NavigatorOutput.cs | 2 +- .../Xml/Xsl/XsltOld/NewInstructionAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/NumberAction.cs | 4 +- .../System/Xml/Xsl/XsltOld/OutKeywords.cs | 2 +- .../System/Xml/Xsl/XsltOld/OutputScope.cs | 2 +- .../Xml/Xsl/XsltOld/OutputScopeManager.cs | 2 +- .../System/Xml/Xsl/XsltOld/PrefixQname.cs | 2 +- .../XsltOld/ProcessingInstructionAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/Processor.cs | 2 +- .../System/Xml/Xsl/XsltOld/ReaderOutput.cs | 2 +- .../System/Xml/Xsl/XsltOld/RecordBuilder.cs | 2 +- .../System/Xml/Xsl/XsltOld/RootAction.cs | 2 +- .../Xml/Xsl/XsltOld/SequentialOutput.cs | 2 +- .../System/Xml/Xsl/XsltOld/SortAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/StateMachine.cs | 2 +- .../System/Xml/Xsl/XsltOld/StringOutput.cs | 2 +- .../System/Xml/Xsl/XsltOld/Stylesheet.cs | 2 +- .../System/Xml/Xsl/XsltOld/TemplateAction.cs | 2 +- .../Xml/Xsl/XsltOld/TemplateBaseAction.cs | 2 +- .../Xml/Xsl/XsltOld/TemplateLookupAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/Templatemanager.cs | 2 +- .../System/Xml/Xsl/XsltOld/TextAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/TextEvent.cs | 2 +- .../System/Xml/Xsl/XsltOld/TextOnlyOutput.cs | 2 +- .../System/Xml/Xsl/XsltOld/TextOutput.cs | 2 +- .../System/Xml/Xsl/XsltOld/TheQuery.cs | 2 +- .../Xml/Xsl/XsltOld/UseAttributesetsAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/ValueOfAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/VariableAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/WithParamAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/WriterOutput.cs | 2 +- .../Xml/Xsl/XsltOld/XsltCompileContext.cs | 4 +- .../System/Xml/Xsl/XsltOld/XsltOutput.cs | 2 +- .../SqlServer/Server/MemoryRecordBuffer.cs | 6 +- .../SqlServer/Server/MetadataUtilsSmi.cs | 4 +- .../SqlServer/Server/SmiConnection.cs | 4 +- .../Microsoft/SqlServer/Server/SmiContext.cs | 4 +- .../SqlServer/Server/SmiContextFactory.cs | 4 +- .../SqlServer/Server/SmiEventSink.cs | 4 +- .../SqlServer/Server/SmiEventSink_Default.cs | 4 +- .../Server/SmiEventSink_DeferedProcessing.cs | 4 +- .../SqlServer/Server/SmiEventStream.cs | 4 +- .../SqlServer/Server/SmiGettersStream.cs | 4 +- .../Microsoft/SqlServer/Server/SmiMetaData.cs | 4 +- .../SqlServer/Server/SmiMetaDataProperty.cs | 4 +- .../SqlServer/Server/SmiRecordBuffer.cs | 4 +- .../SqlServer/Server/SmiRequestExecutor.cs | 4 +- .../SqlServer/Server/SmiSettersStream.cs | 4 +- .../SqlServer/Server/SmiTypedGetterSetter.cs | 4 +- .../SqlServer/Server/SmiXetterAccessMap.cs | 4 +- .../SqlServer/Server/SqlDataRecord.cs | 8 +- .../SqlServer/Server/SqlRecordBuffer.cs | 6 +- .../SqlServer/Server/SqlTriggerContext.cs | 4 +- .../SqlServer/Server/ValueUtilsSmi.cs | 4 +- .../Microsoft/SqlServer/Server/sqlcontext.cs | 4 +- .../Microsoft/SqlServer/Server/sqlpipe.cs | 4 +- System.Data/System/Data/BaseCollection.cs | 6 +- .../Data/CodeGen/StrongTypingException.cs | 6 +- System.Data/System/Data/CodeGen/datacache.cs | 8 +- .../System/Data/ColumnTypeConverter.cs | 6 +- .../System/Data/Common/ActivityCorrelator.cs | 2 +- System.Data/System/Data/Common/AdapterUtil.cs | 46 +- .../System/Data/Common/BigIntegerStorage.cs | 4 +- .../System/Data/Common/BooleanStorage.cs | 6 +- System.Data/System/Data/Common/ByteStorage.cs | 6 +- System.Data/System/Data/Common/CharStorage.cs | 6 +- System.Data/System/Data/Common/DBCommand.cs | 4 +- .../System/Data/Common/DBCommandBuilder.cs | 4 +- .../System/Data/Common/DBConnection.cs | 6 +- .../System/Data/Common/DBConnectionString.cs | 6 +- .../System/Data/Common/DBDataPermission.cs | 4 +- .../Data/Common/DBDataPermissionAttribute.cs | 4 +- System.Data/System/Data/Common/DBParameter.cs | 4 +- System.Data/System/Data/Common/DBSchemaRow.cs | 4 +- .../System/Data/Common/DBSchemaTable.cs | 4 +- System.Data/System/Data/Common/DataAdapter.cs | 4 +- .../System/Data/Common/DataColumnMapping.cs | 4 +- .../Common/DataColumnMappingCollection.cs | 4 +- .../System/Data/Common/DataRecordInternal.cs | 4 +- System.Data/System/Data/Common/DataStorage.cs | 4 +- .../System/Data/Common/DataTableMapping.cs | 4 +- .../Data/Common/DataTableMappingCollection.cs | 4 +- .../Data/Common/DateTimeOffsetStorage.cs | 4 +- .../System/Data/Common/DateTimeStorage.cs | 6 +- .../System/Data/Common/DbConnectionOptions.cs | 4 +- .../System/Data/Common/DbConnectionPoolKey.cs | 4 +- .../Data/Common/DbConnectionStringBuilder.cs | 4 +- .../Data/Common/DbConnectionStringCommon.cs | 4 +- .../System/Data/Common/DbDataAdapter.cs | 4 +- .../System/Data/Common/DbDataReader.cs | 4 +- .../Data/Common/DbDataSourceEnumerator.cs | 4 +- System.Data/System/Data/Common/DbException.cs | 4 +- .../Data/Common/DbParameterCollection.cs | 4 +- .../Common/DbProviderConfigurationHandler.cs | 4 +- .../System/Data/Common/DbProviderFactories.cs | 4 +- ...DbProviderFactoriesConfigurationHandler.cs | 4 +- .../System/Data/Common/DbProviderFactory.cs | 4 +- ...DbProviderSpecificTypePropertyAttribute.cs | 4 +- .../System/Data/Common/DbTransaction.cs | 4 +- .../System/Data/Common/DecimalStorage.cs | 6 +- .../System/Data/Common/DoubleStorage.cs | 6 +- .../System/Data/Common/FieldNameLookup.cs | 4 +- .../System/Data/Common/GreenMethods.cs | 4 +- System.Data/System/Data/Common/HandlerBase.cs | 4 +- .../System/Data/Common/Int16Storage.cs | 6 +- .../System/Data/Common/Int32Storage.cs | 6 +- .../System/Data/Common/Int64Storage.cs | 6 +- .../System/Data/Common/MultipartIdentifier.cs | 4 +- .../System/Data/Common/NameValuePair.cs | 4 +- .../System/Data/Common/NameValuePermission.cs | 4 +- .../System/Data/Common/ObjectStorage.cs | 4 +- .../System/Data/Common/RowUpdatedEventArgs.cs | 4 +- .../Data/Common/RowUpdatingEventArgs.cs | 4 +- .../System/Data/Common/SByteStorage.cs | 6 +- System.Data/System/Data/Common/SQLConvert.cs | 4 +- .../Data/Common/SQLTypes/SQLBinaryStorage.cs | 6 +- .../Data/Common/SQLTypes/SQLByteStorage.cs | 6 +- .../Data/Common/SQLTypes/SQLBytesStorage.cs | 6 +- .../Data/Common/SQLTypes/SQLCharsStorage.cs | 6 +- .../Common/SQLTypes/SQLDateTimeStorage.cs | 6 +- .../Data/Common/SQLTypes/SQLDecimalStorage.cs | 6 +- .../Data/Common/SQLTypes/SQLDoubleStorage.cs | 6 +- .../Data/Common/SQLTypes/SQLGuidStorage.cs | 6 +- .../Data/Common/SQLTypes/SQLInt16Storage.cs | 6 +- .../Data/Common/SQLTypes/SQLInt32Storage.cs | 6 +- .../Data/Common/SQLTypes/SQLInt64Storage.cs | 6 +- .../Data/Common/SQLTypes/SQLMoneyStorage.cs | 6 +- .../Data/Common/SQLTypes/SQLSingleStorage.cs | 6 +- .../Data/Common/SQLTypes/SQLStringStorage.cs | 6 +- .../Data/Common/SQLTypes/SQlBooleanStorage.cs | 6 +- .../Data/Common/SQLTypes/SqlUDTStorage.cs | 6 +- .../Data/Common/SQLTypes/SqlXmlStorage.cs | 6 +- .../System/Data/Common/SafeNativeMethods.cs | 6 +- .../System/Data/Common/SchemaTableColumn.cs | 2 +- .../Data/Common/SchemaTableOptionalColumn.cs | 2 +- .../System/Data/Common/SingleStorage.cs | 6 +- .../System/Data/Common/StringStorage.cs | 6 +- .../System/Data/Common/System.Data_BID.cs | 4 +- .../System/Data/Common/TimeSpanStorage.cs | 6 +- .../System/Data/Common/UInt16Storage.cs | 8 +- .../System/Data/Common/UInt32Storage.cs | 8 +- .../System/Data/Common/UInt64Storage.cs | 8 +- .../System/Data/Common/UnsafeNativeMethods.cs | 6 +- .../System/Data/Common/dbdatarecord.cs | 4 +- .../System/Data/Common/dbenumerator.cs | 4 +- System.Data/System/Data/Constraint.cs | 6 +- .../System/Data/ConstraintCollection.cs | 6 +- .../System/Data/ConstraintConverter.cs | 6 +- .../System/Data/ConstraintEnumerator.cs | 6 +- .../System/Data/DBConcurrencyException.cs | 4 +- System.Data/System/Data/DataColumn.cs | 4 +- .../System/Data/DataColumnChangeEvent.cs | 6 +- .../System/Data/DataColumnCollection.cs | 6 +- .../Data/DataColumnPropertyDescriptor.cs | 6 +- System.Data/System/Data/DataError.cs | 6 +- System.Data/System/Data/DataException.cs | 6 +- System.Data/System/Data/DataKey.cs | 6 +- System.Data/System/Data/DataRelation.cs | 6 +- .../System/Data/DataRelationCollection.cs | 8 +- .../Data/DataRelationPropertyDescriptor.cs | 6 +- System.Data/System/Data/DataRow.cs | 4 +- System.Data/System/Data/DataRowChangeEvent.cs | 6 +- System.Data/System/Data/DataRowCollection.cs | 6 +- System.Data/System/Data/DataRowView.cs | 4 +- System.Data/System/Data/DataSet.cs | 8 +- System.Data/System/Data/DataSysAttribute.cs | 4 +- System.Data/System/Data/DataTable.cs | 16 +- .../System/Data/DataTableClearEvent.cs | 4 +- .../System/Data/DataTableCollection.cs | 6 +- .../System/Data/DataTableNewRowEvent.cs | 4 +- .../Data/DataTablePropertyDescriptor.cs | 6 +- System.Data/System/Data/DataTableReader.cs | 6 +- .../System/Data/DataTableReaderListener.cs | 4 +- .../System/Data/DataTableTypeConverter.cs | 6 +- System.Data/System/Data/DataView.cs | 10 +- System.Data/System/Data/DataViewListener.cs | 4 +- System.Data/System/Data/DataViewManager.cs | 8 +- .../DataViewManagerListItemTypeDescriptor.cs | 6 +- System.Data/System/Data/DataViewSetting.cs | 6 +- .../System/Data/DataViewSettingCollection.cs | 6 +- .../System/Data/DefaultValueTypeConverter.cs | 6 +- System.Data/System/Data/FillErrorEventArgs.cs | 4 +- .../System/Data/Filter/AggregateNode.cs | 4 +- System.Data/System/Data/Filter/BinaryNode.cs | 6 +- System.Data/System/Data/Filter/ConstNode.cs | 6 +- .../System/Data/Filter/DataExpression.cs | 6 +- .../System/Data/Filter/ExpressionNode.cs | 6 +- .../System/Data/Filter/ExpressionParser.cs | 6 +- .../System/Data/Filter/FilterException.cs | 6 +- .../System/Data/Filter/FunctionNode.cs | 6 +- System.Data/System/Data/Filter/LookupNode.cs | 8 +- System.Data/System/Data/Filter/NameNode.cs | 6 +- System.Data/System/Data/Filter/Operators.cs | 6 +- System.Data/System/Data/Filter/UnaryNode.cs | 6 +- System.Data/System/Data/Filter/ZeroOpNode.cs | 6 +- .../System/Data/ForeignKeyConstraint.cs | 6 +- System.Data/System/Data/MergeFailedEvent.cs | 6 +- System.Data/System/Data/Merger.cs | 4 +- System.Data/System/Data/Odbc/DbDataRecord.cs | 4 +- System.Data/System/Data/Odbc/Odbc32.cs | 4 +- System.Data/System/Data/Odbc/OdbcCommand.cs | 4 +- .../System/Data/Odbc/OdbcCommandBuilder.cs | 4 +- .../System/Data/Odbc/OdbcConnection.cs | 4 +- .../System/Data/Odbc/OdbcConnectionFactory.cs | 4 +- .../System/Data/Odbc/OdbcConnectionHandle.cs | 4 +- .../System/Data/Odbc/OdbcConnectionOpen.cs | 4 +- .../Odbc/OdbcConnectionPoolProviderInfo.cs | 4 +- .../System/Data/Odbc/OdbcConnectionString.cs | 4 +- .../Data/Odbc/OdbcConnectionStringbuilder.cs | 4 +- .../System/Data/Odbc/OdbcDataAdapter.cs | 4 +- .../System/Data/Odbc/OdbcDataReader.cs | 4 +- .../System/Data/Odbc/OdbcEnvironment.cs | 4 +- .../System/Data/Odbc/OdbcEnvironmentHandle.cs | 4 +- System.Data/System/Data/Odbc/OdbcError.cs | 4 +- .../System/Data/Odbc/OdbcErrorCollection.cs | 4 +- System.Data/System/Data/Odbc/OdbcException.cs | 4 +- System.Data/System/Data/Odbc/OdbcFactory.cs | 4 +- System.Data/System/Data/Odbc/OdbcHandle.cs | 4 +- .../System/Data/Odbc/OdbcInfoMessageEvent.cs | 4 +- System.Data/System/Data/Odbc/OdbcParameter.cs | 8 +- .../Data/Odbc/OdbcParameterCollection.cs | 4 +- .../System/Data/Odbc/OdbcPermission.cs | 4 +- .../Data/Odbc/OdbcReferenceCollection.cs | 4 +- .../System/Data/Odbc/OdbcRowUpdatingEvent.cs | 4 +- .../System/Data/Odbc/OdbcStatementHandle.cs | 4 +- .../System/Data/Odbc/OdbcTransaction.cs | 4 +- System.Data/System/Data/Odbc/OdbcUtils.cs | 4 +- .../Data/Odbc/odbcmetadatacollectionnames.cs | 4 +- .../Data/Odbc/odbcmetadatacolumnnames.cs | 4 +- .../System/Data/Odbc/odbcmetadatafactory.cs | 4 +- .../System/Data/OleDb/ColumnBinding.cs | 4 +- System.Data/System/Data/OleDb/DBBindings.cs | 4 +- System.Data/System/Data/OleDb/DBPropSet.cs | 4 +- System.Data/System/Data/OleDb/OLEDB_Enum.cs | 4 +- System.Data/System/Data/OleDb/OLEDB_Util.cs | 4 +- System.Data/System/Data/OleDb/OleDbCommand.cs | 4 +- .../System/Data/OleDb/OleDbCommandBuilder.cs | 4 +- .../System/Data/OleDb/OleDbConnection.cs | 4 +- .../Data/OleDb/OleDbConnectionFactory.cs | 4 +- .../Data/OleDb/OleDbConnectionInternal.cs | 4 +- .../OleDbConnectionPoolGroupProviderInfo.cs | 2 +- .../System/Data/OleDb/OleDbDataAdapter.cs | 4 +- .../System/Data/OleDb/OleDbDataReader.cs | 6 +- .../System/Data/OleDb/OleDbEnumerator.cs | 4 +- System.Data/System/Data/OleDb/OleDbError.cs | 4 +- .../System/Data/OleDb/OleDbErrorCollection.cs | 4 +- .../System/Data/OleDb/OleDbException.cs | 4 +- System.Data/System/Data/OleDb/OleDbFactory.cs | 4 +- .../Data/OleDb/OleDbInfoMessageEvent.cs | 4 +- .../System/Data/OleDb/OleDbMetaDataFactory.cs | 2 +- .../System/Data/OleDb/OleDbParameter.cs | 4 +- .../Data/OleDb/OleDbParameterCollection.cs | 4 +- .../System/Data/OleDb/OleDbPermission.cs | 4 +- .../System/Data/OleDb/OleDbPropertySetGuid.cs | 4 +- .../Data/OleDb/OleDbReferenceCollection.cs | 4 +- .../System/Data/OleDb/OleDbRowUpdatedEvent.cs | 4 +- .../Data/OleDb/OleDbRowUpdatingEvent.cs | 4 +- .../System/Data/OleDb/OleDbSchemaGuid.cs | 4 +- System.Data/System/Data/OleDb/OleDbStruct.cs | 4 +- .../System/Data/OleDb/OleDbTransaction.cs | 4 +- System.Data/System/Data/OleDb/OleDbWrapper.cs | 4 +- .../OleDb/OledbConnectionStringbuilder.cs | 4 +- .../System/Data/OleDb/PropertyIDSet.cs | 4 +- .../System/Data/OleDb/PropertyInfoSet.cs | 4 +- System.Data/System/Data/OleDb/RowBinding.cs | 4 +- System.Data/System/Data/OleDb/SafeHandles.cs | 4 +- .../Data/OleDb/oledbconnectionstring.cs | 4 +- .../OleDb/oledbmetadatacollectionnames.cs | 4 +- .../Data/OleDb/oledbmetadatacolumnnames.cs | 4 +- .../System/Data/OperationAbortedException.cs | 4 +- .../System/Data/PrimaryKeyTypeConverter.cs | 6 +- System.Data/System/Data/PropertyCollection.cs | 6 +- .../Data/ProviderBase/DataReaderContainer.cs | 2 +- .../System/Data/ProviderBase/DbBuffer.cs | 2 +- .../Data/ProviderBase/DbConnectionClosed.cs | 4 +- .../Data/ProviderBase/DbConnectionFactory.cs | 4 +- .../Data/ProviderBase/DbConnectionHelper.cs | 2 +- .../Data/ProviderBase/DbConnectionInternal.cs | 8 +- .../Data/ProviderBase/DbConnectionPool.cs | 42 +- .../ProviderBase/DbConnectionPoolCounters.cs | 2 +- .../ProviderBase/DbConnectionPoolGroup.cs | 2 +- .../DbConnectionPoolGroupProviderInfo.cs | 4 +- .../ProviderBase/DbConnectionPoolIdentity.cs | 2 +- .../ProviderBase/DbConnectionPoolOptions.cs | 2 +- .../ProviderBase/DbMetaDataCollectionNames.cs | 4 +- .../ProviderBase/DbMetaDataColumnNames.cs | 4 +- .../Data/ProviderBase/DbMetaDataFactory.cs | 4 +- .../DbParameterCollectionHelper.cs | 2 +- .../Data/ProviderBase/DbParameterHelper.cs | 2 +- .../ProviderBase/DbReferenceCollection.cs | 4 +- .../System/Data/ProviderBase/SchemaMapping.cs | 2 +- .../System/Data/ProviderBase/TimeoutTimer.cs | 4 +- .../Data/ProviderBase/WrappedIUnknown.cs | 4 +- System.Data/System/Data/Range.cs | 6 +- System.Data/System/Data/RbTree.cs | 4 +- System.Data/System/Data/RecordManager.cs | 4 +- .../System/Data/RecordsAffectedEventArgs.cs | 4 +- System.Data/System/Data/RelatedView.cs | 4 +- .../System/Data/RelationshipConverter.cs | 6 +- System.Data/System/Data/SQLTypes/SQLBinary.cs | 4 +- .../System/Data/SQLTypes/SQLBoolean.cs | 4 +- System.Data/System/Data/SQLTypes/SQLByte.cs | 6 +- System.Data/System/Data/SQLTypes/SQLBytes.cs | 4 +- System.Data/System/Data/SQLTypes/SQLChars.cs | 4 +- .../System/Data/SQLTypes/SQLDateTime.cs | 30 +- .../System/Data/SQLTypes/SQLDecimal.cs | 92 +- System.Data/System/Data/SQLTypes/SQLDouble.cs | 4 +- .../System/Data/SQLTypes/SQLFileStream.cs | 8 +- System.Data/System/Data/SQLTypes/SQLGuid.cs | 6 +- System.Data/System/Data/SQLTypes/SQLInt16.cs | 6 +- System.Data/System/Data/SQLTypes/SQLInt32.cs | 8 +- System.Data/System/Data/SQLTypes/SQLInt64.cs | 8 +- System.Data/System/Data/SQLTypes/SQLMoney.cs | 14 +- .../System/Data/SQLTypes/SQLResource.cs | 4 +- System.Data/System/Data/SQLTypes/SQLSingle.cs | 4 +- System.Data/System/Data/SQLTypes/SQLString.cs | 8 +- .../System/Data/SQLTypes/SQLUtility.cs | 4 +- .../System/Data/SQLTypes/SqlCharStream.cs | 4 +- .../Data/SQLTypes/SqlTypesSchemaImporter.cs | 4 +- System.Data/System/Data/SQLTypes/SqlXml.cs | 4 +- .../Data/SQLTypes/UnsafeNativeMethods.cs | 6 +- System.Data/System/Data/Select.cs | 12 +- System.Data/System/Data/Selection.cs | 4 +- System.Data/System/Data/SimpleType.cs | 10 +- .../Data/Sql/SqlDataSourceEnumerator.cs | 4 +- .../System/Data/Sql/SqlFacetAttribute.cs | 8 +- .../System/Data/Sql/SqlFunctionAttribute.cs | 8 +- System.Data/System/Data/Sql/SqlGenericUtil.cs | 4 +- System.Data/System/Data/Sql/SqlMetaData.cs | 6 +- .../System/Data/Sql/SqlMethodAttribute.cs | 8 +- .../System/Data/Sql/SqlNotificationRequest.cs | 6 +- .../System/Data/Sql/SqlProcedureAttribute.cs | 8 +- .../System/Data/Sql/SqlTriggerAttribute.cs | 8 +- .../Sql/SqlUserDefinedAggregateAttribute.cs | 10 +- .../Data/Sql/SqlUserDefinedTypeAttribute.cs | 10 +- .../System/Data/Sql/invalidudtexception.cs | 4 +- System.Data/System/Data/Sql/sqlnorm.cs | 10 +- System.Data/System/Data/Sql/sqlser.cs | 10 +- .../Data/SqlClient/RowsCopiedEventArgs.cs | 4 +- .../System/Data/SqlClient/SqlBuffer.cs | 6 +- .../System/Data/SqlClient/SqlBulkCopy.cs | 20 +- .../SqlClient/SqlBulkCopyColumnMapping.cs | 4 +- .../SqlBulkCopyColumnMappingCollection.cs | 4 +- .../System/Data/SqlClient/SqlCachedBuffer.cs | 4 +- .../System/Data/SqlClient/SqlClientFactory.cs | 4 +- .../SqlClientMetaDataCollectionNames.cs | 4 +- .../Data/SqlClient/SqlClientPermission.cs | 4 +- .../Data/SqlClient/SqlClientSymmetricKey.cs | 8 +- .../SqlClient/SqlClientWrapperSmiStream.cs | 4 +- .../SqlClientWrapperSmiStreamChars.cs | 4 +- .../SqlColumnEncryptionCngProvider.cs | 2 +- .../SqlColumnEncryptionCspProvider.cs | 2 +- .../System/Data/SqlClient/SqlCommand.cs | 12 +- .../Data/SqlClient/SqlCommandBuilder.cs | 4 +- .../System/Data/SqlClient/SqlCommandSet.cs | 4 +- .../System/Data/SqlClient/SqlConnection.cs | 6 +- .../Data/SqlClient/SqlConnectionFactory.cs | 4 +- .../SqlConnectionPoolGroupProviderInfo.cs | 4 +- .../Data/SqlClient/SqlConnectionPoolKey.cs | 4 +- .../SqlConnectionPoolProviderInfo.cs | 2 +- .../Data/SqlClient/SqlConnectionString.cs | 4 +- .../SqlClient/SqlConnectionStringBuilder.cs | 4 +- .../SqlConnectionTimeoutErrorInternal.cs | 2 +- .../System/Data/SqlClient/SqlCredential.cs | 4 +- .../System/Data/SqlClient/SqlDataAdapter.cs | 4 +- .../System/Data/SqlClient/SqlDataReader.cs | 14 +- .../System/Data/SqlClient/SqlDataReaderSmi.cs | 4 +- .../Data/SqlClient/SqlDelegatedTransaction.cs | 4 +- .../System/Data/SqlClient/SqlDependency.cs | 6 +- .../Data/SqlClient/SqlDependencyListener.cs | 12 +- .../Data/SqlClient/SqlDependencyUtils.cs | 16 +- System.Data/System/Data/SqlClient/SqlEnums.cs | 4 +- System.Data/System/Data/SqlClient/SqlError.cs | 8 +- .../Data/SqlClient/SqlErrorCollection.cs | 4 +- .../System/Data/SqlClient/SqlException.cs | 4 +- .../Data/SqlClient/SqlInfoMessageEvent.cs | 4 +- .../Data/SqlClient/SqlInternalConnection.cs | 4 +- .../SqlClient/SqlInternalConnectionSmi.cs | 4 +- .../SqlClient/SqlInternalConnectionTds.cs | 73 +- .../SqlClient/SqlNotificationEventArgs.cs | 6 +- .../System/Data/SqlClient/SqlParameter.cs | 4 +- .../Data/SqlClient/SqlParameterCollection.cs | 4 +- .../Data/SqlClient/SqlReferenceCollection.cs | 4 +- .../Data/SqlClient/SqlRowUpdatedEvent.cs | 4 +- .../Data/SqlClient/SqlRowUpdatingEvent.cs | 4 +- .../Data/SqlClient/SqlSequentialTextReader.cs | 2 +- .../System/Data/SqlClient/SqlStatistics.cs | 4 +- .../System/Data/SqlClient/SqlStream.cs | 4 +- .../System/Data/SqlClient/SqlTransaction.cs | 4 +- .../System/Data/SqlClient/SqlUdtInfo.cs | 4 +- System.Data/System/Data/SqlClient/SqlUtil.cs | 4 +- System.Data/System/Data/SqlClient/TdsEnums.cs | 4 +- .../Data/SqlClient/TdsParameterSetter.cs | 6 +- .../System/Data/SqlClient/TdsParser.cs | 27 +- .../Data/SqlClient/TdsParserHelperClasses.cs | 4 +- .../Data/SqlClient/TdsParserSafeHandles.cs | 7 +- .../Data/SqlClient/TdsParserSessionPool.cs | 4 +- .../Data/SqlClient/TdsParserStateObject.cs | 16 +- .../Data/SqlClient/TdsParserStaticMethods.cs | 4 +- .../Data/SqlClient/TdsRecordBufferSetter.cs | 4 +- .../System/Data/SqlClient/TdsValueSetter.cs | 4 +- .../System/Data/SqlClient/assemblycache.cs | 4 +- .../Data/SqlClient/sqlinternaltransaction.cs | 4 +- .../Data/SqlClient/sqlmetadatafactory.cs | 2 +- System.Data/System/Data/StateChangeEvent.cs | 4 +- System.Data/System/Data/UniqueConstraint.cs | 6 +- System.Data/System/Data/XDRSchema.cs | 6 +- System.Data/System/Data/XMLDiffLoader.cs | 6 +- System.Data/System/Data/XMLSchema.cs | 10 +- System.Data/System/Data/XmlDataLoader.cs | 6 +- System.Data/System/Data/XmlKeywords.cs | 6 +- System.Data/System/Data/XmlToDatasetMap.cs | 14 +- System.Data/System/Data/xmlsaver.cs | 10 +- System.Data/System/NewXml/BaseTreeIterator.cs | 4 +- .../NewXml/DataDocumentXPathNavigator.cs | 4 +- System.Data/System/NewXml/DataPointer.cs | 4 +- System.Data/System/NewXml/DataSetMappper.cs | 4 +- System.Data/System/NewXml/RegionIterator.cs | 4 +- System.Data/System/NewXml/TreeIterator.cs | 4 +- System.Data/System/NewXml/XPathNodePointer.cs | 6 +- System.Data/System/NewXml/XmlBoundElement.cs | 4 +- System.Data/System/NewXml/XmlDataDocument.cs | 26 +- .../System/NewXml/XmlDataImplementation.cs | 4 +- System.Data/bid/inc/cs/bidPrivateBase.cs | 4 +- System.Data/system.data.txt | 168 +- .../common/managed/InfoCardCryptoHelper.cs | 2 +- .../System/AppContextDefaultValues.cs | 5 + .../System/IdentityModel/Claims/Claim.cs | 2 +- .../Claims/X509CertificateClaimSet.cs | 10 +- .../System/IdentityModel/CryptoHelper.cs | 6 +- .../IdentityModel/LocalAppContextSwitches.cs | 20 + .../RsaEncryptionCookieTransform.cs | 125 +- .../RsaSignatureCookieTransform.cs | 9 +- .../System/IdentityModel/SecurityUtils.cs | 10 +- .../System/IdentityModel/SspiWrapper.cs | 14 + .../Tokens/Saml2SecurityTokenHandler.cs | 2 +- .../Tokens/SamlSecurityTokenHandler.cs | 2 +- .../Tokens/X509AsymmetricSecurityKey.cs | 78 +- .../System/IdentityModel/X509Util.cs | 33 +- .../Collaboration/ContactManager.cs | 2 +- .../PeerToPeer/Collaboration/PeerNearMe.cs | 6 +- System.Net/net/PeerToPeer/PeerName.cs | 2 +- System.Net/net/PeerToPeer/PeerNameResolver.cs | 8 +- System.Numerics/System.Numerics.txt | 6 + System.Numerics/System/Numerics/Complex.cs | 8 +- System.Runtime.Caching/R.resx | 183 + .../Resources/R.Designer.cs | 9 + .../System/Caching/CacheMemoryMonitor.cs | 3 +- .../Caching/Configuration/ConfigUtil.cs | 15 + .../System/Caching/MemoryCache.cs | 35 +- .../System/Caching/MemoryCacheStatistics.cs | 4 + .../DurableInstancing/InstanceHandle.cs | 2 +- .../InstancePersistenceContext.cs | 2 +- .../System.Runtime.Serialization.txt | 35 +- .../SerializationSectionGroup.cs | 2 +- .../Json/JsonEncodingStreamWrapper.cs | 2 +- .../Serialization/Json/XmlJsonWriter.cs | 77 +- .../System/Xml/EncodingStreamWrapper.cs | 8 +- .../System/Xml/UniqueID.cs | 2 +- .../System/Xml/ValueHandle.cs | 2 +- .../System/Xml/XmlBaseReader.cs | 4 +- .../System/Xml/XmlConverter.cs | 6 +- .../System/Xml/XmlDictionaryWriter.cs | 14 +- .../System/Xml/XmlMtomReader.cs | 8 +- .../Dispatcher/BufferedReceiveManager.cs | 2 +- .../Dispatcher/DurableInstanceManager.cs | 2 +- .../Dispatcher/PersistenceContext.cs | 2 +- .../PersistenceProviderDirectory.cs | 2 +- .../Dispatcher/WorkflowServiceInstance.cs | 14 +- .../Activities/InternalSendMessage.cs | 10 +- .../ServiceModel/Channels/UdpChannelBase.cs | 4 +- .../ServiceModel/Channels/UdpOutputChannel.cs | 2 +- .../Discovery/AnnouncementService.cs | 12 +- .../ServiceModel/Discovery/DiscoveryProxy.cs | 32 +- .../Discovery/DiscoveryService.cs | 20 +- .../System/Runtime/AsyncResult.cs | 2 +- .../Diagnostics/DiagnosticTraceBase.cs | 2 +- .../Runtime/Diagnostics/EtwDiagnosticTrace.cs | 16 +- .../System/Runtime/MruCache.cs | 2 +- .../System/Runtime/ThreadNeutralSemaphore.cs | 4 +- .../System/Runtime/TraceLevelHelper.cs | 2 +- .../ServiceModel/Routing/RoutingService.cs | 2 +- .../Description/WebHttpBehavior.cs | 20 +- .../Description/WebScriptEnablingBehavior.cs | 8 +- .../HttpUnhandledOperationInvoker.cs | 2 +- .../WebHttpDispatchOperationSelector.cs | 10 +- .../System/ServiceModel/Web/HttpDateParse.cs | 8 +- .../ServiceModel/Web/WebOperationContext.cs | 2 +- .../System/ServiceModel/WebHttpBinding.cs | 2 +- .../ServiceModelActivationSectionGroup.cs | 2 +- .../Activation/ListenerUnsafeNativeMethods.cs | 2 +- .../System/ServiceModel/Activation/Utility.cs | 14 +- .../Administration/ProviderBase.cs | 4 +- .../AppContextDefaultValues.Default.cs | 6 + .../ServiceModel/Channels/AddressHeader.cs | 2 +- .../Channels/AddressHeaderCollection.cs | 2 +- .../Channels/BinaryMessageEncoder.cs | 16 +- .../Channels/BufferedOutputAsyncStream.cs | 12 +- .../Channels/CompositeDuplexBindingElement.cs | 2 +- .../ServiceModel/Channels/Connection.cs | 6 +- .../Channels/ConnectionDemuxer.cs | 2 +- .../Channels/ConnectionModeReader.cs | 4 +- .../ServiceModel/Channels/ConnectionPool.cs | 4 +- .../Channels/ContentOnlyMessage.cs | 4 +- .../ServiceModel/Channels/FramingChannels.cs | 26 +- .../ServiceModel/Channels/FramingDecoders.cs | 38 +- .../Channels/HttpChannelFactory.cs | 12 +- .../Channels/HttpChannelHelpers.cs | 12 +- .../ServiceModel/Channels/HttpPipeline.cs | 4 +- .../Channels/HttpTransportBindingElement.cs | 8 +- .../Channels/HttpsChannelFactory.cs | 4 +- .../Channels/IdlingCommunicationPool.cs | 2 +- .../Channels/InitialServerConnectionReader.cs | 2 +- .../ServiceModel/Channels/InputChannel.cs | 2 +- .../Channels/InternalDuplexBindingElement.cs | 2 +- .../Channels/InternalDuplexChannelListener.cs | 2 +- .../System/ServiceModel/Channels/Message.cs | 67 +- .../ServiceModel/Channels/MessageBuffer.cs | 4 +- .../Channels/MessageEncodingBindingElement.cs | 8 +- .../MessageEncodingBindingElementImporter.cs | 2 +- .../ServiceModel/Channels/MessageFault.cs | 2 +- .../ServiceModel/Channels/MessageHeaders.cs | 2 +- .../Channels/OneWayChannelFactory.cs | 4 +- .../Channels/OneWayChannelListener.cs | 18 +- .../Channels/OverlappedContext.cs | 24 +- .../PeerCustomResolverBindingElement.cs | 10 +- .../ServiceModel/Channels/PeerFlooder.cs | 2 +- .../Channels/PeerNeighborManager.cs | 2 +- .../ServiceModel/Channels/PipeConnection.cs | 10 +- .../Channels/ReliableChannelBinder.cs | 6 + .../ServiceModel/Channels/ReplyChannel.cs | 2 +- .../ServiceModel/Channels/RequestChannel.cs | 2 +- .../Channels/RequestContextBase.cs | 2 +- .../SecurityBindingElementImporter.cs | 2 +- .../Channels/ServiceChannelProxy.cs | 8 +- .../Channels/SessionConnectionReader.cs | 2 +- .../Channels/SharedConnectionListener.cs | 22 +- .../Channels/SingletonConnectionReader.cs | 10 +- .../ServiceModel/Channels/SocketConnection.cs | 68 +- .../SslStreamSecurityBindingElement.cs | 8 +- .../SslStreamSecurityUpgradeProvider.cs | 18 +- .../Channels/StandardBindingImporter.cs | 2 +- ...treamSecurityUpgradeAcceptorAsyncResult.cs | 2 +- ...reamSecurityUpgradeInitiatorAsyncResult.cs | 2 +- .../Channels/StreamedFramingRequestChannel.cs | 16 +- .../Channels/SynchronizedMessageSource.cs | 6 +- .../Channels/TransportBindingElement.cs | 6 +- .../TransportBindingElementImporter.cs | 6 +- .../Channels/TransportDuplexSessionChannel.cs | 14 +- .../ServiceModel/Channels/TransportManager.cs | 2 +- .../Channels/TransportSecurityHelpers.cs | 4 +- .../Channels/UnsafeNativeMethods.cs | 2 +- .../ServiceModel/Channels/UriPrefixTable.cs | 2 +- .../WindowsStreamSecurityBindingElement.cs | 8 +- .../WindowsStreamSecurityUpgradeProvider.cs | 10 +- .../System/ServiceModel/ClientBase.cs | 2 +- .../BinaryMessageEncodingElement.cs | 4 +- .../Configuration/CallbackDebugElement.cs | 2 +- .../Configuration/CallbackTimeoutsElement.cs | 2 +- .../Configuration/ClientCredentialsElement.cs | 2 +- .../Configuration/ClientViaElement.cs | 2 +- .../CommonEndpointBehaviorElement.cs | 4 +- .../CommonServiceBehaviorElement.cs | 4 +- .../Configuration/CompositeDuplexElement.cs | 2 +- .../ConnectionOrientedTransportElement.cs | 2 +- .../DataContractSerializerElement.cs | 2 +- .../Configuration/EndpointBehaviorElement.cs | 4 +- .../Configuration/HttpTransportElement.cs | 2 +- .../Configuration/HttpsTransportElement.cs | 2 +- .../Configuration/IdentityElement.cs | 2 +- .../Configuration/IssuedTokenClientElement.cs | 6 +- .../IssuedTokenServiceElement.cs | 2 +- .../MtomMessageEncodingElement.cs | 4 +- .../NamedPipeTransportElement.cs | 6 +- .../Configuration/OneWayElement.cs | 4 +- .../Configuration/PeerTransportElement.cs | 4 +- .../Configuration/PrivacyNoticeElement.cs | 2 +- .../ReliableMessagingVersionConverter.cs | 2 +- .../Configuration/ReliableSessionElement.cs | 2 +- .../Configuration/RemoveBehaviorElement.cs | 2 +- .../Configuration/SecurityElement.cs | 2 +- .../Configuration/SecurityElementBase.cs | 2 +- .../ServiceAuthorizationElement.cs | 2 +- .../Configuration/ServiceBehaviorElement.cs | 4 +- .../ServiceCredentialsElement.cs | 2 +- .../Configuration/ServiceDebugElement.cs | 2 +- .../ServiceMetadataPublishingElement.cs | 2 +- ...viceModelConfigurationElementCollection.cs | 2 +- .../ServiceModelExtensionCollectionElement.cs | 2 +- .../Configuration/ServiceModelSectionGroup.cs | 2 +- .../ServiceSecurityAuditElement.cs | 2 +- .../Configuration/ServiceThrottlingElement.cs | 2 +- .../Configuration/ServiceTimeoutsElement.cs | 2 +- .../Configuration/SslStreamSecurityElement.cs | 2 +- .../StandardBindingCollectionElement.cs | 2 +- .../StandardEndpointCollectionElement.cs | 2 +- .../Configuration/TcpTransportElement.cs | 8 +- .../TextMessageEncodingElement.cs | 4 +- .../TransactedBatchingElement.cs | 2 +- .../Configuration/TransactionFlowElement.cs | 2 +- .../TransactionProtocolConverter.cs | 2 +- .../Configuration/TransportElement.cs | 2 +- .../WindowsStreamSecurityElement.cs | 2 +- .../Description/ClientClassGenerator.cs | 4 +- .../ServiceModel/Description/ConfigWriter.cs | 4 +- .../ImportedPolicyConversionContext.cs | 2 +- .../Description/MessageContractExporter.cs | 4 +- .../Description/MetadataSection.cs | 2 +- .../ServiceModel/Description/PolicyReader.cs | 6 +- .../Description/ServiceEndpoint.cs | 2 +- .../ServiceModel/Description/SoapHelper.cs | 2 +- .../TaskOperationDescriptionValidator.cs | 2 +- .../ServiceModel/Description/TypeLoader.cs | 14 +- .../ServiceModel/Description/WsdlExporter.cs | 2 +- .../ServiceModel/Description/WsdlImporter.cs | 6 +- .../ServiceModel/Diagnostics/TraceUtility.cs | 8 +- .../Dispatcher/ActionMessageFilterTable.cs | 8 +- .../Dispatcher/DuplexChannelBinder.cs | 29 +- .../EndpointAddressMessageFilter.cs | 2 +- .../EndpointAddressMessageFilterTable.cs | 8 +- .../Dispatcher/ImmutableDispatchRuntime.cs | 2 +- .../Dispatcher/InputChannelBinder.cs | 2 +- .../Dispatcher/MessageFilterTable.cs | 2 +- .../Dispatcher/OperationInvokerBehavior.cs | 4 +- .../Dispatcher/OutputChannelBinder.cs | 2 +- .../PrefixEndpointAddressMessageFilter.cs | 2 +- ...PrefixEndpointAddressMessageFilterTable.cs | 4 +- .../Dispatcher/PrimitiveOperationFormatter.cs | 4 +- .../ServiceModel/Dispatcher/QueryFunctions.cs | 6 +- .../ServiceModel/Dispatcher/QueryNode.cs | 14 +- .../ServiceModel/Dispatcher/QueryProcessor.cs | 4 +- .../ServiceModel/Dispatcher/QuerySelectOp.cs | 2 +- .../Dispatcher/QuerySubExprEliminator.cs | 6 +- .../ServiceModel/Dispatcher/QueryUtil.cs | 4 +- .../Dispatcher/ReplyChannelBinder.cs | 2 +- .../Dispatcher/SecurityValidationBehavior.cs | 2 +- .../Dispatcher/SeekableMessageNavigator.cs | 14 +- .../Dispatcher/StreamFormatter.cs | 2 +- .../Dispatcher/XPathMessageContext.cs | 6 +- .../System/ServiceModel/EndpointAddress.cs | 4 +- .../System/ServiceModel/FaultReason.cs | 2 +- .../ServiceModel/LocalAppContextSwitches.cs | 11 + .../System/ServiceModel/OperationContext.cs | 18 +- .../ServiceModel/OperationContextScope.cs | 43 +- .../ServiceModel/Security/CryptoHelper.cs | 4 +- .../SecuritySessionSecurityTokenProvider.cs | 4 +- .../ServiceModel/Security/SecurityUtils.cs | 8 +- .../Security/TlsnegoTokenAuthenticator.cs | 11 +- .../Security/TlsnegoTokenProvider.cs | 11 +- .../ServiceModel/Security/WSSecurityPolicy.cs | 2 +- .../Security/WSTrustServiceContract.cs | 2 +- .../ServiceModel/ServiceModelAppSettings.cs | 17 + .../Syndication/Rss20FeedFormatter.cs | 12 +- .../ApplicationServicesStrings.resx | 183 + .../Common/Annotation/AnnotationBase.cs | 4437 ++++++ .../Common/Annotation/AnnotationCollection.cs | 844 ++ .../Common/Annotation/ArrowAnnotation.cs | 471 + .../Common/Annotation/CalloutAnnotation.cs | 1901 +++ .../Common/Annotation/GroupAnnotation.cs | 995 ++ .../Common/Annotation/ImageAnnotation.cs | 730 + .../Common/Annotation/LineAnnotation.cs | 910 ++ .../Common/Annotation/PolygonAnnotation.cs | 1739 +++ .../Common/Annotation/RectangleAnnotation.cs | 722 + .../Common/Annotation/TextAnnotation.cs | 1263 ++ .../Common/Borders3D/Borders3D.cs | 784 + .../Common/Borders3D/EmbedBorder.cs | 1102 ++ .../Common/Borders3D/EmbossBorder.cs | 268 + .../Common/ChartTypes/AreaChart.cs | 1647 ++ .../Common/ChartTypes/BarChart.cs | 2351 +++ .../Common/ChartTypes/BoxPlotChart.cs | 1856 +++ .../Common/ChartTypes/BubbleChart.cs | 497 + .../Common/ChartTypes/ChartTypeRegistry.cs | 453 + .../Common/ChartTypes/ColumnChart.cs | 1414 ++ .../Common/ChartTypes/DoughnutChart.cs | 143 + .../Common/ChartTypes/ErrorBarChart.cs | 1887 +++ .../Common/ChartTypes/FastLineChart.cs | 738 + .../Common/ChartTypes/FastPointChart.cs | 700 + .../Common/ChartTypes/FunnelChart.cs | 3044 ++++ .../Common/ChartTypes/KagiChart.cs | 996 ++ .../Common/ChartTypes/LineChart.cs | 2472 +++ .../Common/ChartTypes/PieChart.cs | 5703 +++++++ .../Common/ChartTypes/PointAndFigureChart.cs | 913 ++ .../Common/ChartTypes/PointChart.cs | 1822 +++ .../Common/ChartTypes/PolarChart.cs | 271 + .../Common/ChartTypes/RadarChart.cs | 1685 +++ .../Common/ChartTypes/RangeChart.cs | 1820 +++ .../Common/ChartTypes/RenkoChart.cs | 722 + .../Common/ChartTypes/StackedAreaChart.cs | 1695 +++ .../Common/ChartTypes/StackedBarChart.cs | 2156 +++ .../Common/ChartTypes/StackedColumnChart.cs | 2023 +++ .../Common/ChartTypes/StepLineChart.cs | 409 + .../Common/ChartTypes/StockChart.cs | 1957 +++ .../Common/ChartTypes/ThreeLineBreakChart.cs | 716 + .../Common/Converters/AnnotationConverters.cs | 136 + .../Common/Converters/AxesArrayConverter.cs | 94 + .../Common/Converters/AxisConverters.cs | 691 + .../Converters/CustomAttributesConverters.cs | 985 ++ .../Converters/DataManagerConverters.cs | 899 ++ .../Converters/ElementPositionConverter.cs | 140 + .../Common/Converters/LegendConverters.cs | 502 + .../Common/DataManager/DataManager.cs | 1183 ++ .../Common/DataManager/DataPoint.cs | 7044 +++++++++ .../Common/DataManager/DataSeries.cs | 2694 ++++ .../Common/EditorNames.cs | 263 + .../Common/Formulas/FormulaHelpers.cs | 1636 ++ .../Common/Formulas/FormulaRegistry.cs | 201 + .../Common/Formulas/GeneralFormulas.cs | 193 + .../Common/Formulas/Oscillator.cs | 686 + .../Common/Formulas/PriceIndicators.cs | 1174 ++ .../Common/Formulas/StatisticalAnalysis.cs | 2189 +++ .../Common/Formulas/TechGeneralIndicators.cs | 876 ++ .../Formulas/TimeSeriesAndForecasting.cs | 647 + .../Common/Formulas/VolumeIndicator.cs | 527 + .../Common/General/Axis.cs | 6508 ++++++++ .../Common/General/AxisLabels.cs | 941 ++ .../Common/General/AxisScale.cs | 2369 +++ .../Common/General/AxisScaleBreaks.cs | 1108 ++ .../Common/General/AxisScaleSegments.cs | 1014 ++ .../Common/General/AxisScrollBar.cs | 1952 +++ .../Common/General/AxisScrollZoom.cs | 1770 +++ .../Common/General/BaseClasses.cs | 403 + .../Common/General/BaseCollections.cs | 619 + .../Common/General/BaseInterfaces.cs | 80 + .../Common/General/Chart.cs | 4361 ++++++ .../Common/General/ChartArea.cs | 3157 ++++ .../Common/General/ChartArea3D.cs | 2239 +++ .../Common/General/ChartAreaAxes.cs | 1986 +++ .../Common/General/ChartAreaCircular.cs | 109 + .../Common/General/ChartAreaCollection.cs | 107 + .../Common/General/ChartAreaCursor.cs | 1682 +++ .../Common/General/ChartElement.cs | 1458 ++ .../Common/General/ChartGraphics.cs | 5779 +++++++ .../Common/General/ChartGraphics3D.cs | 4735 ++++++ .../Common/General/ChartRenderingEngine.cs | 853 ++ .../Common/General/ChartSerializer.cs | 789 + .../Common/General/CommonElements.cs | 327 + .../Common/General/Constants.cs | 28 + .../Common/General/DataManipulator.cs | 3495 +++++ .../Common/General/FormulaData.cs | 1312 ++ .../Common/General/GdiGraphics.cs | 732 + .../Common/General/GridTickMarks.cs | 2046 +++ .../Common/General/IChartRenderingEngine.cs | 536 + .../Common/General/ImageMap.cs | 891 ++ .../Common/General/Label.cs | 3002 ++++ .../Common/General/Legend.cs | 6284 ++++++++ .../Common/General/LegendColumns.cs | 2909 ++++ .../Common/General/Matrix3D.cs | 1222 ++ .../Common/General/NamedImageCollection.cs | 175 + .../Common/General/Selection.cs | 3495 +++++ .../Common/General/SmartLabels.cs | 1710 +++ .../Common/General/Statistics.cs | 1671 +++ .../Common/General/StripLine.cs | 1616 ++ .../Common/General/SubAxis.cs | 823 + .../Common/General/Title.cs | 2237 +++ System.Web.DataVisualization/Common/SR.cs | 12528 ++++++++++++++++ .../Common/SRCategoryAttribute.cs | 26 + .../Common/SRDescriptionAttribute.cs | 41 + .../Common/Utilities/ColorPalette.cs | 396 + .../Utilities/CustomAttributesRegistry.cs | 1974 +++ .../Common/Utilities/ElementPosition.cs | 535 + .../Common/Utilities/ImageLoader.cs | 421 + .../Common/Utilities/KeywordsRegistry.cs | 495 + .../Common/Utilities/ValueConverter.cs | 194 + .../Common/Utilities/XmlSerializer.cs | 3274 ++++ .../WebForm/AssemblyInfo.cs | 27 + .../WebForm/ChartWebControl.cs | 3408 +++++ .../Converters/MapAreaCoordinatesConverter.cs | 103 + .../WebForm/FxCopExclusionsByDesign.cs | 553 + .../WebForm/General/ChartHttpHandler.cs | 2158 +++ .../DynamicData/DynamicDataExtensions.cs | 2 +- .../DynamicData/DynamicDataManager.cs | 2 +- .../EntityConnectionStringBuilderItem.cs | 4 +- .../EntityDataSourceConfigureObjectContext.cs | 4 +- ...tyDataSourceConfigureObjectContextPanel.cs | 4 +- ...rceConfigureObjectContextPanel.designer.cs | 4 +- .../EntityDataSourceContainerNameConverter.cs | 4 +- .../EntityDataSourceContainerNameItem.cs | 4 +- .../Design/EntityDataSourceDataSelection.cs | 4 +- .../EntityDataSourceDataSelectionPanel.cs | 4 +- ...tyDataSourceDataSelectionPanel.designer.cs | 4 +- .../Design/EntityDataSourceDesigner.cs | 4 +- .../Design/EntityDataSourceDesignerHelper.cs | 4 +- .../EntityDataSourceEntitySetNameConverter.cs | 4 +- .../EntityDataSourceEntitySetNameItem.cs | 4 +- ...tityDataSourceEntityTypeFilterConverter.cs | 4 +- .../EntityDataSourceEntityTypeFilterItem.cs | 4 +- .../Design/EntityDataSourceState.cs | 4 +- .../Design/EntityDataSourceStatementEditor.cs | 4 +- .../EntityDataSourceStatementEditorForm.cs | 4 +- .../Design/EntityDataSourceWizardForm.cs | 4 +- .../Design/EntityDesignerDataSourceView.cs | 4 +- .../WebControls/Design/Util/DesignerForm.cs | 4 +- .../Design/Util/RTLAwareMessageBox.cs | 4 +- .../Util/ResourceDescriptionAttribute.cs | 4 +- .../WebControls/Design/Util/TaskFormBase.cs | 4 +- .../Data/WebControls/Design/Util/UIHelper.cs | 4 +- .../WebControls/Design/Util/WizardForm.cs | 4 +- .../WebControls/Design/Util/WizardPanel.cs | 4 +- .../Util/WizardPanelChangingEventArgs.cs | 4 +- .../Data/WebControls/EntityDataSource.cs | 4 +- .../EntityDataSourceChangedEventArgs.cs | 2 +- .../EntityDataSourceChangingEventArgs.cs | 2 +- .../WebControls/EntityDataSourceColumn.cs | 4 +- ...EntityDataSourceContextCreatedEventArgs.cs | 2 +- ...ntityDataSourceContextCreatingEventArgs.cs | 2 +- ...tityDataSourceContextDisposingEventArgs.cs | 2 +- .../WebControls/EntityDataSourceMemberPath.cs | 4 +- .../EntityDataSourceQueryBuilder.cs | 4 +- .../EntityDataSourceReferenceGroup.cs | 4 +- .../EntityDataSourceSelectedEventArgs.cs | 2 +- .../EntityDataSourceSelectingEventArgs.cs | 2 +- .../Data/WebControls/EntityDataSourceUtil.cs | 4 +- .../EntityDataSourceValidationException.cs | 4 +- .../Data/WebControls/EntityDataSourceView.cs | 4 +- .../WebControls/EntityDataSourceViewSchema.cs | 4 +- .../WebControls/EntityDataSourceWrapper.cs | 4 +- .../EntityDataSourceWrapperCollection.cs | 4 +- ...tityDataSourceWrapperPropertyDescriptor.cs | 4 +- .../ResourceDescriptionAttribute.cs | 4 +- .../ResourceDisplayNameAttribute.cs | 4 +- .../WebControls/WebControlParameterProxy.cs | 2 +- .../Design/AppliedDeviceFiltersDialog.cs | 2 +- .../MobileControls/Design/Util/GenericUI.cs | 2 +- .../MobileControls/Design/Util/MSHTMLHost.cs | 6 +- .../UI/MobileControls/MobilePage.cs | 4 +- .../UI/MobileControls/ObjectList.cs | 2 +- .../UI/MobileControls/SessionViewState.cs | 2 +- System.Web.Services/System.Web.Services.txt | 477 + .../Description/SoapProtocolImporter.cs | 4 +- .../Services/Discovery/DiscoveryDocument.cs | 2 +- .../Discovery/DiscoveryDocumentReference.cs | 2 +- .../Discovery/DynamicVirtualDiscoSearcher.cs | 2 +- .../Web/Services/Protocols/ClientProtocol.cs | 2 +- .../Services/Protocols/LogicalMethodInfo.cs | 4 +- .../System/Web/Services/Protocols/Scalars.cs | 4 +- .../Web/Services/Protocols/SoapException.cs | 2 +- System.Web/AspNetEventSource.cs | 6 +- System.Web/Cache/CacheDependency.cs | 173 +- System.Web/Cache/CacheEntry.cs | 38 +- System.Web/Cache/OutputCache.cs | 84 +- System.Web/Cache/SqlCacheDependency.cs | 25 +- System.Web/Cache/cache.cs | 1744 +-- System.Web/CachedPathData.cs | 23 +- System.Web/Compilation/BuildManager.cs | 6 +- System.Web/Compilation/BuildResultCache.cs | 37 +- System.Web/Compilation/CompilationLock.cs | 2 +- .../Compilation/ResourceExpressionBuilder.cs | 12 +- System.Web/Configuration/CacheSection.cs | 39 +- .../Configuration/HandlerFactoryCache.cs | 3 + .../HttpCapabilitiesEvaluator.cs | 12 +- .../Configuration/MetabaseServerConfig.cs | 5 +- .../Configuration/ProcessHostMapPath.cs | 5 +- System.Web/Configuration/ProvidersHelper.cs | 37 + .../Configuration/SessionStateSection.cs | 2 +- System.Web/FileChangesMonitor.cs | 6 +- System.Web/Hosting/ApplicationManager.cs | 85 +- System.Web/Hosting/HostingEnvironment.cs | 78 +- System.Web/Hosting/IIS7WorkerRequest.cs | 2 +- System.Web/Hosting/ISAPIWorkerRequest.cs | 4 +- .../MapPathBasedVirtualPathProvider.cs | 4 +- System.Web/Hosting/ObjectCacheHost.cs | 18 - System.Web/Hosting/SuspendManager.cs | 10 +- System.Web/HttpApplication.cs | 16 +- System.Web/HttpBufferlessInputStream.cs | 2 +- System.Web/HttpCachePolicy.cs | 6 +- System.Web/HttpContext.cs | 4 +- System.Web/HttpCookie.cs | 2 +- System.Web/HttpCookieCollection.cs | 15 +- System.Web/HttpRequest.cs | 7 +- System.Web/HttpResponse.cs | 16 +- System.Web/HttpRuntime.cs | 63 +- .../NDP_Common/inc/StrongNameHelpers.cs | 40 +- .../LegacyAspNetSynchronizationContext.cs | 4 +- System.Web/Management/WebEvents.cs | 10 +- System.Web/PipelineModuleStepContainer.cs | 2 +- System.Web/Routing/Route.cs | 2 +- System.Web/Routing/RouteCollection.cs | 6 + System.Web/Security/ADMembershipProvider.cs | 38 +- .../Security/Cryptography/CryptoAlgorithms.cs | 2 +- .../Security/FileAuthorizationModule.cs | 11 +- System.Web/Security/Membership.cs | 20 + System.Web/Security/RoleClaimProvider.cs | 2 +- System.Web/State/InProcStateClientManager.cs | 28 +- System.Web/State/SessionStateModule.cs | 61 +- System.Web/State/StateRuntime.cs | 36 +- System.Web/State/StateWorkerRequest.cs | 2 +- System.Web/System.Web.txt | 24 +- System.Web/ThreadContext.cs | 6 +- System.Web/UI/DataSourceCache.cs | 10 +- System.Web/UI/HTMLTextWriter.cs | 2 +- System.Web/UI/ObjectStateFormatter.cs | 4 +- System.Web/UI/Page.cs | 4 +- System.Web/UI/WebControls/AdRotator.cs | 6 +- System.Web/UI/WebControls/ChangePassword.cs | 12 +- System.Web/UI/WebControls/DetailsView.cs | 2 +- System.Web/UI/WebControls/PasswordRecovery.cs | 4 +- System.Web/UI/WebControls/Wizard.cs | 4 +- System.Web/UI/WebControls/xml.cs | 13 +- System.Web/UI/WebParts/CatalogZoneBase.cs | 2 +- System.Web/UI/WebParts/EditorPart.cs | 2 +- System.Web/UI/WebParts/EditorZoneBase.cs | 2 +- System.Web/UI/WebParts/WebPartManager.cs | 2 +- System.Web/UI/WebParts/WebPartZoneBase.cs | 4 +- System.Web/UnsafeNativeMethods.cs | 2 +- System.Web/Util/AppSettings.cs | 14 + System.Web/Util/AppVerifier.cs | 2 +- System.Web/Util/AspCompat.cs | 4 +- System.Web/Util/BinaryCompatibility.cs | 10 +- System.Web/Util/DateTimeUtil.cs | 30 +- System.Web/Util/ParseHttpDate.cs | 2 +- System.Web/Util/SecUtil.cs | 13 +- System.Web/Util/VersionUtil.cs | 1 + System.Web/cacheexpires.cspp | 1328 ++ System.Web/cacheusage.cspp | 1537 ++ System.Web/httpserverutility.cs | 2 +- System.Web/misc/SecurityUtils.cs | 6 +- .../Common/BasePropertyDescriptor.cs | 2 +- .../Common/CompModHelpers.cs | 2 +- .../Common/CompilerHelpers.cs | 2 +- .../Common/DelegateTypeInfo.cs | 2 +- .../Common/NativeMethods.cs | 2 +- .../Common/TypeSystemHelpers.cs | 2 +- .../Common/ValidationHelpers.cs | 2 +- System.Workflow.Activities/Common/Walker.cs | 2 +- .../Common/userdatakeys.cs | 2 +- .../LocalService/FollowerQueueCreator.cs | 2 +- .../Compiler/TypeSystem/DesignTimeType.cs | 2 +- .../AuthoringOM/Design/CommandSet.cs | 4 +- .../Dialogs/ThemeConfigurationDialog.cs | 2 +- .../Design/Dialogs/WorkflowPageSetupDialog.cs | 2 +- .../AuthoringOM/Design/MenuCommands.cs | 2 +- .../AuthoringOM/Design/ReferenceService.cs | 2 +- .../StructuredCompositeActivityDesigner.cs | 2 +- .../AuthoringOM/Design/WorkflowView.cs | 2 +- .../Shared/BasePropertyDescriptor.cs | 2 +- .../Shared/CompModHelpers.cs | 2 +- .../Shared/CompilerHelpers.cs | 2 +- .../Shared/DelegateTypeInfo.cs | 2 +- .../Shared/NativeMethods.cs | 2 +- .../Shared/TypeSystemHelpers.cs | 2 +- .../Shared/ValidationHelpers.cs | 2 +- .../Shared/Walker.cs | 2 +- .../Shared/userdatakeys.cs | 2 +- .../ExecutorLocksHeldException.cs | 2 +- .../Hosting/WorkflowWebHostingModule.cs | 2 +- .../System/Activities/Statements/Interop.cs | 2 +- System.Workflow.Runtime/WorkflowEventArgs.cs | 2 +- System.Workflow.Runtime/WorkflowExecutor.cs | 14 +- .../ServiceModel/WorkflowServiceHost.cs | 2 +- .../Design/OperationPickerDialog.cs | 2 +- ...nizationContextWorkflowSchedulerService.cs | 2 +- .../NDP_Common/inc/Win8Helpers.cs | 2 +- System.Xml/System/Xml/Base64Decoder.cs | 2 +- System.Xml/System/Xml/Base64Encoder.cs | 2 +- System.Xml/System/Xml/BinHexDecoder.cs | 2 +- System.Xml/System/Xml/BinHexEncoder.cs | 2 +- System.Xml/System/Xml/BinaryXml/SqlUtils.cs | 2 +- .../System/Xml/BinaryXml/XmlBinaryReader.cs | 2 +- .../Xml/BinaryXml/XmlBinaryReaderAsync.cs | 2 +- System.Xml/System/Xml/BitStack.cs | 2 +- System.Xml/System/Xml/Bits.cs | 2 +- System.Xml/System/Xml/ByteStack.cs | 2 +- .../System/Xml/Cache/XPathDocumentBuilder.cs | 2 +- .../System/Xml/Cache/XPathDocumentIterator.cs | 2 +- .../Xml/Cache/XPathDocumentNavigator.cs | 2 +- System.Xml/System/Xml/Cache/XPathNode.cs | 2 +- .../System/Xml/Cache/XPathNodeHelper.cs | 2 +- .../System/Xml/Cache/XPathNodeInfoAtom.cs | 2 +- .../Xml/Core/CharEntityEncoderFallback.cs | 2 +- .../Xml/Core/HtmlEncodedRawTextWriter.cs | 2 +- System.Xml/System/Xml/Core/HtmlTernaryTree.cs | 2 +- .../System/Xml/Core/HtmlUtf8RawTextWriter.cs | 2 +- .../Xml/Core/IncrementalReadDecoders.cs | 2 +- .../System/Xml/Core/QueryOutputWriter.cs | 2 +- .../System/Xml/Core/QueryOutputWriterV1.cs | 2 +- .../Xml/Core/ReadContentAsBinaryHelper.cs | 2 +- .../System/Xml/Core/ReadOnlyTernaryTree.cs | 4 +- .../System/Xml/Core/SecureStringHasher.cs | 2 +- .../Xml/Core/TextEncodedRawTextWriter.cs | 2 +- .../System/Xml/Core/TextUtf8RawTextWriter.cs | 2 +- .../Xml/Core/ValidatingReaderNodeData.cs | 2 +- .../System/Xml/Core/XmlAsyncCheckReader.cs | 2 +- .../System/Xml/Core/XmlAsyncCheckWriter.cs | 2 +- .../System/Xml/Core/XmlAutoDetectWriter.cs | 2 +- .../System/Xml/Core/XmlCharCheckingReader.cs | 2 +- .../System/Xml/Core/XmlCharCheckingWriter.cs | 2 +- .../Xml/Core/XmlEncodedRawTextWriter.cs | 2 +- System.Xml/System/Xml/Core/XmlEventCache.cs | 2 +- .../System/Xml/Core/XmlParserContext.cs | 2 +- System.Xml/System/Xml/Core/XmlRawWriter.cs | 2 +- System.Xml/System/Xml/Core/XmlReader.cs | 2 +- .../System/Xml/Core/XmlReaderSettings.cs | 2 +- .../System/Xml/Core/XmlSubtreeReader.cs | 2 +- System.Xml/System/Xml/Core/XmlTextEncoder.cs | 2 +- System.Xml/System/Xml/Core/XmlTextReader.cs | 2 +- .../System/Xml/Core/XmlTextReaderImpl.cs | 2 +- .../Xml/Core/XmlTextReaderImplHelpers.cs | 2 +- System.Xml/System/Xml/Core/XmlTextWriter.cs | 2 +- .../System/Xml/Core/XmlUtf8RawTextWriter.cs | 2 +- .../System/Xml/Core/XmlValidatingReader.cs | 2 +- .../Xml/Core/XmlValidatingReaderImpl.cs | 2 +- .../System/Xml/Core/XmlWellFormedWriter.cs | 2 +- .../Xml/Core/XmlWellFormedWriterHelpers.cs | 2 +- .../System/Xml/Core/XmlWrappingReader.cs | 2 +- .../System/Xml/Core/XmlWrappingWriter.cs | 2 +- System.Xml/System/Xml/Core/XmlWriter.cs | 2 +- System.Xml/System/Xml/Core/XmlWriterAsync.cs | 2 +- .../System/Xml/Core/XmlWriterSettings.cs | 2 +- .../System/Xml/Core/XsdCachingReader.cs | 2 +- .../System/Xml/Core/XsdValidatingReader.cs | 2 +- System.Xml/System/Xml/DiagnosticsSwitches.cs | 2 +- .../System/Xml/Dom/DocumentSchemaValidator.cs | 2 +- .../System/Xml/Dom/DocumentXPathNavigator.cs | 2 +- .../System/Xml/Dom/DocumentXmlWriter.cs | 2 +- System.Xml/System/Xml/Dom/DomNameTable.cs | 2 +- System.Xml/System/Xml/Dom/XPathNodeList.cs | 2 +- System.Xml/System/Xml/Dom/XmlAttribute.cs | 2 +- .../System/Xml/Dom/XmlAttributeCollection.cs | 2 +- System.Xml/System/Xml/Dom/XmlCDataSection.cs | 2 +- System.Xml/System/Xml/Dom/XmlCharacterData.cs | 2 +- .../System/Xml/Dom/XmlChildEnumerator.cs | 2 +- System.Xml/System/Xml/Dom/XmlChildNodes.cs | 2 +- System.Xml/System/Xml/Dom/XmlComment.cs | 2 +- System.Xml/System/Xml/Dom/XmlDeclaration.cs | 2 +- System.Xml/System/Xml/Dom/XmlDocument.cs | 2 +- .../System/Xml/Dom/XmlDocumentFragment.cs | 2 +- System.Xml/System/Xml/Dom/XmlDocumentType.cs | 2 +- System.Xml/System/Xml/Dom/XmlDomTextWriter.cs | 2 +- System.Xml/System/Xml/Dom/XmlElement.cs | 2 +- System.Xml/System/Xml/Dom/XmlElementList.cs | 2 +- System.Xml/System/Xml/Dom/XmlEntity.cs | 2 +- .../System/Xml/Dom/XmlEntityReference.cs | 2 +- .../System/Xml/Dom/XmlImplementation.cs | 2 +- System.Xml/System/Xml/Dom/XmlLinkedNode.cs | 2 +- System.Xml/System/Xml/Dom/XmlLoader.cs | 2 +- System.Xml/System/Xml/Dom/XmlName.cs | 2 +- System.Xml/System/Xml/Dom/XmlNamedNodemap.cs | 2 +- System.Xml/System/Xml/Dom/XmlNode.cs | 2 +- .../System/Xml/Dom/XmlNodeChangedEventArgs.cs | 2 +- System.Xml/System/Xml/Dom/XmlNodeList.cs | 2 +- System.Xml/System/Xml/Dom/XmlNodeReader.cs | 2 +- System.Xml/System/Xml/Dom/XmlNotation.cs | 2 +- .../Xml/Dom/XmlProcessingInstruction.cs | 2 +- .../Xml/Dom/XmlSignificantWhiteSpace.cs | 2 +- System.Xml/System/Xml/Dom/XmlText.cs | 2 +- .../System/Xml/Dom/XmlUnspecifiedAttribute.cs | 2 +- System.Xml/System/Xml/Dom/XmlWhitespace.cs | 2 +- System.Xml/System/Xml/EmptyEnumerator.cs | 2 +- System.Xml/System/Xml/HWStack.cs | 2 +- System.Xml/System/Xml/IXmlLineInfo.cs | 2 +- System.Xml/System/Xml/LineInfo.cs | 2 +- System.Xml/System/Xml/NameTable.cs | 2 +- System.Xml/System/Xml/Ref.cs | 2 +- .../Xml/Resolvers/XmlPreloadedResolver.cs | 2 +- .../Resolvers/XmlPreloadedResolverAsync.cs | 2 +- System.Xml/System/Xml/Schema/Asttree.cs | 2 +- System.Xml/System/Xml/Schema/AutoValidator.cs | 2 +- System.Xml/System/Xml/Schema/BaseProcessor.cs | 2 +- System.Xml/System/Xml/Schema/BaseValidator.cs | 2 +- System.Xml/System/Xml/Schema/BitSet.cs | 2 +- System.Xml/System/Xml/Schema/Chameleonkey.cs | 2 +- .../Xml/Schema/CompiledidEntityConstraint.cs | 2 +- .../System/Xml/Schema/ConstraintStruct.cs | 2 +- .../System/Xml/Schema/ContentValidator.cs | 2 +- .../Xml/Schema/DataTypeImplementation.cs | 4 +- System.Xml/System/Xml/Schema/DtdParser.cs | 2 +- System.Xml/System/Xml/Schema/DtdValidator.cs | 2 +- System.Xml/System/Xml/Schema/FacetChecker.cs | 2 +- .../System/Xml/Schema/Inference/Infer.cs | 4 +- .../Inference/XmlSchemaInferenceException.cs | 4 +- System.Xml/System/Xml/Schema/NamespaceList.cs | 2 +- System.Xml/System/Xml/Schema/Parser.cs | 2 +- System.Xml/System/Xml/Schema/Preprocessor.cs | 2 +- System.Xml/System/Xml/Schema/SchemaAttDef.cs | 2 +- .../Xml/Schema/SchemaCollectionCompiler.cs | 2 +- .../Schema/SchemaCollectionpreProcessor.cs | 2 +- .../System/Xml/Schema/SchemaDeclBase.cs | 2 +- .../System/Xml/Schema/SchemaElementDecl.cs | 2 +- System.Xml/System/Xml/Schema/SchemaEntity.cs | 2 +- System.Xml/System/Xml/Schema/SchemaInfo.cs | 2 +- System.Xml/System/Xml/Schema/SchemaNames.cs | 2 +- .../Xml/Schema/SchemaNamespacemanager.cs | 2 +- .../System/Xml/Schema/SchemaNotation.cs | 2 +- .../System/Xml/Schema/SchemaSetCompiler.cs | 6 +- .../System/Xml/Schema/ValidationEventArgs.cs | 2 +- .../System/Xml/Schema/ValidationState.cs | 2 +- System.Xml/System/Xml/Schema/XdrBuilder.cs | 2 +- System.Xml/System/Xml/Schema/XdrValidator.cs | 2 +- .../System/Xml/Schema/XmlAtomicValue.cs | 2 +- System.Xml/System/Xml/Schema/XmlSchema.cs | 2 +- System.Xml/System/Xml/Schema/XmlSchemaAll.cs | 2 +- .../System/Xml/Schema/XmlSchemaAnnotated.cs | 2 +- .../System/Xml/Schema/XmlSchemaAnnotation.cs | 2 +- System.Xml/System/Xml/Schema/XmlSchemaAny.cs | 2 +- .../Xml/Schema/XmlSchemaAnyAttribute.cs | 2 +- .../System/Xml/Schema/XmlSchemaAppInfo.cs | 2 +- .../System/Xml/Schema/XmlSchemaAttribute.cs | 2 +- .../Xml/Schema/XmlSchemaAttributeGroup.cs | 2 +- .../Xml/Schema/XmlSchemaAttributeGroupref.cs | 2 +- .../System/Xml/Schema/XmlSchemaChoice.cs | 2 +- .../System/Xml/Schema/XmlSchemaCollection.cs | 2 +- .../Schema/XmlSchemaCompilationSettings.cs | 2 +- .../Xml/Schema/XmlSchemaComplexContent.cs | 2 +- .../XmlSchemaComplexContentExtension.cs | 2 +- .../XmlSchemaComplexContentRestriction.cs | 2 +- .../System/Xml/Schema/XmlSchemaComplexType.cs | 2 +- .../System/Xml/Schema/XmlSchemaDataType.cs | 4 +- .../Xml/Schema/XmlSchemaDocumentation.cs | 2 +- .../System/Xml/Schema/XmlSchemaElement.cs | 2 +- .../System/Xml/Schema/XmlSchemaException.cs | 2 +- .../System/Xml/Schema/XmlSchemaExternal.cs | 2 +- .../System/Xml/Schema/XmlSchemaFacet.cs | 2 +- .../System/Xml/Schema/XmlSchemaGroup.cs | 2 +- .../System/Xml/Schema/XmlSchemaGroupRef.cs | 2 +- .../Xml/Schema/XmlSchemaIdEntityConstraint.cs | 2 +- .../System/Xml/Schema/XmlSchemaImport.cs | 2 +- .../System/Xml/Schema/XmlSchemaInclude.cs | 2 +- System.Xml/System/Xml/Schema/XmlSchemaInfo.cs | 2 +- .../System/Xml/Schema/XmlSchemaNotation.cs | 2 +- .../System/Xml/Schema/XmlSchemaObject.cs | 2 +- .../Xml/Schema/XmlSchemaObjectCollection.cs | 2 +- .../System/Xml/Schema/XmlSchemaObjectTable.cs | 2 +- .../System/Xml/Schema/XmlSchemaParticle.cs | 2 +- .../System/Xml/Schema/XmlSchemaRedefine.cs | 2 +- .../System/Xml/Schema/XmlSchemaSequence.cs | 2 +- System.Xml/System/Xml/Schema/XmlSchemaSet.cs | 2 +- .../Xml/Schema/XmlSchemaSimpleContent.cs | 2 +- .../Schema/XmlSchemaSimpleContentExtension.cs | 2 +- .../XmlSchemaSimpleContentRestriction.cs | 2 +- .../System/Xml/Schema/XmlSchemaSimpleType.cs | 2 +- .../Xml/Schema/XmlSchemaSimpleTypeList.cs | 2 +- .../Schema/XmlSchemaSimpleTypeRestriction.cs | 2 +- .../Xml/Schema/XmlSchemaSimpleTypeUnion.cs | 2 +- .../Xml/Schema/XmlSchemaSubstitutionGroup.cs | 2 +- System.Xml/System/Xml/Schema/XmlSchemaType.cs | 2 +- .../Schema/XmlSchemaValidationException.cs | 2 +- .../System/Xml/Schema/XmlSchemaValidator.cs | 2 +- .../System/Xml/Schema/XmlValueConverter.cs | 2 +- System.Xml/System/Xml/Schema/XsdBuilder.cs | 2 +- System.Xml/System/Xml/Schema/XsdDateTime.cs | 2 +- System.Xml/System/Xml/Schema/XsdDuration.cs | 2 +- System.Xml/System/Xml/Schema/XsdValidator.cs | 2 +- .../Advanced/SchemaImporterExtension.cs | 2 +- .../System/Xml/Serialization/CodeExporter.cs | 2 +- .../System/Xml/Serialization/CodeGenerator.cs | 2 +- .../Xml/Serialization/CodeIdentifier.cs | 2 +- .../Xml/Serialization/CodeIdentifiers.cs | 2 +- .../System/Xml/Serialization/Compilation.cs | 2 +- .../System/Xml/Serialization/Compiler.cs | 2 +- .../Configuration/ConfigurationStrings.cs | 2 +- .../DateTimeSerializationSection.cs | 2 +- .../SchemaImporterExtensionElement.cs | 2 +- ...chemaImporterExtensionElementCollection.cs | 2 +- .../SchemaImporterExtensionsSection.cs | 2 +- .../SerializationSectionGroup.cs | 2 +- .../System/Xml/Serialization/ImportContext.cs | 2 +- .../System/Xml/Serialization/Mappings.cs | 2 +- System.Xml/System/Xml/Serialization/Models.cs | 2 +- .../System/Xml/Serialization/NameTable.cs | 2 +- .../Serialization/PrimitiveXmlSerializers.cs | 2 +- .../Xml/Serialization/SchemaImporter.cs | 2 +- .../Xml/Serialization/SchemaObjectWriter.cs | 2 +- .../Serialization/SoapAttributeAttribute.cs | 2 +- .../Serialization/SoapAttributeOverrides.cs | 2 +- .../Xml/Serialization/SoapAttributes.cs | 2 +- .../Xml/Serialization/SoapCodeExporter.cs | 2 +- .../Xml/Serialization/SoapElementAttribute.cs | 2 +- .../Xml/Serialization/SoapEnumAttribute.cs | 2 +- .../Xml/Serialization/SoapIgnoreAttribute.cs | 2 +- .../Xml/Serialization/SoapIncludeAttribute.cs | 2 +- .../Serialization/SoapReflectionImporter.cs | 2 +- .../Xml/Serialization/SoapSchemaExporter.cs | 2 +- .../Xml/Serialization/SoapSchemaImporter.cs | 2 +- .../Xml/Serialization/SoapSchemamember.cs | 2 +- .../Xml/Serialization/SoapTypeAttribute.cs | 2 +- .../System/Xml/Serialization/SourceInfo.cs | 2 +- System.Xml/System/Xml/Serialization/Types.cs | 4 +- .../Serialization/XmlAnyAttributeAttribute.cs | 2 +- .../Serialization/XmlAnyElementAttribute.cs | 2 +- .../Serialization/XmlAnyElementAttributes.cs | 2 +- .../Xml/Serialization/XmlArrayAttribute.cs | 2 +- .../Serialization/XmlArrayItemAttribute.cs | 2 +- .../Serialization/XmlArrayItemAttributes.cs | 2 +- .../Serialization/XmlAttributeAttribute.cs | 2 +- .../Serialization/XmlAttributeOverrides.cs | 2 +- .../System/Xml/Serialization/XmlAttributes.cs | 2 +- .../XmlChoiceIdentifierAttribute.cs | 2 +- .../Xml/Serialization/XmlCodeExporter.cs | 2 +- .../Xml/Serialization/XmlElementAttribute.cs | 2 +- .../Xml/Serialization/XmlElementAttributes.cs | 2 +- .../Xml/Serialization/XmlEnumAttribute.cs | 2 +- .../Xml/Serialization/XmlIgnoreAttribute.cs | 2 +- .../Xml/Serialization/XmlIncludeAttribute.cs | 2 +- .../System/Xml/Serialization/XmlMapping.cs | 2 +- .../Xml/Serialization/XmlMemberMapping.cs | 2 +- .../Xml/Serialization/XmlMembersMapping.cs | 2 +- .../XmlNamespaceDeclarationsAttribute.cs | 2 +- .../Serialization/XmlReflectionImporter.cs | 2 +- .../Xml/Serialization/XmlReflectionMember.cs | 2 +- .../Xml/Serialization/XmlRootAttribute.cs | 2 +- .../Xml/Serialization/XmlSchemaExporter.cs | 2 +- .../Xml/Serialization/XmlSchemaImporter.cs | 2 +- .../XmlSchemaProviderAttribute.cs | 2 +- .../System/Xml/Serialization/XmlSchemas.cs | 2 +- .../XmlSerializationGeneratedCode.cs | 2 +- .../Serialization/XmlSerializationILGen.cs | 2 +- .../Serialization/XmlSerializationReader.cs | 4 +- .../XmlSerializationReaderILGen.cs | 4 +- .../Serialization/XmlSerializationWriter.cs | 4 +- .../XmlSerializationWriterILGen.cs | 2 +- .../System/Xml/Serialization/XmlSerializer.cs | 2 +- .../XmlSerializerAssemblyAttribute.cs | 2 +- .../Xml/Serialization/XmlSerializerFactory.cs | 2 +- .../Serialization/XmlSerializerNamespaces.cs | 2 +- .../XmlSerializerVersionAttribute.cs | 2 +- .../Xml/Serialization/XmlTextAttribute.cs | 2 +- .../Xml/Serialization/XmlTypeAttribute.cs | 2 +- .../Xml/Serialization/XmlTypeMapping.cs | 2 +- .../Xml/Serialization/Xmlcustomformatter.cs | 2 +- .../System/Xml/Serialization/_Events.cs | 2 +- .../Xml/Serialization/indentedWriter.cs | 2 +- System.Xml/System/Xml/ValidateNames.cs | 2 +- .../Xml/XPath/Internal/AbsoluteQuery.cs | 2 +- .../Xml/XPath/Internal/AttributeQuery.cs | 2 +- System.Xml/System/Xml/XPath/Internal/Axis.cs | 2 +- .../Xml/XPath/Internal/BaseAxisQuery.cs | 2 +- .../System/Xml/XPath/Internal/BooleanExpr.cs | 2 +- .../Xml/XPath/Internal/BooleanFunctions.cs | 2 +- .../Xml/XPath/Internal/CacheAxisQuery.cs | 2 +- .../Xml/XPath/Internal/CacheChildrenQuery.cs | 2 +- .../Xml/XPath/Internal/CacheOutputQuery.cs | 2 +- .../Xml/XPath/Internal/ChildrenQuery.cs | 2 +- .../Xml/XPath/Internal/ClonableStack.cs | 2 +- .../Xml/XPath/Internal/CompiledXPathExpr.cs | 2 +- .../System/Xml/XPath/Internal/ContextQuery.cs | 2 +- .../Xml/XPath/Internal/DescendantBaseQuery.cs | 2 +- .../Xml/XPath/Internal/DescendantQuery.cs | 2 +- .../Internal/DescendantoverDescendantQuery.cs | 2 +- .../Xml/XPath/Internal/DocumentorderQuery.cs | 2 +- .../System/Xml/XPath/Internal/EmptyQuery.cs | 2 +- .../Xml/XPath/Internal/ExtensionQuery.cs | 2 +- .../System/Xml/XPath/Internal/Filter.cs | 2 +- .../System/Xml/XPath/Internal/FilterQuery.cs | 2 +- .../Xml/XPath/Internal/FollowingQuery.cs | 2 +- .../Xml/XPath/Internal/FollowingSibling.cs | 2 +- .../XPath/Internal/ForwardPositionQuery.cs | 2 +- .../System/Xml/XPath/Internal/Function.cs | 2 +- .../Xml/XPath/Internal/FunctionQuery.cs | 2 +- System.Xml/System/Xml/XPath/Internal/Group.cs | 2 +- .../System/Xml/XPath/Internal/GroupQuery.cs | 2 +- .../System/Xml/XPath/Internal/IdQuery.cs | 2 +- .../Xml/XPath/Internal/IteratorFilter.cs | 2 +- .../System/Xml/XPath/Internal/LogicalExpr.cs | 2 +- .../Xml/XPath/Internal/MergeFilterQuery.cs | 2 +- .../Xml/XPath/Internal/NamespaceQuery.cs | 2 +- .../Xml/XPath/Internal/NodeFunctions.cs | 2 +- .../Xml/XPath/Internal/NumberFunctions.cs | 2 +- .../System/Xml/XPath/Internal/NumericExpr.cs | 2 +- .../System/Xml/XPath/Internal/Operand.cs | 2 +- .../System/Xml/XPath/Internal/OperandQuery.cs | 2 +- .../System/Xml/XPath/Internal/Operator.cs | 2 +- .../System/Xml/XPath/Internal/ParentQuery.cs | 2 +- .../Xml/XPath/Internal/PrecedingQuery.cs | 2 +- .../Xml/XPath/Internal/PrecedingSibling.cs | 2 +- System.Xml/System/Xml/XPath/Internal/Query.cs | 2 +- .../System/Xml/XPath/Internal/QueryBuilder.cs | 2 +- .../Xml/XPath/Internal/ResetableIterator.cs | 2 +- .../XPath/Internal/ReversePositionQuery.cs | 2 +- System.Xml/System/Xml/XPath/Internal/Root.cs | 2 +- .../System/Xml/XPath/Internal/SortQuery.cs | 2 +- .../Xml/XPath/Internal/StringFunctions.cs | 2 +- .../System/Xml/XPath/Internal/UnionExpr.cs | 2 +- .../System/Xml/XPath/Internal/ValueQuery.cs | 2 +- .../System/Xml/XPath/Internal/Variable.cs | 2 +- .../Xml/XPath/Internal/VariableQuery.cs | 2 +- .../XPath/Internal/XPathAncestorIterator.cs | 2 +- .../Xml/XPath/Internal/XPathAncestorQuery.cs | 2 +- .../Xml/XPath/Internal/XPathArrayIterator.cs | 2 +- .../Xml/XPath/Internal/XPathAxisIterator.cs | 2 +- .../Xml/XPath/Internal/XPathChildIterator.cs | 2 +- .../XPath/Internal/XPathDescendantIterator.cs | 2 +- .../Xml/XPath/Internal/XPathEmptyIterator.cs | 2 +- .../Xml/XPath/Internal/XPathMultyIterator.cs | 2 +- .../System/Xml/XPath/Internal/XPathParser.cs | 2 +- .../System/Xml/XPath/Internal/XPathScanner.cs | 2 +- .../XPath/Internal/XPathSelectionIterator.cs | 2 +- .../Xml/XPath/Internal/XPathSelfQuery.cs | 2 +- .../XPath/Internal/XPathSingletonIterator.cs | 2 +- System.Xml/System/Xml/XPath/XPathDocument.cs | 4 +- System.Xml/System/Xml/XPath/XPathException.cs | 2 +- System.Xml/System/Xml/XPath/XPathExpr.cs | 2 +- System.Xml/System/Xml/XPath/XPathItem.cs | 2 +- System.Xml/System/Xml/XPath/XPathNavigator.cs | 2 +- .../Xml/XPath/XPathNavigatorKeyComparer.cs | 2 +- .../System/Xml/XPath/XPathNavigatorReader.cs | 2 +- .../System/Xml/XPath/XPathNodeIterator.cs | 2 +- System.Xml/System/Xml/XmlCharType.cs | 2 +- System.Xml/System/Xml/XmlComplianceUtil.cs | 2 +- System.Xml/System/Xml/XmlConvert.cs | 2 +- System.Xml/System/Xml/XmlDownloadManager.cs | 2 +- System.Xml/System/Xml/XmlEncoding.cs | 2 +- System.Xml/System/Xml/XmlException.cs | 2 +- System.Xml/System/Xml/XmlNamespacemanager.cs | 2 +- System.Xml/System/Xml/XmlNullResolver.cs | 2 +- System.Xml/System/Xml/XmlQualifiedName.cs | 2 +- System.Xml/System/Xml/XmlResolver.cs | 2 +- System.Xml/System/Xml/XmlSecureResolver.cs | 2 +- System.Xml/System/Xml/XmlUrlResolver.cs | 2 +- .../System/Xml/Xslt/XslCompiledTransform.cs | 2 +- System.Xml/System/Xml/Xslt/XslTransform.cs | 2 +- .../System/Xml/Xslt/XsltArgumentList.cs | 2 +- System.Xml/System/Xml/Xslt/XsltContext.cs | 2 +- System.Xml/System/Xml/Xslt/XsltException.cs | 2 +- System.Xml/System/Xml/Xslt/XsltSettings.cs | 2 +- System/System.txt | 23 +- .../microsoft/win32/UnsafeNativeMethods.cs | 6 +- .../safehandles/SafeEventLogReadHandle.cs | 2 +- .../safehandles/SafeEventLogWriteHandle.cs | 2 +- .../safehandles/SafeFileMapViewHandle.cs | 2 +- .../safehandles/SafeFileMappingHandle.cs | 2 +- .../win32/safehandles/SafeLibraryHandle.cs | 2 +- .../win32/safehandles/SafeLocalMemHandle.cs | 2 +- .../win32/safehandles/SafeTimerHandle.cs | 2 +- .../win32/safehandles/SafeUserTokenHandle.cs | 2 +- .../CodeArgumentReferenceExpression.cs | 2 +- .../codedom/CodeArrayCreateExpression.cs | 2 +- .../codedom/CodeArrayIndexerExpression.cs | 2 +- .../system/codedom/CodeAssignStatement.cs | 2 +- .../codedom/CodeAttachEventStatement.cs | 2 +- .../system/codedom/CodeAttributeArgument.cs | 2 +- .../CodeAttributeArgumentCollection.cs | 2 +- .../codedom/CodeAttributeDeclaration.cs | 2 +- .../CodeAttributeDeclarationCollection.cs | 2 +- .../codedom/CodeBinaryOperatorExpression.cs | 2 +- .../system/codedom/CodeCastExpression.cs | 2 +- .../compmod/system/codedom/CodeCatchClause.cs | 2 +- .../codedom/CodeCatchClauseCollection.cs | 2 +- .../system/codedom/CodeChecksumPragma.cs | 2 +- System/compmod/system/codedom/CodeComment.cs | 2 +- .../system/codedom/CodeCommentStatement.cs | 2 +- .../codedom/CodeCommentStatementCollection.cs | 2 +- .../compmod/system/codedom/CodeCompileUnit.cs | 2 +- .../system/codedom/CodeConditionStatement.cs | 2 +- .../compmod/system/codedom/CodeConstructor.cs | 2 +- .../codedom/CodeDefaultValueExpression.cs | 2 +- .../codedom/CodeDelegateCreateExpression.cs | 2 +- .../codedom/CodeDelegateInvokeExpression.cs | 2 +- .../system/codedom/CodeDirectionExpression.cs | 2 +- .../system/codedom/CodeDirectiveCollection.cs | 2 +- .../system/codedom/CodeEntryPointMethod.cs | 2 +- .../codedom/CodeEventReferenceExpression.cs | 2 +- .../codedom/CodeExpressionCollection.cs | 2 +- .../system/codedom/CodeExpressionStatement.cs | 2 +- .../codedom/CodeFieldReferenceExpression.cs | 2 +- .../system/codedom/CodeGotoStatement.cs | 2 +- .../system/codedom/CodeIndexerExpression.cs | 2 +- .../system/codedom/CodeIterationStatement.cs | 2 +- .../system/codedom/CodeLabeledStatement.cs | 2 +- .../compmod/system/codedom/CodeLinePragma.cs | 2 +- .../compmod/system/codedom/CodeMemberEvent.cs | 2 +- .../compmod/system/codedom/CodeMemberField.cs | 2 +- .../system/codedom/CodeMemberMethod.cs | 2 +- .../system/codedom/CodeMemberProperty.cs | 2 +- .../codedom/CodeMethodInvokeExpression.cs | 2 +- .../codedom/CodeMethodReturnStatement.cs | 2 +- .../compmod/system/codedom/CodeNamespace.cs | 2 +- .../system/codedom/CodeNamespaceCollection.cs | 2 +- .../system/codedom/CodeNamespaceImport.cs | 2 +- .../codedom/CodeNamespaceImportCollection.cs | 2 +- System/compmod/system/codedom/CodeObject.cs | 2 +- .../codedom/CodeObjectCreateExpression.cs | 2 +- .../CodeParameterDeclarationExpression.cs | 2 +- ...arameterDeclarationExpressionCollection.cs | 2 +- .../system/codedom/CodePrimitiveExpression.cs | 2 +- .../CodePropertyReferenceExpression.cs | 2 +- .../system/codedom/CodeRegionDirective.cs | 2 +- .../codedom/CodeRemoveEventStatement.cs | 2 +- .../system/codedom/CodeSnippetCompileUnit.cs | 2 +- .../system/codedom/CodeSnippetExpression.cs | 2 +- .../system/codedom/CodeSnippetStatement.cs | 2 +- .../system/codedom/CodeSnippetTypeMember.cs | 2 +- .../compmod/system/codedom/CodeStatement.cs | 2 +- .../system/codedom/CodeStatementCollection.cs | 2 +- .../codedom/CodeThrowExceptionStatement.cs | 2 +- .../codedom/CodeTryCatchFinallyStatement.cs | 2 +- .../system/codedom/CodeTypeConstructor.cs | 2 +- .../system/codedom/CodeTypeDeclaration.cs | 2 +- .../codedom/CodeTypeDeclarationCollection.cs | 2 +- .../system/codedom/CodeTypeDelegate.cs | 2 +- .../compmod/system/codedom/CodeTypeMember.cs | 2 +- .../codedom/CodeTypeMemberCollection.cs | 2 +- .../system/codedom/CodeTypeOfExpression.cs | 2 +- .../system/codedom/CodeTypeParameter.cs | 2 +- .../codedom/CodeTypeParameterCollection.cs | 2 +- .../system/codedom/CodeTypeReference.cs | 2 +- .../codedom/CodeTypeReferenceCollection.cs | 2 +- .../codedom/CodeTypeReferenceExpression.cs | 2 +- .../CodeVariableDeclarationStatement.cs | 2 +- .../CodeVariableReferenceExpression.cs | 2 +- .../codedom/codemethodreferenceexpression.cs | 2 +- .../system/codedom/compiler/CodeCompiler.cs | 2 +- .../codedom/compiler/CodeDOMProvider.cs | 2 +- .../compiler/CodeDomConfigurationHandler.cs | 2 +- .../system/codedom/compiler/CodeGenerator.cs | 2 +- .../codedom/compiler/CodeGeneratorOptions.cs | 2 +- .../system/codedom/compiler/CodeValidator.cs | 2 +- .../system/codedom/compiler/CompilerError.cs | 2 +- .../compiler/CompilerErrorCollection.cs | 2 +- .../system/codedom/compiler/CompilerInfo.cs | 2 +- .../codedom/compiler/CompilerParameters.cs | 2 +- .../codedom/compiler/CompilerResults.cs | 2 +- .../system/codedom/compiler/Executor.cs | 2 +- .../compiler/GeneratedCodeAttribute.cs | 2 +- .../codedom/compiler/IndentTextWriter.cs | 2 +- .../codedom/compiler/RedistVersionInfo.cs | 2 +- .../system/codedom/compiler/TempFiles.cs | 2 +- .../system/collections/generic/stack.cs | 2 +- .../objectmodel/observablecollection.cs | 2 +- .../specialized/marshalinghelpers.cs | 2 +- .../system/componentmodel/AsyncOperation.cs | 2 +- .../system/componentmodel/MemberDescriptor.cs | 2 +- .../componentmodel/PropertyDescriptor.cs | 2 +- .../componentmodel/design/DesignerVerb.cs | 2 +- .../system/diagnostics/assertwrapper.cs | 8 +- System/misc/ClientUtils.cs | 6 +- System/misc/SecurityUtils.cs | 6 +- System/misc/externdll.cs | 1 + .../Net/Cache/HttpRequestCacheValidator.cs | 2 +- System/net/System/Net/Cache/IERequestCache.cs | 2 +- .../System/Net/Cache/RequestCachePolicy.cs | 4 +- .../Net/Configuration/DefaultProxySection.cs | 2 +- .../TimeoutValidationAttribute.cs | 4 +- System/net/System/Net/FtpWebRequest.cs | 10 +- System/net/System/Net/HttpListenerRequest.cs | 131 +- System/net/System/Net/HttpWebRequest.cs | 34 +- System/net/System/Net/Internal.cs | 2 +- .../Net/SecureProtocols/NegotiateStream.cs | 10 +- .../Net/SecureProtocols/SslEnumTypes.cs | 8 +- .../System/Net/SecureProtocols/SslStream.cs | 83 +- .../Net/SecureProtocols/_FixedSizeReader.cs | 4 +- .../System/Net/SecureProtocols/_NegoStream.cs | 12 +- .../System/Net/SecureProtocols/_SslState.cs | 67 +- .../System/Net/SecureProtocols/_SslStream.cs | 17 +- System/net/System/Net/ServicePoint.cs | 2 +- System/net/System/Net/ServicePointManager.cs | 420 +- .../net/System/Net/Sockets/NetworkStream.cs | 14 +- System/net/System/Net/Sockets/Socket.cs | 12 +- System/net/System/Net/UnsafeNativeMethods.cs | 116 +- System/net/System/Net/WebRequest.cs | 2 +- .../WebSocketHttpListenerDuplexStream.cs | 12 +- System/net/System/Net/WebUtility.cs | 4 +- System/net/System/Net/_AuthenticationState.cs | 2 +- System/net/System/Net/_ChunkParser.cs | 2 +- System/net/System/Net/_CommandStream.cs | 8 +- System/net/System/Net/_ConnectStream.cs | 18 +- System/net/System/Net/_Connection.cs | 20 +- System/net/System/Net/_ContextAwareResult.cs | 2 +- System/net/System/Net/_DigestClient.cs | 2 +- System/net/System/Net/_HTTPDateParse.cs | 4 +- System/net/System/Net/_LazyAsyncResult.cs | 2 +- .../net/System/Net/_ListenerResponseStream.cs | 2 +- System/net/System/Net/_NativeSSPI.cs | 11 + System/net/System/Net/_SSPIWrapper.cs | 58 + System/net/System/Net/_SafeNetHandles.cs | 121 + System/net/System/Net/_SecureChannel.cs | 189 +- System/net/System/Net/_TLSstream.cs | 14 +- System/net/System/Net/_TimerThread.cs | 2 +- System/net/System/Net/mail/MailHeaderInfo.cs | 6 +- System/net/System/Net/mail/SmtpClient.cs | 2 +- System/net/System/Net/mail/SmtpTransport.cs | 2 +- System/net/System/Net/mail/smtpconnection.cs | 4 +- System/net/System/URI.cs | 30 +- .../system/text/regularexpressions/Regex.cs | 10 +- .../text/regularexpressions/RegexCompiler.cs | 4 +- .../text/regularexpressions/RegexGroup.cs | 21 +- .../RegexGroupCollection.cs | 3 +- .../text/regularexpressions/RegexMatch.cs | 2 +- .../system/diagnosticts/EventLog.cs | 12 +- .../system/diagnosticts/EventLogEntry.cs | 2 +- .../diagnosticts/EventLogEntryCollection.cs | 2 +- .../system/diagnosticts/EventLogInternal.cs | 22 +- .../system/diagnosticts/ProcessManager.cs | 2 +- .../system/diagnosticts/SharedUtils.cs | 2 +- System/services/timers/system/timers/Timer.cs | 2 +- .../sys/AppContextDefaultValues.Defaults.cs | 11 +- System/sys/LocalAppContextSwitches.cs | 25 + System/sys/system/IO/ports/SerialStream.cs | 10 +- System/sys/system/Media/SoundPlayer.cs | 2 +- .../concurrent/BlockingCollection.cs | 2 +- .../collections/concurrent/ConcurrentBag.cs | 2 +- System/sys/system/threading/Barrier.cs | 2 +- .../markup/ValueSerializerAttribute.cs | 2 +- .../NDP_Common/inc/StrongNameHelpers.cs | 40 +- mscorlib/microsoft/win32/oavariantlib.cs | 2 +- .../win32/safehandles/saferegistryhandle.cs | 2 +- mscorlib/mscorlib.txt | 682 +- mscorlib/system/AggregateException.cs | 2 +- mscorlib/system/AppContext/AppContext.cs | 88 +- .../AppContextDefaultValues.Defaults.cs | 10 +- ...ppContextDefaultValues.DesktopOverrides.cs | 50 +- .../system/AppContext/AppContextSwitches.cs | 10 + mscorlib/system/Lazy.cs | 4 +- mscorlib/system/appdomain.cs | 25 +- mscorlib/system/appdomainattributes.cs | 2 +- mscorlib/system/appdomainunloadedexception.cs | 2 +- mscorlib/system/argiterator.cs | 2 +- mscorlib/system/array.cs | 2 +- mscorlib/system/badimageformatexception.cs | 2 +- .../system/cannotunloadappdomainexception.cs | 2 +- .../Concurrent/CDSCollectionETWBCLProvider.cs | 2 +- .../Concurrent/ConcurrentDictionary.cs | 2 +- .../collections/Concurrent/ConcurrentQueue.cs | 2 +- .../collections/Concurrent/ConcurrentStack.cs | 2 +- .../Concurrent/IProducerConsumerCollection.cs | 2 +- .../Concurrent/OrderablePartitioner.cs | 2 +- .../collections/Concurrent/Partitioner.cs | 2 +- .../Concurrent/PartitionerStatic.cs | 2 +- mscorlib/system/collections/arraylist.cs | 2 +- mscorlib/system/collections/bitarray.cs | 2 +- .../collections/caseinsensitivecomparer.cs | 2 +- .../caseinsensitivehashcodeprovider.cs | 2 +- mscorlib/system/collections/collectionbase.cs | 2 +- mscorlib/system/collections/comparer.cs | 2 +- .../system/collections/compatiblecomparer.cs | 2 +- mscorlib/system/collections/dictionarybase.cs | 2 +- .../system/collections/dictionaryentry.cs | 2 +- .../emptyreadonlydictionaryinternal.cs | 2 +- .../collections/generic/arraysorthelper.cs | 2 +- .../system/collections/generic/comparer.cs | 2 +- .../system/collections/generic/debugview.cs | 2 +- .../system/collections/generic/dictionary.cs | 2 +- .../collections/generic/equalitycomparer.cs | 2 +- .../generic/keynotfoundexception.cs | 2 +- .../collections/generic/keyvaluepair.cs | 2 +- mscorlib/system/collections/generic/list.cs | 2 +- mscorlib/system/collections/hashtable.cs | 2 +- mscorlib/system/collections/keyvaluepairs.cs | 2 +- .../collections/listdictionaryinternal.cs | 2 +- .../collections/objectmodel/collection.cs | 2 +- .../objectmodel/keyedcollection.cs | 2 +- .../objectmodel/readonlycollection.cs | 2 +- mscorlib/system/collections/queue.cs | 2 +- .../collections/readonlycollectionbase.cs | 2 +- mscorlib/system/collections/sortedlist.cs | 2 +- mscorlib/system/collections/stack.cs | 4 +- .../collections/structuralcomparisons.cs | 2 +- mscorlib/system/delegate.cs | 2 +- .../system/diagnostics/contracts/contracts.cs | 2 +- .../diagnostics/contracts/contractsbcl.cs | 2 +- .../eventing/TraceLogging/EventPayload.cs | 5 +- .../diagnostics/eventing/activitytracker.cs | 2 +- .../diagnostics/eventing/eventdescriptor.cs | 2 +- .../diagnostics/eventing/eventsource.cs | 31 +- .../eventing/frameworkeventsource.cs | 4 +- mscorlib/system/exception.cs | 2 +- mscorlib/system/executionengineexception.cs | 2 +- .../system/globalization/Persiancalendar.cs | 2 +- mscorlib/system/globalization/calendar.cs | 2 +- mscorlib/system/globalization/calendardata.cs | 2 +- mscorlib/system/globalization/culturedata.cs | 2 +- mscorlib/system/globalization/cultureinfo.cs | 2 +- .../system/globalization/datetimeparse.cs | 2 +- .../eastasianlunisolarcalendar.cs | 2 +- mscorlib/system/globalization/hebrewnumber.cs | 4 +- mscorlib/system/globalization/regioninfo.cs | 2 +- mscorlib/system/globalization/stringinfo.cs | 2 +- .../system/globalization/taiwancalendar.cs | 2 +- .../globalization/textelementenumerator.cs | 2 +- mscorlib/system/globalization/textinfo.cs | 2 +- .../system/globalization/timespanformat.cs | 2 +- .../system/globalization/timespanparse.cs | 2 +- .../system/globalization/umalquracalendar.cs | 2 +- mscorlib/system/io/__consolestream.cs | 2 +- mscorlib/system/io/__error.cs | 2 +- mscorlib/system/io/bufferedstream.cs | 4 +- mscorlib/system/io/directory.cs | 153 +- mscorlib/system/io/directoryinfo.cs | 115 +- .../system/io/directorynotfoundexception.cs | 2 +- mscorlib/system/io/driveinfo.cs | 2 +- mscorlib/system/io/drivenotfoundexception.cs | 2 +- mscorlib/system/io/endofstreamexception.cs | 2 +- mscorlib/system/io/file.cs | 2 +- mscorlib/system/io/fileinfo.cs | 2 +- mscorlib/system/io/fileloadexception.cs | 4 +- mscorlib/system/io/filenotfoundexception.cs | 4 +- mscorlib/system/io/filestream.cs | 22 +- mscorlib/system/io/filesystemenumerable.cs | 2 +- mscorlib/system/io/filesysteminfo.cs | 44 +- mscorlib/system/io/ioexception.cs | 2 +- .../io/isolatedstorage/isolatedstorage.cs | 6 +- .../isolatedstorageexception.cs | 2 +- .../io/isolatedstorage/isolatedstoragefile.cs | 12 +- .../isolatedstoragefilestream.cs | 2 +- mscorlib/system/io/longpath.cs | 2 +- mscorlib/system/io/memorystream.cs | 4 +- mscorlib/system/io/path.cs | 24 +- mscorlib/system/io/pathinternal.cs | 645 + mscorlib/system/io/pathtoolongexception.cs | 2 +- .../system/io/pinnedbuffermemorystream.cs | 2 +- mscorlib/system/io/stringreader.cs | 2 +- mscorlib/system/io/stringwriter.cs | 2 +- mscorlib/system/io/textreader.cs | 2 +- mscorlib/system/io/textwriter.cs | 2 +- mscorlib/system/io/unmanagedmemoryaccessor.cs | 2 +- mscorlib/system/io/unmanagedmemorystream.cs | 6 +- .../system/io/unmanagedmemorystreamwrapper.cs | 4 +- mscorlib/system/object.cs | 2 +- mscorlib/system/progress.cs | 10 +- mscorlib/system/reflection/Associates.cs | 2 +- mscorlib/system/reflection/ConstructorInfo.cs | 2 +- mscorlib/system/reflection/__filters.cs | 2 +- .../reflection/ambiguousmatchexception.cs | 2 +- mscorlib/system/reflection/assembly.cs | 2 +- .../system/reflection/assemblyattributes.cs | 2 +- mscorlib/system/reflection/assemblyname.cs | 4 +- .../system/reflection/assemblynameproxy.cs | 4 +- mscorlib/system/reflection/customattribute.cs | 2 +- .../customattributeformatexception.cs | 4 +- .../reflection/defaultmemberattribute.cs | 2 +- mscorlib/system/reflection/emit/aqnbuilder.cs | 2 +- .../system/reflection/emit/assemblybuilder.cs | 4 +- .../reflection/emit/assemblybuilderdata.cs | 2 +- .../reflection/emit/constructorbuilder.cs | 2 +- .../reflection/emit/customattributebuilder.cs | 2 +- .../reflection/emit/dynamicilgenerator.cs | 4 +- .../system/reflection/emit/dynamicmethod.cs | 2 +- .../system/reflection/emit/enumbuilder.cs | 2 +- .../system/reflection/emit/eventbuilder.cs | 2 +- mscorlib/system/reflection/emit/eventtoken.cs | 2 +- .../system/reflection/emit/fieldbuilder.cs | 2 +- mscorlib/system/reflection/emit/fieldtoken.cs | 2 +- .../emit/generictypeparameterbuilder.cs | 2 +- .../system/reflection/emit/ilgenerator.cs | 2 +- mscorlib/system/reflection/emit/label.cs | 2 +- .../system/reflection/emit/localbuilder.cs | 2 +- .../system/reflection/emit/methodbuilder.cs | 4 +- .../emit/methodbuilderinstantiation.cs | 2 +- .../system/reflection/emit/methodrental.cs | 2 +- .../system/reflection/emit/methodtoken.cs | 2 +- .../system/reflection/emit/modulebuilder.cs | 2 +- .../reflection/emit/modulebuilderdata.cs | 2 +- mscorlib/system/reflection/emit/opcode.cs | 2 +- mscorlib/system/reflection/emit/opcodes.cs | 2 +- .../reflection/emit/parameterbuilder.cs | 2 +- .../system/reflection/emit/parametertoken.cs | 2 +- .../system/reflection/emit/propertybuilder.cs | 2 +- .../system/reflection/emit/propertytoken.cs | 2 +- .../system/reflection/emit/signaturehelper.cs | 2 +- .../system/reflection/emit/signaturetoken.cs | 2 +- .../system/reflection/emit/stringtoken.cs | 2 +- .../system/reflection/emit/symbolmethod.cs | 2 +- mscorlib/system/reflection/emit/symboltype.cs | 2 +- .../system/reflection/emit/typebuilder.cs | 2 +- .../emit/typebuilderinstantiation.cs | 2 +- mscorlib/system/reflection/emit/typetoken.cs | 2 +- .../reflection/emit/unmanagedmarshal.cs | 2 +- .../emit/xxxontypebuilderinstantiation.cs | 2 +- mscorlib/system/reflection/eventinfo.cs | 2 +- mscorlib/system/reflection/fieldinfo.cs | 2 +- .../reflection/introspectionextensions.cs | 2 +- .../invalidfiltercriteriaexception.cs | 2 +- mscorlib/system/reflection/loaderallocator.cs | 2 +- .../system/reflection/manifestresourceinfo.cs | 2 +- mscorlib/system/reflection/mdconstant.cs | 2 +- mscorlib/system/reflection/mdimport.cs | 6 +- mscorlib/system/reflection/memberinfo.cs | 2 +- .../memberinfoserializationholder.cs | 2 +- mscorlib/system/reflection/methodbase.cs | 2 +- mscorlib/system/reflection/methodbody.cs | 2 +- mscorlib/system/reflection/methodinfo.cs | 2 +- mscorlib/system/reflection/missing.cs | 2 +- mscorlib/system/reflection/module.cs | 4 +- .../reflection/obfuscateassemblyattribute.cs | 2 +- .../system/reflection/obfuscationattribute.cs | 2 +- mscorlib/system/reflection/parameterinfo.cs | 2 +- .../system/reflection/parametermodifier.cs | 2 +- mscorlib/system/reflection/pointer.cs | 2 +- mscorlib/system/reflection/propertyinfo.cs | 2 +- .../system/reflection/reflectioncontext.cs | 2 +- .../reflection/reflectiontypeloadexception.cs | 2 +- .../system/reflection/strongnamekeypair.cs | 2 +- mscorlib/system/reflection/targetexception.cs | 2 +- .../reflection/targetinvocationexception.cs | 2 +- .../targetparametercountexception.cs | 2 +- mscorlib/system/reflection/typedelegator.cs | 2 +- mscorlib/system/reflection/typeinfo.cs | 2 +- .../resources/__fastresourcecomparer.cs | 2 +- .../resources/filebasedresourcegroveler.cs | 2 +- .../manifestbasedresourcegroveler.cs | 2 +- .../missingmanifestresourceexception.cs | 2 +- .../missingsatelliteassemblyexception.cs | 2 +- .../neutralresourceslanguageattribute.cs | 2 +- .../resources/resourcefallbackmanager.cs | 4 +- mscorlib/system/resources/resourcemanager.cs | 4 +- mscorlib/system/resources/resourcereader.cs | 17 +- mscorlib/system/resources/resourceset.cs | 2 +- mscorlib/system/resources/resourcewriter.cs | 2 +- .../system/resources/runtimeresourceset.cs | 2 +- .../satellitecontractversionattribute.cs | 2 +- mscorlib/system/rttype.cs | 6 +- .../compilerservices/AsyncMethodBuilder.cs | 4 +- .../compilerservices/ConditionalWeakTable.cs | 2 +- .../runtime/compilerservices/TaskAwaiter.cs | 2 +- .../compilerservices/YieldAwaitable.cs | 2 +- .../compilationrelaxations.cs | 2 +- .../compilerservices/runtimehelpers.cs | 2 +- .../corruptingexceptioncommon.cs | 2 +- .../exceptionnotification.cs | 2 +- .../exceptionservicescommon.cs | 2 +- .../runtime/interopservices/attributes.cs | 5 +- .../runtime/interopservices/gchandle.cs | 2 +- .../windowsruntime/attributes.cs | 6 +- .../bindablevectortocollectionadapter.cs | 4 +- .../bindablevectortolistadapter.cs | 2 +- .../windowsruntime/clrikeyvaluepairimpl.cs | 4 +- .../windowsruntime/clripropertyvalueimpl.cs | 8 +- .../windowsruntime/clrireferenceimpl.cs | 6 +- .../windowsruntime/custompropertyimpl.cs | 2 +- .../windowsruntime/dictionarytomapadapter.cs | 2 +- .../enumeratortoiteratoradapter.cs | 6 +- .../windowsruntime/eventregistrationtoken.cs | 6 +- .../eventregistrationtokentable.cs | 6 +- .../windowsruntime/icustompropertyprovider.cs | 2 +- .../imapviewtoireadonlydictionaryadapter.cs | 2 +- .../ireadonlydictionarytoimapviewadapter.cs | 2 +- .../ireadonlylisttoivectorviewadapter.cs | 2 +- .../iteratortoenumeratoradapter.cs | 4 +- .../ivectorviewtoireadonlylistadapter.cs | 2 +- .../listtobindablevectoradapter.cs | 2 +- .../listtobindablevectorviewadapter.cs | 2 +- .../windowsruntime/listtovectoradapter.cs | 2 +- .../managedactivationfactory.cs | 6 +- .../windowsruntime/maptocollectionadapter.cs | 2 +- .../windowsruntime/maptodictionaryadapter.cs | 2 +- .../mapviewtoreadonlycollectionadapter.cs | 2 +- .../vectortocollectionadapter.cs | 2 +- .../windowsruntime/vectortolistadapter.cs | 2 +- .../vectorviewtoreadonlycollectionadapter.cs | 2 +- .../windowsruntime/windowsruntimemarshal.cs | 6 +- .../windowsruntime/windowsruntimemetadata.cs | 2 +- .../windowsruntime/winrtclassactivator.cs | 2 +- .../runtime/remoting/activationservices.cs | 2 +- .../runtime/remoting/channelservices.cs | 2 +- .../runtime/remoting/channelsinkstacks.cs | 2 +- .../system/runtime/remoting/clientsponsor.cs | 4 +- .../system/runtime/remoting/configuration.cs | 2 +- mscorlib/system/runtime/remoting/context.cs | 2 +- .../runtime/remoting/crossappdomainchannel.cs | 10 +- .../runtime/remoting/crosscontextchannel.cs | 4 +- .../system/runtime/remoting/identityholder.cs | 2 +- mscorlib/system/runtime/remoting/lease.cs | 2 +- .../system/runtime/remoting/leasemanager.cs | 2 +- mscorlib/system/runtime/remoting/message.cs | 6 +- mscorlib/system/runtime/remoting/objref.cs | 8 +- mscorlib/system/runtime/remoting/realproxy.cs | 8 +- .../runtime/remoting/remotingattributes.cs | 2 +- .../system/runtime/remoting/remotingproxy.cs | 2 +- .../runtime/remoting/remotingservices.cs | 4 +- .../runtime/remoting/soapinteroptypes.cs | 2 +- .../runtime/remoting/synchronizeddispatch.cs | 40 +- .../system/runtime/remoting/urlattribute.cs | 4 +- .../serialization/formatters/soapfault.cs | 2 +- .../serialization/formatterservices.cs | 44 +- .../serialization/safeserializationmanager.cs | 2 +- .../runtime/serialization/streamingcontext.cs | 2 +- .../runtime/versioning/binarycompatibility.cs | 2 +- .../versioning/multitargetinghelpers.cs | 2 +- mscorlib/system/runtimehandles.cs | 2 +- mscorlib/system/security/accesscontrol/acl.cs | 2 +- .../accesscontrol/securitydescriptor.cs | 4 +- mscorlib/system/security/attributes.cs | 2 +- .../system/security/builtinpermissionsets.cs | 2 +- mscorlib/system/security/claims/Claim.cs | 2 +- .../system/security/claims/ClaimsIdentity.cs | 2 +- .../system/security/claims/ClaimsPrincipal.cs | 2 +- .../security/claims/RoleClaimProvider.cs | 2 +- .../system/security/codeaccesspermission.cs | 2 +- .../security/codeaccesssecurityengine.cs | 4 +- .../cryptography/asymmetricalgorithm.cs | 2 +- .../asymmetrickeyexchangedeformatter.cs | 2 +- .../asymmetrickeyexchangeformatter.cs | 2 +- .../asymmetricsignaturedeformatter.cs | 2 +- .../asymmetricsignatureformatter.cs | 2 +- .../security/cryptography/base64transforms.cs | 2 +- .../system/security/cryptography/crypto.cs | 4 +- .../cryptography/cryptoapitransform.cs | 2 +- .../security/cryptography/cryptoconfig.cs | 2 +- .../security/cryptography/cryptostream.cs | 2 +- .../security/cryptography/derivebytes.cs | 2 +- mscorlib/system/security/cryptography/des.cs | 2 +- .../cryptography/descryptoserviceprovider.cs | 2 +- mscorlib/system/security/cryptography/dsa.cs | 2 +- .../cryptography/dsacryptoserviceprovider.cs | 2 +- .../cryptography/dsasignaturedeformatter.cs | 2 +- .../cryptography/dsasignatureformatter.cs | 2 +- .../security/cryptography/hashalgorithm.cs | 2 +- mscorlib/system/security/cryptography/hmac.cs | 2 +- .../system/security/cryptography/hmacmd5.cs | 2 +- .../security/cryptography/hmacripemd160.cs | 2 +- .../system/security/cryptography/hmacsha1.cs | 2 +- .../security/cryptography/hmacsha256.cs | 2 +- .../security/cryptography/hmacsha384.cs | 2 +- .../security/cryptography/hmacsha512.cs | 2 +- .../cryptography/icspasymmetricalgorithm.cs | 2 +- .../cryptography/keyedhashalgorithm.cs | 2 +- .../security/cryptography/mactripledes.cs | 2 +- mscorlib/system/security/cryptography/md5.cs | 2 +- .../cryptography/md5cryptoserviceprovider.cs | 2 +- .../cryptography/passwordderivebytes.cs | 2 +- .../cryptography/pkcs1maskgenerationmethod.cs | 2 +- .../cryptography/randomnumbergenerator.cs | 2 +- mscorlib/system/security/cryptography/rc2.cs | 2 +- .../cryptography/rc2cryptoserviceprovider.cs | 2 +- .../cryptography/rfc2898derivebytes.cs | 2 +- .../system/security/cryptography/rijndael.cs | 2 +- .../security/cryptography/rijndaelmanaged.cs | 2 +- .../cryptography/rijndaelmanagedtransform.cs | 2 +- .../system/security/cryptography/ripemd160.cs | 2 +- .../security/cryptography/ripemd160managed.cs | 2 +- .../cryptography/rngcryptoserviceprovider.cs | 2 +- mscorlib/system/security/cryptography/rsa.cs | 2 +- .../cryptography/rsacryptoserviceprovider.cs | 2 +- .../rsaoaepkeyexchangedeformatter.cs | 2 +- .../rsaoaepkeyexchangeformatter.cs | 2 +- .../rsapkcs1keyexchangedeformatter.cs | 2 +- .../rsapkcs1keyexchangeformatter.cs | 2 +- .../rsapkcs1signaturedeformatter.cs | 2 +- .../rsapkcs1signatureformatter.cs | 2 +- .../cryptography/safecryptohandles.cs | 2 +- mscorlib/system/security/cryptography/sha1.cs | 2 +- .../cryptography/sha1cryptoserviceprovider.cs | 2 +- .../security/cryptography/sha1managed.cs | 2 +- .../system/security/cryptography/sha256.cs | 2 +- .../security/cryptography/sha256managed.cs | 2 +- .../system/security/cryptography/sha384.cs | 2 +- .../security/cryptography/sha384managed.cs | 2 +- .../system/security/cryptography/sha512.cs | 2 +- .../security/cryptography/sha512managed.cs | 2 +- .../cryptography/signaturedescription.cs | 2 +- .../cryptography/symmetricalgorithm.cs | 2 +- .../system/security/cryptography/tripledes.cs | 2 +- .../tripledescryptoserviceprovider.cs | 2 +- .../system/security/cryptography/utils.cs | 18 +- .../security/framesecuritydescriptor.cs | 2 +- .../security/hostprotectionexception.cs | 2 +- .../system/security/hostsecuritymanager.cs | 2 +- .../system/security/namedpermissionset.cs | 2 +- mscorlib/system/security/permissionlistset.cs | 4 +- .../permissions/environmentpermission.cs | 2 +- .../permissions/filedialogpermission.cs | 2 +- .../security/permissions/fileiopermission.cs | 33 +- .../permissions/gacidentitypermission.cs | 2 +- .../permissions/hostprotectionpermission.cs | 4 +- .../isolatedstoragefilepermission.cs | 2 +- .../permissions/isolatedstoragepermission.cs | 2 +- .../permissions/keycontainerpermission.cs | 2 +- .../permissions/permissionattributes.cs | 2 +- .../permissions/principalpermission.cs | 2 +- .../publisheridentitypermission.cs | 2 +- .../permissions/reflectionpermission.cs | 2 +- .../permissions/registrypermission.cs | 2 +- .../permissions/securitypermission.cs | 2 +- .../permissions/siteidentitypermission.cs | 2 +- .../strongnameidentitypermission.cs | 2 +- .../permissions/strongnamepublickeyblob.cs | 2 +- .../security/permissions/uipermission.cs | 2 +- .../permissions/urlidentitypermission.cs | 2 +- .../permissions/zoneidentitypermission.cs | 2 +- mscorlib/system/security/permissionset.cs | 2 +- .../security/permissionsetenumerator.cs | 2 +- .../system/security/permissionsettriple.cs | 2 +- mscorlib/system/security/permissiontoken.cs | 2 +- .../security/policy/allmembershipcondition.cs | 2 +- .../security/policy/applicationdirectory.cs | 2 +- ...applicationdirectorymembershipcondition.cs | 2 +- .../policy/applicationsecurityinfo.cs | 2 +- .../policy/applicationsecuritymanager.cs | 2 +- .../security/policy/applicationtrust.cs | 6 +- .../policy/assemblyevidencefactory.cs | 2 +- mscorlib/system/security/policy/codegroup.cs | 2 +- mscorlib/system/security/policy/evidence.cs | 2 +- .../system/security/policy/evidencebase.cs | 4 +- .../security/policy/evidencetypedescriptor.cs | 2 +- .../system/security/policy/filecodegroup.cs | 2 +- .../security/policy/firstmatchcodegroup.cs | 2 +- mscorlib/system/security/policy/gac.cs | 2 +- .../security/policy/gacmembershipcondition.cs | 2 +- mscorlib/system/security/policy/hash.cs | 2 +- .../policy/hashmembershipcondition.cs | 2 +- .../policy/iapplicationtrustmanager.cs | 2 +- .../system/security/policy/netcodegroup.cs | 2 +- .../security/policy/pefileevidencefactory.cs | 4 +- .../policy/permissionrequestevidence.cs | 2 +- .../system/security/policy/policyexception.cs | 2 +- .../system/security/policy/policylevel.cs | 2 +- .../system/security/policy/policystatement.cs | 2 +- mscorlib/system/security/policy/publisher.cs | 2 +- .../policy/publishermembershipcondition.cs | 2 +- mscorlib/system/security/policy/site.cs | 2 +- .../policy/sitemembershipcondition.cs | 2 +- mscorlib/system/security/policy/strongname.cs | 2 +- .../policy/strongnamemembershipcondition.cs | 2 +- .../system/security/policy/unioncodegroup.cs | 2 +- mscorlib/system/security/policy/url.cs | 2 +- .../security/policy/urlmembershipcondition.cs | 2 +- mscorlib/system/security/policy/zone.cs | 2 +- .../policy/zonemembershipcondition.cs | 2 +- mscorlib/system/security/policymanager.cs | 4 +- .../security/principal/genericidentity.cs | 2 +- .../security/principal/genericprincipal.cs | 2 +- .../principal/identitynotmappedexception.cs | 2 +- .../security/principal/identityreference.cs | 2 +- .../system/security/principal/ircollection.cs | 2 +- .../system/security/principal/ntaccount.cs | 2 +- mscorlib/system/security/principal/sid.cs | 2 +- mscorlib/system/security/principal/win32.cs | 2 +- .../security/principal/windowsidentity.cs | 4 +- .../principal/windowsimpersonationcontext.cs | 2 +- .../security/principal/windowsprincipal.cs | 2 +- .../system/security/readonlypermissionset.cs | 2 +- .../system/security/safesecurityhandles.cs | 2 +- mscorlib/system/security/securestring.cs | 2 +- mscorlib/system/security/securitycontext.cs | 4 +- mscorlib/system/security/securitydocument.cs | 2 +- mscorlib/system/security/securityelement.cs | 2 +- mscorlib/system/security/securityexception.cs | 2 +- mscorlib/system/security/securitymanager.cs | 2 +- mscorlib/system/security/securityruntime.cs | 2 +- mscorlib/system/security/securitystate.cs | 2 +- mscorlib/system/security/util/config.cs | 2 +- mscorlib/system/security/util/hex.cs | 2 +- mscorlib/system/security/util/parser.cs | 2 +- mscorlib/system/security/util/sitestring.cs | 2 +- .../security/util/stringexpressionset.cs | 2 +- .../system/security/util/tokenbasedset.cs | 2 +- .../security/util/tokenbasedsetenumerator.cs | 2 +- mscorlib/system/security/util/tokenizer.cs | 2 +- mscorlib/system/security/util/urlstring.cs | 2 +- mscorlib/system/security/util/xmlutil.cs | 2 +- .../system/security/verificationexception.cs | 2 +- .../system/security/xmlsyntaxexception.cs | 2 +- mscorlib/system/string.cs | 12 +- mscorlib/system/stubhelpers.cs | 115 +- mscorlib/system/text/asciiencoding.cs | 2 +- mscorlib/system/text/encoding.cs | 2 +- mscorlib/system/text/iso2022encoding.cs | 2 +- mscorlib/system/text/unicodeencoding.cs | 2 +- mscorlib/system/text/utf32encoding.cs | 2 +- mscorlib/system/text/utf7encoding.cs | 2 +- mscorlib/system/text/utf8encoding.cs | 2 +- .../system/threading/CDSsyncETWBCLProvider.cs | 10 +- .../system/threading/CancellationToken.cs | 6 +- .../CancellationTokenRegistration.cs | 2 +- .../threading/CancellationTokenSource.cs | 8 +- mscorlib/system/threading/CountdownEvent.cs | 4 +- mscorlib/system/threading/LazyInitializer.cs | 2 +- .../system/threading/ManualResetEventSlim.cs | 4 +- mscorlib/system/threading/SemaphoreSlim.cs | 2 +- mscorlib/system/threading/SpinLock.cs | 2 +- mscorlib/system/threading/SpinWait.cs | 2 +- .../Tasks/BeginEndAwaitableAdapter.cs | 2 +- .../Tasks/ConcurrentExclusiveSchedulerPair.cs | 6 +- mscorlib/system/threading/Tasks/Future.cs | 2 +- .../system/threading/Tasks/FutureFactory.cs | 2 +- mscorlib/system/threading/Tasks/Parallel.cs | 2 +- .../threading/Tasks/ParallelLoopState.cs | 2 +- .../threading/Tasks/ParallelRangeManager.cs | 2 +- .../threading/Tasks/ProducerConsumerQueues.cs | 4 +- .../system/threading/Tasks/TPLETWProvider.cs | 2 +- mscorlib/system/threading/Tasks/Task.cs | 2 +- .../threading/Tasks/TaskCanceledException.cs | 2 +- .../threading/Tasks/TaskCompletionSource.cs | 2 +- .../threading/Tasks/TaskContinuation.cs | 4 +- .../threading/Tasks/TaskExceptionHolder.cs | 2 +- .../system/threading/Tasks/TaskFactory.cs | 2 +- .../system/threading/Tasks/TaskScheduler.cs | 49 +- .../threading/Tasks/TaskSchedulerException.cs | 2 +- mscorlib/system/threading/Tasks/TaskToApm.cs | 2 +- .../Tasks/ThreadPoolTaskScheduler.cs | 5 +- mscorlib/system/threading/ThreadLocal.cs | 2 +- .../threading/abandonedmutexexception.cs | 2 +- mscorlib/system/threading/asynclocal.cs | 2 +- mscorlib/system/threading/autoresetevent.cs | 2 +- mscorlib/system/threading/compressedstack.cs | 4 +- mscorlib/system/threading/eventwaithandle.cs | 2 +- mscorlib/system/threading/executioncontext.cs | 6 +- .../threading/hostexecutioncontextmanager.cs | 2 +- mscorlib/system/threading/interlocked.cs | 2 +- mscorlib/system/threading/lockcookie.cs | 4 +- .../threading/lockrecursionexception.cs | 4 +- mscorlib/system/threading/manualresetevent.cs | 2 +- mscorlib/system/threading/monitor.cs | 2 +- mscorlib/system/threading/mutex.cs | 2 +- mscorlib/system/threading/overlapped.cs | 2 +- mscorlib/system/threading/readerwriterlock.cs | 2 +- .../threading/semaphorefullexception.cs | 2 +- .../threading/synchronizationcontext.cs | 6 +- .../threading/synchronizationlockexception.cs | 2 +- mscorlib/system/threading/thread.cs | 2 +- .../system/threading/threadabortexception.cs | 2 +- .../threading/threadinterruptedexception.cs | 2 +- mscorlib/system/threading/threadpool.cs | 4 +- .../system/threading/threadstartexception.cs | 2 +- .../system/threading/threadstateexception.cs | 2 +- mscorlib/system/threading/timeout.cs | 2 +- mscorlib/system/threading/timer.cs | 4 +- mscorlib/system/threading/volatile.cs | 2 +- mscorlib/system/threading/waithandle.cs | 4 +- .../waithandlecannotbeopenedexception.cs | 2 +- mscorlib/system/type.cs | 2 +- 3092 files changed, 197924 insertions(+), 8312 deletions(-) create mode 100644 System.ComponentModel.DataAnnotations/DataAnnotationsResources.resx create mode 100644 System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.Resources.txt create mode 100644 System.Runtime.Caching/R.resx create mode 100644 System.Web.ApplicationServices/ApplicationServicesStrings.resx create mode 100644 System.Web.DataVisualization/Common/Annotation/AnnotationBase.cs create mode 100644 System.Web.DataVisualization/Common/Annotation/AnnotationCollection.cs create mode 100644 System.Web.DataVisualization/Common/Annotation/ArrowAnnotation.cs create mode 100644 System.Web.DataVisualization/Common/Annotation/CalloutAnnotation.cs create mode 100644 System.Web.DataVisualization/Common/Annotation/GroupAnnotation.cs create mode 100644 System.Web.DataVisualization/Common/Annotation/ImageAnnotation.cs create mode 100644 System.Web.DataVisualization/Common/Annotation/LineAnnotation.cs create mode 100644 System.Web.DataVisualization/Common/Annotation/PolygonAnnotation.cs create mode 100644 System.Web.DataVisualization/Common/Annotation/RectangleAnnotation.cs create mode 100644 System.Web.DataVisualization/Common/Annotation/TextAnnotation.cs create mode 100644 System.Web.DataVisualization/Common/Borders3D/Borders3D.cs create mode 100644 System.Web.DataVisualization/Common/Borders3D/EmbedBorder.cs create mode 100644 System.Web.DataVisualization/Common/Borders3D/EmbossBorder.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/AreaChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/BarChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/BoxPlotChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/BubbleChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/ChartTypeRegistry.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/ColumnChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/DoughnutChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/ErrorBarChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/FastLineChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/FastPointChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/FunnelChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/KagiChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/LineChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/PieChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/PointAndFigureChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/PointChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/PolarChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/RadarChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/RangeChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/RenkoChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/StackedAreaChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/StackedBarChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/StackedColumnChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/StepLineChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/StockChart.cs create mode 100644 System.Web.DataVisualization/Common/ChartTypes/ThreeLineBreakChart.cs create mode 100644 System.Web.DataVisualization/Common/Converters/AnnotationConverters.cs create mode 100644 System.Web.DataVisualization/Common/Converters/AxesArrayConverter.cs create mode 100644 System.Web.DataVisualization/Common/Converters/AxisConverters.cs create mode 100644 System.Web.DataVisualization/Common/Converters/CustomAttributesConverters.cs create mode 100644 System.Web.DataVisualization/Common/Converters/DataManagerConverters.cs create mode 100644 System.Web.DataVisualization/Common/Converters/ElementPositionConverter.cs create mode 100644 System.Web.DataVisualization/Common/Converters/LegendConverters.cs create mode 100644 System.Web.DataVisualization/Common/DataManager/DataManager.cs create mode 100644 System.Web.DataVisualization/Common/DataManager/DataPoint.cs create mode 100644 System.Web.DataVisualization/Common/DataManager/DataSeries.cs create mode 100644 System.Web.DataVisualization/Common/EditorNames.cs create mode 100644 System.Web.DataVisualization/Common/Formulas/FormulaHelpers.cs create mode 100644 System.Web.DataVisualization/Common/Formulas/FormulaRegistry.cs create mode 100644 System.Web.DataVisualization/Common/Formulas/GeneralFormulas.cs create mode 100644 System.Web.DataVisualization/Common/Formulas/Oscillator.cs create mode 100644 System.Web.DataVisualization/Common/Formulas/PriceIndicators.cs create mode 100644 System.Web.DataVisualization/Common/Formulas/StatisticalAnalysis.cs create mode 100644 System.Web.DataVisualization/Common/Formulas/TechGeneralIndicators.cs create mode 100644 System.Web.DataVisualization/Common/Formulas/TimeSeriesAndForecasting.cs create mode 100644 System.Web.DataVisualization/Common/Formulas/VolumeIndicator.cs create mode 100644 System.Web.DataVisualization/Common/General/Axis.cs create mode 100644 System.Web.DataVisualization/Common/General/AxisLabels.cs create mode 100644 System.Web.DataVisualization/Common/General/AxisScale.cs create mode 100644 System.Web.DataVisualization/Common/General/AxisScaleBreaks.cs create mode 100644 System.Web.DataVisualization/Common/General/AxisScaleSegments.cs create mode 100644 System.Web.DataVisualization/Common/General/AxisScrollBar.cs create mode 100644 System.Web.DataVisualization/Common/General/AxisScrollZoom.cs create mode 100644 System.Web.DataVisualization/Common/General/BaseClasses.cs create mode 100644 System.Web.DataVisualization/Common/General/BaseCollections.cs create mode 100644 System.Web.DataVisualization/Common/General/BaseInterfaces.cs create mode 100644 System.Web.DataVisualization/Common/General/Chart.cs create mode 100644 System.Web.DataVisualization/Common/General/ChartArea.cs create mode 100644 System.Web.DataVisualization/Common/General/ChartArea3D.cs create mode 100644 System.Web.DataVisualization/Common/General/ChartAreaAxes.cs create mode 100644 System.Web.DataVisualization/Common/General/ChartAreaCircular.cs create mode 100644 System.Web.DataVisualization/Common/General/ChartAreaCollection.cs create mode 100644 System.Web.DataVisualization/Common/General/ChartAreaCursor.cs create mode 100644 System.Web.DataVisualization/Common/General/ChartElement.cs create mode 100644 System.Web.DataVisualization/Common/General/ChartGraphics.cs create mode 100644 System.Web.DataVisualization/Common/General/ChartGraphics3D.cs create mode 100644 System.Web.DataVisualization/Common/General/ChartRenderingEngine.cs create mode 100644 System.Web.DataVisualization/Common/General/ChartSerializer.cs create mode 100644 System.Web.DataVisualization/Common/General/CommonElements.cs create mode 100644 System.Web.DataVisualization/Common/General/Constants.cs create mode 100644 System.Web.DataVisualization/Common/General/DataManipulator.cs create mode 100644 System.Web.DataVisualization/Common/General/FormulaData.cs create mode 100644 System.Web.DataVisualization/Common/General/GdiGraphics.cs create mode 100644 System.Web.DataVisualization/Common/General/GridTickMarks.cs create mode 100644 System.Web.DataVisualization/Common/General/IChartRenderingEngine.cs create mode 100644 System.Web.DataVisualization/Common/General/ImageMap.cs create mode 100644 System.Web.DataVisualization/Common/General/Label.cs create mode 100644 System.Web.DataVisualization/Common/General/Legend.cs create mode 100644 System.Web.DataVisualization/Common/General/LegendColumns.cs create mode 100644 System.Web.DataVisualization/Common/General/Matrix3D.cs create mode 100644 System.Web.DataVisualization/Common/General/NamedImageCollection.cs create mode 100644 System.Web.DataVisualization/Common/General/Selection.cs create mode 100644 System.Web.DataVisualization/Common/General/SmartLabels.cs create mode 100644 System.Web.DataVisualization/Common/General/Statistics.cs create mode 100644 System.Web.DataVisualization/Common/General/StripLine.cs create mode 100644 System.Web.DataVisualization/Common/General/SubAxis.cs create mode 100644 System.Web.DataVisualization/Common/General/Title.cs create mode 100644 System.Web.DataVisualization/Common/SR.cs create mode 100644 System.Web.DataVisualization/Common/SRCategoryAttribute.cs create mode 100644 System.Web.DataVisualization/Common/SRDescriptionAttribute.cs create mode 100644 System.Web.DataVisualization/Common/Utilities/ColorPalette.cs create mode 100644 System.Web.DataVisualization/Common/Utilities/CustomAttributesRegistry.cs create mode 100644 System.Web.DataVisualization/Common/Utilities/ElementPosition.cs create mode 100644 System.Web.DataVisualization/Common/Utilities/ImageLoader.cs create mode 100644 System.Web.DataVisualization/Common/Utilities/KeywordsRegistry.cs create mode 100644 System.Web.DataVisualization/Common/Utilities/ValueConverter.cs create mode 100644 System.Web.DataVisualization/Common/Utilities/XmlSerializer.cs create mode 100644 System.Web.DataVisualization/WebForm/AssemblyInfo.cs create mode 100644 System.Web.DataVisualization/WebForm/ChartWebControl.cs create mode 100644 System.Web.DataVisualization/WebForm/Converters/MapAreaCoordinatesConverter.cs create mode 100644 System.Web.DataVisualization/WebForm/FxCopExclusionsByDesign.cs create mode 100644 System.Web.DataVisualization/WebForm/General/ChartHttpHandler.cs create mode 100644 System.Web.Services/System.Web.Services.txt create mode 100644 System.Web/cacheexpires.cspp create mode 100644 System.Web/cacheusage.cspp create mode 100644 mscorlib/system/io/pathinternal.cs diff --git a/System.Activities.Core.Presentation/SR.Designer.cs b/System.Activities.Core.Presentation/SR.Designer.cs index d61d6e68a..a1d8f4cfb 100644 --- a/System.Activities.Core.Presentation/SR.Designer.cs +++ b/System.Activities.Core.Presentation/SR.Designer.cs @@ -839,7 +839,7 @@ internal static string ViewParameterContent { } /// - /// Looks up a localized string similar to ActivityDelegate arguments don't match. Check your activity configuration to make sure it is in [....] with the declared ActivityDelegate.. + /// Looks up a localized string similar to ActivityDelegate arguments don't match. Check your activity configuration to make sure it is in sync with the declared ActivityDelegate.. /// internal static string WrongNumberOfArgumentsForActivityDelegate { get { diff --git a/System.Activities.Core.Presentation/System/Activities/Core/Presentation/MorphHelpers.cs b/System.Activities.Core.Presentation/System/Activities/Core/Presentation/MorphHelpers.cs index 11ae9394f..2fd2fdc5c 100644 --- a/System.Activities.Core.Presentation/System/Activities/Core/Presentation/MorphHelpers.cs +++ b/System.Activities.Core.Presentation/System/Activities/Core/Presentation/MorphHelpers.cs @@ -55,7 +55,7 @@ internal static Argument MorphArgument(ModelItem originalValue, Type targetType) { morphed.Expression = morphedExpression; } - //[....] + //Microsoft } } diff --git a/System.Activities.Core.Presentation/System/Activities/Presentation/DynamicArgumentDesigner.xaml.cs b/System.Activities.Core.Presentation/System/Activities/Presentation/DynamicArgumentDesigner.xaml.cs index 9c989f039..a9d222366 100644 --- a/System.Activities.Core.Presentation/System/Activities/Presentation/DynamicArgumentDesigner.xaml.cs +++ b/System.Activities.Core.Presentation/System/Activities/Presentation/DynamicArgumentDesigner.xaml.cs @@ -560,7 +560,7 @@ internal void ValidateEntry(DynamicArgumentWrapperObject entry, DependencyProper } else { - //[....] + //Microsoft entry.Expression = null; } diff --git a/System.Activities.DurableInstancing/System/Activities/DurableInstancing/SqlCommandAsyncResult.cs b/System.Activities.DurableInstancing/System/Activities/DurableInstancing/SqlCommandAsyncResult.cs index 8335154ac..3fadf8b20 100644 --- a/System.Activities.DurableInstancing/System/Activities/DurableInstancing/SqlCommandAsyncResult.cs +++ b/System.Activities.DurableInstancing/System/Activities/DurableInstancing/SqlCommandAsyncResult.cs @@ -118,7 +118,7 @@ static void StartCommandCallback(object state) SqlCommandAsyncResult thisPtr = (SqlCommandAsyncResult) state; try { - // this can throw on the [....] path - we need to signal the callback + // this can throw on the sync path - we need to signal the callback thisPtr.StartCommandInternal(false); } catch (Exception e) @@ -171,7 +171,7 @@ bool CompleteExecuteReader(IAsyncResult result) this.sqlCommand.Connection.Close(); } - // If we completed [....] then any retry is done by the original caller. + // If we completed sync then any retry is done by the original caller. if (!result.CompletedSynchronously) { if (this.CheckRetryCountAndTimer() && ShouldRetryForSqlError(exception.Number, RetryErrorOptions.RetryOnEnd)) diff --git a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/CategoryList.cs b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/CategoryList.cs index cd5a3a478..a8e8f2083 100644 --- a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/CategoryList.cs +++ b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/CategoryList.cs @@ -582,7 +582,7 @@ protected override void OnIsKeyboardFocusWithinChanged(DependencyPropertyChanged if (hasKeyboardFocus) { - // We just gained keyboard focus. Make sure we [....] up the current property selection + // We just gained keyboard focus. Make sure we sync up the current property selection // with the keyboard focus, so that navigation works. SynchronizeSelectionFocus(StealFocusMode.OnlyIfCurrentSelectionDoesNotHaveFocusWithin); } diff --git a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/FromExpression/Framework/ValueEditors/ChoiceEditor.cs b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/FromExpression/Framework/ValueEditors/ChoiceEditor.cs index 92992285f..598876c57 100644 --- a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/FromExpression/Framework/ValueEditors/ChoiceEditor.cs +++ b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/FromExpression/Framework/ValueEditors/ChoiceEditor.cs @@ -992,7 +992,7 @@ private void OnFinishEditing() private void ItemsSourceChanged() { - // The collection just changed, so we need to make sure that things are in [....] + // The collection just changed, so we need to make sure that things are in sync // ################################################### // CIDER-SPECIFIC CHANGE IN NEED OF PORTING - BEGIN @@ -1131,7 +1131,7 @@ protected bool UpdateValueFromInternalValues() this.Value = newValue; - // At this point it is possible that the value that we just set is out of [....] with the internal value + // At this point it is possible that the value that we just set is out of sync with the internal value if (newValue != this.InternalValue) { this.UpdateInternalValuesFromValue(); diff --git a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/PropertyValueDialogHost.cs b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/PropertyValueDialogHost.cs index d0d06ddf4..4fc58c4b9 100644 --- a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/PropertyValueDialogHost.cs +++ b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/PropertyValueDialogHost.cs @@ -22,7 +22,7 @@ namespace System.Activities.Presentation.Internal.PropertyEditing using Microsoft.Win32; // - // Helper class that is responsible for opening a [....] Form that hosts the WPF + // Helper class that is responsible for opening a Microsoft Form that hosts the WPF // PropertyValueDialogControl that ultimately hosts a DialogPropertyValueEditor. // Both PropertyInspector control as well as PropertyValueDialogControl use this class. // @@ -71,7 +71,7 @@ public void OnCanOpenDialogWindow(object sender, CanExecuteRoutedEventArgs e) // // Called in response to OpenDialogWindow command firing. The method opens a - // [....] Form that contains an ElementHost that, in turn, contains + // Microsoft Form that contains an ElementHost that, in turn, contains // PropertyValueDialogControl. // // diff --git a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/VisualTreeUtils.cs b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/VisualTreeUtils.cs index a9d683bd5..3d7712e3b 100644 --- a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/VisualTreeUtils.cs +++ b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/Internal/PropertyEditing/VisualTreeUtils.cs @@ -22,7 +22,7 @@ internal static class VisualTreeUtils private const int MaxSearchDepth = 5; // The maxium wpf visual tree depth - // this value should be kept in [....] with WPF's limit + // this value should be kept in sync with WPF's limit private const int MaxAllowedTreeDepth = 250; // diff --git a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/PropertyEditing/EditModeSwitchButton.cs b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/PropertyEditing/EditModeSwitchButton.cs index 68652bc26..14cc52fea 100644 --- a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/PropertyEditing/EditModeSwitchButton.cs +++ b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Base/Core/PropertyEditing/EditModeSwitchButton.cs @@ -61,7 +61,7 @@ private static object OnCoerceEditModeProperty(DependencyObject obj, object valu EditModeSwitchButton theThis = (EditModeSwitchButton) obj; - // [....] to the owning PropertyContainer only if requested to do so + // Sync to the owning PropertyContainer only if requested to do so if (!theThis.SyncModeToOwningContainer) return value; diff --git a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Hosting/WindowHelperService.cs b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Hosting/WindowHelperService.cs index a4b11aaf0..4a6104361 100644 --- a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Hosting/WindowHelperService.cs +++ b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Hosting/WindowHelperService.cs @@ -159,7 +159,7 @@ void HookupMessageProcessing() { this.hwndSource = HwndSource.FromHwnd(this.ParentWindowHwnd); } - //if didn't succeed - (either handle is null or we are hosted in [....] app) + //if didn't succeed - (either handle is null or we are hosted in Microsoft app) //try to create hwnd source out of designer's view if (null == this.hwndSource) { diff --git a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Model/ModelItemDictionaryImpl.cs b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Model/ModelItemDictionaryImpl.cs index 8be4b9043..4b4ca979b 100644 --- a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Model/ModelItemDictionaryImpl.cs +++ b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Model/ModelItemDictionaryImpl.cs @@ -751,7 +751,7 @@ private void AddCore(ModelItem key, ModelItem value, bool updateInstance) if (updateInstance) { - //no need to [....] if the ItemsCollection is not DictionaryItemsCollection wrapped by ModelItemCollectionImpl + //no need to sync if the ItemsCollection is not DictionaryItemsCollection wrapped by ModelItemCollectionImpl ModelItemCollectionImpl itemsCollectionImpl = this.ItemsCollectionModelItemCollection as ModelItemCollectionImpl; if (ItemsCollectionObject != null && itemsCollectionImpl != null) { @@ -810,7 +810,7 @@ private void ClearCore(bool updateInstance) IList removed = this.modelItems.ToList>(); if (updateInstance) { - //no need to [....] if the ItemsCollection is not DictionaryItemsCollection wrapped by ModelItemCollectionImpl + //no need to sync if the ItemsCollection is not DictionaryItemsCollection wrapped by ModelItemCollectionImpl ModelItemCollectionImpl itemsCollectionImpl = this.ItemsCollectionModelItemCollection as ModelItemCollectionImpl; if (ItemsCollectionObject != null && itemsCollectionImpl != null) { diff --git a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Model/ModelPropertyImpl.cs b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Model/ModelPropertyImpl.cs index d3237f8b0..a2d7921da 100644 --- a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Model/ModelPropertyImpl.cs +++ b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Model/ModelPropertyImpl.cs @@ -10,7 +10,7 @@ namespace System.Activities.Presentation.Model // This class provides the implementation for a model property. // this intercepts sets /gets to the property and works with modeltreemanager - // to keep the xaml in [....]. + // to keep the xaml in sync. class ModelPropertyImpl : ModelProperty { diff --git a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/View/ExpressionTextBox.xaml.cs b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/View/ExpressionTextBox.xaml.cs index e6497e158..012a9c67a 100644 --- a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/View/ExpressionTextBox.xaml.cs +++ b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/View/ExpressionTextBox.xaml.cs @@ -176,7 +176,7 @@ public bool ExplicitCommit set { SetValue(ExplicitCommitProperty, value); } } - //[....] + //Microsoft public IExpressionEditorService ExpressionEditorService { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] diff --git a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/View/VariableDesigner.xaml.cs b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/View/VariableDesigner.xaml.cs index 91dc3737a..c57fd7b12 100644 --- a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/View/VariableDesigner.xaml.cs +++ b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/View/VariableDesigner.xaml.cs @@ -1232,7 +1232,7 @@ void SetVariableType(Type type) { variable.Default = morphedExpression; } - //[....] + //Microsoft } } diff --git a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Xaml/ErrorTolerantObjectWriter.cs b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Xaml/ErrorTolerantObjectWriter.cs index 19dd93267..e3c674e4d 100644 --- a/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Xaml/ErrorTolerantObjectWriter.cs +++ b/System.Activities.Presentation/System.Activities.Presentation/System/Activities/Presentation/Xaml/ErrorTolerantObjectWriter.cs @@ -195,7 +195,7 @@ public void SetLineInfo(int lineNumber, int linePosition) this.lineNumber = lineNumber; this.linePosition = linePosition; - // But we also need to keep it in [....] with the nodestream, for XOW errors + // But we also need to keep it in sync with the nodestream, for XOW errors // XOW and XamlNodeQueue.Writer both implement IXamlLineInfoConsumer, so we can do a straight cast if (this.rootFragment.HasError) { diff --git a/System.Activities/System/Activities/Debugger/StateManager.cs b/System.Activities/System/Activities/Debugger/StateManager.cs index 367172448..1a3a2fb07 100644 --- a/System.Activities/System/Activities/Debugger/StateManager.cs +++ b/System.Activities/System/Activities/Debugger/StateManager.cs @@ -37,7 +37,6 @@ public sealed class StateManager : IDisposable static Type threadWorkerControllerType = typeof(ThreadWorkerController); static MethodInfo islandWorkerMethodInfo = threadWorkerControllerType.GetMethod("IslandWorker", BindingFlags.Static | BindingFlags.Public); - const string Md5Identifier = "406ea660-64cf-4c82-b6f0-42d48172a799"; internal const string MethodWithPrimingPrefix = "_"; List threads; @@ -681,7 +680,7 @@ MethodBuilder CreateIsland(TypeBuilder typeBuilder, State state, bool withPrimin [SecurityCritical] void InitDynamicModule(string asmName) { - // See http://blogs.msdn.com/[....]/archive/2005/02/03/366429.aspx for a simple example + // See http://blogs.msdn.com/Microsoft/archive/2005/02/03/366429.aspx for a simple example // of debuggable reflection-emit. Fx.Assert(dynamicModule == null, "can only be initialized once"); @@ -791,7 +790,7 @@ private ISymbolDocumentWriter GetSourceDocument(string fileName, byte[] checksum if (checksumBytes != null) { - documentWriter.SetCheckSum(new Guid(Md5Identifier), checksumBytes); + documentWriter.SetCheckSum(SymbolHelper.ChecksumProviderId, checksumBytes); } } return documentWriter; diff --git a/System.Activities/System/Activities/Debugger/Symbol/SymbolHelper.cs b/System.Activities/System/Activities/Debugger/Symbol/SymbolHelper.cs index 9e021231c..00aaa7e97 100644 --- a/System.Activities/System/Activities/Debugger/Symbol/SymbolHelper.cs +++ b/System.Activities/System/Activities/Debugger/Symbol/SymbolHelper.cs @@ -14,6 +14,24 @@ namespace System.Activities.Debugger.Symbol internal static class SymbolHelper { + static readonly Guid Md5IdentifierGuid = new Guid("406ea660-64cf-4c82-b6f0-42d48172a799"); + static readonly Guid Sha1IdentifierGuid = new Guid("ff1816ec-aa5e-4d10-87f7-6f4963833460"); + + public static Guid ChecksumProviderId + { + get + { + if (LocalAppContextSwitches.UseMD5ForWFDebugger) + { + return Md5IdentifierGuid; + } + else + { + return Sha1IdentifierGuid; + } + } + } + // This is the same Encode/Decode logic as the WCF FramingEncoder public static int ReadEncodedInt32(BinaryReader reader) { @@ -61,8 +79,6 @@ public static int GetEncodedSize(int value) return count; } - [SuppressMessage("Microsoft.Cryptographic.Standard", "CA5350:MD5CannotBeUsed", - Justification = "Design has been approved. We are not using MD5 for any security or cryptography purposes but rather as a hash.")] public static byte[] CalculateChecksum(string fileName) { Fx.Assert(!string.IsNullOrEmpty(fileName), "fileName should not be empty or null"); @@ -71,8 +87,10 @@ public static byte[] CalculateChecksum(string fileName) { using (StreamReader streamReader = new StreamReader(fileName)) { - MD5 md5 = new MD5CryptoServiceProvider(); - checksum = md5.ComputeHash(streamReader.BaseStream); + using (HashAlgorithm hashAlgorithm = CreateHashProvider()) + { + checksum = hashAlgorithm.ComputeHash(streamReader.BaseStream); + } } } catch (IOException) @@ -108,7 +126,28 @@ public static string GetHexStringFromChecksum(byte[] checksum) internal static bool ValidateChecksum(byte[] checksumToValidate) { // We are using MD5.ComputeHash, which will return a 16 byte array. - return checksumToValidate.Length == 16; + if (LocalAppContextSwitches.UseMD5ForWFDebugger) + { + return checksumToValidate.Length == 16; + } + else + { + return checksumToValidate.Length == 20; + } + } + + [SuppressMessage("Microsoft.Cryptographic.Standard", "CA5350:MD5CannotBeUsed", + Justification = "Design has been approved. We are not using MD5 for any security or cryptography purposes but rather as a hash.")] + static HashAlgorithm CreateHashProvider() + { + if (LocalAppContextSwitches.UseMD5ForWFDebugger) + { + return new MD5CryptoServiceProvider(); + } + else + { + return new SHA1CryptoServiceProvider(); + } } } } diff --git a/System.Activities/System/Activities/Runtime/ActivityExecutor.cs b/System.Activities/System/Activities/Runtime/ActivityExecutor.cs index b9cf8fe7e..417960427 100644 --- a/System.Activities/System/Activities/Runtime/ActivityExecutor.cs +++ b/System.Activities/System/Activities/Runtime/ActivityExecutor.cs @@ -1921,7 +1921,7 @@ internal Scheduler.RequestedAction OnExecuteWorkItem(WorkItem workItem) return Scheduler.Continue; } - // We only check this in the [....] path because there are no ways of changing the keys collections from the work items that can + // We only check this in the sync path because there are no ways of changing the keys collections from the work items that can // go async. There's an assert to this effect in FinishWorkItem. if (this.bookmarkScopeManager != null && this.bookmarkScopeManager.HasKeysToUpdate) { diff --git a/System.Activities/System/Activities/Runtime/ActivityInstanceMap.cs b/System.Activities/System/Activities/Runtime/ActivityInstanceMap.cs index 7c4cae273..c4983a022 100644 --- a/System.Activities/System/Activities/Runtime/ActivityInstanceMap.cs +++ b/System.Activities/System/Activities/Runtime/ActivityInstanceMap.cs @@ -599,7 +599,7 @@ public void LoadActivityTree(Activity rootActivity, ActivityInstance rootInstanc } // We need to null this out once we've recreated the dictionary to avoid - // having out of [....] data + // having out of sync data this.rawDeserializedLists = null; // then walk our instance list, fixup parent references, and perform basic validation diff --git a/System.Activities/System/Activities/Statements/MethodExecutor.cs b/System.Activities/System/Activities/Statements/MethodExecutor.cs index 3819a0e64..432dd9efc 100644 --- a/System.Activities/System/Activities/Statements/MethodExecutor.cs +++ b/System.Activities/System/Activities/Statements/MethodExecutor.cs @@ -114,12 +114,12 @@ public IAsyncResult BeginExecuteMethod(AsyncCodeActivityContext context, AsyncCa } } - return BeginMakeMethodCall(context, targetInstance, callback, state); // defer to concrete instance for [....]/async variations + return BeginMakeMethodCall(context, targetInstance, callback, state); // defer to concrete instance for sync/async variations } public void EndExecuteMethod(AsyncCodeActivityContext context, IAsyncResult result) { - EndMakeMethodCall(context, result); // defer to concrete instance for [....]/async variations + EndMakeMethodCall(context, result); // defer to concrete instance for sync/async variations } [SuppressMessage("Reliability", "Reliability108:IsFatalRule", diff --git a/System.Activities/System/Activities/Statements/MethodResolver.cs b/System.Activities/System/Activities/Statements/MethodResolver.cs index 2a7b1084b..5181f4f2a 100644 --- a/System.Activities/System/Activities/Statements/MethodResolver.cs +++ b/System.Activities/System/Activities/Statements/MethodResolver.cs @@ -355,7 +355,7 @@ MethodInfo Resolve(Type targetType, string methodName, BindingFlags bindingFlags { return null; } - else // For a regular [....] method, ambiguity is distinct from no match and gets an explicit error message + else // For a regular sync method, ambiguity is distinct from no match and gets an explicit error message { throw; } diff --git a/System.Activities/System/Activities/WorkflowApplication.cs b/System.Activities/System/Activities/WorkflowApplication.cs index ff9b74d72..952c17975 100644 --- a/System.Activities/System/Activities/WorkflowApplication.cs +++ b/System.Activities/System/Activities/WorkflowApplication.cs @@ -367,7 +367,7 @@ static void EventFrame(IAsyncResult result) try { - // The "false" is to notify that we are not still [....] + // The "false" is to notify that we are not still sync done = data.NextCallback(result, thisPtr, false); } catch (Exception e) @@ -1100,7 +1100,7 @@ public void EndTerminate(IAsyncResult result) TerminateAsyncResult.End(result); } - // called from the [....] and async paths + // called from the sync and async paths void CancelCore() { // We only actually do any work if we haven't completed and we aren't @@ -3867,7 +3867,7 @@ bool DeleteOwner() if (this.instance.HasPersistenceProvider && this.instance.persistenceManager.OwnerWasCreated && (this.operation == PersistenceOperation.Unload || this.operation == PersistenceOperation.Complete)) { - // This call uses the ambient transaction directly if there was one, to mimic the [....] case. + // This call uses the ambient transaction directly if there was one, to mimic the sync case. // IAsyncResult deleteOwnerResult = null; using (PrepareTransactionalCall(this.dependentTransaction)) diff --git a/System.Activities/System/Activities/WorkflowPersistenceContext.cs b/System.Activities/System/Activities/WorkflowPersistenceContext.cs index d056669a4..78f8b6127 100644 --- a/System.Activities/System/Activities/WorkflowPersistenceContext.cs +++ b/System.Activities/System/Activities/WorkflowPersistenceContext.cs @@ -74,7 +74,7 @@ public bool TryBeginComplete(AsyncCallback callback, object state, out IAsyncRes { // In the interest of allocating less objects we don't implement // the full async pattern here. Instead, we've flattened it to - // do the [....] part and then optionally delegate down to the inner + // do the sync part and then optionally delegate down to the inner // BeginCommit. if (this.contextOwnedTransaction != null) diff --git a/System.ComponentModel.DataAnnotations/DataAnnotationsResources.resx b/System.ComponentModel.DataAnnotations/DataAnnotationsResources.resx new file mode 100644 index 000000000..11b1bd4c0 --- /dev/null +++ b/System.ComponentModel.DataAnnotations/DataAnnotationsResources.resx @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The associated metadata type for type '{0}' contains the following unknown properties or fields: {1}. Please make sure that the names of these members match the names of the properties on the main type. + + + The type '{0}' must be public. + + + The type '{0}' does not contain a public method named '{1}'. + + + The type '{0}' does not contain a public property named '{1}'. + + + The CustomValidationAttribute method '{0}' in type '{1}' must return System.ComponentModel.DataAnnotations.ValidationResult. Use System.ComponentModel.DataAnnotations.ValidationResult.Success to represent success. + + + The CustomValidationAttribute method '{0}' does not exist in type '{1}' or is not public and static. + + + The CustomValidationAttribute.Method was not specified. + + + The CustomValidationAttribute method '{0}' in type '{1}' must match the expected signature: public static ValidationResult {0}(object value, ValidationContext context). The value can be strongly typed. The ValidationContext parameter is optional. + + + The custom validation type '{0}' must be public. + + + {0} is not valid. + + + The CustomValidationAttribute.ValidatorType was not specified. + + + The custom DataType string cannot be null or empty. + + + Cannot retrieve property '{0}' because localization failed. Type '{1}' is not public or does not contain a public static string property with the name '{2}'. + + + The value for property '{0}' must be of type '{1}'. + + + The type {0} must implement {1}. + + + The maximum value '{0}' must be greater than or equal to the minimum value '{1}'. + + + The minimum and maximum values must be set. + + + The OperandType must be set when strings are used for minimum and maximum values. + + + The field {0} must be between {1} and {2}. + + + The field {0} must match the regular expression '{1}'. + + + The pattern must be set to a valid regular expression. + + + The {0} field is required. + + + The maximum length must be a nonnegative integer. + + + The field {0} must be a string with a maximum length of {1}. + + + The key parameter at position {0} with value '{1}' is not a string. Every key control parameter must be a string. + + + The key parameter at position {0} is null. Every key control parameter must be a string. + + + The number of control parameters must be even. + + + The key parameter at position {0} with value '{1}' occurs more than once. + + + Either ErrorMessageString or ErrorMessageResourceName must be set, but not both. + + + Both ErrorMessageResourceType and ErrorMessageResourceName need to be set on this attribute. + + + The property '{0}' on resource type '{1}' is not a string type. + + + The resource type '{0}' does not have an accessible static property named '{1}'. + + + The field {0} is invalid. + + + The ValidationContext for the type '{0}', member name '{1}' must provide the MethodInfo. + + + The type '{0}' needs to represent an enumeration type. + + + The type provided for EnumDataTypeAttribute cannot be null. + + + MetadataClassType cannot be null. + + + The {0} property has not been set. Use the {1} method to get the value. + + + A service of type '{0}' already exists in the container. + + + The instance provided must match the ObjectInstance on the ValidationContext supplied. + + + IsValid(object value) has not been implemented by this class. The preferred entry point is GetValidationResult() and classes should override IsValid(object value, ValidationContext context). + + + Could not convert the value of type '{0}' to '{1}' as expected by method {2}.{3}. + + + The field {0} must be a string with a minimum length of {2} and a maximum length of {1}. + + + The {0} field is not a valid credit card number. + + + The {0} field is not a valid e-mail address. + + + The {0} field only accepts files with the following extensions: {1} + + + The {0} field is not a valid fully-qualified http, https, or ftp URL. + + + '{0}' and '{1}' do not match. + + + Value cannot be null or empty. + + + Could not find a property named {0}. + + + The property {0}.{1} could not be found. + + + The {0} field is not a valid phone number. + + + MaxLengthAttribute must have a Length value that is greater than zero. Use MaxLength() without parameters to indicate that the string or array can have the maximum allowable length. + + + The field {0} must be a string or array type with a maximum length of '{1}'. + + + MinLengthAttribute must have a Length value that is zero or greater. + + + The field {0} must be a string or array type with a minimum length of '{1}'. + + + The argument '{0}' cannot be null, empty or contain only white space. + + \ No newline at end of file diff --git a/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.Resources.txt b/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.Resources.txt new file mode 100644 index 000000000..ecbd61f15 --- /dev/null +++ b/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations.Resources.txt @@ -0,0 +1,16 @@ +; NOTE: don't use \", use ' instead +; NOTE: don't use #, use ; instead for comments +; NOTE: leave the [strings] alone + +MaxLengthAttribute_ValidationError=The field {0} must be a string or array type with a maximum length of '{1}'. + +## ExceptionType=InvalidOperationException +MaxLengthAttribute_InvalidMaxLength=MaxLengthAttribute must have a Length value that is greater than zero. Use MaxLength() without parameters to indicate that the string or array can have the maximum allowable length. + +MinLengthAttribute_ValidationError=The field {0} must be a string or array type with a minimum length of '{1}'. + +## ExceptionType=InvalidOperationException +MinLengthAttribute_InvalidMinLength=MinLengthAttribute must have a Length value that is zero or greater. + +## ExceptionType=ArgumentException +ArgumentIsNullOrWhitespace=The argument '{0}' cannot be null, empty or contain only white space. \ No newline at end of file diff --git a/System.Configuration/System/Configuration/BaseConfigurationRecord.cs b/System.Configuration/System/Configuration/BaseConfigurationRecord.cs index c378f1d68..4b30c4caf 100644 --- a/System.Configuration/System/Configuration/BaseConfigurationRecord.cs +++ b/System.Configuration/System/Configuration/BaseConfigurationRecord.cs @@ -4124,9 +4124,12 @@ internal bool RecordSupportsLocation { // const string ProtectedConfigurationSectionTypeName = "System.Configuration.ProtectedConfigurationSection, " + AssemblyRef.SystemConfiguration; internal const string RESERVED_SECTION_PROTECTED_CONFIGURATION = "configProtectedData"; + internal const string Microsoft_CONFIGURATION_SECTION = ConfigurationStringConstants.WinformsApplicationConfigurationSectionName; + const string SystemConfigurationSectionTypeName = "System.Configuration.AppSettingsSection, " + AssemblyRef.SystemConfiguration; internal static bool IsImplicitSection(string configKey) { - if (configKey == RESERVED_SECTION_PROTECTED_CONFIGURATION) { + if (string.Equals(configKey, RESERVED_SECTION_PROTECTED_CONFIGURATION, StringComparison.Ordinal) || + string.Equals(configKey, Microsoft_CONFIGURATION_SECTION, StringComparison.Ordinal)) { return true; } else { @@ -4172,6 +4175,34 @@ private void AddImplicitSections(Hashtable factoryList) { null, // filename -1); // lineNumber } + + factoryRecord = (FactoryRecord)factoryList[Microsoft_CONFIGURATION_SECTION]; + + // If the user has mistakenly declared an implicit section, we should leave the factoryRecord + // alone because it contains the error and the error will be thrown later. + if (factoryRecord != null) + { + Debug.Assert(factoryRecord.HasErrors, "If the user has mistakenly declared an implicit section, we should have recorded an error."); + } + else + { + factoryList[Microsoft_CONFIGURATION_SECTION] = + new FactoryRecord( + Microsoft_CONFIGURATION_SECTION, // configKey + string.Empty, // group + Microsoft_CONFIGURATION_SECTION, // name + SystemConfigurationSectionTypeName, // factoryTypeName + true, // allowLocation + ConfigurationAllowDefinition.Everywhere, // allowDefinition + ConfigurationAllowExeDefinition.MachineToApplication, // allowExeDefinition + OverrideModeSetting.SectionDefault, // overrideModeDefault + true, // restartOnExternalChanges + true, // requirePermission + true, // isFromTrustedConfig + true, // isUndeclared + null, // filename + -1); // lineNumber + } } } diff --git a/System.Configuration/System/Configuration/Internal/InternalConfigHost.cs b/System.Configuration/System/Configuration/Internal/InternalConfigHost.cs index 962ac400d..128702ad5 100644 --- a/System.Configuration/System/Configuration/Internal/InternalConfigHost.cs +++ b/System.Configuration/System/Configuration/Internal/InternalConfigHost.cs @@ -69,7 +69,7 @@ string IInternalConfigHost.GetStreamName(string configPath) { [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "The callers don't leak this information.")] static internal string StaticGetStreamNameForConfigSource(string streamName, string configSource) { // - // Note ([....] 7/08/05): + // Note (Microsoft 7/08/05): // RemoteWebConfigurationHost also redirects GetStreamNameForConfigSource to this // method, and that means streamName is referring to a path that's on the remote // machine. The problem is that Path.GetFullPath will demand FileIOPermission on diff --git a/System.Configuration/System/Configuration/MgmtConfigurationRecord.cs b/System.Configuration/System/Configuration/MgmtConfigurationRecord.cs index 748bf3a8a..f3ec52b9d 100644 --- a/System.Configuration/System/Configuration/MgmtConfigurationRecord.cs +++ b/System.Configuration/System/Configuration/MgmtConfigurationRecord.cs @@ -1743,8 +1743,17 @@ private void GetConfigDefinitionUpdates( saveMode == ConfigurationSaveMode.Full) { // Note: we won't use RawXml if saveMode == Full because Full means we want to // write all properties, and RawXml may not have all properties. - ConfigurationSection parentConfigSection = FindImmediateParentSection(configSection); - updatedXml = configSection.SerializeSection(parentConfigSection, configSection.SectionInformation.Name, saveMode); + + // 'System.Windows.Forms.ApplicationConfiguration' is declared as an implicit section. Saving this section definition without declaration in machine .config file is causing IIS + // and "wcfservice' project creation failed. See bug #297811 for more details. Following fix exclude this section empty definition in the machine.config while saving it. + if (String.Equals(configSection.SectionInformation.Name, ConfigurationStringConstants.WinformsApplicationConfigurationSectionName, StringComparison.Ordinal) && + String.Equals(configSection._configRecord.ConfigPath, ClientConfigurationHost.MachineConfigName, StringComparison.Ordinal)) { + updatedXml = null; + } + else { + ConfigurationSection parentConfigSection = FindImmediateParentSection(configSection); + updatedXml = configSection.SerializeSection(parentConfigSection, configSection.SectionInformation.Name, saveMode); + } ValidateSectionXml(updatedXml, configKey); } else { diff --git a/System.Core/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs b/System.Core/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs index 9e09c9feb..ab3a042e0 100644 --- a/System.Core/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs +++ b/System.Core/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs @@ -263,7 +263,7 @@ private bool IsValidOpenState { T duplicate = new T(); // We need to do this operation in a CER in order to ensure that everybody's state stays consistent - // with the current view of the world. If the state of the various handles gets out of [....], then + // with the current view of the world. If the state of the various handles gets out of sync, then // we'll end up leaking since reference counts will not be set up properly. RuntimeHelpers.PrepareConstrainedRegions(); try { } diff --git a/System.Core/System.Core.txt b/System.Core/System.Core.txt index e2d5fa714..00695316d 100644 --- a/System.Core/System.Core.txt +++ b/System.Core/System.Core.txt @@ -96,6 +96,7 @@ IO_IO_SharingViolation_File=The process cannot access the file '{0}' because it IO_IO_SharingViolation_NoFileName=The process cannot access the file because it is being used by another process. IO_IO_PipeBroken=Pipe is broken. IO_IO_InvalidPipeHandle=Invalid pipe handle. +IO_OperationAborted=IO operation was aborted unexpectedly. ; ; DirectoryNotFoundException ; @@ -382,3 +383,37 @@ NotSupported_MMViewStreamsFixedLength=MemoryMappedViewStreams are fixed length. ObjectDisposed_ViewAccessorClosed=Cannot access a closed accessor. ObjectDisposed_StreamIsClosed=Cannot access a closed Stream. +; +; 4.6.x string (only add at the end) +; +NotSupported_Method=Method not supported. +NotSupported_SubclassOverride=Method not supported. Derived class must override. +Cryptography_ArgDSARequiresDSAKey=Keys used with the DSACng algorithm must have an algorithm group of DSA. +Cryptography_ArgRSAaRequiresRSAKey=Keys used with the RSACng algorithm must have an algorithm group of RSA. +Cryptography_CngKeyWrongAlgorithm=This key is for algorithm '{0}'. Expected '{1}'. +Cryptography_DSA_HashTooShort=The supplied hash cannot be shorter in length than the DSA key's Q value. +Cryptography_HashAlgorithmNameNullOrEmpty=The hash algorithm name cannot be null or empty. +Cryptography_InvalidDsaParameters_MissingFields=The specified DSA parameters are not valid; P, Q, G and Y are all required. +Cryptography_InvalidDsaParameters_MismatchedPGY=The specified DSA parameters are not valid; P, G and Y must be the same length (the key size). +Cryptography_InvalidDsaParameters_MismatchedQX=The specified DSA parameters are not valid; Q and X (if present) must be the same length. +Cryptography_InvalidDsaParameters_MismatchedPJ=The specified DSA parameters are not valid; J (if present) must be shorter than P. +Cryptography_InvalidDsaParameters_SeedRestriction_ShortKey=The specified DSA parameters are not valid; Seed, if present, must be 20 bytes long for keys shorter than 1024 bits. +Cryptography_InvalidDsaParameters_QRestriction_ShortKey=The specified DSA parameters are not valid; Q must be 20 bytes long for keys shorter than 1024 bits. +Cryptography_InvalidDsaParameters_QRestriction_LargeKey=The specified DSA parameters are not valid; Q's length must be one of 20, 32 or 64 bytes. +Cryptography_InvalidRsaParameters=The specified RSA parameters are not valid; both Exponent and Modulus are required fields. +Cryptography_InvalidSignatureAlgorithm=The hash algorithm is not supported for signatures. Only MD5, SHA1, SHA256,SHA384, and SHA512 are supported at this time. +Cryptography_KeyBlobParsingError=Key Blob not in expected format. +Cryptography_NotSupportedKeyAlgorithm=Key Algorithm is not supported. +Cryptography_NotValidPublicOrPrivateKey=Key is not a valid public or private key. +Cryptography_NotValidPrivateKey=Key is not a valid private key. +Cryptography_UnexpectedTransformTruncation=CNG provider unexpectedly terminated encryption or decryption prematurely. +Cryptography_UnsupportedPaddingMode=The specified PaddingMode is not supported. +Cryptography_WeakKey=Specified key is a known weak key for this algorithm and cannot be used. +Cryptography_CurveNotSupported=The specified curve '{0}' or its parameters are not valid for this platform. +Cryptography_InvalidCurve=The specified curve '{0}' is not valid for this platform. +Cryptography_InvalidCurveOid=The specified Oid is not valid. The Oid.FriendlyName or Oid.Value property must be set. +Cryptography_InvalidCurveKeyParameters=The specified key parameters are not valid. Q.X and Q.Y are required fields. Q.X, Q.Y must be the same length. If D is specified it must be the same length as Q.X and Q.Y for named curves or the same length as Order for explicit curves. +Cryptography_InvalidECCharacteristic2Curve=The specified Characteristic2 curve parameters are not valid. Polynomial, A, B, G.X, G.Y, and Order are required. A, B, G.X, G.Y must be the same length, and the same length as Q.X, Q.Y and D if those are specified. Seed, Cofactor and Hash are optional. Other parameters are not allowed. +Cryptography_InvalidECPrimeCurve=The specified prime curve parameters are not valid. Prime, A, B, G.X, G.Y and Order are required and must be the same length, and the same length as Q.X, Q.Y and D if those are specified. Seed, Cofactor and Hash are optional. Other parameters are not allowed. +Cryptography_InvalidECNamedCurve=The specified named curve parameters are not valid. Only the Oid parameter must be set. +Cryptography_UnknownHashAlgorithm='{0}' is not a known hash algorithm. diff --git a/System.Core/System/Diagnostics/Eventing/EventDescriptor.cs b/System.Core/System/Diagnostics/Eventing/EventDescriptor.cs index 767fdd4cd..cfe9bd24a 100644 --- a/System.Core/System/Diagnostics/Eventing/EventDescriptor.cs +++ b/System.Core/System/Diagnostics/Eventing/EventDescriptor.cs @@ -28,7 +28,7 @@ public struct EventDescriptor [FieldOffset(8)] private long m_keywords; - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "opcode", Justification = "[....]: Shipped public in 3.5, breaking change to fix now.")] + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "opcode", Justification = "Microsoft: Shipped public in 3.5, breaking change to fix now.")] public EventDescriptor( int id, byte version, @@ -98,7 +98,7 @@ public byte Level } } - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcode", Justification = "[....]: Shipped public in 3.5, breaking change to fix now.")] + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcode", Justification = "Microsoft: Shipped public in 3.5, breaking change to fix now.")] public byte Opcode { get diff --git a/System.Core/System/Diagnostics/Eventing/Reader/EventLogSession.cs b/System.Core/System/Diagnostics/Eventing/Reader/EventLogSession.cs index 6515e3d87..408bce798 100644 --- a/System.Core/System/Diagnostics/Eventing/Reader/EventLogSession.cs +++ b/System.Core/System/Diagnostics/Eventing/Reader/EventLogSession.cs @@ -52,7 +52,7 @@ public class EventLogSession : IDisposable { internal EventLogHandle renderContextHandleSystem = EventLogHandle.Zero; internal EventLogHandle renderContextHandleUser = EventLogHandle.Zero; - //the dummy [....] object for the two contextes. + //the dummy sync object for the two contextes. private object syncObject = null; private string server; diff --git a/System.Core/System/Diagnostics/Eventing/Reader/EventMetadata.cs b/System.Core/System/Diagnostics/Eventing/Reader/EventMetadata.cs index 4aa1910d9..ce3f4c8d0 100644 --- a/System.Core/System/Diagnostics/Eventing/Reader/EventMetadata.cs +++ b/System.Core/System/Diagnostics/Eventing/Reader/EventMetadata.cs @@ -86,7 +86,7 @@ public EventLevel Level { } } - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcode", Justification = "[....]: Shipped public in 3.5, breaking change to fix now.")] + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcode", Justification = "Microsoft: Shipped public in 3.5, breaking change to fix now.")] public EventOpcode Opcode { get { return new EventOpcode(this.opcode, this.pmReference); diff --git a/System.Core/System/Diagnostics/Eventing/Reader/EventOpcode.cs b/System.Core/System/Diagnostics/Eventing/Reader/EventOpcode.cs index c597a47c2..f930037c3 100644 --- a/System.Core/System/Diagnostics/Eventing/Reader/EventOpcode.cs +++ b/System.Core/System/Diagnostics/Eventing/Reader/EventOpcode.cs @@ -20,7 +20,7 @@ namespace System.Diagnostics.Eventing.Reader { [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcode", Justification = "[....]: Shipped public in 3.5, breaking change to fix now.")] + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcode", Justification = "Microsoft: Shipped public in 3.5, breaking change to fix now.")] public sealed class EventOpcode { private int value; private string name; diff --git a/System.Core/System/Diagnostics/Eventing/Reader/EventRecord.cs b/System.Core/System/Diagnostics/Eventing/Reader/EventRecord.cs index e50e1f0e4..c81eb96bf 100644 --- a/System.Core/System/Diagnostics/Eventing/Reader/EventRecord.cs +++ b/System.Core/System/Diagnostics/Eventing/Reader/EventRecord.cs @@ -30,7 +30,7 @@ public abstract class EventRecord : IDisposable { public abstract byte? Level { get; } public abstract int? Task { get; } - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcode", Justification = "[....]: Shipped public in 3.5, breaking change to fix now.")] + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcode", Justification = "Microsoft: Shipped public in 3.5, breaking change to fix now.")] public abstract short? Opcode { get; } public abstract long? Keywords { get; } @@ -55,7 +55,7 @@ public abstract class EventRecord : IDisposable { public abstract string LevelDisplayName { get; } - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcode", Justification = "[....]: Shipped public in 3.5, breaking change to fix now.")] + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcode", Justification = "Microsoft: Shipped public in 3.5, breaking change to fix now.")] public abstract string OpcodeDisplayName { get; } public abstract string TaskDisplayName { get; } public abstract IEnumerable KeywordsDisplayNames { get; } diff --git a/System.Core/System/Diagnostics/Eventing/Reader/ProviderMetadata.cs b/System.Core/System/Diagnostics/Eventing/Reader/ProviderMetadata.cs index fc82c7058..b1cf7fc07 100644 --- a/System.Core/System/Diagnostics/Eventing/Reader/ProviderMetadata.cs +++ b/System.Core/System/Diagnostics/Eventing/Reader/ProviderMetadata.cs @@ -440,7 +440,7 @@ public IList Levels { } } - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcodes", Justification = "[....]: Shipped public in 3.5, breaking change to fix now.")] + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Opcodes", Justification = "Microsoft: Shipped public in 3.5, breaking change to fix now.")] public IList Opcodes { get { List eo; diff --git a/System.Core/System/IO/BufferedStream2.cs b/System.Core/System/IO/BufferedStream2.cs index d95846011..ba1e49453 100644 --- a/System.Core/System/IO/BufferedStream2.cs +++ b/System.Core/System/IO/BufferedStream2.cs @@ -265,7 +265,7 @@ public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, A // (either synchronously or asynchronously) before the first one // returns. This would involve some sort of complex buffer locking // that we probably don't want to get into, at least not in V1. - // If we did a [....] read to fill the buffer, we could avoid the + // If we did a sync read to fill the buffer, we could avoid the // problem, and any async read less than 64K gets turned into a // synchronous read by NT anyways... -- @@ -508,7 +508,7 @@ public override void Flush() // Reading is done by blocks from the file, but someone could read // 1 byte from the buffer then write. At that point, the OS's file - // pointer is out of [....] with the stream's position. All write + // pointer is out of sync with the stream's position. All write // functions should call this function to preserve the position in the file. [MethodImplAttribute(MethodImplOptions.Synchronized)] protected void FlushRead() { diff --git a/System.Core/System/IO/LogStream.cs b/System.Core/System/IO/LogStream.cs index 69179635a..37b0623d3 100644 --- a/System.Core/System/IO/LogStream.cs +++ b/System.Core/System/IO/LogStream.cs @@ -278,7 +278,7 @@ unsafe private int WriteFileNative(byte[] bytes, int offset, int count, NativeOv } if (r == 0) { - // We should never silently ---- an error here without some + // We should never silently swallow an error here without some // extra work. We must make sure that BeginWriteCore won't return an // IAsyncResult that will cause EndWrite to block, since the OS won't // call AsyncFSCallback for us. diff --git a/System.Core/System/IO/MemoryMappedFiles/MemoryMappedView.cs b/System.Core/System/IO/MemoryMappedFiles/MemoryMappedView.cs index 98e30f009..a88b941d0 100644 --- a/System.Core/System/IO/MemoryMappedFiles/MemoryMappedView.cs +++ b/System.Core/System/IO/MemoryMappedFiles/MemoryMappedView.cs @@ -167,7 +167,7 @@ internal unsafe static MemoryMappedView CreateView(SafeMemoryMappedFileHandle me } - // Flushes the changes such that they are in [....] with the FileStream bits (ones obtained + // Flushes the changes such that they are in sync with the FileStream bits (ones obtained // with the win32 ReadFile and WriteFile functions). Need to call FileStream's Flush to // flush to the disk. // NOTE: This will flush all bytes before and after the view up until an offset that is a multiple diff --git a/System.Core/System/IO/MemoryMappedFiles/MemoryMappedViewAccessor.cs b/System.Core/System/IO/MemoryMappedFiles/MemoryMappedViewAccessor.cs index 3df123c55..c79b81dfe 100644 --- a/System.Core/System/IO/MemoryMappedFiles/MemoryMappedViewAccessor.cs +++ b/System.Core/System/IO/MemoryMappedFiles/MemoryMappedViewAccessor.cs @@ -76,7 +76,7 @@ protected override void Dispose(bool disposing) { } } - // Flushes the changes such that they are in [....] with the FileStream bits (ones obtained + // Flushes the changes such that they are in sync with the FileStream bits (ones obtained // with the win32 ReadFile and WriteFile functions). Need to call FileStream's Flush to // flush to the disk. // NOTE: This will flush all bytes before and after the view up until an offset that is a diff --git a/System.Core/System/IO/MemoryMappedFiles/MemoryMappedViewStream.cs b/System.Core/System/IO/MemoryMappedFiles/MemoryMappedViewStream.cs index 283048b06..c531a45d5 100644 --- a/System.Core/System/IO/MemoryMappedFiles/MemoryMappedViewStream.cs +++ b/System.Core/System/IO/MemoryMappedFiles/MemoryMappedViewStream.cs @@ -78,7 +78,7 @@ protected override void Dispose(bool disposing) { } } - // Flushes the changes such that they are in [....] with the FileStream bits (ones obtained + // Flushes the changes such that they are in sync with the FileStream bits (ones obtained // with the win32 ReadFile and WriteFile functions). Need to call FileStream's Flush to // flush to the disk. // NOTE: This will flush all bytes before and after the view up until an offset that is a diff --git a/System.Core/System/IO/Pipes/PipeStream.cs b/System.Core/System/IO/Pipes/PipeStream.cs index d3b913c00..02018024c 100644 --- a/System.Core/System/IO/Pipes/PipeStream.cs +++ b/System.Core/System/IO/Pipes/PipeStream.cs @@ -256,7 +256,7 @@ public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, Asy CheckReadOperations(); if (!m_isAsync) { - // special case when this is called for [....] broken pipes because otherwise Stream's + // special case when this is called for sync broken pipes because otherwise Stream's // Begin/EndRead hang. Reads return 0 bytes in this case so we can call the user's // callback immediately if (m_state == PipeState.Broken) { @@ -645,7 +645,7 @@ private unsafe int ReadFileNative(SafePipeHandle handle, byte[] buffer, int offs } if (r == 0) { - // We should never silently ---- an error here without some + // We should never silently swallow an error here without some // extra work. We must make sure that BeginReadCore won't return an // IAsyncResult that will cause EndRead to block, since the OS won't // call AsyncPSCallback for us. @@ -695,7 +695,7 @@ private unsafe int WriteFileNative(SafePipeHandle handle, byte[] buffer, int off } if (r == 0) { - // We should never silently ---- an error here without some + // We should never silently swallow an error here without some // extra work. We must make sure that BeginWriteCore won't return an // IAsyncResult that will cause EndWrite to block, since the OS won't // call AsyncPSCallback for us. diff --git a/System.Core/System/Linq/Enumerable.cs b/System.Core/System/Linq/Enumerable.cs index f062ca5e6..66e864ef0 100644 --- a/System.Core/System/Linq/Enumerable.cs +++ b/System.Core/System/Linq/Enumerable.cs @@ -2128,7 +2128,7 @@ IEnumerator IEnumerable.GetEnumerator() { internal int InternalGetHashCode(TKey key) { - //[....] DevDivBugs 171937. work around comparer implementations that throw when passed null + //Microsoft DevDivBugs 171937. work around comparer implementations that throw when passed null return (key == null) ? 0 : comparer.GetHashCode(key) & 0x7FFFFFFF; } @@ -2346,7 +2346,7 @@ void Resize() { internal int InternalGetHashCode(TElement value) { - //[....] DevDivBugs 171937. work around comparer implementations that throw when passed null + //Microsoft DevDivBugs 171937. work around comparer implementations that throw when passed null return (value == null) ? 0 : comparer.GetHashCode(value) & 0x7FFFFFFF; } diff --git a/System.Core/System/Linq/Parallel/Channels/AsynchronousChannel.cs b/System.Core/System/Linq/Parallel/Channels/AsynchronousChannel.cs index d249e8749..0024bf3c9 100644 --- a/System.Core/System/Linq/Parallel/Channels/AsynchronousChannel.cs +++ b/System.Core/System/Linq/Parallel/Channels/AsynchronousChannel.cs @@ -7,7 +7,7 @@ // // AsynchronousOneToOneChannel.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Channels/SynchronousChannel.cs b/System.Core/System/Linq/Parallel/Channels/SynchronousChannel.cs index ac27781a0..79cdc7a9b 100644 --- a/System.Core/System/Linq/Parallel/Channels/SynchronousChannel.cs +++ b/System.Core/System/Linq/Parallel/Channels/SynchronousChannel.cs @@ -7,7 +7,7 @@ // // SynchronousChannel.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Enumerables/AggregationMinMaxHelpers.cs b/System.Core/System/Linq/Parallel/Enumerables/AggregationMinMaxHelpers.cs index af69de8aa..3d560db8c 100644 --- a/System.Core/System/Linq/Parallel/Enumerables/AggregationMinMaxHelpers.cs +++ b/System.Core/System/Linq/Parallel/Enumerables/AggregationMinMaxHelpers.cs @@ -7,7 +7,7 @@ // // AggregationMinMaxHelpers.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Enumerables/EmptyEnumerable.cs b/System.Core/System/Linq/Parallel/Enumerables/EmptyEnumerable.cs index 56c3c621c..0d3335d7d 100644 --- a/System.Core/System/Linq/Parallel/Enumerables/EmptyEnumerable.cs +++ b/System.Core/System/Linq/Parallel/Enumerables/EmptyEnumerable.cs @@ -7,7 +7,7 @@ // // EmptyEnumerable.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Enumerables/EnumerableWrapperWeakToStrong.cs b/System.Core/System/Linq/Parallel/Enumerables/EnumerableWrapperWeakToStrong.cs index 95dbb1e0e..6d7ec46c7 100644 --- a/System.Core/System/Linq/Parallel/Enumerables/EnumerableWrapperWeakToStrong.cs +++ b/System.Core/System/Linq/Parallel/Enumerables/EnumerableWrapperWeakToStrong.cs @@ -7,7 +7,7 @@ // // EnumerableWrapperWeakToStrong.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Enumerables/OrderedParallelQuery.cs b/System.Core/System/Linq/Parallel/Enumerables/OrderedParallelQuery.cs index 07e4c2a1f..70167618e 100644 --- a/System.Core/System/Linq/Parallel/Enumerables/OrderedParallelQuery.cs +++ b/System.Core/System/Linq/Parallel/Enumerables/OrderedParallelQuery.cs @@ -7,7 +7,7 @@ // // OrderedParallelQuery.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Enumerables/ParallelEnumerableWrapper.cs b/System.Core/System/Linq/Parallel/Enumerables/ParallelEnumerableWrapper.cs index 8c5fb1912..31d072f3b 100644 --- a/System.Core/System/Linq/Parallel/Enumerables/ParallelEnumerableWrapper.cs +++ b/System.Core/System/Linq/Parallel/Enumerables/ParallelEnumerableWrapper.cs @@ -7,7 +7,7 @@ // // ParallelEnumerableWrapper.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Enumerables/ParallelQuery.cs b/System.Core/System/Linq/Parallel/Enumerables/ParallelQuery.cs index 9503c3043..b9a9477a7 100644 --- a/System.Core/System/Linq/Parallel/Enumerables/ParallelQuery.cs +++ b/System.Core/System/Linq/Parallel/Enumerables/ParallelQuery.cs @@ -7,7 +7,7 @@ // // ParallelQuery.cs // -// [....] +// Microsoft // // ParallelQuery is an abstract class that represents a PLINQ query. // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Enumerables/RangeEnumerable.cs b/System.Core/System/Linq/Parallel/Enumerables/RangeEnumerable.cs index 1bb58a81f..8c5808446 100644 --- a/System.Core/System/Linq/Parallel/Enumerables/RangeEnumerable.cs +++ b/System.Core/System/Linq/Parallel/Enumerables/RangeEnumerable.cs @@ -7,7 +7,7 @@ // // RangeEnumerable.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Enumerables/RepeatEnumerable.cs b/System.Core/System/Linq/Parallel/Enumerables/RepeatEnumerable.cs index 1998eabb0..6951c939b 100644 --- a/System.Core/System/Linq/Parallel/Enumerables/RepeatEnumerable.cs +++ b/System.Core/System/Linq/Parallel/Enumerables/RepeatEnumerable.cs @@ -7,7 +7,7 @@ // // RepeatEnumerable.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Merging/ArrayMergeHelper.cs b/System.Core/System/Linq/Parallel/Merging/ArrayMergeHelper.cs index 97559c5fd..feebc57bf 100644 --- a/System.Core/System/Linq/Parallel/Merging/ArrayMergeHelper.cs +++ b/System.Core/System/Linq/Parallel/Merging/ArrayMergeHelper.cs @@ -7,7 +7,7 @@ // // ArrayMergeHelper.cs // -// [....] +// Microsoft // // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Merging/AsynchronousChannelMergeEnumerator.cs b/System.Core/System/Linq/Parallel/Merging/AsynchronousChannelMergeEnumerator.cs index 599f13ae4..b76d1e427 100644 --- a/System.Core/System/Linq/Parallel/Merging/AsynchronousChannelMergeEnumerator.cs +++ b/System.Core/System/Linq/Parallel/Merging/AsynchronousChannelMergeEnumerator.cs @@ -7,7 +7,7 @@ // // AsynchronousChannelMergeEnumerator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Merging/DefaultMergeHelper.cs b/System.Core/System/Linq/Parallel/Merging/DefaultMergeHelper.cs index d1115094a..b288fffec 100644 --- a/System.Core/System/Linq/Parallel/Merging/DefaultMergeHelper.cs +++ b/System.Core/System/Linq/Parallel/Merging/DefaultMergeHelper.cs @@ -7,7 +7,7 @@ // // DefaultMergeHelper.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -32,7 +32,7 @@ internal class DefaultMergeHelper : IMergeHelper m_partitions; // Source partitions. private AsynchronousChannel[] m_asyncChannels; // Destination channels (async). - private SynchronousChannel[] m_syncChannels; // Destination channels ([....]). + private SynchronousChannel[] m_syncChannels; // Destination channels (sync). private IEnumerator m_channelEnumerator; // Output enumerator. private TaskScheduler m_taskScheduler; // The task manager to execute the query. private bool m_ignoreOutput; // Whether we're enumerating "for effect". diff --git a/System.Core/System/Linq/Parallel/Merging/MergeEnumerator.cs b/System.Core/System/Linq/Parallel/Merging/MergeEnumerator.cs index 8fac0d62c..da0298ce1 100644 --- a/System.Core/System/Linq/Parallel/Merging/MergeEnumerator.cs +++ b/System.Core/System/Linq/Parallel/Merging/MergeEnumerator.cs @@ -7,7 +7,7 @@ // // MergeEnumerator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Merging/MergeExecutor.cs b/System.Core/System/Linq/Parallel/Merging/MergeExecutor.cs index f3136f12e..2e0d8d901 100644 --- a/System.Core/System/Linq/Parallel/Merging/MergeExecutor.cs +++ b/System.Core/System/Linq/Parallel/Merging/MergeExecutor.cs @@ -7,7 +7,7 @@ // // MergeExecutor.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Merging/OrderPreservingMergeHelper.cs b/System.Core/System/Linq/Parallel/Merging/OrderPreservingMergeHelper.cs index d45653452..b7015a48d 100644 --- a/System.Core/System/Linq/Parallel/Merging/OrderPreservingMergeHelper.cs +++ b/System.Core/System/Linq/Parallel/Merging/OrderPreservingMergeHelper.cs @@ -7,7 +7,7 @@ // // OrderPreservingMergeHelper.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Merging/OrderPreservingPipeliningMergeHelper.cs b/System.Core/System/Linq/Parallel/Merging/OrderPreservingPipeliningMergeHelper.cs index f9fc2bc49..5da2671db 100644 --- a/System.Core/System/Linq/Parallel/Merging/OrderPreservingPipeliningMergeHelper.cs +++ b/System.Core/System/Linq/Parallel/Merging/OrderPreservingPipeliningMergeHelper.cs @@ -7,7 +7,7 @@ // // OrderPreservingPipeliningMergeHelper.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Merging/SynchronousChannelMergeEnumerator.cs b/System.Core/System/Linq/Parallel/Merging/SynchronousChannelMergeEnumerator.cs index ba302d416..0bdc6ea7c 100644 --- a/System.Core/System/Linq/Parallel/Merging/SynchronousChannelMergeEnumerator.cs +++ b/System.Core/System/Linq/Parallel/Merging/SynchronousChannelMergeEnumerator.cs @@ -7,7 +7,7 @@ // // SynchronousChannelMergeEnumerator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Partitioning/HashRepartitionEnumerator.cs b/System.Core/System/Linq/Parallel/Partitioning/HashRepartitionEnumerator.cs index 5f8cd482e..001eb1b31 100644 --- a/System.Core/System/Linq/Parallel/Partitioning/HashRepartitionEnumerator.cs +++ b/System.Core/System/Linq/Parallel/Partitioning/HashRepartitionEnumerator.cs @@ -7,7 +7,7 @@ // // HashRepartitionEnumerator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Partitioning/HashRepartitionStream.cs b/System.Core/System/Linq/Parallel/Partitioning/HashRepartitionStream.cs index 96aaf2d4c..949e4f419 100644 --- a/System.Core/System/Linq/Parallel/Partitioning/HashRepartitionStream.cs +++ b/System.Core/System/Linq/Parallel/Partitioning/HashRepartitionStream.cs @@ -7,7 +7,7 @@ // // HashPartitionedStream.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Partitioning/OrderedHashRepartitionEnumerator.cs b/System.Core/System/Linq/Parallel/Partitioning/OrderedHashRepartitionEnumerator.cs index 39ca3fb03..35865feb9 100644 --- a/System.Core/System/Linq/Parallel/Partitioning/OrderedHashRepartitionEnumerator.cs +++ b/System.Core/System/Linq/Parallel/Partitioning/OrderedHashRepartitionEnumerator.cs @@ -7,7 +7,7 @@ // // OrderedHashRepartitionEnumerator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Partitioning/OrderedHashRepartitionStream.cs b/System.Core/System/Linq/Parallel/Partitioning/OrderedHashRepartitionStream.cs index f12862e8f..dfd79fd68 100644 --- a/System.Core/System/Linq/Parallel/Partitioning/OrderedHashRepartitionStream.cs +++ b/System.Core/System/Linq/Parallel/Partitioning/OrderedHashRepartitionStream.cs @@ -7,7 +7,7 @@ // // OrderedHashRepartitionStream.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Partitioning/PartitionedDataSource.cs b/System.Core/System/Linq/Parallel/Partitioning/PartitionedDataSource.cs index e9f639c79..2f661a9e3 100644 --- a/System.Core/System/Linq/Parallel/Partitioning/PartitionedDataSource.cs +++ b/System.Core/System/Linq/Parallel/Partitioning/PartitionedDataSource.cs @@ -7,7 +7,7 @@ // // PartitionedDataSource.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Partitioning/PartitionedStream.cs b/System.Core/System/Linq/Parallel/Partitioning/PartitionedStream.cs index dd6c687fe..fc7477fe3 100644 --- a/System.Core/System/Linq/Parallel/Partitioning/PartitionedStream.cs +++ b/System.Core/System/Linq/Parallel/Partitioning/PartitionedStream.cs @@ -7,7 +7,7 @@ // // PartitionedStream.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Partitioning/UnorderedHashRepartitionStream.cs b/System.Core/System/Linq/Parallel/Partitioning/UnorderedHashRepartitionStream.cs index b8d1e6be9..7edc4d07d 100644 --- a/System.Core/System/Linq/Parallel/Partitioning/UnorderedHashRepartitionStream.cs +++ b/System.Core/System/Linq/Parallel/Partitioning/UnorderedHashRepartitionStream.cs @@ -7,7 +7,7 @@ // // UnorderedHashRepartitionStream.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/AssociativeAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/AssociativeAggregationOperator.cs index 6df8e3e6c..add046683 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/AssociativeAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/AssociativeAggregationOperator.cs @@ -7,7 +7,7 @@ // // AssociativeAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Binary/ExceptQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Binary/ExceptQueryOperator.cs index d84be6b56..c8a8d2206 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Binary/ExceptQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Binary/ExceptQueryOperator.cs @@ -7,7 +7,7 @@ // // ExceptQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Binary/GroupJoinQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Binary/GroupJoinQueryOperator.cs index a56fe2f67..60b6befd6 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Binary/GroupJoinQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Binary/GroupJoinQueryOperator.cs @@ -7,7 +7,7 @@ // // GroupJoinQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Binary/HashJoinQueryOperatorEnumerator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Binary/HashJoinQueryOperatorEnumerator.cs index 88196b526..e09d4d92b 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Binary/HashJoinQueryOperatorEnumerator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Binary/HashJoinQueryOperatorEnumerator.cs @@ -7,7 +7,7 @@ // // HashJoinQueryOperatorEnumerator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Binary/IntersectQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Binary/IntersectQueryOperator.cs index 869795154..3ce35c451 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Binary/IntersectQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Binary/IntersectQueryOperator.cs @@ -7,7 +7,7 @@ // // IntersectQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Binary/JoinQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Binary/JoinQueryOperator.cs index a80990550..9dbd672ec 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Binary/JoinQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Binary/JoinQueryOperator.cs @@ -7,7 +7,7 @@ // // JoinQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Binary/UnionQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Binary/UnionQueryOperator.cs index c2d07020d..8251ef549 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Binary/UnionQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Binary/UnionQueryOperator.cs @@ -7,7 +7,7 @@ // // UnionQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Binary/ZipQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Binary/ZipQueryOperator.cs index 3b2d74cfd..3465f80d4 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Binary/ZipQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Binary/ZipQueryOperator.cs @@ -7,7 +7,7 @@ // // ZipQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/BinaryQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/BinaryQueryOperator.cs index f159f1c25..3beed03e1 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/BinaryQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/BinaryQueryOperator.cs @@ -7,7 +7,7 @@ // // BinaryQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/CountAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/CountAggregationOperator.cs index 84ae158c3..95b660b22 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/CountAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/CountAggregationOperator.cs @@ -7,7 +7,7 @@ // // CountAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalAverageAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalAverageAggregationOperator.cs index f7e86aaa2..d321018d7 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalAverageAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalAverageAggregationOperator.cs @@ -7,7 +7,7 @@ // // DecimalAverageAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalMinMaxAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalMinMaxAggregationOperator.cs index 55e2f78e8..eaa22795f 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalMinMaxAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalMinMaxAggregationOperator.cs @@ -7,7 +7,7 @@ // // DecimalMinMaxAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalSumAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalSumAggregationOperator.cs index 17d0658b9..30560fecc 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalSumAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DecimalSumAggregationOperator.cs @@ -7,7 +7,7 @@ // // DecimalSumAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleAverageAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleAverageAggregationOperator.cs index 5d6aa8e41..dba1e1021 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleAverageAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleAverageAggregationOperator.cs @@ -7,7 +7,7 @@ // // DoubleAverageAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleMinMaxAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleMinMaxAggregationOperator.cs index 85c2e84cc..a7cd5df65 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleMinMaxAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleMinMaxAggregationOperator.cs @@ -7,7 +7,7 @@ // // DoubleMinMaxAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleSumAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleSumAggregationOperator.cs index c464be095..b2477cfd7 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleSumAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/DoubleSumAggregationOperator.cs @@ -7,7 +7,7 @@ // // DoubleSumAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatAverageAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatAverageAggregationOperator.cs index 8d310b488..d2d294f1f 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatAverageAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatAverageAggregationOperator.cs @@ -7,7 +7,7 @@ // // FloatAverageAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatMinMaxAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatMinMaxAggregationOperator.cs index 1cc5d0d25..10be7b55e 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatMinMaxAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatMinMaxAggregationOperator.cs @@ -7,7 +7,7 @@ // // FloatMinMaxAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatSumAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatSumAggregationOperator.cs index 03949d7aa..ecf0656a9 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatSumAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/FloatSumAggregationOperator.cs @@ -7,7 +7,7 @@ // // FloatSumAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/InlinedAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/InlinedAggregationOperator.cs index 31ba533d8..865ccaac7 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/InlinedAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/InlinedAggregationOperator.cs @@ -7,7 +7,7 @@ // // InlinedAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/InlinedAggregationOperatorEnumerator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/InlinedAggregationOperatorEnumerator.cs index 416844cfb..b53d200df 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/InlinedAggregationOperatorEnumerator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/InlinedAggregationOperatorEnumerator.cs @@ -7,7 +7,7 @@ // // InlinedAggregationOperatorEnumerator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntAverageAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntAverageAggregationOperator.cs index 9733071e8..88a779aeb 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntAverageAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntAverageAggregationOperator.cs @@ -7,7 +7,7 @@ // // IntAverageAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntMinMaxAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntMinMaxAggregationOperator.cs index 5bd686ab5..469a90346 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntMinMaxAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntMinMaxAggregationOperator.cs @@ -7,7 +7,7 @@ // // IntMinMaxAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntSumAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntSumAggregationOperator.cs index f57f4ec52..28b5048b0 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntSumAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/IntSumAggregationOperator.cs @@ -7,7 +7,7 @@ // // IntSumAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongAverageAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongAverageAggregationOperator.cs index 61478be33..3de0feed3 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongAverageAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongAverageAggregationOperator.cs @@ -7,7 +7,7 @@ // // LongAverageAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongCountAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongCountAggregationOperator.cs index 4332cee83..1c1ecc3a3 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongCountAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongCountAggregationOperator.cs @@ -7,7 +7,7 @@ // // CountAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongMinMaxAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongMinMaxAggregationOperator.cs index 0c7bdfbd8..bb45b5b83 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongMinMaxAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongMinMaxAggregationOperator.cs @@ -7,7 +7,7 @@ // // LongMinMaxAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongSumAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongSumAggregationOperator.cs index df856cc34..bc29d47ba 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongSumAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/LongSumAggregationOperator.cs @@ -7,7 +7,7 @@ // // LongSumAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalAverageAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalAverageAggregationOperator.cs index 246aa40dc..cdaf0301e 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalAverageAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalAverageAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableDecimalAverageAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalMinMaxAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalMinMaxAggregationOperator.cs index 8d78b129d..abbacb4e2 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalMinMaxAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalMinMaxAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableDecimalMinMaxAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalSumAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalSumAggregationOperator.cs index 2602c9eb2..5c32e0cc8 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalSumAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDecimalSumAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableDecimalSumAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleAverageAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleAverageAggregationOperator.cs index 69b52aaa3..44eb13ad6 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleAverageAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleAverageAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableDoubleAverageAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleMinMaxAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleMinMaxAggregationOperator.cs index 7b4427764..a2a7fcb3e 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleMinMaxAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleMinMaxAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableDoubleMinMaxAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleSumAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleSumAggregationOperator.cs index 9f92f75d1..f1ced299f 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleSumAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableDoubleSumAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableDoubleSumAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatAverageAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatAverageAggregationOperator.cs index 2b7c0d452..b33baf58a 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatAverageAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatAverageAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableFloatAverageAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatMinMaxAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatMinMaxAggregationOperator.cs index b1b8064e0..8180ef534 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatMinMaxAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatMinMaxAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableFloatMinMaxAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatSumAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatSumAggregationOperator.cs index d2ea8a423..d4aa289c0 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatSumAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableFloatSumAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableFloatSumAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntAverageAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntAverageAggregationOperator.cs index 4604a595f..ea9bcd10d 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntAverageAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntAverageAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableIntAverageAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntMinMaxAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntMinMaxAggregationOperator.cs index 5c57d26b0..6ff77bd7e 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntMinMaxAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntMinMaxAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableIntMinMaxAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntSumAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntSumAggregationOperator.cs index c00fdb01d..14389d8fc 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntSumAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableIntSumAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableIntSumAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongAverageAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongAverageAggregationOperator.cs index ddf75c89f..bacb98750 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongAverageAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongAverageAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableLongAverageAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongMinMaxAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongMinMaxAggregationOperator.cs index 7d4e369d9..824bb98a4 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongMinMaxAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongMinMaxAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableLongMinMaxAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongSumAggregationOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongSumAggregationOperator.cs index 97e53a64e..313e7c182 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongSumAggregationOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Inlined/NullableLongSumAggregationOperator.cs @@ -7,7 +7,7 @@ // // NullableLongSumAggregationOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/ListQueryResults.cs b/System.Core/System/Linq/Parallel/QueryOperators/ListQueryResults.cs index 55069c3b3..e55d313c0 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/ListQueryResults.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/ListQueryResults.cs @@ -7,7 +7,7 @@ // // ListQueryResults.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Options/OrderingQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Options/OrderingQueryOperator.cs index 33baf3f80..27f7bf886 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Options/OrderingQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Options/OrderingQueryOperator.cs @@ -7,7 +7,7 @@ // // OrderingQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Options/QueryExecutionOption.cs b/System.Core/System/Linq/Parallel/QueryOperators/Options/QueryExecutionOption.cs index 1bef24bed..8ddc79645 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Options/QueryExecutionOption.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Options/QueryExecutionOption.cs @@ -7,7 +7,7 @@ // // QueryExecutionOption.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/PartitionedStreamMerger.cs b/System.Core/System/Linq/Parallel/QueryOperators/PartitionedStreamMerger.cs index 282c6cd90..77682f695 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/PartitionedStreamMerger.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/PartitionedStreamMerger.cs @@ -7,7 +7,7 @@ // // PartitionedStreamMerger.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/PartitionerQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/PartitionerQueryOperator.cs index c239cb7e4..62ed43dba 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/PartitionerQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/PartitionerQueryOperator.cs @@ -7,7 +7,7 @@ // // PartitionerQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/QueryOpeningEnumerator.cs b/System.Core/System/Linq/Parallel/QueryOperators/QueryOpeningEnumerator.cs index 570b9e4ab..4ed5e6f2f 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/QueryOpeningEnumerator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/QueryOpeningEnumerator.cs @@ -7,7 +7,7 @@ // // QueryOpeningEnumerator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/QueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/QueryOperator.cs index c83015bb3..60d656c1e 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/QueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/QueryOperator.cs @@ -7,7 +7,7 @@ // // QueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/QueryOperatorEnumerator.cs b/System.Core/System/Linq/Parallel/QueryOperators/QueryOperatorEnumerator.cs index db776f878..6f78b8177 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/QueryOperatorEnumerator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/QueryOperatorEnumerator.cs @@ -7,7 +7,7 @@ // // QueryOperatorEnumerator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/QueryResults.cs b/System.Core/System/Linq/Parallel/QueryOperators/QueryResults.cs index cee66591f..d062a698e 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/QueryResults.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/QueryResults.cs @@ -7,7 +7,7 @@ // // QueryResults.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/QuerySettings.cs b/System.Core/System/Linq/Parallel/QueryOperators/QuerySettings.cs index 08f410f98..84b6c8826 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/QuerySettings.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/QuerySettings.cs @@ -7,7 +7,7 @@ // // QuerySettings.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/ScanQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/ScanQueryOperator.cs index e70b13e18..1310302c2 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/ScanQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/ScanQueryOperator.cs @@ -7,7 +7,7 @@ // // ScanQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/AnyAllSearchOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/AnyAllSearchOperator.cs index fd4b201e7..2dc5b284f 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/AnyAllSearchOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/AnyAllSearchOperator.cs @@ -7,7 +7,7 @@ // // AnyAllSearchOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/ConcatQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/ConcatQueryOperator.cs index d55436aff..4f07a9f2e 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/ConcatQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/ConcatQueryOperator.cs @@ -7,7 +7,7 @@ // // ConcatQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/ContainsSearchOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/ContainsSearchOperator.cs index 78de10051..b41748052 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/ContainsSearchOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/ContainsSearchOperator.cs @@ -7,7 +7,7 @@ // // ContainsSearchOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/DefaultIfEmptyQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/DefaultIfEmptyQueryOperator.cs index 9a0346995..6611cc280 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/DefaultIfEmptyQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/DefaultIfEmptyQueryOperator.cs @@ -7,7 +7,7 @@ // // DefaultIfEmptyQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/DistinctQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/DistinctQueryOperator.cs index 4de47cea4..fc5ecd5f7 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/DistinctQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/DistinctQueryOperator.cs @@ -7,7 +7,7 @@ // // DistinctQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/ElementAtQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/ElementAtQueryOperator.cs index 0560b753f..70660e9fc 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/ElementAtQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/ElementAtQueryOperator.cs @@ -7,7 +7,7 @@ // // ElementAtQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/FirstQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/FirstQueryOperator.cs index 38c143c5f..8181237ca 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/FirstQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/FirstQueryOperator.cs @@ -7,7 +7,7 @@ // // FirstQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/ForAllOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/ForAllOperator.cs index 867610402..825d755f4 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/ForAllOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/ForAllOperator.cs @@ -7,7 +7,7 @@ // // ForAllQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/GroupByQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/GroupByQueryOperator.cs index ed3b2f440..ab4d27254 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/GroupByQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/GroupByQueryOperator.cs @@ -7,7 +7,7 @@ // // GroupByQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/IndexedSelectQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/IndexedSelectQueryOperator.cs index f1d0e5ef3..1a304e459 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/IndexedSelectQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/IndexedSelectQueryOperator.cs @@ -7,7 +7,7 @@ // // IndexedSelectQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/IndexedWhereQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/IndexedWhereQueryOperator.cs index a4d65f3cf..fddb99260 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/IndexedWhereQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/IndexedWhereQueryOperator.cs @@ -7,7 +7,7 @@ // // IndexedWhereQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/LastQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/LastQueryOperator.cs index 8b354de11..f4a74d0c7 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/LastQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/LastQueryOperator.cs @@ -7,7 +7,7 @@ // // LastQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/ReverseQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/ReverseQueryOperator.cs index d66add119..9f4a4eece 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/ReverseQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/ReverseQueryOperator.cs @@ -7,7 +7,7 @@ // // ReverseQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/SelectManyQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/SelectManyQueryOperator.cs index 741bb24cd..8a4c0f3e7 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/SelectManyQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/SelectManyQueryOperator.cs @@ -7,7 +7,7 @@ // // SelectManyQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/SelectQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/SelectQueryOperator.cs index 2301c1d06..7eaa46765 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/SelectQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/SelectQueryOperator.cs @@ -7,7 +7,7 @@ // // SelectQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/SingleQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/SingleQueryOperator.cs index d5539ceaf..c2cb9d451 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/SingleQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/SingleQueryOperator.cs @@ -7,7 +7,7 @@ // // SingleQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/SortQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/SortQueryOperator.cs index b73b8bd08..af64f227a 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/SortQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/SortQueryOperator.cs @@ -7,7 +7,7 @@ // // SortQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/TakeOrSkipQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/TakeOrSkipQueryOperator.cs index c0c708a7c..67a70ce8f 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/TakeOrSkipQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/TakeOrSkipQueryOperator.cs @@ -7,7 +7,7 @@ // // TakeOrSkipQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/TakeOrSkipWhileQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/TakeOrSkipWhileQueryOperator.cs index a04bf2bfb..64f089adc 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/TakeOrSkipWhileQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/TakeOrSkipWhileQueryOperator.cs @@ -7,7 +7,7 @@ // // TakeOrSkipWhileQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/Unary/WhereQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/Unary/WhereQueryOperator.cs index 3ec343a9f..d447915d8 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/Unary/WhereQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/Unary/WhereQueryOperator.cs @@ -7,7 +7,7 @@ // // WhereQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/QueryOperators/UnaryQueryOperator.cs b/System.Core/System/Linq/Parallel/QueryOperators/UnaryQueryOperator.cs index b66aa49f7..0baa5ad62 100644 --- a/System.Core/System/Linq/Parallel/QueryOperators/UnaryQueryOperator.cs +++ b/System.Core/System/Linq/Parallel/QueryOperators/UnaryQueryOperator.cs @@ -7,7 +7,7 @@ // // UnaryQueryOperator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Scheduling/CancellationState.cs b/System.Core/System/Linq/Parallel/Scheduling/CancellationState.cs index c084abb4b..e84bced81 100644 --- a/System.Core/System/Linq/Parallel/Scheduling/CancellationState.cs +++ b/System.Core/System/Linq/Parallel/Scheduling/CancellationState.cs @@ -7,7 +7,7 @@ // // CancellationState.cs // -// [....] +// Microsoft // // A bag of cancellation-related items that are passed around as a group. // diff --git a/System.Core/System/Linq/Parallel/Scheduling/OrderPreservingPipeliningSpoolingTask.cs b/System.Core/System/Linq/Parallel/Scheduling/OrderPreservingPipeliningSpoolingTask.cs index f1e99baed..a402e317e 100644 --- a/System.Core/System/Linq/Parallel/Scheduling/OrderPreservingPipeliningSpoolingTask.cs +++ b/System.Core/System/Linq/Parallel/Scheduling/OrderPreservingPipeliningSpoolingTask.cs @@ -7,7 +7,7 @@ // // OrderPreservingPipeliningSpoolingTask.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Scheduling/OrderPreservingSpoolingTask.cs b/System.Core/System/Linq/Parallel/Scheduling/OrderPreservingSpoolingTask.cs index 478533db2..20c751571 100644 --- a/System.Core/System/Linq/Parallel/Scheduling/OrderPreservingSpoolingTask.cs +++ b/System.Core/System/Linq/Parallel/Scheduling/OrderPreservingSpoolingTask.cs @@ -7,7 +7,7 @@ // // OrderPreservingSpoolingTask.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Scheduling/QueryLifecycle.cs b/System.Core/System/Linq/Parallel/Scheduling/QueryLifecycle.cs index 92ead1bfb..3f0e70731 100644 --- a/System.Core/System/Linq/Parallel/Scheduling/QueryLifecycle.cs +++ b/System.Core/System/Linq/Parallel/Scheduling/QueryLifecycle.cs @@ -7,7 +7,7 @@ // // QueryLifecycle.cs // -// [....] +// Microsoft // // A convenient place to put things associated with entire queries and their lifecycle events. // diff --git a/System.Core/System/Linq/Parallel/Scheduling/QueryTask.cs b/System.Core/System/Linq/Parallel/Scheduling/QueryTask.cs index 97dc14d53..7ca188a35 100644 --- a/System.Core/System/Linq/Parallel/Scheduling/QueryTask.cs +++ b/System.Core/System/Linq/Parallel/Scheduling/QueryTask.cs @@ -7,7 +7,7 @@ // // QueryTask.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -88,7 +88,7 @@ internal Task RunAsynchronously(TaskScheduler taskScheduler) } //----------------------------------------------------------------------------------- - // Common function called regardless of [....] or async execution. Just wraps some + // Common function called regardless of sync or async execution. Just wraps some // amount of tracing around the call to the real work API. // diff --git a/System.Core/System/Linq/Parallel/Scheduling/QueryTaskGroupState.cs b/System.Core/System/Linq/Parallel/Scheduling/QueryTaskGroupState.cs index f3666afb0..bb802725b 100644 --- a/System.Core/System/Linq/Parallel/Scheduling/QueryTaskGroupState.cs +++ b/System.Core/System/Linq/Parallel/Scheduling/QueryTaskGroupState.cs @@ -7,7 +7,7 @@ // // QueryTaskGroupState.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Scheduling/Scheduling.cs b/System.Core/System/Linq/Parallel/Scheduling/Scheduling.cs index f43d3fdd5..306b5411b 100644 --- a/System.Core/System/Linq/Parallel/Scheduling/Scheduling.cs +++ b/System.Core/System/Linq/Parallel/Scheduling/Scheduling.cs @@ -7,7 +7,7 @@ // // Scheduling.cs // -// [....] +// Microsoft // // Infrastructure for setting up concurrent work, marshaling exceptions, determining // the recommended degree-of-parallelism, and so forth. diff --git a/System.Core/System/Linq/Parallel/Scheduling/SpoolingTask.cs b/System.Core/System/Linq/Parallel/Scheduling/SpoolingTask.cs index ab614a047..a80160150 100644 --- a/System.Core/System/Linq/Parallel/Scheduling/SpoolingTask.cs +++ b/System.Core/System/Linq/Parallel/Scheduling/SpoolingTask.cs @@ -7,7 +7,7 @@ // // SpoolingTask.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Scheduling/SpoolingTaskBase.cs b/System.Core/System/Linq/Parallel/Scheduling/SpoolingTaskBase.cs index fdbe37adf..26d878fe0 100644 --- a/System.Core/System/Linq/Parallel/Scheduling/SpoolingTaskBase.cs +++ b/System.Core/System/Linq/Parallel/Scheduling/SpoolingTaskBase.cs @@ -7,7 +7,7 @@ // // SpoolingTaskBase.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/CancellableEnumerable.cs b/System.Core/System/Linq/Parallel/Utils/CancellableEnumerable.cs index fc3855ea7..8eb45c4ba 100644 --- a/System.Core/System/Linq/Parallel/Utils/CancellableEnumerable.cs +++ b/System.Core/System/Linq/Parallel/Utils/CancellableEnumerable.cs @@ -7,7 +7,7 @@ // // CancellableEnumerable.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/ExceptionAggregator.cs b/System.Core/System/Linq/Parallel/Utils/ExceptionAggregator.cs index 7423b7eda..1a9b354fe 100644 --- a/System.Core/System/Linq/Parallel/Utils/ExceptionAggregator.cs +++ b/System.Core/System/Linq/Parallel/Utils/ExceptionAggregator.cs @@ -7,7 +7,7 @@ // // ExceptionAggregator.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/ExchangeUtilities.cs b/System.Core/System/Linq/Parallel/Utils/ExchangeUtilities.cs index 7df87b5a4..c52cec2fa 100644 --- a/System.Core/System/Linq/Parallel/Utils/ExchangeUtilities.cs +++ b/System.Core/System/Linq/Parallel/Utils/ExchangeUtilities.cs @@ -7,7 +7,7 @@ // // ExchangeUtilities.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/FixedMaxHeap.cs b/System.Core/System/Linq/Parallel/Utils/FixedMaxHeap.cs index 74f4f6fb6..43547483f 100644 --- a/System.Core/System/Linq/Parallel/Utils/FixedMaxHeap.cs +++ b/System.Core/System/Linq/Parallel/Utils/FixedMaxHeap.cs @@ -7,7 +7,7 @@ // // FixedMaxHeap.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/GrowingArray.cs b/System.Core/System/Linq/Parallel/Utils/GrowingArray.cs index 7e431a8d2..ccb3d1f97 100644 --- a/System.Core/System/Linq/Parallel/Utils/GrowingArray.cs +++ b/System.Core/System/Linq/Parallel/Utils/GrowingArray.cs @@ -7,7 +7,7 @@ // // GrowingArray.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/HashLookup.cs b/System.Core/System/Linq/Parallel/Utils/HashLookup.cs index 5cbd0bb5e..8251e6c6b 100644 --- a/System.Core/System/Linq/Parallel/Utils/HashLookup.cs +++ b/System.Core/System/Linq/Parallel/Utils/HashLookup.cs @@ -7,7 +7,7 @@ // // HashLookup.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/ListChunk.cs b/System.Core/System/Linq/Parallel/Utils/ListChunk.cs index 2b0b099c6..8ae361044 100644 --- a/System.Core/System/Linq/Parallel/Utils/ListChunk.cs +++ b/System.Core/System/Linq/Parallel/Utils/ListChunk.cs @@ -7,7 +7,7 @@ // // ListChunk.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/Lookup.cs b/System.Core/System/Linq/Parallel/Utils/Lookup.cs index e3b1561f6..4b7a65c5c 100644 --- a/System.Core/System/Linq/Parallel/Utils/Lookup.cs +++ b/System.Core/System/Linq/Parallel/Utils/Lookup.cs @@ -7,7 +7,7 @@ // // Lookup.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/PLINQETWProvider.cs b/System.Core/System/Linq/Parallel/Utils/PLINQETWProvider.cs index 294a86d54..bbfec3cd6 100644 --- a/System.Core/System/Linq/Parallel/Utils/PLINQETWProvider.cs +++ b/System.Core/System/Linq/Parallel/Utils/PLINQETWProvider.cs @@ -7,7 +7,7 @@ // // PlinqEtwProvider.cs // -// [....] +// Microsoft // // EventSource for PLINQ. // diff --git a/System.Core/System/Linq/Parallel/Utils/Pair.cs b/System.Core/System/Linq/Parallel/Utils/Pair.cs index 57ed99389..0c8ed3672 100644 --- a/System.Core/System/Linq/Parallel/Utils/Pair.cs +++ b/System.Core/System/Linq/Parallel/Utils/Pair.cs @@ -7,7 +7,7 @@ // // Pair.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/PairComparer.cs b/System.Core/System/Linq/Parallel/Utils/PairComparer.cs index 99cf8fd1d..ea0cc96ad 100644 --- a/System.Core/System/Linq/Parallel/Utils/PairComparer.cs +++ b/System.Core/System/Linq/Parallel/Utils/PairComparer.cs @@ -7,7 +7,7 @@ // // PairComparer.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/ReverseComparer.cs b/System.Core/System/Linq/Parallel/Utils/ReverseComparer.cs index b9ad3cced..e8e81bd32 100644 --- a/System.Core/System/Linq/Parallel/Utils/ReverseComparer.cs +++ b/System.Core/System/Linq/Parallel/Utils/ReverseComparer.cs @@ -7,7 +7,7 @@ // // ReverseComparer.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/Shared.cs b/System.Core/System/Linq/Parallel/Utils/Shared.cs index ebe195311..28da58a61 100644 --- a/System.Core/System/Linq/Parallel/Utils/Shared.cs +++ b/System.Core/System/Linq/Parallel/Utils/Shared.cs @@ -7,7 +7,7 @@ // // Shared.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/Sorting.cs b/System.Core/System/Linq/Parallel/Utils/Sorting.cs index fb3559972..dba1de364 100644 --- a/System.Core/System/Linq/Parallel/Utils/Sorting.cs +++ b/System.Core/System/Linq/Parallel/Utils/Sorting.cs @@ -7,7 +7,7 @@ // // Sorting.cs // -// [....] +// Microsoft // // Support for sorting. // diff --git a/System.Core/System/Linq/Parallel/Utils/TraceHelpers.cs b/System.Core/System/Linq/Parallel/Utils/TraceHelpers.cs index 5c1ad9f45..00202eb30 100644 --- a/System.Core/System/Linq/Parallel/Utils/TraceHelpers.cs +++ b/System.Core/System/Linq/Parallel/Utils/TraceHelpers.cs @@ -7,7 +7,7 @@ // // TraceHelpers.cs // -// [....] +// Microsoft // // Common routines used to trace information about execution, the state of things, etc. // diff --git a/System.Core/System/Linq/Parallel/Utils/Util.cs b/System.Core/System/Linq/Parallel/Utils/Util.cs index b877250e9..e15b085aa 100644 --- a/System.Core/System/Linq/Parallel/Utils/Util.cs +++ b/System.Core/System/Linq/Parallel/Utils/Util.cs @@ -7,7 +7,7 @@ // // Util.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/Wrapper.cs b/System.Core/System/Linq/Parallel/Utils/Wrapper.cs index c96085b02..4878dedf2 100644 --- a/System.Core/System/Linq/Parallel/Utils/Wrapper.cs +++ b/System.Core/System/Linq/Parallel/Utils/Wrapper.cs @@ -7,7 +7,7 @@ // // Wrapper.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/Parallel/Utils/WrapperEqualityComparer.cs b/System.Core/System/Linq/Parallel/Utils/WrapperEqualityComparer.cs index c2cb403ce..38fa75ba4 100644 --- a/System.Core/System/Linq/Parallel/Utils/WrapperEqualityComparer.cs +++ b/System.Core/System/Linq/Parallel/Utils/WrapperEqualityComparer.cs @@ -7,7 +7,7 @@ // // WrapperEqualityComparer.cs // -// [....] +// Microsoft // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/System.Core/System/Linq/ParallelEnumerable.cs b/System.Core/System/Linq/ParallelEnumerable.cs index 89dd8d769..daa567abe 100644 --- a/System.Core/System/Linq/ParallelEnumerable.cs +++ b/System.Core/System/Linq/ParallelEnumerable.cs @@ -7,7 +7,7 @@ // // ParallelEnumerable.cs // -// [....] +// Microsoft // // The standard IEnumerable-based LINQ-to-Objects query provider. This class basically // mirrors the System.Linq.Enumerable class, but (1) takes as input a special "parallel diff --git a/System.Core/System/Linq/SequenceQuery.cs b/System.Core/System/Linq/SequenceQuery.cs index c26925aae..ebcd614d3 100644 --- a/System.Core/System/Linq/SequenceQuery.cs +++ b/System.Core/System/Linq/SequenceQuery.cs @@ -96,7 +96,7 @@ IQueryable IQueryProvider.CreateQuery(Expression expression){ // critical (which was the original annotation when porting to silverlight) would violate // fxcop security rules if the interface isn't also critical. However, transparent code // can't access this anyway for Mix since we're not exposing AsQueryable(). - // [....]: the above assertion no longer holds. Now making AsQueryable() public again + // Microsoft: the above assertion no longer holds. Now making AsQueryable() public again // the security fallout of which will need to be re-examined. object IQueryProvider.Execute(Expression expression){ if (expression == null) diff --git a/System.Core/System/Security/Cryptography/BCryptNative.cs b/System.Core/System/Security/Cryptography/BCryptNative.cs index cfc18b21f..0d71079ee 100644 --- a/System.Core/System/Security/Cryptography/BCryptNative.cs +++ b/System.Core/System/Security/Cryptography/BCryptNative.cs @@ -75,9 +75,11 @@ internal static class BCryptNative { /// Well known algorithm names /// internal static class AlgorithmName { + public const string ECDH = "ECDH"; // BCRYPT_ECDH_ALGORITHM public const string ECDHP256 = "ECDH_P256"; // BCRYPT_ECDH_P256_ALGORITHM public const string ECDHP384 = "ECDH_P384"; // BCRYPT_ECDH_P384_ALGORITHM public const string ECDHP521 = "ECDH_P521"; // BCRYPT_ECDH_P521_ALGORITHM + public const string ECDsa = "ECDSA"; // BCRYPT_ECDSA_ALGORITHM public const string ECDsaP256 = "ECDSA_P256"; // BCRYPT_ECDSA_P256_ALGORITHM public const string ECDsaP384 = "ECDSA_P384"; // BCRYPT_ECDSA_P384_ALGORITHM public const string ECDsaP521 = "ECDSA_P521"; // BCRYPT_ECDSA_P521_ALGORITHM @@ -183,6 +185,10 @@ internal static class KeyDerivationFunction { internal const string BCRYPT_ECCPUBLIC_BLOB = "ECCPUBLICBLOB"; internal const string BCRYPT_ECCPRIVATE_BLOB = "ECCPRIVATEBLOB"; + internal const string BCRYPT_ECC_CURVE_NISTP256 = "nistP256"; + internal const string BCRYPT_ECC_CURVE_NISTP384 = "nistP384"; + internal const string BCRYPT_ECC_CURVE_NISTP521 = "nistP521"; + /// /// Well known BCrypt provider names /// diff --git a/System.Core/System/Security/Cryptography/CngAlgorithm.cs b/System.Core/System/Security/Cryptography/CngAlgorithm.cs index bb161cb53..4b83b7687 100644 --- a/System.Core/System/Security/Cryptography/CngAlgorithm.cs +++ b/System.Core/System/Security/Cryptography/CngAlgorithm.cs @@ -17,9 +17,11 @@ namespace System.Security.Cryptography { [Serializable] [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class CngAlgorithm : IEquatable { + private static volatile CngAlgorithm s_ecdh; private static volatile CngAlgorithm s_ecdhp256; private static volatile CngAlgorithm s_ecdhp384; private static volatile CngAlgorithm s_ecdhp521; + private static volatile CngAlgorithm s_ecdsa; private static volatile CngAlgorithm s_ecdsap256; private static volatile CngAlgorithm s_ecdsap384; private static volatile CngAlgorithm s_ecdsap521; @@ -110,6 +112,18 @@ public static CngAlgorithm Rsa { } } + public static CngAlgorithm ECDiffieHellman { + get { + Contract.Ensures(Contract.Result() != null); + + if (s_ecdh == null) { + s_ecdh = new CngAlgorithm(BCryptNative.AlgorithmName.ECDH); + } + + return s_ecdh; + } + } + public static CngAlgorithm ECDiffieHellmanP256 { get { Contract.Ensures(Contract.Result() != null); @@ -146,6 +160,18 @@ public static CngAlgorithm ECDiffieHellmanP521 { } } + public static CngAlgorithm ECDsa { + get { + Contract.Ensures(Contract.Result() != null); + + if (s_ecdsa == null) { + s_ecdsa = new CngAlgorithm(BCryptNative.AlgorithmName.ECDsa); + } + + return s_ecdsa; + } + } + public static CngAlgorithm ECDsaP256 { get { Contract.Ensures(Contract.Result() != null); diff --git a/System.Core/System/Security/Cryptography/CngKey.cs b/System.Core/System/Security/Cryptography/CngKey.cs index 13ea41c2f..205a733da 100644 --- a/System.Core/System/Security/Cryptography/CngKey.cs +++ b/System.Core/System/Security/Cryptography/CngKey.cs @@ -30,7 +30,7 @@ public enum CngKeyHandleOpenOptions { /// Managed representation of an NCrypt key /// [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] - public sealed class CngKey : IDisposable { + public sealed partial class CngKey : IDisposable { private SafeNCryptKeyHandle m_keyHandle; private SafeNCryptProviderHandle m_kspHandle; @@ -97,6 +97,15 @@ public CngExportPolicies ExportPolicy { return (CngExportPolicies)policy; } + + internal set { + var property = new CngProperty( + NCryptNative.KeyPropertyName.ExportPolicy, + BitConverter.GetBytes((int)value), + CngPropertyOptions.Persist); + + SetProperty(property); + } } /// @@ -200,6 +209,23 @@ public int KeySize { [SecuritySafeCritical] get { Contract.Assert(m_keyHandle != null); + + // First, try the Win10+ Public Key Length property, it matches the purpose + // of this property better when it and Length disagree. + int keySize = 0; + + NCryptNative.ErrorCode errorCode = NCryptNative.GetPropertyAsInt( + m_keyHandle, + NCryptNative.KeyPropertyName.PublicKeyLength, + CngPropertyOptions.None, + ref keySize); + + // If the new property reports it was successful, use it. + // Otherwise, ask the old question. + if (errorCode == NCryptNative.ErrorCode.Success) { + return keySize; + } + return NCryptNative.GetPropertyAsDWord(m_keyHandle, NCryptNative.KeyPropertyName.Length, CngPropertyOptions.None); @@ -527,10 +553,20 @@ public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format) { return Import(keyBlob, format, CngProvider.MicrosoftSoftwareKeyStorageProvider); } - [SecuritySafeCritical] + internal static CngKey Import(byte[] keyBlob, string curveName, CngKeyBlobFormat format) { + Contract.Ensures(Contract.Result() != null); + return Import(keyBlob, curveName, format, CngProvider.MicrosoftSoftwareKeyStorageProvider); + } + public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider) { Contract.Ensures(Contract.Result() != null); + return Import(keyBlob, null, format, provider); + } + [SecuritySafeCritical] + internal static CngKey Import(byte[] keyBlob, string curveName, CngKeyBlobFormat format, CngProvider provider) + { + Contract.Ensures(Contract.Result() != null); if (keyBlob == null) { throw new ArgumentNullException("keyBlob"); } @@ -550,6 +586,7 @@ public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format, CngProvider // permission. Since we won't know the name of the key until it's too late, we demand a full Import // rather than one scoped to the key. bool safeKeyImport = format == CngKeyBlobFormat.EccPublicBlob || + format == CngKeyBlobFormat.EccFullPublicBlob || format == CngKeyBlobFormat.GenericPublicBlob; if (!safeKeyImport) { @@ -558,11 +595,17 @@ public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format, CngProvider // Import the key into the KSP SafeNCryptProviderHandle kspHandle = NCryptNative.OpenStorageProvider(provider.Provider); - SafeNCryptKeyHandle keyHandle = NCryptNative.ImportKey(kspHandle, keyBlob, format.Format); + SafeNCryptKeyHandle keyHandle; + + if (curveName == null) { + keyHandle = NCryptNative.ImportKey(kspHandle, keyBlob, format.Format); + } else { + keyHandle = ECCng.ImportKeyBlob(format.Format, keyBlob, curveName, kspHandle); + } // Prepare the key for use CngKey key = new CngKey(kspHandle, keyHandle); - + // We can't tell directly if an OpaqueTransport blob imported as an ephemeral key or not key.IsEphemeral = format != CngKeyBlobFormat.OpaqueTransportBlob; diff --git a/System.Core/System/Security/Cryptography/CngKeyBlobFormat.cs b/System.Core/System/Security/Cryptography/CngKeyBlobFormat.cs index d5e9331e5..171e71c4a 100644 --- a/System.Core/System/Security/Cryptography/CngKeyBlobFormat.cs +++ b/System.Core/System/Security/Cryptography/CngKeyBlobFormat.cs @@ -20,6 +20,8 @@ namespace System.Security.Cryptography { public sealed class CngKeyBlobFormat : IEquatable { private static volatile CngKeyBlobFormat s_eccPrivate; private static volatile CngKeyBlobFormat s_eccPublic; + private static volatile CngKeyBlobFormat s_eccFullPrivate; + private static volatile CngKeyBlobFormat s_eccFullPublic; private static volatile CngKeyBlobFormat s_genericPrivate; private static volatile CngKeyBlobFormat s_genericPublic; private static volatile CngKeyBlobFormat s_opaqueTransport; @@ -119,6 +121,30 @@ public static CngKeyBlobFormat EccPublicBlob { } } + public static CngKeyBlobFormat EccFullPrivateBlob { + get { + Contract.Ensures(Contract.Result() != null); + + if (s_eccFullPrivate == null) { + s_eccFullPrivate = new CngKeyBlobFormat("ECCFULLPRIVATEBLOB"); // BCRYPT_ECCFULLPRIVATE_BLOB + } + + return s_eccFullPrivate; + } + } + + public static CngKeyBlobFormat EccFullPublicBlob { + get { + Contract.Ensures(Contract.Result() != null); + + if (s_eccFullPublic == null) { + s_eccFullPublic = new CngKeyBlobFormat("ECCFULLPUBLICBLOB"); // BCRYPT_ECCFULLPUBLIC_BLOB + } + + return s_eccFullPublic; + } + } + public static CngKeyBlobFormat GenericPrivateBlob { get { Contract.Ensures(Contract.Result() != null); diff --git a/System.Core/System/Security/Cryptography/ECDiffieHellman.cs b/System.Core/System/Security/Cryptography/ECDiffieHellman.cs index 7403ffbe8..e3800a762 100644 --- a/System.Core/System/Security/Cryptography/ECDiffieHellman.cs +++ b/System.Core/System/Security/Cryptography/ECDiffieHellman.cs @@ -37,6 +37,52 @@ public override string SignatureAlgorithm { return CryptoConfig.CreateFromName(algorithm) as ECDiffieHellman; } + /// + /// Creates a new instance of the default implementation of the Elliptic Curve Diffie-Hellman Algorithm + /// (ECDH) with a newly generated key over the specified curve. + /// + /// The curve to use for key generation. + /// A new instance of the default implementation of this class. + public static ECDiffieHellman Create(ECCurve curve) + { + ECDiffieHellman ecdh = Create(); + + if (ecdh != null) { + try { + ecdh.GenerateKey(curve); + } + catch { + ecdh.Dispose(); + throw; + } + } + + return ecdh; + } + + /// + /// Creates a new instance of the default implementation of the Elliptic Curve Diffie-Hellman Algorithm + /// (ECDH) using the specified ECParameters as the key. + /// + /// The parameters representing the key to use. + /// A new instance of the default implementation of this class. + public static ECDiffieHellman Create(ECParameters parameters) + { + ECDiffieHellman ecdh = Create(); + + if (ecdh != null) { + try { + ecdh.ImportParameters(parameters); + } + catch { + ecdh.Dispose(); + throw; + } + } + + return ecdh; + } + // // Key derivation // @@ -138,5 +184,45 @@ private static Exception DerivedClassMustOverride() { return new NotImplementedException(SR.GetString(SR.NotSupported_SubclassOverride)); } + + /// + /// When overridden in a derived class, exports the named or explicit ECParameters for an ECCurve. + /// If the curve has a name, the Curve property will contain named curve parameters, otherwise it + /// will contain explicit parameters. + /// + /// true to include private parameters, otherwise, false. + /// The ECParameters representing the point on the curve for this key. + public virtual ECParameters ExportParameters(bool includePrivateParameters) + { + throw DerivedClassMustOverride(); + } + + /// + /// When overridden in a derived class, exports the explicit ECParameters for an ECCurve. + /// + /// true to include private parameters, otherwise, false. + /// The ECParameters representing the point on the curve for this key, using the explicit curve format. + public virtual ECParameters ExportExplicitParameters(bool includePrivateParameters) + { + throw DerivedClassMustOverride(); + } + + /// + /// When overridden in a derived class, imports the specified ECParameters. + /// + /// The curve parameters. + public virtual void ImportParameters(ECParameters parameters) + { + throw DerivedClassMustOverride(); + } + + /// + /// When overridden in a derived class, generates a new public/private keypair for the specified curve. + /// + /// The curve to use. + public virtual void GenerateKey(ECCurve curve) + { + throw new NotSupportedException(SR.GetString(SR.NotSupported_SubclassOverride)); + } } } diff --git a/System.Core/System/Security/Cryptography/ECDiffieHellmanCng.cs b/System.Core/System/Security/Cryptography/ECDiffieHellmanCng.cs index 4a555dae5..5b741341b 100644 --- a/System.Core/System/Security/Cryptography/ECDiffieHellmanCng.cs +++ b/System.Core/System/Security/Cryptography/ECDiffieHellmanCng.cs @@ -60,6 +60,11 @@ public ECDiffieHellmanCng(int keySize) { KeySize = keySize; } + public ECDiffieHellmanCng(ECCurve curve) { + // GenerateKey will already do all of the validation we need. + GenerateKey(curve); + } + [SecuritySafeCritical] public ECDiffieHellmanCng(CngKey key) { Contract.Ensures(LegalKeySizesValue != null); @@ -286,7 +291,7 @@ private set { public override ECDiffieHellmanPublicKey PublicKey { get { Contract.Ensures(Contract.Result() != null); - return new ECDiffieHellmanCngPublicKey(Key); + return ECDiffieHellmanCngPublicKey.FromKey(Key); } } @@ -534,6 +539,19 @@ protected override void Dispose(bool disposing) { } } + public override void GenerateKey(ECCurve curve) { + curve.Validate(); + + if (m_key != null) { + m_key.Dispose(); + m_key = null; + } + + CngKey newKey = CngKey.Create(curve, name => CngKey.EcdhCurveNameToAlgorithm(name)); + m_key = newKey; + KeySizeValue = newKey.KeySize; + } + // // XML Import // @@ -554,7 +572,14 @@ public void FromXmlString(string xml, ECKeyXmlFormat format) { throw new ArgumentOutOfRangeException("format"); } - Key = Rfc4050KeyFormatter.FromXml(xml); + bool isEcdh; + ECParameters ecParams = Rfc4050KeyFormatter.FromXml(xml, out isEcdh); + + if (!isEcdh) { + throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHRequiresECDHKey), "xml"); + } + + ImportParameters(ecParams); } // @@ -576,7 +601,54 @@ public string ToXmlString(ECKeyXmlFormat format) { throw new ArgumentOutOfRangeException("format"); } - return Rfc4050KeyFormatter.ToXml(Key); + ECParameters ecParams = ExportParameters(false); + return Rfc4050KeyFormatter.ToXml(ecParams, isEcdh: true); + } + + /// + /// ImportParameters will replace the existing key that this object is working with by creating a + /// new CngKey. If the parameters contains only Q, then only a public key will be imported. + /// If the parameters also contains D, then a full key pair will be imported. + /// The parameters Curve value specifies the type of the curve to import. + /// + /// + /// if does not contain valid values. + /// + /// + /// if references a curve that cannot be imported. + /// + /// + /// if references a curve that is not supported by this platform. + /// + public override void ImportParameters(ECParameters parameters) { + Key = ECCng.ImportEcdhParameters(ref parameters); + } + + /// + /// Exports the key and explicit curve parameters used by the ECC object into an object. + /// + /// + /// if there was an issue obtaining the curve values. + /// + /// + /// if explicit export is not supported by this platform. Windows 10 or higher is required. + /// + /// The key and explicit curve parameters used by the ECC object. + public override ECParameters ExportExplicitParameters(bool includePrivateParameters) { + return ECCng.ExportExplicitParameters(Key, includePrivateParameters); + } + + /// + /// Exports the key used by the ECC object into an object. + /// If the key was created as a named curve, the Curve property will contain named curve parameters + /// otherwise it will contain explicit parameters. + /// + /// + /// if there was an issue obtaining the curve values. + /// + /// The key and named curve parameters used by the ECC object. + public override ECParameters ExportParameters(bool includePrivateParameters) { + return ECCng.ExportParameters(Key, includePrivateParameters); } } } diff --git a/System.Core/System/Security/Cryptography/ECDiffieHellmanCngPublicKey.cs b/System.Core/System/Security/Cryptography/ECDiffieHellmanCngPublicKey.cs index 67232bb0e..0417c4fcc 100644 --- a/System.Core/System/Security/Cryptography/ECDiffieHellmanCngPublicKey.cs +++ b/System.Core/System/Security/Cryptography/ECDiffieHellmanCngPublicKey.cs @@ -18,35 +18,20 @@ namespace System.Security.Cryptography { [Serializable] [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class ECDiffieHellmanCngPublicKey : ECDiffieHellmanPublicKey { - [NonSerialized] - private CngKey m_key; private CngKeyBlobFormat m_format; + [OptionalField] private string m_curveName; /// /// Wrap a CNG key /// [SecuritySafeCritical] - internal ECDiffieHellmanCngPublicKey(CngKey key) : base(key.Export(CngKeyBlobFormat.EccPublicBlob)) { - Contract.Requires(key != null && key.AlgorithmGroup == CngAlgorithmGroup.ECDiffieHellman); + internal ECDiffieHellmanCngPublicKey(byte[] keyBlob, string curveName, CngKeyBlobFormat format) : base(keyBlob) { + Contract.Requires(format != null); Contract.Ensures(m_format != null); - m_format = CngKeyBlobFormat.EccPublicBlob; - - // - // We need to make a copy of the key to prevent the situation where the ECDiffieHellmanCng algorithm - // object is disposed (this disposing its key) before the ECDiffieHellmanCngPublic key is disposed. - // - // Accessing the handle in partial trust is safe because we're not exposing it back out to user code - // - - new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); - - // This looks odd, but .Handle returns a duplicate, so we need to dispose it - using (SafeNCryptKeyHandle importKey = key.Handle) { - m_key = CngKey.Open(importKey, key.IsEphemeral ? CngKeyHandleOpenOptions.EphemeralKey : CngKeyHandleOpenOptions.None); - } - - CodeAccessPermission.RevertAssert(); + m_format = format; + // Can be null for P256, P384, P521, or an explicit blob + m_curveName = curveName; } /// @@ -65,16 +50,7 @@ public CngKeyBlobFormat BlobFormat { /// Clean up the key /// protected override void Dispose(bool disposing) { - try { - if (disposing) { - if (m_key != null) { - m_key.Dispose(); - } - } - } - finally { - base.Dispose(disposing); - } + base.Dispose(disposing); } /// @@ -89,15 +65,26 @@ public static ECDiffieHellmanPublicKey FromByteArray(byte[] publicKeyBlob, CngKe throw new ArgumentNullException("format"); } + // Verify that the key can import successfully, because we did in the past. using (CngKey imported = CngKey.Import(publicKeyBlob, format)) { if (imported.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) { throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHRequiresECDHKey)); } - return new ECDiffieHellmanCngPublicKey(imported); + return new ECDiffieHellmanCngPublicKey(publicKeyBlob, null, format); } } + internal static ECDiffieHellmanCngPublicKey FromKey(CngKey key) { + Contract.Requires(key != null && key.AlgorithmGroup == CngAlgorithmGroup.ECDiffieHellman); + Contract.Ensures(Contract.Result() != null); + + CngKeyBlobFormat format; + string curveName; + byte[] blob = ECCng.ExportKeyBlob(key, false, out format, out curveName); + return new ECDiffieHellmanCngPublicKey(blob, curveName, format); + } + /// /// Hydrate a public key from XML /// @@ -110,13 +97,17 @@ public static ECDiffieHellmanCngPublicKey FromXmlString(string xml) { throw new ArgumentNullException("xml"); } - using (CngKey imported = Rfc4050KeyFormatter.FromXml(xml)) { - if (imported.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) { - throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHRequiresECDHKey), "xml"); - } + bool isEcdh; + ECParameters parameters = Rfc4050KeyFormatter.FromXml(xml, out isEcdh); - return new ECDiffieHellmanCngPublicKey(imported); + if (!isEcdh) { + throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHRequiresECDHKey), "xml"); } + + CngKeyBlobFormat format; + string curveName; + byte[] blob = ECCng.EcdhParametersToBlob(ref parameters, out format, out curveName); + return new ECDiffieHellmanCngPublicKey(blob, curveName, format); } /// @@ -127,7 +118,7 @@ public CngKey Import() { Contract.Ensures(Contract.Result() != null); Contract.Assert(m_format != null); - return CngKey.Import(ToByteArray(), BlobFormat); + return CngKey.Import(ToByteArray(), m_curveName, BlobFormat); } /// @@ -139,11 +130,39 @@ public CngKey Import() { public override string ToXmlString() { Contract.Ensures(!String.IsNullOrEmpty(Contract.Result())); - if (m_key == null) { - m_key = Import(); + ECParameters ecParams = ExportParameters(); + return Rfc4050KeyFormatter.ToXml(ecParams, isEcdh: true); + } + + /// + /// Exports the key and explicit curve parameters used by the ECC object into an object. + /// + /// + /// if there was an issue obtaining the curve values. + /// + /// + /// if explicit export is not supported by this platform. Windows 10 or higher is required. + /// + /// The key and explicit curve parameters used by the ECC object. + public override ECParameters ExportExplicitParameters() { + using (CngKey key = Import()) { + return ECCng.ExportExplicitParameters(key, includePrivateParameters: false); } + } - return Rfc4050KeyFormatter.ToXml(m_key); + /// + /// Exports the key used by the ECC object into an object. + /// If the key was created as a named curve, the Curve property will contain named curve parameters + /// otherwise it will contain explicit parameters. + /// + /// + /// if there was an issue obtaining the curve values. + /// + /// The key and named curve parameters used by the ECC object. + public override ECParameters ExportParameters() { + using (CngKey key = Import()) { + return ECCng.ExportParameters(key, includePrivateParameters: false); + } } } } diff --git a/System.Core/System/Security/Cryptography/ECDiffieHellmanPublicKey.cs b/System.Core/System/Security/Cryptography/ECDiffieHellmanPublicKey.cs index 91e89d8be..62b83951f 100644 --- a/System.Core/System/Security/Cryptography/ECDiffieHellmanPublicKey.cs +++ b/System.Core/System/Security/Cryptography/ECDiffieHellmanPublicKey.cs @@ -17,6 +17,10 @@ namespace System.Security.Cryptography { public abstract class ECDiffieHellmanPublicKey : IDisposable { private byte[] m_keyBlob; + protected ECDiffieHellmanPublicKey() { + m_keyBlob = new byte[0]; + } + protected ECDiffieHellmanPublicKey(byte[] keyBlob) { Contract.Ensures(m_keyBlob != null); @@ -41,9 +45,26 @@ public virtual byte[] ToByteArray() { } // This method must be implemented by derived classes. In order to conform to the contract, it cannot be abstract. - public virtual string ToXmlString() - { + public virtual string ToXmlString() { throw new NotImplementedException(SR.GetString(SR.NotSupported_SubclassOverride)); } + + /// + /// When overridden in a derived class, exports the named or explicit ECParameters for an ECCurve. + /// If the curve has a name, the Curve property will contain named curve parameters, otherwise it + /// will contain explicit parameters. + /// + /// The ECParameters representing the point on the curve for this key. + public virtual ECParameters ExportParameters() { + throw new NotSupportedException(SR.GetString(SR.NotSupported_SubclassOverride)); + } + + /// + /// When overridden in a derived class, exports the explicit ECParameters for an ECCurve. + /// + /// The ECParameters representing the point on the curve for this key, using the explicit curve format. + public virtual ECParameters ExportExplicitParameters() { + throw new NotSupportedException(SR.GetString(SR.NotSupported_SubclassOverride)); + } } } diff --git a/System.Core/System/Security/Cryptography/ECDsa.cs b/System.Core/System/Security/Cryptography/ECDsa.cs index 114729dfd..fcb55ccd1 100644 --- a/System.Core/System/Security/Cryptography/ECDsa.cs +++ b/System.Core/System/Security/Cryptography/ECDsa.cs @@ -37,6 +37,50 @@ public override string SignatureAlgorithm { return CryptoConfig.CreateFromName(algorithm) as ECDsa; } + /// + /// Creates a new instance of the default implementation of the Elliptic Curve Digital Signature Algorithm + /// (ECDSA) with a newly generated key over the specified curve. + /// + /// The curve to use for key generation. + /// A new instance of the default implementation of this class. + public static ECDsa Create(ECCurve curve) { + ECDsa ecdsa = Create(); + + if (ecdsa != null) { + try { + ecdsa.GenerateKey(curve); + } + catch { + ecdsa.Dispose(); + throw; + } + } + + return ecdsa; + } + + /// + /// Creates a new instance of the default implementation of the Elliptic Curve Digital Signature Algorithm + /// (ECDSA) using the specified ECParameters as the key. + /// + /// The parameters representing the key to use. + /// A new instance of the default implementation of this class. + public static ECDsa Create(ECParameters parameters) { + ECDsa ecdsa = Create(); + + if (ecdsa != null) { + try { + ecdsa.ImportParameters(parameters); + } + catch { + ecdsa.Dispose(); + throw; + } + } + + return ecdsa; + } + // // Signature operations // @@ -126,6 +170,42 @@ public bool VerifyData(Stream data, byte[] signature, HashAlgorithmName hashAlgo return VerifyHash(hash, signature); } + /// + /// When overridden in a derived class, exports the named or explicit ECParameters for an ECCurve. + /// If the curve has a name, the Curve property will contain named curve parameters, otherwise it + /// will contain explicit parameters. + /// + /// true to include private parameters, otherwise, false. + /// The ECParameters representing the point on the curve for this key. + public virtual ECParameters ExportParameters(bool includePrivateParameters) { + throw new NotSupportedException(SR.GetString(SR.NotSupported_SubclassOverride)); + } + + /// + /// When overridden in a derived class, exports the explicit ECParameters for an ECCurve. + /// + /// true to include private parameters, otherwise, false. + /// The ECParameters representing the point on the curve for this key, using the explicit curve format. + public virtual ECParameters ExportExplicitParameters(bool includePrivateParameters) { + throw new NotSupportedException(SR.GetString(SR.NotSupported_SubclassOverride)); + } + + /// + /// When overridden in a derived class, imports the specified ECParameters. + /// + /// The curve parameters. + public virtual void ImportParameters(ECParameters parameters) { + throw new NotSupportedException(SR.GetString(SR.NotSupported_SubclassOverride)); + } + + /// + /// When overridden in a derived class, generates a new public/private keypair for the specified curve. + /// + /// The curve to use. + public virtual void GenerateKey(ECCurve curve) { + throw new NotSupportedException(SR.GetString(SR.NotSupported_SubclassOverride)); + } + private static Exception DerivedClassMustOverride() { return new NotImplementedException(SR.GetString(SR.NotSupported_SubclassOverride)); } diff --git a/System.Core/System/Security/Cryptography/ECDsaCng.cs b/System.Core/System/Security/Cryptography/ECDsaCng.cs index 096ce83a0..06e05f223 100644 --- a/System.Core/System/Security/Cryptography/ECDsaCng.cs +++ b/System.Core/System/Security/Cryptography/ECDsaCng.cs @@ -17,7 +17,7 @@ namespace System.Security.Cryptography { /// Wrapper for NCrypt's implementation of elliptic curve DSA /// [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] - public sealed class ECDsaCng : ECDsa { + public sealed partial class ECDsaCng : ECDsa { private static KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(256, 384, 128), new KeySizes(521, 521, 0) }; private CngKey m_key; @@ -42,6 +42,11 @@ public ECDsaCng(int keySize) { KeySize = keySize; } + public ECDsaCng(ECCurve curve) { + // GenerateKey will already do all of the validation we need. + GenerateKey(curve); + } + [SecuritySafeCritical] public ECDsaCng(CngKey key) { Contract.Ensures(LegalKeySizesValue != null); @@ -231,7 +236,13 @@ public void FromXmlString(string xml, ECKeyXmlFormat format) { throw new ArgumentOutOfRangeException("format"); } - Key = Rfc4050KeyFormatter.FromXml(xml); + bool isEcdh; + ECParameters parameters = Rfc4050KeyFormatter.FromXml(xml, out isEcdh); + + // .NET 4.6.2 allowed ECDsaCng to wrap ECDH keys because of interop with non-Windows PFX files. + // As a result XML marked as ECDiffieHellman loaded just fine, so no check should be done on the + // key type. + ImportParameters(parameters); } // @@ -329,7 +340,8 @@ public string ToXmlString(ECKeyXmlFormat format) { throw new ArgumentOutOfRangeException("format"); } - return Rfc4050KeyFormatter.ToXml(Key); + ECParameters ecParams = ExportParameters(false); + return Rfc4050KeyFormatter.ToXml(ecParams, isEcdh: false); } // @@ -405,6 +417,19 @@ public override bool VerifyHash(byte[] hash, byte[] signature) { } } + public override void GenerateKey(ECCurve curve) { + curve.Validate(); + + if (m_key != null) { + m_key.Dispose(); + m_key = null; + } + + CngKey newKey = CngKey.Create(curve, name => CngKey.EcdsaCurveNameToAlgorithm(name)); + m_key = newKey; + KeySizeValue = newKey.KeySize; + } + /// /// Helper property to get the NCrypt key handle /// diff --git a/System.Core/System/Security/Cryptography/NCryptNative.cs b/System.Core/System/Security/Cryptography/NCryptNative.cs index 4b7adf451..854d7e20d 100644 --- a/System.Core/System/Security/Cryptography/NCryptNative.cs +++ b/System.Core/System/Security/Cryptography/NCryptNative.cs @@ -145,6 +145,7 @@ internal static class KeyPropertyName { internal const string Length = "Length"; // NCRYPT_LENGTH_PROPERTY internal const string Name = "Name"; // NCRYPT_NAME_PROPERTY internal const string ParentWindowHandle = "HWND Handle"; // NCRYPT_WINDOW_HANDLE_PROPERTY + internal const string PublicKeyLength = "PublicKeyLength"; // NCRYPT_PUBLIC_KEY_LENGTH (Win10+) internal const string ProviderHandle = "Provider Handle"; // NCRYPT_PROVIDER_HANDLE_PROPERTY internal const string UIPolicy = "UI Policy"; // NCRYPT_UI_POLICY_PROPERTY internal const string UniqueName = "Unique Name"; // NCRYPT_UNIQUE_NAME_PROPERTY @@ -274,6 +275,17 @@ internal static extern ErrorCode NCryptGetProperty(SafeNCryptHandle hObject, [Out] out int pcbResult, CngPropertyOptions dwFlags); + /// + /// Get the value of a property of an NCrypt object + /// + [DllImport("ncrypt.dll", CharSet = CharSet.Unicode)] + internal static extern ErrorCode NCryptGetProperty(SafeNCryptHandle hObject, + string pszProperty, + ref int pbOutput, + int cbOutput, + [Out] out int pcbResult, + CngPropertyOptions dwFlags); + /// /// Get the value of a pointer property of an NCrypt object /// @@ -433,7 +445,7 @@ internal static extern ErrorCode NCryptDecrypt(SafeNCryptKeyHandle hKey, internal static extern ErrorCode NCryptDecrypt(SafeNCryptKeyHandle hKey, [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbInput, int cbInput, - [In] ref BCryptNative.BCRYPT_PKCS1_PADDING_INFO pvPadding, + IntPtr pvPaddingZero, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbOutput, int cbOutput, [Out] out int pcbResult, @@ -453,7 +465,7 @@ internal static extern ErrorCode NCryptEncrypt(SafeNCryptKeyHandle hKey, internal static extern ErrorCode NCryptEncrypt(SafeNCryptKeyHandle hKey, [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbInput, int cbInput, - [In] ref BCryptNative.BCRYPT_PKCS1_PADDING_INFO pvPadding, + IntPtr pvPaddingZero, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbOutput, int cbOutput, [Out] out int pcbResult, @@ -580,7 +592,7 @@ internal static byte[] DecryptDataPkcs1(SafeNCryptKeyHandle key, byte[] data) { data, ref pkcs1Info, AsymmetricPaddingMode.Pkcs1, - UnsafeNativeMethods.NCryptDecrypt); + Pkcs1PaddingDecryptionWrapper); } /// @@ -602,6 +614,27 @@ internal static byte[] DecryptDataOaep(SafeNCryptKeyHandle key, UnsafeNativeMethods.NCryptDecrypt); } + [SecurityCritical] + private static ErrorCode Pkcs1PaddingDecryptionWrapper(SafeNCryptKeyHandle hKey, + byte[] pbInput, + int cbInput, + ref BCryptNative.BCRYPT_PKCS1_PADDING_INFO pvPadding, + byte[] pbOutput, + int cbOutput, + out int pcbResult, + AsymmetricPaddingMode dwFlags) + { + Debug.Assert(dwFlags == AsymmetricPaddingMode.Pkcs1, "dwFlags == AsymmetricPaddingMode.Pkcs1"); + + // This method exists to match a generic-based delegate (the ref parameter), but in PKCS#1 mode + // the value for pvPadding must be NULL with keys in the Smart Card KSP. + // + // Passing the ref PKCS1 (signature) padding info will work for software keys, which ignore the value; + // but hardware keys fail if it's any value other than NULL (and PKCS#1 was specified). + + return UnsafeNativeMethods.NCryptDecrypt(hKey, pbInput, cbInput, IntPtr.Zero, pbOutput, cbOutput, out pcbResult, dwFlags); + } + /// /// Generic encryption method, wrapped by decryption calls for specific padding modes /// @@ -677,7 +710,27 @@ internal static byte[] EncryptDataPkcs1(SafeNCryptKeyHandle key, byte[] data) { data, ref pkcs1Info, AsymmetricPaddingMode.Pkcs1, - UnsafeNativeMethods.NCryptEncrypt); + Pkcs1PaddingEncryptionWrapper); + } + + [SecurityCritical] + private static ErrorCode Pkcs1PaddingEncryptionWrapper(SafeNCryptKeyHandle hKey, + byte[] pbInput, + int cbInput, + ref BCryptNative.BCRYPT_PKCS1_PADDING_INFO pvPadding, + byte[] pbOutput, + int cbOutput, + out int pcbResult, + AsymmetricPaddingMode dwFlags) { + Debug.Assert(dwFlags == AsymmetricPaddingMode.Pkcs1, "dwFlags == AsymmetricPaddingMode.Pkcs1"); + + // This method exists to match a generic-based delegate (the ref parameter), but in PKCS#1 mode + // the value for pvPadding must be NULL with keys in the Smart Card KSP. + // + // Passing the ref PKCS1 (signature) padding info will work for software keys, which ignore the value; + // but hardware keys fail if it's any value other than NULL (and PKCS#1 was specified). + + return UnsafeNativeMethods.NCryptEncrypt(hKey, pbInput, cbInput, IntPtr.Zero, pbOutput, cbOutput, out pcbResult, dwFlags); } /// @@ -1345,6 +1398,32 @@ internal static int GetPropertyAsDWord(SafeNCryptHandle ncryptObject, } } + [SecurityCritical] + internal static ErrorCode GetPropertyAsInt(SafeNCryptHandle ncryptObject, + string propertyName, + CngPropertyOptions propertyOptions, + ref int propertyValue) { + Contract.Requires(ncryptObject != null); + Contract.Requires(propertyName != null); + + int cbResult; + + ErrorCode errorCode = UnsafeNativeMethods.NCryptGetProperty( + ncryptObject, + propertyName, + ref propertyValue, + sizeof(int), + out cbResult, + propertyOptions); + + if (errorCode == ErrorCode.Success) + { + System.Diagnostics.Debug.Assert(cbResult == sizeof(int), "Expected cbResult=4, got " + cbResult); + } + + return errorCode; + } + /// /// Get the value of a pointer NCrypt property /// @@ -1464,6 +1543,36 @@ internal static SafeNCryptKeyHandle ImportKey(SafeNCryptProviderHandle provider, return keyHandle; } + [System.Security.SecurityCritical] + internal static SafeNCryptKeyHandle ImportKey(SafeNCryptProviderHandle provider, + byte[] keyBlob, + string format, + IntPtr pParametersList) { + Contract.Requires(provider != null); + Contract.Requires(keyBlob != null); + Contract.Requires(!String.IsNullOrEmpty(format)); + Contract.Ensures(Contract.Result() != null && + !Contract.Result().IsInvalid && + !Contract.Result().IsClosed); + + SafeNCryptKeyHandle keyHandle = null; + ErrorCode error = UnsafeNativeMethods.NCryptImportKey(provider, + IntPtr.Zero, + format, + pParametersList, + out keyHandle, + keyBlob, + keyBlob.Length, + 0); + + if (error != ErrorCode.Success) + { + throw new CryptographicException((int)error); + } + + return keyHandle; + } + /// /// Open an existing key /// diff --git a/System.Core/System/Security/Cryptography/Rfc4050KeyFormatter.cs b/System.Core/System/Security/Cryptography/Rfc4050KeyFormatter.cs index 1660bd45d..111da8d3d 100644 --- a/System.Core/System/Security/Cryptography/Rfc4050KeyFormatter.cs +++ b/System.Core/System/Security/Cryptography/Rfc4050KeyFormatter.cs @@ -18,7 +18,7 @@ namespace System.Security.Cryptography { /// - /// Utility class to convert NCrypt keys into XML and back using a format similar to the one described + /// Utility class to convert ECC keys into XML and back using a format similar to the one described /// in RFC 4050 (http://www.ietf.org/rfc/rfc4050.txt). /// /// #RFC4050ECKeyFormat @@ -41,6 +41,7 @@ internal static class Rfc4050KeyFormatter { private const string ECDsaRoot = "ECDSAKeyValue"; private const string NamedCurveElement = "NamedCurve"; private const string Namespace = "http://www.w3.org/2001/04/xmldsig-more#"; + private const string OidUrnPrefix = "urn:oid:"; private const string PublicKeyRoot = "PublicKey"; private const string UrnAttribute = "URN"; private const string ValueAttribute = "Value"; @@ -52,17 +53,19 @@ internal static class Rfc4050KeyFormatter { private const string XsiNamespace = "http://www.w3.org/2001/XMLSchema-instance"; private const string XsiNamespacePrefix = "xsi"; - private const string Prime256CurveUrn = "urn:oid:1.2.840.10045.3.1.7"; - private const string Prime384CurveUrn = "urn:oid:1.3.132.0.34"; - private const string Prime521CurveUrn = "urn:oid:1.3.132.0.35"; + private const string ECDSA_P256_OID_VALUE = "1.2.840.10045.3.1.7"; // nistP256 or secP256r1 + private const string ECDSA_P384_OID_VALUE = "1.3.132.0.34"; // nistP384 or secP384r1 + private const string ECDSA_P521_OID_VALUE = "1.3.132.0.35"; // nistP521 or secP521r1 /// /// Restore a key from XML /// - internal static CngKey FromXml(string xml) { + internal static ECParameters FromXml(string xml, out bool isEcdh) { Contract.Requires(xml != null); Contract.Ensures(Contract.Result() != null); + ECParameters parameters = new ECParameters(); + // Load the XML into an XPathNavigator to access sub elements using (TextReader textReader = new StringReader(xml)) using (XmlTextReader xmlReader = new XmlTextReader(textReader)) { @@ -76,70 +79,22 @@ internal static CngKey FromXml(string xml) { } // First figure out which algorithm this key belongs to - CngAlgorithm algorithm = ReadAlgorithm(navigator); + parameters.Curve = ReadCurve(navigator, out isEcdh); // Then read out the public key value if (!navigator.MoveToNext(XPathNodeType.Element)) { throw new ArgumentException(SR.GetString(SR.Cryptography_MissingPublicKey)); } - BigInteger x; - BigInteger y; - ReadPublicKey(navigator, out x, out y); - - // Finally, convert them into a key blob to import into a CngKey - byte[] keyBlob = NCryptNative.BuildEccPublicBlob(algorithm.Algorithm, x, y); - return CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob); - } - } - - /// - /// Map a curve URN to the size of the key associated with the curve - /// - [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Justification = "The parameters to the exception are in the correct order")] - private static int GetKeySize(string urn) { - Contract.Requires(!String.IsNullOrEmpty(urn)); - Contract.Ensures(Contract.Result() > 0); - - switch (urn) { - case Prime256CurveUrn: - return 256; - - case Prime384CurveUrn: - return 384; - - case Prime521CurveUrn: - return 521; - - default: - throw new ArgumentException(SR.GetString(SR.Cryptography_UnknownEllipticCurve), "algorithm"); - } - } - - /// - /// Get the OID which represents an elliptic curve - /// - private static string GetCurveUrn(CngAlgorithm algorithm) { - Contract.Requires(algorithm != null); - - if (algorithm == CngAlgorithm.ECDsaP256 || algorithm == CngAlgorithm.ECDiffieHellmanP256) { - return Prime256CurveUrn; - } - else if (algorithm == CngAlgorithm.ECDsaP384 || algorithm == CngAlgorithm.ECDiffieHellmanP384) { - return Prime384CurveUrn; - } - else if (algorithm == CngAlgorithm.ECDsaP521 || algorithm == CngAlgorithm.ECDiffieHellmanP521) { - return Prime521CurveUrn; - } - else { - throw new ArgumentException(SR.GetString(SR.Cryptography_UnknownEllipticCurve), "algorithm"); + ReadPublicKey(navigator, ref parameters); + return parameters; } } /// - /// Determine which ECC algorithm the key refers to + /// Determine which ECC curve the key refers to /// - private static CngAlgorithm ReadAlgorithm(XPathNavigator navigator) { + private static ECCurve ReadCurve(XPathNavigator navigator, out bool isEcdh) { Contract.Requires(navigator != null); Contract.Ensures(Contract.Result() != null); @@ -176,48 +131,27 @@ private static CngAlgorithm ReadAlgorithm(XPathNavigator navigator) { throw new ArgumentException(SR.GetString(SR.Cryptography_MissingDomainParameters)); } - int keySize = GetKeySize(navigator.Value); + string oidUrn = navigator.Value; + if (!oidUrn.StartsWith(OidUrnPrefix, StringComparison.OrdinalIgnoreCase)) { + throw new ArgumentException(SR.GetString(SR.Cryptography_UnknownEllipticCurve)); + } + // position the navigator at the end of the domain parameters navigator.MoveToParent(); // NamedCurve navigator.MoveToParent(); // DomainParameters - // - // Given the algorithm type and key size, we can now map back to a CNG algorithm ID - // - - if (isDHKey) { - if (keySize == 256) { - return CngAlgorithm.ECDiffieHellmanP256; - } - else if (keySize == 384) { - return CngAlgorithm.ECDiffieHellmanP384; - } - else { - Debug.Assert(keySize == 521, "keySize == 521"); - return CngAlgorithm.ECDiffieHellmanP521; - } - } - else { - Debug.Assert(isDsaKey, "isDsaKey"); - - if (keySize == 256) { - return CngAlgorithm.ECDsaP256; - } - else if (keySize == 384) { - return CngAlgorithm.ECDsaP384; - } - else { - Debug.Assert(keySize == 521, "keySize == 521"); - return CngAlgorithm.ECDsaP521; - } - } + // The out-bool only works because we have either/or. If a third type of data is handled + // then a more complex signal is required. + Debug.Assert(isDHKey || isDsaKey); + isEcdh = isDHKey; + return ECCurve.CreateFromValue(oidUrn.Substring(OidUrnPrefix.Length)); } /// /// Read the x and y components of the public key /// - private static void ReadPublicKey(XPathNavigator navigator, out BigInteger x, out BigInteger y) { + private static void ReadPublicKey(XPathNavigator navigator, ref ECParameters parameters) { Contract.Requires(navigator != null); if (navigator.NamespaceURI != Namespace) { @@ -238,7 +172,7 @@ private static void ReadPublicKey(XPathNavigator navigator, out BigInteger x, ou throw new ArgumentException(SR.GetString(SR.Cryptography_MissingPublicKey)); } - x = BigInteger.Parse(navigator.Value, CultureInfo.InvariantCulture); + BigInteger x = BigInteger.Parse(navigator.Value, CultureInfo.InvariantCulture); navigator.MoveToParent(); // Then the y parameter @@ -249,36 +183,158 @@ private static void ReadPublicKey(XPathNavigator navigator, out BigInteger x, ou throw new ArgumentException(SR.GetString(SR.Cryptography_MissingPublicKey)); } - y = BigInteger.Parse(navigator.Value, CultureInfo.InvariantCulture); + BigInteger y = BigInteger.Parse(navigator.Value, CultureInfo.InvariantCulture); + + byte[] xBytes = x.ToByteArray(); + byte[] yBytes = y.ToByteArray(); + + int xLen = xBytes.Length; + int yLen = yBytes.Length; + + // If the last byte of X is 0x00 that's a padding byte by BigInteger to indicate X is + // a positive number with the highest bit in the most significant byte set. We can't count + // that in the length of the number. + if (xLen > 0 && xBytes[xLen - 1] == 0) + { + xLen--; + } + + // Ditto for Y. + if (yLen > 0 && yBytes[yLen - 1] == 0) + { + yLen--; + } + + // Q.X and Q.Y have to be the same length. They ultimately have to be the right length for the curve, + // but that requires more knowledge than we have. So we'll ask the system. If it doesn't know, just make + // them match each other. + int requiredLength = Math.Max(xLen, yLen); + + try { + using (ECDsa ecdsa = ECDsa.Create(parameters.Curve)) { + // Convert the bit value of keysize to a byte value. + // EC curves can have non-mod-8 keysizes (e.g. 521), so the +7 is really necessary. + int curveLength = (ecdsa.KeySize + 7) / 8; + + // We could just use this answer, but if the user has formatted the input to be + // too long, maybe they know something we don't. + requiredLength = Math.Max(requiredLength, curveLength); + } + } + catch (ArgumentException) { /* Curve had invalid data, like an empty OID */ } + catch (CryptographicException) { /* The system failed to generate a key for the curve */ } + catch (NotSupportedException) { /* An unknown curve type was requested */ } + + // There is a chance that the curve is known to Windows but not allowed for ECDH + // (curve25519 is known to be in this state). Since RFC4050 is officially only + // concerned with ECDSA, and the only known example of this problem does not have + // an OID, it is not worth trying to generate the curve under ECDH as a fallback. + + // Since BigInteger does Little Endian and Array.Resize maintains indexes when growing, + // just Array.Resize, then Array.Reverse. We could optimize this to be 1N instead of 2N, + // but this isn't a very hot codepath, so use tried-and-true methods. + Array.Resize(ref xBytes, requiredLength); + Array.Resize(ref yBytes, requiredLength); + Array.Reverse(xBytes); + Array.Reverse(yBytes); + + parameters.Q.X = xBytes; + parameters.Q.Y = yBytes; } /// /// Serialize out information about the elliptic curve /// - private static void WriteDomainParameters(XmlWriter writer, CngKey key) { + private static void WriteDomainParameters(XmlWriter writer, ref ECParameters parameters) { Contract.Requires(writer != null); - Contract.Requires(key != null && (key.AlgorithmGroup == CngAlgorithmGroup.ECDsa || key.AlgorithmGroup == CngAlgorithmGroup.ECDiffieHellman)); + + Oid curveOid = parameters.Curve.Oid; + + if (!parameters.Curve.IsNamed || curveOid == null) + throw new ArgumentException(SR.GetString(SR.Cryptography_UnknownEllipticCurve)); + + string oidValue = curveOid.Value; + + // If the OID didn't specify a value, use the mutable FriendlyName behavior of + // resolving the value without throwing an exception. + if (string.IsNullOrEmpty(oidValue)) + { + // The name strings for the 3 NIST curves from Win7 changed in Win10, but the Win10 + // names are what we use. This fallback supports Win7-Win8.1 resolution + switch (curveOid.FriendlyName) + { + case BCryptNative.BCRYPT_ECC_CURVE_NISTP256: + oidValue = ECDSA_P256_OID_VALUE; + break; + + case BCryptNative.BCRYPT_ECC_CURVE_NISTP384: + oidValue = ECDSA_P384_OID_VALUE; + break; + + case BCryptNative.BCRYPT_ECC_CURVE_NISTP521: + oidValue = ECDSA_P521_OID_VALUE; + break; + + default: + Oid resolver = new Oid(); + resolver.FriendlyName = curveOid.FriendlyName; + oidValue = resolver.Value; + break; + } + } + + if (string.IsNullOrEmpty(oidValue)) + throw new ArgumentException(SR.GetString(SR.Cryptography_UnknownEllipticCurve)); writer.WriteStartElement(DomainParametersRoot); // We always use OIDs for the named prime curves writer.WriteStartElement(NamedCurveElement); - writer.WriteAttributeString(UrnAttribute, GetCurveUrn(key.Algorithm)); + writer.WriteAttributeString(UrnAttribute, OidUrnPrefix + oidValue); writer.WriteEndElement(); // writer.WriteEndElement(); // } - private static void WritePublicKeyValue(XmlWriter writer, CngKey key) { + private static void WritePublicKeyValue(XmlWriter writer, ref ECParameters parameters) { Contract.Requires(writer != null); - Contract.Requires(key != null && (key.AlgorithmGroup == CngAlgorithmGroup.ECDsa || key.AlgorithmGroup == CngAlgorithmGroup.ECDiffieHellman)); - + writer.WriteStartElement(PublicKeyRoot); - byte[] exportedKey = key.Export(CngKeyBlobFormat.EccPublicBlob); - BigInteger x; - BigInteger y; - NCryptNative.UnpackEccPublicBlob(exportedKey, out x, out y); + byte[] providedX = parameters.Q.X; + byte[] providedY = parameters.Q.Y; + + int xSize = providedX.Length; + int ySize = providedY.Length; + const byte SignBit = 0x80; + + // BigInteger will interpret a byte[] number as negative if the most significant bit is set. + // Since we're still in Big Endian at this point that means checking val[0]. + // If the high bit is set, we need to extract into a byte[] with a padding zero to keep the + // sign bit cleared. + + if ((providedX[0] & SignBit) == SignBit) { + xSize++; + } + + if ((providedY[0] & SignBit) == SignBit) { + ySize++; + } + + // We can't just use the arrays that are passed in even when the number wasn't negative, + // because we need to reverse the bytes to load into BigInteger. + byte[] xBytes = new byte[xSize]; + byte[] yBytes = new byte[ySize]; + + // If the size grew then the offset will be 1, otherwise 0. + Buffer.BlockCopy(providedX, 0, xBytes, xSize - providedX.Length, providedX.Length); + Buffer.BlockCopy(providedY, 0, yBytes, ySize - providedY.Length, providedY.Length); + + Array.Reverse(xBytes); + Array.Reverse(yBytes); + + BigInteger x = new BigInteger(xBytes); + BigInteger y = new BigInteger(yBytes); writer.WriteStartElement(XElement); writer.WriteAttributeString(ValueAttribute, x.ToString("R", CultureInfo.InvariantCulture)); @@ -296,10 +352,11 @@ private static void WritePublicKeyValue(XmlWriter writer, CngKey key) { /// /// Convert a key to XML /// - internal static string ToXml(CngKey key) { - Contract.Requires(key != null && (key.AlgorithmGroup == CngAlgorithmGroup.ECDsa || key.AlgorithmGroup == CngAlgorithmGroup.ECDiffieHellman)); + internal static string ToXml(ECParameters parameters, bool isEcdh) { Contract.Ensures(Contract.Result() != null); + parameters.Validate(); + StringBuilder keyXml = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings(); @@ -309,11 +366,11 @@ internal static string ToXml(CngKey key) { using (XmlWriter writer = XmlWriter.Create(keyXml, settings)) { // The root element depends upon the type of key - string rootElement = key.AlgorithmGroup == CngAlgorithmGroup.ECDsa ? ECDsaRoot : ECDHRoot; + string rootElement = isEcdh ? ECDHRoot : ECDsaRoot; writer.WriteStartElement(rootElement, Namespace); - WriteDomainParameters(writer, key); - WritePublicKeyValue(writer, key); + WriteDomainParameters(writer, ref parameters); + WritePublicKeyValue(writer, ref parameters); writer.WriteEndElement(); // root element } diff --git a/System.Core/System/threading/Tasks/TaskExtensions.cs b/System.Core/System/threading/Tasks/TaskExtensions.cs index 2853b837a..11c673bf5 100644 --- a/System.Core/System/threading/Tasks/TaskExtensions.cs +++ b/System.Core/System/threading/Tasks/TaskExtensions.cs @@ -7,7 +7,7 @@ // // TaskExtensions.cs // -// [....] +// Microsoft // // Extensions to Task/Task classes // diff --git a/System.Data.DataSetExtensions/System/Data/DataRowComparer.cs b/System.Data.DataSetExtensions/System/Data/DataRowComparer.cs index 83d84faa2..20ee67a63 100644 --- a/System.Data.DataSetExtensions/System/Data/DataRowComparer.cs +++ b/System.Data.DataSetExtensions/System/Data/DataRowComparer.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft // spather //------------------------------------------------------------------------------ using System; diff --git a/System.Data.DataSetExtensions/System/Data/DataRowExtensions.cs b/System.Data.DataSetExtensions/System/Data/DataRowExtensions.cs index 172aaa055..c1321fd25 100644 --- a/System.Data.DataSetExtensions/System/Data/DataRowExtensions.cs +++ b/System.Data.DataSetExtensions/System/Data/DataRowExtensions.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft // spather //------------------------------------------------------------------------------ using System; diff --git a/System.Data.DataSetExtensions/System/Data/DataSetUtil.cs b/System.Data.DataSetExtensions/System/Data/DataSetUtil.cs index 16c100fd3..cbb567e0b 100644 --- a/System.Data.DataSetExtensions/System/Data/DataSetUtil.cs +++ b/System.Data.DataSetExtensions/System/Data/DataSetUtil.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data.DataSetExtensions/System/Data/DataTableExtensions.cs b/System.Data.DataSetExtensions/System/Data/DataTableExtensions.cs index f9d681be6..9c02c11df 100644 --- a/System.Data.DataSetExtensions/System/Data/DataTableExtensions.cs +++ b/System.Data.DataSetExtensions/System/Data/DataTableExtensions.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data.DataSetExtensions/System/Data/EnumerableRowCollection.cs b/System.Data.DataSetExtensions/System/Data/EnumerableRowCollection.cs index 6ef1b93e8..2aa098fd1 100644 --- a/System.Data.DataSetExtensions/System/Data/EnumerableRowCollection.cs +++ b/System.Data.DataSetExtensions/System/Data/EnumerableRowCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data.DataSetExtensions/System/Data/EnumerableRowCollectionExtensions.cs b/System.Data.DataSetExtensions/System/Data/EnumerableRowCollectionExtensions.cs index d4b54919c..cc1ff7a80 100644 --- a/System.Data.DataSetExtensions/System/Data/EnumerableRowCollectionExtensions.cs +++ b/System.Data.DataSetExtensions/System/Data/EnumerableRowCollectionExtensions.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data.DataSetExtensions/System/Data/LinqDataView.cs b/System.Data.DataSetExtensions/System/Data/LinqDataView.cs index 5b5635888..13f891636 100644 --- a/System.Data.DataSetExtensions/System/Data/LinqDataView.cs +++ b/System.Data.DataSetExtensions/System/Data/LinqDataView.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.DataSetExtensions/System/Data/OrderedEnumerableRowCollection.cs b/System.Data.DataSetExtensions/System/Data/OrderedEnumerableRowCollection.cs index 3deed3f8b..a09a082e8 100644 --- a/System.Data.DataSetExtensions/System/Data/OrderedEnumerableRowCollection.cs +++ b/System.Data.DataSetExtensions/System/Data/OrderedEnumerableRowCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data.DataSetExtensions/System/Data/SortExpressionBuilder.cs b/System.Data.DataSetExtensions/System/Data/SortExpressionBuilder.cs index da6192b17..e7f2aca7a 100644 --- a/System.Data.DataSetExtensions/System/Data/SortExpressionBuilder.cs +++ b/System.Data.DataSetExtensions/System/Data/SortExpressionBuilder.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data.DataSetExtensions/System/Data/TypedTableBase.cs b/System.Data.DataSetExtensions/System/Data/TypedTableBase.cs index 2d8289f89..4a4a0ee70 100644 --- a/System.Data.DataSetExtensions/System/Data/TypedTableBase.cs +++ b/System.Data.DataSetExtensions/System/Data/TypedTableBase.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft // spather //------------------------------------------------------------------------------ diff --git a/System.Data.DataSetExtensions/System/Data/TypedTableBaseExtensions.cs b/System.Data.DataSetExtensions/System/Data/TypedTableBaseExtensions.cs index 4b9b7e51e..5d6b9e6d9 100644 --- a/System.Data.DataSetExtensions/System/Data/TypedTableBaseExtensions.cs +++ b/System.Data.DataSetExtensions/System/Data/TypedTableBaseExtensions.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/BuildProviderUtils.cs b/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/BuildProviderUtils.cs index 3111c8566..338e6d617 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/BuildProviderUtils.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/BuildProviderUtils.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Diagnostics; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/EntityDesignerBuildProvider.cs b/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/EntityDesignerBuildProvider.cs index 09e66a21b..1a4745d48 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/EntityDesignerBuildProvider.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/EntityDesignerBuildProvider.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/EntityModelBuildProvider.cs b/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/EntityModelBuildProvider.cs index 8223ed939..3abf99539 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/EntityModelBuildProvider.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/EntityModelBuildProvider.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/MappingModelBuildProvider.cs b/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/MappingModelBuildProvider.cs index 2c51a2866..018bbedf8 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/MappingModelBuildProvider.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/MappingModelBuildProvider.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/StorageModelBuildProvider.cs b/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/StorageModelBuildProvider.cs index f79a5ba3a..0cc456310 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/StorageModelBuildProvider.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/AspNet/StorageModelBuildProvider.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/Common/EDesignUtil.cs b/System.Data.Entity.Design/System/Data/Entity/Design/Common/EDesignUtil.cs index ce09de026..4a3cf74b9 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/Common/EDesignUtil.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/Common/EDesignUtil.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.Entity.Design.Common { diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/Common/MetadataItemSerializer.cs b/System.Data.Entity.Design/System/Data/Entity/Design/Common/MetadataItemSerializer.cs index f285bbca5..7fb8a1be6 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/Common/MetadataItemSerializer.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/Common/MetadataItemSerializer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Data.Common; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/Common/MetadataUtil.cs b/System.Data.Entity.Design/System/Data/Entity/Design/Common/MetadataUtil.cs index 2039e6a1d..9f11c4c78 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/Common/MetadataUtil.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/Common/MetadataUtil.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/Common/OneToOneMappingSerializer.cs b/System.Data.Entity.Design/System/Data/Entity/Design/Common/OneToOneMappingSerializer.cs index fac123e43..e5b6fccbf 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/Common/OneToOneMappingSerializer.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/Common/OneToOneMappingSerializer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Data.Common; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/Common/UniqueIdentifierService.cs b/System.Data.Entity.Design/System/Data/Entity/Design/Common/UniqueIdentifierService.cs index 2ceeb737c..eeb540311 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/Common/UniqueIdentifierService.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/Common/UniqueIdentifierService.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/EntityCodeGenerator.cs b/System.Data.Entity.Design/System/Data/Entity/Design/EntityCodeGenerator.cs index 2f8d3a152..db62698c5 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/EntityCodeGenerator.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/EntityCodeGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- //#define ENABLE_TEMPLATE_DEBUGGING diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/EntityDesignerUtils.cs b/System.Data.Entity.Design/System/Data/Entity/Design/EntityDesignerUtils.cs index 3d8b9c438..e0d234d53 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/EntityDesignerUtils.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/EntityDesignerUtils.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.IO; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/EntityFrameworkVersions.cs b/System.Data.Entity.Design/System/Data/Entity/Design/EntityFrameworkVersions.cs index 587e68dbc..6fd70791f 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/EntityFrameworkVersions.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/EntityFrameworkVersions.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/EntityModelSchemaGenerator.cs b/System.Data.Entity.Design/System/Data/Entity/Design/EntityModelSchemaGenerator.cs index 537a769cc..827b1a256 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/EntityModelSchemaGenerator.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/EntityModelSchemaGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Diagnostics; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaFilterEntry.cs b/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaFilterEntry.cs index ed03f5675..b086b3fbc 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaFilterEntry.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaFilterEntry.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator.cs b/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator.cs index 57f59c442..4b1c9d046 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Diagnostics; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator/EntityStoreSchemaGenerator.DbObjectKey.cs b/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator/EntityStoreSchemaGenerator.DbObjectKey.cs index e059181a3..78d87ade5 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator/EntityStoreSchemaGenerator.DbObjectKey.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator/EntityStoreSchemaGenerator.DbObjectKey.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Diagnostics; namespace System.Data.Entity.Design diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator/EntityStoreSchemaGenerator.LoadMethodSessionState.cs b/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator/EntityStoreSchemaGenerator.LoadMethodSessionState.cs index 6a360dbcb..2b1460a25 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator/EntityStoreSchemaGenerator.LoadMethodSessionState.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/EntityStoreSchemaGenerator/EntityStoreSchemaGenerator.LoadMethodSessionState.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Entity.Design.Common; using System.Collections.Generic; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/EntityViewGeneration/EntityViewGenerationConstants.cs b/System.Data.Entity.Design/System/Data/Entity/Design/EntityViewGeneration/EntityViewGenerationConstants.cs index 69f9e7f3d..fbb3711e9 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/EntityViewGeneration/EntityViewGenerationConstants.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/EntityViewGeneration/EntityViewGenerationConstants.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/EntityViewGeneration/EntityViewGenerator.cs b/System.Data.Entity.Design/System/Data/Entity/Design/EntityViewGeneration/EntityViewGenerator.cs index 8102ba338..027c7eb93 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/EntityViewGeneration/EntityViewGenerator.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/EntityViewGeneration/EntityViewGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/MetadataExtensionMethods.cs b/System.Data.Entity.Design/System/Data/Entity/Design/MetadataExtensionMethods.cs index 05fadc535..3c0325be0 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/MetadataExtensionMethods.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/MetadataExtensionMethods.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Entity.Design diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/MetadataItemCollectionFactory.cs b/System.Data.Entity.Design/System/Data/Entity/Design/MetadataItemCollectionFactory.cs index 4f496c57f..a0bd90d32 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/MetadataItemCollectionFactory.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/MetadataItemCollectionFactory.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Entity.Design diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/BidirectionalDictionary.cs b/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/BidirectionalDictionary.cs index 1085686e0..f40b62456 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/BidirectionalDictionary.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/BidirectionalDictionary.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/EnglishPluralizationService.cs b/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/EnglishPluralizationService.cs index a0885995a..2ca6171af 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/EnglishPluralizationService.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/EnglishPluralizationService.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/EntityDesignPluralizationHandler.cs b/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/EntityDesignPluralizationHandler.cs index ccd70127b..547983643 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/EntityDesignPluralizationHandler.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/EntityDesignPluralizationHandler.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/PluralizationServiceUtil.cs b/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/PluralizationServiceUtil.cs index 5002205ed..59a95d917 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/PluralizationServiceUtil.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/PluralizationService/PluralizationServiceUtil.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/EntityStoreSchemaGeneratorDatabaseSchemaLoader.cs b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/EntityStoreSchemaGeneratorDatabaseSchemaLoader.cs index 49d484d13..697013be7 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/EntityStoreSchemaGeneratorDatabaseSchemaLoader.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/EntityStoreSchemaGeneratorDatabaseSchemaLoader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Globalization; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/FunctionDetailsReader.cs b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/FunctionDetailsReader.cs index 95a9c2eb1..6b0c5c767 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/FunctionDetailsReader.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/FunctionDetailsReader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/RelationshipDetailsCollection.cs b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/RelationshipDetailsCollection.cs index 8f13e94ac..9b8f93b6f 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/RelationshipDetailsCollection.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/RelationshipDetailsCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Xml; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/RelationshipDetailsRow.cs b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/RelationshipDetailsRow.cs index 4d202670c..892fa572d 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/RelationshipDetailsRow.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/RelationshipDetailsRow.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Xml; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/TableDetailsCollection.cs b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/TableDetailsCollection.cs index 5eca9413a..b79aee2c9 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/TableDetailsCollection.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/TableDetailsCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Xml; diff --git a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/TableDetailsRow.cs b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/TableDetailsRow.cs index cd3ca3660..ad95e0103 100644 --- a/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/TableDetailsRow.cs +++ b/System.Data.Entity.Design/System/Data/Entity/Design/SSDLGenerator/TableDetailsRow.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Xml; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/EdmToObjectNamespaceMap.cs b/System.Data.Entity.Design/System/Data/EntityModel/EdmToObjectNamespaceMap.cs index c45935e9a..2a5277fad 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/EdmToObjectNamespaceMap.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/EdmToObjectNamespaceMap.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/AssociationTypeEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/AssociationTypeEmitter.cs index ae05595ad..5b87e6fdc 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/AssociationTypeEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/AssociationTypeEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/AttributeEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/AttributeEmitter.cs index 45124ca35..f52b61f18 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/AttributeEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/AttributeEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.CodeDom; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/ClientApiGenerator.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/ClientApiGenerator.cs index d4ec4cf42..2c4663dfa 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/ClientApiGenerator.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/ClientApiGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/CommentEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/CommentEmitter.cs index d898e7012..d2942485f 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/CommentEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/CommentEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/ComplexTypeEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/ComplexTypeEmitter.cs index 7f3692230..3785fefaf 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/ComplexTypeEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/ComplexTypeEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/Emitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/Emitter.cs index aad4ff051..28f5daf85 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/Emitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/Emitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/EntityContainerEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/EntityContainerEmitter.cs index 2aebd4d83..928d13c2e 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/EntityContainerEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/EntityContainerEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/EntityTypeEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/EntityTypeEmitter.cs index f4cf839d8..d842bb38f 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/EntityTypeEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/EntityTypeEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/FixUp.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/FixUp.cs index 2058e54f8..c6fd702e2 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/FixUp.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/FixUp.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/FixUpCollection.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/FixUpCollection.cs index 86a73f3ae..d32878775 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/FixUpCollection.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/FixUpCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/MetadataItemEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/MetadataItemEmitter.cs index aaf1e80ce..bbb721431 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/MetadataItemEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/MetadataItemEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //---------------------------------------------------------------------using System; using System.Collections.Generic; using System.Text; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/NamespaceEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/NamespaceEmitter.cs index e200f5d2a..171726227 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/NamespaceEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/NamespaceEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/NavigationPropertyEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/NavigationPropertyEmitter.cs index 121868eb6..ef0104ca7 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/NavigationPropertyEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/NavigationPropertyEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/PropertyEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/PropertyEmitter.cs index bbcb468e2..78c8d78e5 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/PropertyEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/PropertyEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.CodeDom; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/PropertyEmitterBase.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/PropertyEmitterBase.cs index aab6dc731..04a9326d5 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/PropertyEmitterBase.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/PropertyEmitterBase.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/SchemaTypeEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/SchemaTypeEmitter.cs index e74471f3f..348ddae3b 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/SchemaTypeEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/SchemaTypeEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/StructuredTypeEmitter.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/StructuredTypeEmitter.cs index 2689c5b99..3af30235c 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/StructuredTypeEmitter.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/StructuredTypeEmitter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/TypeReference.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/TypeReference.cs index 9381d82cf..9336dbf7b 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/TypeReference.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/TypeReference.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/Utils.cs b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/Utils.cs index a85445adb..e35e67cbb 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/Emitters/Utils.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/Emitters/Utils.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/EntityClassGenerator.cs b/System.Data.Entity.Design/System/Data/EntityModel/EntityClassGenerator.cs index cd27ddb97..6f530f56b 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/EntityClassGenerator.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/EntityClassGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/LazyTextWriterCreator.cs b/System.Data.Entity.Design/System/Data/EntityModel/LazyTextWriterCreator.cs index 70e90b89b..a6f6f0589 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/LazyTextWriterCreator.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/LazyTextWriterCreator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/PropertyGeneratedEventArgs.cs b/System.Data.Entity.Design/System/Data/EntityModel/PropertyGeneratedEventArgs.cs index d80bd5d64..5bbb41588 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/PropertyGeneratedEventArgs.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/PropertyGeneratedEventArgs.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Data; diff --git a/System.Data.Entity.Design/System/Data/EntityModel/TypeGeneratedEventArgs.cs b/System.Data.Entity.Design/System/Data/EntityModel/TypeGeneratedEventArgs.cs index d4133aadc..63e42956a 100644 --- a/System.Data.Entity.Design/System/Data/EntityModel/TypeGeneratedEventArgs.cs +++ b/System.Data.Entity.Design/System/Data/EntityModel/TypeGeneratedEventArgs.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Data; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/AbstractExpressions.cs b/System.Data.Entity/System/Data/Common/CommandTrees/AbstractExpressions.cs index 32f66a934..7b5d7192b 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/AbstractExpressions.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/AbstractExpressions.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Aggregates.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Aggregates.cs index 4be1672eb..13a5cb17c 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Aggregates.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Aggregates.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/BasicCommandTreeVisitor.cs b/System.Data.Entity/System/Data/Common/CommandTrees/BasicCommandTreeVisitor.cs index 065b1f15d..b2c449026 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/BasicCommandTreeVisitor.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/BasicCommandTreeVisitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/BasicExpressionVisitor.cs b/System.Data.Entity/System/Data/Common/CommandTrees/BasicExpressionVisitor.cs index 62816a815..524792543 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/BasicExpressionVisitor.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/BasicExpressionVisitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbCommandTree.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbCommandTree.cs index ffbe27823..86b6ed952 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbCommandTree.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbCommandTree.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbDeleteCommandTree.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbDeleteCommandTree.cs index bd2a0cd47..22ccf2daf 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbDeleteCommandTree.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbDeleteCommandTree.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], [....] -// @backupOwner [....] +// @owner Microsoft, Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbExpressionVisitor.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbExpressionVisitor.cs index 819515f3c..3fe00156b 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbExpressionVisitor.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbExpressionVisitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbExpressionVisitor_TResultType.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbExpressionVisitor_TResultType.cs index add222197..0fde73b97 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbExpressionVisitor_TResultType.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbExpressionVisitor_TResultType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbFunctionCommandTree.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbFunctionCommandTree.cs index cb0d6513d..219ab1ae7 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbFunctionCommandTree.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbFunctionCommandTree.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbInsertCommandTree.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbInsertCommandTree.cs index 4d3d41e5c..10dbfbaf8 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbInsertCommandTree.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbInsertCommandTree.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], [....] -// @backupOwner [....] +// @owner Microsoft, Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbLambda.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbLambda.cs index db7105b54..0a1574382 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbLambda.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbLambda.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbModificationClause.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbModificationClause.cs index c9ea82ce3..71eecb4b2 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbModificationClause.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbModificationClause.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbModificationCommandTree.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbModificationCommandTree.cs index 67f0bc2ea..b129bb2ef 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbModificationCommandTree.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbModificationCommandTree.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], [....] -// @backupOwner [....] +// @owner Microsoft, Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbQueryCommandTree.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbQueryCommandTree.cs index 0816cae13..56039e69f 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbQueryCommandTree.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbQueryCommandTree.cs @@ -4,8 +4,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbSetClause.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbSetClause.cs index 4b97556f1..82794eccd 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbSetClause.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbSetClause.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DbUpdateCommandTree.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DbUpdateCommandTree.cs index 65e72e88d..4e486f0be 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DbUpdateCommandTree.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DbUpdateCommandTree.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], [....] -// @backupOwner [....] +// @owner Microsoft, Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/DefaultExpressionVisitor.cs b/System.Data.Entity/System/Data/Common/CommandTrees/DefaultExpressionVisitor.cs index 3eaea9451..520d5dcd0 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/DefaultExpressionVisitor.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/DefaultExpressionVisitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBindings.cs b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBindings.cs index 6b24b054e..7c39a76a7 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBindings.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBindings.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/DbExpressionBuilder.cs b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/DbExpressionBuilder.cs index 018822d25..6db0404e3 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/DbExpressionBuilder.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/DbExpressionBuilder.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees.ExpressionBuilder diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/EdmFunctions.cs b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/EdmFunctions.cs index 564193b7f..026dac119 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/EdmFunctions.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/EdmFunctions.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees.ExpressionBuilder diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Internal/ArgumentValidation.cs b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Internal/ArgumentValidation.cs index c0e80490b..02c45b471 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Internal/ArgumentValidation.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Internal/ArgumentValidation.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees.ExpressionBuilder.Internal diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Internal/EnumerableValidator.cs b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Internal/EnumerableValidator.cs index 77c9bbb42..9010a31ed 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Internal/EnumerableValidator.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Internal/EnumerableValidator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees.ExpressionBuilder.Internal diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Row.cs b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Row.cs index 6b2e6f372..17f4e2615 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Row.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Row.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Spatial/SpatialEdmFunctions.cs b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Spatial/SpatialEdmFunctions.cs index 10c2e8748..70a627702 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Spatial/SpatialEdmFunctions.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/ExpressionBuilder/Spatial/SpatialEdmFunctions.cs @@ -5,7 +5,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees.ExpressionBuilder.Spatial diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/DbExpressionRules.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/DbExpressionRules.cs index 92fb84d99..5227cd067 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/DbExpressionRules.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/DbExpressionRules.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionCopier.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionCopier.cs index 72b700598..764d80a4d 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionCopier.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionCopier.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees.Internal diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionDumper.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionDumper.cs index 020ea578f..3f57a0ac5 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionDumper.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionDumper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionKeyGen.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionKeyGen.cs index d769ea835..3e9e050e2 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionKeyGen.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionKeyGen.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft // @backupOwner venkatja //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionList.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionList.cs index b7c12c7df..15d0c154a 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionList.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionList.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionPrinter.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionPrinter.cs index 17c708d70..11f70731f 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionPrinter.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ExpressionPrinter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees.Internal diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ParameterRetriever.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ParameterRetriever.cs index 89396b7b6..29005dc52 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ParameterRetriever.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ParameterRetriever.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/PatternMatchRules.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/PatternMatchRules.cs index 33f8a8a7f..66e3a0286 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/PatternMatchRules.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/PatternMatchRules.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/Validator.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/Validator.cs index 75ddb2626..182e58592 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/Validator.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/Validator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees.Internal diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ViewSimplifier.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ViewSimplifier.cs index 485339fce..3a65b24a5 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ViewSimplifier.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/ViewSimplifier.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], [....] -// @backupOwner [....] +// @owner Microsoft, Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/XmlExpressionDumper.cs b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/XmlExpressionDumper.cs index e5ed294bc..c50dad6b3 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/Internal/XmlExpressionDumper.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/Internal/XmlExpressionDumper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/OperatorExpressions.cs b/System.Data.Entity/System/Data/Common/CommandTrees/OperatorExpressions.cs index d3bfc50dc..45e384904 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/OperatorExpressions.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/OperatorExpressions.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/RelationalExpressions.cs b/System.Data.Entity/System/Data/Common/CommandTrees/RelationalExpressions.cs index 05f52deba..a6e626c2f 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/RelationalExpressions.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/RelationalExpressions.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/CommandTrees/ValueExpressions.cs b/System.Data.Entity/System/Data/Common/CommandTrees/ValueExpressions.cs index 7d9bef3d9..7546835ec 100644 --- a/System.Data.Entity/System/Data/Common/CommandTrees/ValueExpressions.cs +++ b/System.Data.Entity/System/Data/Common/CommandTrees/ValueExpressions.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.CommandTrees diff --git a/System.Data.Entity/System/Data/Common/DataRecord.cs b/System.Data.Entity/System/Data/Common/DataRecord.cs index 22945e86e..b2d286185 100644 --- a/System.Data.Entity/System/Data/Common/DataRecord.cs +++ b/System.Data.Entity/System/Data/Common/DataRecord.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Objects @@ -426,7 +426,7 @@ public override bool IsDBNull(int ordinal) } #region ICustomTypeDescriptor implementation - //[[....]] Reference: http://msdn.microsoft.com/msdnmag/issues/05/04/NETMatters/ + //[Microsoft] Reference: http://msdn.microsoft.com/msdnmag/issues/05/04/NETMatters/ //Holds all of the PropertyDescriptors for the PrimitiveType objects in _values private PropertyDescriptorCollection _propertyDescriptors = null; private FilterCache _filterCache; diff --git a/System.Data.Entity/System/Data/Common/DataRecordInfo.cs b/System.Data.Entity/System/Data/Common/DataRecordInfo.cs index b5fcf313e..9e892e98d 100644 --- a/System.Data.Entity/System/Data/Common/DataRecordInfo.cs +++ b/System.Data.Entity/System/Data/Common/DataRecordInfo.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common diff --git a/System.Data.Entity/System/Data/Common/DbCommandDefinition.cs b/System.Data.Entity/System/Data/Common/DbCommandDefinition.cs index af5490530..ed4b28e27 100644 --- a/System.Data.Entity/System/Data/Common/DbCommandDefinition.cs +++ b/System.Data.Entity/System/Data/Common/DbCommandDefinition.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Data.Entity/System/Data/Common/DbProviderManifest.cs b/System.Data.Entity/System/Data/Common/DbProviderManifest.cs index 4258cb147..b043bb402 100644 --- a/System.Data.Entity/System/Data/Common/DbProviderManifest.cs +++ b/System.Data.Entity/System/Data/Common/DbProviderManifest.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common diff --git a/System.Data.Entity/System/Data/Common/DbProviderServices.cs b/System.Data.Entity/System/Data/Common/DbProviderServices.cs index 6647b41a6..e12c1c8cd 100644 --- a/System.Data.Entity/System/Data/Common/DbProviderServices.cs +++ b/System.Data.Entity/System/Data/Common/DbProviderServices.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Data.SqlClient; diff --git a/System.Data.Entity/System/Data/Common/DbXmlEnabledProviderManifest.cs b/System.Data.Entity/System/Data/Common/DbXmlEnabledProviderManifest.cs index b06d9eb2f..456a6d5ce 100644 --- a/System.Data.Entity/System/Data/Common/DbXmlEnabledProviderManifest.cs +++ b/System.Data.Entity/System/Data/Common/DbXmlEnabledProviderManifest.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common diff --git a/System.Data.Entity/System/Data/Common/EntityRecordInfo.cs b/System.Data.Entity/System/Data/Common/EntityRecordInfo.cs index fac34b50b..d98de0bc8 100644 --- a/System.Data.Entity/System/Data/Common/EntityRecordInfo.cs +++ b/System.Data.Entity/System/Data/Common/EntityRecordInfo.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/AliasedExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/AliasedExpr.cs index df9f6e839..102e5da53 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/AliasedExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/AliasedExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/AstNode.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/AstNode.cs index e9d15458b..f0532e26f 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/AstNode.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/AstNode.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/BuiltInExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/BuiltInExpr.cs index fde232bf3..66f3ca72c 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/BuiltInExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/BuiltInExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/CaseExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/CaseExpr.cs index e1cae1bea..b04a76624 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/CaseExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/CaseExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/Command.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/Command.cs index 905d1de7c..a984def3d 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/Command.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/Command.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/ConstructorExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/ConstructorExpr.cs index e347d8e49..8f4e103e7 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/ConstructorExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/ConstructorExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/CreateRefExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/CreateRefExpr.cs index 0757273be..365783ede 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/CreateRefExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/CreateRefExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/DotExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/DotExpr.cs index cdd820cf2..1d5b129ea 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/DotExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/DotExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/FunctionDefinition.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/FunctionDefinition.cs index 3331eacd6..c42aebb76 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/FunctionDefinition.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/FunctionDefinition.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/GroupAggregateExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/GroupAggregateExpr.cs index 2806c7f43..228845313 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/GroupAggregateExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/GroupAggregateExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/GroupPartitionExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/GroupPartitionExpr.cs index 128f9605e..892604a96 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/GroupPartitionExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/GroupPartitionExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/Identifier.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/Identifier.cs index 027fecca6..bf7ea32b8 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/Identifier.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/Identifier.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/Literal.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/Literal.cs index 5616b9262..b29f3a6ea 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/Literal.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/Literal.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/MethodExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/MethodExpr.cs index dd49950d7..b95887f0a 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/MethodExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/MethodExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/NamespaceImport.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/NamespaceImport.cs index bfc5b7406..d6ad41432 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/NamespaceImport.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/NamespaceImport.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/NavigationExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/NavigationExpr.cs index e57134ce2..b9ece4526 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/NavigationExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/NavigationExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/ParenExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/ParenExpr.cs index f7e675102..724fe2fef 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/ParenExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/ParenExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryExpr.cs index 2929b1ac2..ab258763c 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryParameter.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryParameter.cs index 42000a872..0913e91f9 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryParameter.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryParameter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryStatement.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryStatement.cs index d417b7cd2..4567c4fde 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryStatement.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/QueryStatement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/RefExpr.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/RefExpr.cs index ecb09bd2b..9a3478111 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/RefExpr.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/RefExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/AST/TypeDefinition.cs b/System.Data.Entity/System/Data/Common/EntitySql/AST/TypeDefinition.cs index bb6f19e81..c7bf3a98b 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/AST/TypeDefinition.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/AST/TypeDefinition.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql.AST diff --git a/System.Data.Entity/System/Data/Common/EntitySql/CqlErrorHelper.cs b/System.Data.Entity/System/Data/Common/EntitySql/CqlErrorHelper.cs index 681bf9fe7..0e53206e9 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/CqlErrorHelper.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/CqlErrorHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntitySql/CqlLexer.cs b/System.Data.Entity/System/Data/Common/EntitySql/CqlLexer.cs index ddb98d334..8d8c09279 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/CqlLexer.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/CqlLexer.cs @@ -15,8 +15,8 @@ namespace System.Data.Common.EntitySql // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //----------------------------------------------------------------------------*/ using System; using System.Globalization; diff --git a/System.Data.Entity/System/Data/Common/EntitySql/CqlLexerHelpers.cs b/System.Data.Entity/System/Data/Common/EntitySql/CqlLexerHelpers.cs index 23dcbc379..477807623 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/CqlLexerHelpers.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/CqlLexerHelpers.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntitySql/CqlParser.cs b/System.Data.Entity/System/Data/Common/EntitySql/CqlParser.cs index 1049adebd..d6ba939fb 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/CqlParser.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/CqlParser.cs @@ -27,8 +27,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //---------------------------------------------------------------------------*/ using System; diff --git a/System.Data.Entity/System/Data/Common/EntitySql/CqlParserHelpers.cs b/System.Data.Entity/System/Data/Common/EntitySql/CqlParserHelpers.cs index 901fbd4ec..9dcc68e18 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/CqlParserHelpers.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/CqlParserHelpers.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntitySql/CqlQuery.cs b/System.Data.Entity/System/Data/Common/EntitySql/CqlQuery.cs index e68915008..8c8fbe0d7 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/CqlQuery.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/CqlQuery.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntitySql/EntitySqlParser.cs b/System.Data.Entity/System/Data/Common/EntitySql/EntitySqlParser.cs index 17b62f5bb..a6f018832 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/EntitySqlParser.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/EntitySqlParser.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntitySql/FunctionOverloadResolver.cs b/System.Data.Entity/System/Data/Common/EntitySql/FunctionOverloadResolver.cs index fe00e0c48..0207198e6 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/FunctionOverloadResolver.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/FunctionOverloadResolver.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntitySql/ParseResult.cs b/System.Data.Entity/System/Data/Common/EntitySql/ParseResult.cs index fdbf4be14..77fa73c45 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/ParseResult.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/ParseResult.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntitySql/ParserOptions.cs b/System.Data.Entity/System/Data/Common/EntitySql/ParserOptions.cs index cdfc03cda..bf61750a9 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/ParserOptions.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/ParserOptions.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntitySql/SemanticAnalyzer.cs b/System.Data.Entity/System/Data/Common/EntitySql/SemanticAnalyzer.cs index 43bd38b5f..51130912b 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/SemanticAnalyzer.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/SemanticAnalyzer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntitySql/SemanticResolver.cs b/System.Data.Entity/System/Data/Common/EntitySql/SemanticResolver.cs index ddc2fe1ed..9009be640 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/SemanticResolver.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/SemanticResolver.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntitySql/StaticContext.cs b/System.Data.Entity/System/Data/Common/EntitySql/StaticContext.cs index 810e2dde4..1000b4d4d 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/StaticContext.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/StaticContext.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntitySql/TypeResolver.cs b/System.Data.Entity/System/Data/Common/EntitySql/TypeResolver.cs index 53052c6f9..99d2fcb2f 100644 --- a/System.Data.Entity/System/Data/Common/EntitySql/TypeResolver.cs +++ b/System.Data.Entity/System/Data/Common/EntitySql/TypeResolver.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql diff --git a/System.Data.Entity/System/Data/Common/EntityUtil.cs b/System.Data.Entity/System/Data/Common/EntityUtil.cs index 273ba8bf5..0198bed47 100644 --- a/System.Data.Entity/System/Data/Common/EntityUtil.cs +++ b/System.Data.Entity/System/Data/Common/EntityUtil.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data.Entity/System/Data/Common/FieldMetadata.cs b/System.Data.Entity/System/Data/Common/FieldMetadata.cs index 5ed39f171..f9c967c80 100644 --- a/System.Data.Entity/System/Data/Common/FieldMetadata.cs +++ b/System.Data.Entity/System/Data/Common/FieldMetadata.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data.Entity/System/Data/Common/FieldNameLookup.cs b/System.Data.Entity/System/Data/Common/FieldNameLookup.cs index e65c7390d..8d7177d5d 100644 --- a/System.Data.Entity/System/Data/Common/FieldNameLookup.cs +++ b/System.Data.Entity/System/Data/Common/FieldNameLookup.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ diff --git a/System.Data.Entity/System/Data/Common/Internal/DbTypeMap.cs b/System.Data.Entity/System/Data/Common/Internal/DbTypeMap.cs index 65ab8650c..7a85d27b4 100644 --- a/System.Data.Entity/System/Data/Common/Internal/DbTypeMap.cs +++ b/System.Data.Entity/System/Data/Common/Internal/DbTypeMap.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Text; diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/ColumnMapKeyBuilder.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/ColumnMapKeyBuilder.cs index 19041a0c3..af3717ef8 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/ColumnMapKeyBuilder.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/ColumnMapKeyBuilder.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/CompensatingCollection.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/CompensatingCollection.cs index 8526686cd..3b48e5f40 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/CompensatingCollection.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/CompensatingCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common.Internal.Materialization diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/Coordinator.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/Coordinator.cs index 23be3839d..93a4e6c90 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/Coordinator.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/Coordinator.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/CoordinatorFactory.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/CoordinatorFactory.cs index 0ec0331c8..b6807fa20 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/CoordinatorFactory.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/CoordinatorFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/CoordinatorScratchpad.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/CoordinatorScratchpad.cs index d2f81f02f..96323de31 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/CoordinatorScratchpad.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/CoordinatorScratchpad.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordState.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordState.cs index 096fd6615..b2c725f98 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordState.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordState.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordStateFactory.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordStateFactory.cs index 69904d04f..0df64e380 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordStateFactory.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordStateFactory.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordStateScratchpad.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordStateScratchpad.cs index 7a5f65e0d..796548170 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordStateScratchpad.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/RecordStateScratchpad.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/Shaper.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/Shaper.cs index 659e0e1c4..db09b27ac 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/Shaper.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/Shaper.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common.Internal.Materialization diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/ShaperFactory.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/ShaperFactory.cs index 0a4c89a46..3fd39f9d2 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/ShaperFactory.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/ShaperFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Data.Common.QueryCache; diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/Translator.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/Translator.cs index 065d41fc1..13268cda9 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/Translator.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/Translator.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common.Internal.Materialization diff --git a/System.Data.Entity/System/Data/Common/Internal/Materialization/Util.cs b/System.Data.Entity/System/Data/Common/Internal/Materialization/Util.cs index fd7cac415..a968ae5ff 100644 --- a/System.Data.Entity/System/Data/Common/Internal/Materialization/Util.cs +++ b/System.Data.Entity/System/Data/Common/Internal/Materialization/Util.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/Common/Internal/MultipartIdentifier.cs b/System.Data.Entity/System/Data/Common/Internal/MultipartIdentifier.cs index 53cef9b28..b4f9fb478 100644 --- a/System.Data.Entity/System/Data/Common/Internal/MultipartIdentifier.cs +++ b/System.Data.Entity/System/Data/Common/Internal/MultipartIdentifier.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Diagnostics; diff --git a/System.Data.Entity/System/Data/Common/QueryCache/CompiledQueryCacheEntry.cs b/System.Data.Entity/System/Data/Common/QueryCache/CompiledQueryCacheEntry.cs index 64adc859e..d12784031 100644 --- a/System.Data.Entity/System/Data/Common/QueryCache/CompiledQueryCacheEntry.cs +++ b/System.Data.Entity/System/Data/Common/QueryCache/CompiledQueryCacheEntry.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common.QueryCache diff --git a/System.Data.Entity/System/Data/Common/QueryCache/CompiledQueryCacheKey.cs b/System.Data.Entity/System/Data/Common/QueryCache/CompiledQueryCacheKey.cs index 2654fe187..bd601d72a 100644 --- a/System.Data.Entity/System/Data/Common/QueryCache/CompiledQueryCacheKey.cs +++ b/System.Data.Entity/System/Data/Common/QueryCache/CompiledQueryCacheKey.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common.QueryCache diff --git a/System.Data.Entity/System/Data/Common/QueryCache/EntityClientCacheKey.cs b/System.Data.Entity/System/Data/Common/QueryCache/EntityClientCacheKey.cs index e15581534..f779d4bc6 100644 --- a/System.Data.Entity/System/Data/Common/QueryCache/EntityClientCacheKey.cs +++ b/System.Data.Entity/System/Data/Common/QueryCache/EntityClientCacheKey.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common.QueryCache diff --git a/System.Data.Entity/System/Data/Common/QueryCache/EntitySqlQueryCacheKey.cs b/System.Data.Entity/System/Data/Common/QueryCache/EntitySqlQueryCacheKey.cs index e522b27cb..c768adabf 100644 --- a/System.Data.Entity/System/Data/Common/QueryCache/EntitySqlQueryCacheKey.cs +++ b/System.Data.Entity/System/Data/Common/QueryCache/EntitySqlQueryCacheKey.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common.QueryCache diff --git a/System.Data.Entity/System/Data/Common/QueryCache/LinqQueryCacheKey.cs b/System.Data.Entity/System/Data/Common/QueryCache/LinqQueryCacheKey.cs index 48e751b3a..eda5cfd72 100644 --- a/System.Data.Entity/System/Data/Common/QueryCache/LinqQueryCacheKey.cs +++ b/System.Data.Entity/System/Data/Common/QueryCache/LinqQueryCacheKey.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft // @backupOwner venkatja //------------------------------------------------------------------------------ diff --git a/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheEntry.cs b/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheEntry.cs index 095192735..b24ea21c6 100644 --- a/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheEntry.cs +++ b/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheEntry.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common.QueryCache diff --git a/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheKey.cs b/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheKey.cs index 4619758ae..28884ac06 100644 --- a/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheKey.cs +++ b/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheKey.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common.QueryCache diff --git a/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheManager.cs b/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheManager.cs index 1b0ccd787..7bbc1a392 100644 --- a/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheManager.cs +++ b/System.Data.Entity/System/Data/Common/QueryCache/QueryCacheManager.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common.QueryCache diff --git a/System.Data.Entity/System/Data/Common/QueryCache/ShaperFactoryQueryCacheKey.cs b/System.Data.Entity/System/Data/Common/QueryCache/ShaperFactoryQueryCacheKey.cs index 4b47edc6e..dd3826dae 100644 --- a/System.Data.Entity/System/Data/Common/QueryCache/ShaperFactoryQueryCacheKey.cs +++ b/System.Data.Entity/System/Data/Common/QueryCache/ShaperFactoryQueryCacheKey.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Data.Entity/System/Data/Common/Utils/AliasGenerator.cs b/System.Data.Entity/System/Data/Common/Utils/AliasGenerator.cs index 670f5e62d..5417635a7 100644 --- a/System.Data.Entity/System/Data/Common/Utils/AliasGenerator.cs +++ b/System.Data.Entity/System/Data/Common/Utils/AliasGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/BoolExpr.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/BoolExpr.cs index c06db3a12..4ddc93a15 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/BoolExpr.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/BoolExpr.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/Clause.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/Clause.cs index 510cf51b4..f06cf05f8 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/Clause.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/Clause.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/ConversionContext.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/ConversionContext.cs index ba6cb2b83..944a59a9a 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/ConversionContext.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/ConversionContext.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/Converter.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/Converter.cs index c5bf38311..893ab5a69 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/Converter.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/Converter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/DomainConstraint.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/DomainConstraint.cs index aa8d12e3c..0b69ae686 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/DomainConstraint.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/DomainConstraint.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/IdentifierService.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/IdentifierService.cs index 36d5bd118..bfe37791d 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/IdentifierService.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/IdentifierService.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/KnowledgeBase.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/KnowledgeBase.cs index cb9d5569c..1fc9e9fd9 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/KnowledgeBase.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/KnowledgeBase.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/Literal.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/Literal.cs index 372a0cfa3..90f18519c 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/Literal.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/Literal.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/NegationPusher.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/NegationPusher.cs index 4a86fee78..0123003f2 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/NegationPusher.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/NegationPusher.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/Sentence.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/Sentence.cs index 2b6716c3e..92c7f9bee 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/Sentence.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/Sentence.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/Simplifier.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/Simplifier.cs index 2bad66e26..b591a6645 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/Simplifier.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/Simplifier.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/Solver.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/Solver.cs index d9769c5f3..8d0f77d72 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/Solver.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/Solver.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; @@ -315,7 +315,7 @@ public bool Equals(Vertex x, Vertex y) { if (x.IsSink()) { - // [....] nodes '1' and '0' each have one static instance; use reference + // sync nodes '1' and '0' each have one static instance; use reference return x.Equals(y); } @@ -338,7 +338,7 @@ public bool Equals(Vertex x, Vertex y) public int GetHashCode(Vertex vertex) { - // [....] nodes '1' and '0' each have one static instance; use reference + // sync nodes '1' and '0' each have one static instance; use reference if (vertex.IsSink()) { return vertex.GetHashCode(); diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/Vertex.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/Vertex.cs index 6806a73b2..38b8b5f87 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/Vertex.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/Vertex.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Boolean/Visitor.cs b/System.Data.Entity/System/Data/Common/Utils/Boolean/Visitor.cs index d4f25a816..b02fa5d12 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Boolean/Visitor.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Boolean/Visitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/ByValueEqualityComparer.cs b/System.Data.Entity/System/Data/Common/Utils/ByValueEqualityComparer.cs index 4cd2051c0..0be82c086 100644 --- a/System.Data.Entity/System/Data/Common/Utils/ByValueEqualityComparer.cs +++ b/System.Data.Entity/System/Data/Common/Utils/ByValueEqualityComparer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/CommandHelper.cs b/System.Data.Entity/System/Data/Common/Utils/CommandHelper.cs index 39952ce67..1163bf8f8 100644 --- a/System.Data.Entity/System/Data/Common/Utils/CommandHelper.cs +++ b/System.Data.Entity/System/Data/Common/Utils/CommandHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common.Utils diff --git a/System.Data.Entity/System/Data/Common/Utils/DisposableCollectionWrapper.cs b/System.Data.Entity/System/Data/Common/Utils/DisposableCollectionWrapper.cs index 2096b0887..73f8b6299 100644 --- a/System.Data.Entity/System/Data/Common/Utils/DisposableCollectionWrapper.cs +++ b/System.Data.Entity/System/Data/Common/Utils/DisposableCollectionWrapper.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; using System.Linq; diff --git a/System.Data.Entity/System/Data/Common/Utils/Helpers.cs b/System.Data.Entity/System/Data/Common/Utils/Helpers.cs index 98a32e33e..232648f3e 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Helpers.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Helpers.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Common/Utils/InternalBase.cs b/System.Data.Entity/System/Data/Common/Utils/InternalBase.cs index 44fe649dc..a35fdc2da 100644 --- a/System.Data.Entity/System/Data/Common/Utils/InternalBase.cs +++ b/System.Data.Entity/System/Data/Common/Utils/InternalBase.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Common/Utils/KeyToListMap.cs b/System.Data.Entity/System/Data/Common/Utils/KeyToListMap.cs index aaa2b0df3..12a2a1333 100644 --- a/System.Data.Entity/System/Data/Common/Utils/KeyToListMap.cs +++ b/System.Data.Entity/System/Data/Common/Utils/KeyToListMap.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Common/Utils/Memoizer.cs b/System.Data.Entity/System/Data/Common/Utils/Memoizer.cs index f9f9d1d34..84395cf4c 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Memoizer.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Memoizer.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], [....] +// @owner Microsoft, Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/Utils/MetadataHelper.cs b/System.Data.Entity/System/Data/Common/Utils/MetadataHelper.cs index 8d7a31911..299763a4b 100644 --- a/System.Data.Entity/System/Data/Common/Utils/MetadataHelper.cs +++ b/System.Data.Entity/System/Data/Common/Utils/MetadataHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Common/Utils/ModifiableIteratorCollection.cs b/System.Data.Entity/System/Data/Common/Utils/ModifiableIteratorCollection.cs index 06db634ab..17f7d6b56 100644 --- a/System.Data.Entity/System/Data/Common/Utils/ModifiableIteratorCollection.cs +++ b/System.Data.Entity/System/Data/Common/Utils/ModifiableIteratorCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Common/Utils/Pair.cs b/System.Data.Entity/System/Data/Common/Utils/Pair.cs index 78e1362f7..4e6716346 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Pair.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Pair.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Common/Utils/Set.cs b/System.Data.Entity/System/Data/Common/Utils/Set.cs index 4b9b0fac3..4eead566c 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Set.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Set.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Common/Utils/Singleton.cs b/System.Data.Entity/System/Data/Common/Utils/Singleton.cs index cb7a53fc9..9d5282ada 100644 --- a/System.Data.Entity/System/Data/Common/Utils/Singleton.cs +++ b/System.Data.Entity/System/Data/Common/Utils/Singleton.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/Utils/StringUtil.cs b/System.Data.Entity/System/Data/Common/Utils/StringUtil.cs index bdd52eaa5..79e347e38 100644 --- a/System.Data.Entity/System/Data/Common/Utils/StringUtil.cs +++ b/System.Data.Entity/System/Data/Common/Utils/StringUtil.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Common/Utils/ThreadSafeList.cs b/System.Data.Entity/System/Data/Common/Utils/ThreadSafeList.cs index e867acd6f..1a26a4a10 100644 --- a/System.Data.Entity/System/Data/Common/Utils/ThreadSafeList.cs +++ b/System.Data.Entity/System/Data/Common/Utils/ThreadSafeList.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/Utils/TrailingSpaceComparer.cs b/System.Data.Entity/System/Data/Common/Utils/TrailingSpaceComparer.cs index 87929e26b..261894900 100644 --- a/System.Data.Entity/System/Data/Common/Utils/TrailingSpaceComparer.cs +++ b/System.Data.Entity/System/Data/Common/Utils/TrailingSpaceComparer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Common/Utils/TreePrinter.cs b/System.Data.Entity/System/Data/Common/Utils/TreePrinter.cs index fd2ab6566..dd2a101c5 100644 --- a/System.Data.Entity/System/Data/Common/Utils/TreePrinter.cs +++ b/System.Data.Entity/System/Data/Common/Utils/TreePrinter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/EntityClient/DbConnectionOptions.cs b/System.Data.Entity/System/Data/EntityClient/DbConnectionOptions.cs index 1a2aaea18..4e0339f88 100644 --- a/System.Data.Entity/System/Data/EntityClient/DbConnectionOptions.cs +++ b/System.Data.Entity/System/Data/EntityClient/DbConnectionOptions.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityClient diff --git a/System.Data.Entity/System/Data/EntityClient/DbParameterCollectionHelper.cs b/System.Data.Entity/System/Data/EntityClient/DbParameterCollectionHelper.cs index 4fbe922b7..05513caf8 100644 --- a/System.Data.Entity/System/Data/EntityClient/DbParameterCollectionHelper.cs +++ b/System.Data.Entity/System/Data/EntityClient/DbParameterCollectionHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityClient diff --git a/System.Data.Entity/System/Data/EntityClient/DbParameterHelper.cs b/System.Data.Entity/System/Data/EntityClient/DbParameterHelper.cs index c56ef6076..6d34f8a1a 100644 --- a/System.Data.Entity/System/Data/EntityClient/DbParameterHelper.cs +++ b/System.Data.Entity/System/Data/EntityClient/DbParameterHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/EntityClient/EntityAdapter.cs b/System.Data.Entity/System/Data/EntityClient/EntityAdapter.cs index 5a175d33d..3881760b3 100644 --- a/System.Data.Entity/System/Data/EntityClient/EntityAdapter.cs +++ b/System.Data.Entity/System/Data/EntityClient/EntityAdapter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityClient { diff --git a/System.Data.Entity/System/Data/EntityClient/EntityCommand.cs b/System.Data.Entity/System/Data/EntityClient/EntityCommand.cs index 84e2df32c..ea6a1d391 100644 --- a/System.Data.Entity/System/Data/EntityClient/EntityCommand.cs +++ b/System.Data.Entity/System/Data/EntityClient/EntityCommand.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityClient diff --git a/System.Data.Entity/System/Data/EntityClient/EntityCommandDefinition.cs b/System.Data.Entity/System/Data/EntityClient/EntityCommandDefinition.cs index 0f00c170e..c0f9ea430 100644 --- a/System.Data.Entity/System/Data/EntityClient/EntityCommandDefinition.cs +++ b/System.Data.Entity/System/Data/EntityClient/EntityCommandDefinition.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.EntityClient { diff --git a/System.Data.Entity/System/Data/EntityClient/EntityConnection.cs b/System.Data.Entity/System/Data/EntityClient/EntityConnection.cs index 38de95d81..eb3909609 100644 --- a/System.Data.Entity/System/Data/EntityClient/EntityConnection.cs +++ b/System.Data.Entity/System/Data/EntityClient/EntityConnection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/EntityClient/EntityConnectionStringBuilder.cs b/System.Data.Entity/System/Data/EntityClient/EntityConnectionStringBuilder.cs index 22ba703d3..f6061e487 100644 --- a/System.Data.Entity/System/Data/EntityClient/EntityConnectionStringBuilder.cs +++ b/System.Data.Entity/System/Data/EntityClient/EntityConnectionStringBuilder.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityClient diff --git a/System.Data.Entity/System/Data/EntityClient/EntityDataReader.cs b/System.Data.Entity/System/Data/EntityClient/EntityDataReader.cs index f79b0546c..14b88c927 100644 --- a/System.Data.Entity/System/Data/EntityClient/EntityDataReader.cs +++ b/System.Data.Entity/System/Data/EntityClient/EntityDataReader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityClient diff --git a/System.Data.Entity/System/Data/EntityClient/EntityParameter.cs b/System.Data.Entity/System/Data/EntityClient/EntityParameter.cs index 17c7aa105..33fd94821 100644 --- a/System.Data.Entity/System/Data/EntityClient/EntityParameter.cs +++ b/System.Data.Entity/System/Data/EntityClient/EntityParameter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityClient { diff --git a/System.Data.Entity/System/Data/EntityClient/EntityParameterCollection.cs b/System.Data.Entity/System/Data/EntityClient/EntityParameterCollection.cs index 8303a9172..72b8c1bc9 100644 --- a/System.Data.Entity/System/Data/EntityClient/EntityParameterCollection.cs +++ b/System.Data.Entity/System/Data/EntityClient/EntityParameterCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/EntityClient/EntityProviderFactory.cs b/System.Data.Entity/System/Data/EntityClient/EntityProviderFactory.cs index f633d9b29..5687ab06d 100644 --- a/System.Data.Entity/System/Data/EntityClient/EntityProviderFactory.cs +++ b/System.Data.Entity/System/Data/EntityClient/EntityProviderFactory.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; diff --git a/System.Data.Entity/System/Data/EntityClient/EntityProviderServices.cs b/System.Data.Entity/System/Data/EntityClient/EntityProviderServices.cs index aa7b9d3a3..579cf6ba8 100644 --- a/System.Data.Entity/System/Data/EntityClient/EntityProviderServices.cs +++ b/System.Data.Entity/System/Data/EntityClient/EntityProviderServices.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.EntityClient { diff --git a/System.Data.Entity/System/Data/EntityClient/EntityTransaction.cs b/System.Data.Entity/System/Data/EntityClient/EntityTransaction.cs index 69c546691..ffaeda4db 100644 --- a/System.Data.Entity/System/Data/EntityClient/EntityTransaction.cs +++ b/System.Data.Entity/System/Data/EntityClient/EntityTransaction.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Text; diff --git a/System.Data.Entity/System/Data/EntityClient/NameValuePair.cs b/System.Data.Entity/System/Data/EntityClient/NameValuePair.cs index 19ec74327..3d548d105 100644 --- a/System.Data.Entity/System/Data/EntityClient/NameValuePair.cs +++ b/System.Data.Entity/System/Data/EntityClient/NameValuePair.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.EntityClient diff --git a/System.Data.Entity/System/Data/EntityCommandCompilationException.cs b/System.Data.Entity/System/Data/EntityCommandCompilationException.cs index 6f88b7700..0975cf1d4 100644 --- a/System.Data.Entity/System/Data/EntityCommandCompilationException.cs +++ b/System.Data.Entity/System/Data/EntityCommandCompilationException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data { diff --git a/System.Data.Entity/System/Data/EntityCommandExecutionException.cs b/System.Data.Entity/System/Data/EntityCommandExecutionException.cs index b464bf4d1..db9a7c62e 100644 --- a/System.Data.Entity/System/Data/EntityCommandExecutionException.cs +++ b/System.Data.Entity/System/Data/EntityCommandExecutionException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data { diff --git a/System.Data.Entity/System/Data/EntityException.cs b/System.Data.Entity/System/Data/EntityException.cs index 4060610bb..84fd61e5c 100644 --- a/System.Data.Entity/System/Data/EntityException.cs +++ b/System.Data.Entity/System/Data/EntityException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data diff --git a/System.Data.Entity/System/Data/EntityKey.cs b/System.Data.Entity/System/Data/EntityKey.cs index 249249a77..84c60eb7e 100644 --- a/System.Data.Entity/System/Data/EntityKey.cs +++ b/System.Data.Entity/System/Data/EntityKey.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/BooleanFacetDescriptionElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/BooleanFacetDescriptionElement.cs index 99ee5aa72..f48665f8b 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/BooleanFacetDescriptionElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/BooleanFacetDescriptionElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ByteFacetDescriptionElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ByteFacetDescriptionElement.cs index 8beec1311..f9a3f58dc 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ByteFacetDescriptionElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ByteFacetDescriptionElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/CollectionTypeElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/CollectionTypeElement.cs index 987631ed9..e59c73944 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/CollectionTypeElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/CollectionTypeElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Documentation.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Documentation.cs index 855c7b9ab..6edbe3939 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Documentation.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Documentation.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainer.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainer.cs index 89d93ac8f..1fd962260 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainer.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerAssociationSet.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerAssociationSet.cs index d3bf53f96..1123c77d6 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerAssociationSet.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerAssociationSet.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerAssociationSetEnd.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerAssociationSetEnd.cs index 9c1aa9ee3..94a82e4a5 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerAssociationSetEnd.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerAssociationSetEnd.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerEntitySet.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerEntitySet.cs index 84f1077ff..058927b46 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerEntitySet.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerEntitySet.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerEntitySetDefiningQuery.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerEntitySetDefiningQuery.cs index e28c9e245..a8e156eb9 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerEntitySetDefiningQuery.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerEntitySetDefiningQuery.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerRelationshipSet.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerRelationshipSet.cs index 1a97aa2eb..dca3bc5e3 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerRelationshipSet.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerRelationshipSet.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerRelationshipSetEnd.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerRelationshipSetEnd.cs index 1d1ece883..05d03efff 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerRelationshipSetEnd.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityContainerRelationshipSetEnd.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityKeyElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityKeyElement.cs index 07445c951..2126b2a9c 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityKeyElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/EntityKeyElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FacetDescriptionElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FacetDescriptionElement.cs index 49f2b7a86..eb40d3dc2 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FacetDescriptionElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FacetDescriptionElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FacetEnabledSchemaElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FacetEnabledSchemaElement.cs index fc0323241..bb05b4a3e 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FacetEnabledSchemaElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FacetEnabledSchemaElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FilteredSchemaElementLookUpTable.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FilteredSchemaElementLookUpTable.cs index 1f831a311..3e5c9917d 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FilteredSchemaElementLookUpTable.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FilteredSchemaElementLookUpTable.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Function.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Function.cs index 30a10dcee..a037456cd 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Function.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Function.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FunctionCommandText.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FunctionCommandText.cs index 2ce12d538..de1322b8e 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FunctionCommandText.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FunctionCommandText.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FunctionImportElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FunctionImportElement.cs index 9839bdd1f..a1847012c 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FunctionImportElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/FunctionImportElement.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel { diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/IntegerFacetDescriptionElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/IntegerFacetDescriptionElement.cs index 8e5edae4b..1e2c8644b 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/IntegerFacetDescriptionElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/IntegerFacetDescriptionElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ItemType.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ItemType.cs index 3a5149eef..47d691af5 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ItemType.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ItemType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/KeyProperty.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/KeyProperty.cs index bc0940010..7f79e8774 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/KeyProperty.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/KeyProperty.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ModelFunction.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ModelFunction.cs index a44097e95..1b62350a0 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ModelFunction.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ModelFunction.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ModelFunctionTypeElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ModelFunctionTypeElement.cs index 97449e9f0..89348cb93 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ModelFunctionTypeElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ModelFunctionTypeElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/NavigationProperty.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/NavigationProperty.cs index 3909de586..796497f28 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/NavigationProperty.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/NavigationProperty.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/OnOperation.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/OnOperation.cs index 53f19784b..b1dbc31b2 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/OnOperation.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/OnOperation.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Parameter.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Parameter.cs index 87bb5caf5..b290e9a74 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Parameter.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Parameter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/PrimitiveSchema.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/PrimitiveSchema.cs index 6a7c4c121..bda27b31e 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/PrimitiveSchema.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/PrimitiveSchema.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel { diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Property.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Property.cs index 20550a805..54e400806 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Property.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Property.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferenceSchema.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferenceSchema.cs index d55c26c74..5965358fd 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferenceSchema.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferenceSchema.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferenceTypeElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferenceTypeElement.cs index 38d5da73b..40e555cfc 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferenceTypeElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferenceTypeElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel { diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferentialConstraint.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferentialConstraint.cs index 64ac3051c..66d00ca22 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferentialConstraint.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferentialConstraint.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferentialConstraintRoleElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferentialConstraintRoleElement.cs index d3634f435..f6ed7efc2 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferentialConstraintRoleElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReferentialConstraintRoleElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Relationship.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Relationship.cs index b8c9f47ad..5091d573a 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Relationship.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Relationship.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RelationshipEnd.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RelationshipEnd.cs index fb1f5f1cf..e1806d8a6 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RelationshipEnd.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RelationshipEnd.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RelationshipEndCollection.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RelationshipEndCollection.cs index e9ec6b566..15314c5f4 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RelationshipEndCollection.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RelationshipEndCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReturnType.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReturnType.cs index 0a04f994f..fd81011ad 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReturnType.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReturnType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReturnValue.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReturnValue.cs index 7ac9a584e..07c82622a 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReturnValue.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ReturnValue.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RowTypeElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RowTypeElement.cs index 99783ac47..b7742c276 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RowTypeElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RowTypeElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RowTypePropertyElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RowTypePropertyElement.cs index e17b0b9f0..cdbd4108a 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RowTypePropertyElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/RowTypePropertyElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ScalarType.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ScalarType.cs index 7e2f1be53..16d543e00 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ScalarType.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ScalarType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Schema.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Schema.cs index adb7b34c7..636fc889f 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Schema.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Schema.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel @@ -540,13 +540,13 @@ private set } } - // ISSUE: jthunter-03/14/05 - The [....] "schemas" don't follow the ".Store" assembly + // ISSUE: jthunter-03/14/05 - The Sync "schemas" don't follow the ".Store" assembly // naming convention but need to have the right StoreNamespace reported. // private static readonly string[] ClientNamespaceOfSchemasMissingStoreSuffix = { - "System.Storage.[....].Utility", - "System.Storage.[....].Services" + "System.Storage.Sync.Utility", + "System.Storage.Sync.Services" }; /// diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaComplexType.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaComplexType.cs index 1c4aa5f7a..2a768a1cb 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaComplexType.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaComplexType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElement.cs index eed8906e8..79be13fdd 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElementLookUpTable.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElementLookUpTable.cs index 044bb35f3..25bb4f749 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElementLookUpTable.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElementLookUpTable.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElementLookUpTableEnumerator.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElementLookUpTableEnumerator.cs index 428a071ab..fdcacf10d 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElementLookUpTableEnumerator.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaElementLookUpTableEnumerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaEnumMember.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaEnumMember.cs index 6e680d0b7..ad6c82d1e 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaEnumMember.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaEnumMember.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaEnumType.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaEnumType.cs index 9c3b3153b..073088e11 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaEnumType.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaEnumType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaLookupTable.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaLookupTable.cs index 3b550b8e6..e6ea1117a 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaLookupTable.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaLookupTable.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaManager.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaManager.cs index fbb7a3ae9..1afb48b5d 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaManager.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaManager.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaType.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaType.cs index 5e830ffb9..f20a29651 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaType.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SchemaType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SridFacetDescriptionElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SridFacetDescriptionElement.cs index 23f186522..09196b79e 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SridFacetDescriptionElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/SridFacetDescriptionElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/StructuredProperty.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/StructuredProperty.cs index fb95425bf..20c9da270 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/StructuredProperty.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/StructuredProperty.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/StructuredType.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/StructuredType.cs index c95e93da8..887d82668 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/StructuredType.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/StructuredType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TextElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TextElement.cs index 87637e605..914cb26e5 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TextElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TextElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeElement.cs index 36d8b5c77..d0f548aef 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel { diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeRefElement.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeRefElement.cs index 12e7e50dd..29ca6faa0 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeRefElement.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeRefElement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeUsageBuilder.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeUsageBuilder.cs index 6db83bb2c..62786cbaa 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeUsageBuilder.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/TypeUsageBuilder.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Utils.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Utils.cs index 61003c001..dd3425434 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Utils.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/Utils.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.EntityModel.SchemaObjectModel diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ValidationHelper.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ValidationHelper.cs index 1095504e1..a9ea0c731 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ValidationHelper.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/ValidationHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/XmlSchemaResource.cs b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/XmlSchemaResource.cs index eb3f3763f..151fed0e6 100644 --- a/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/XmlSchemaResource.cs +++ b/System.Data.Entity/System/Data/EntityModel/SchemaObjectModel/XmlSchemaResource.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Diagnostics; using System.Data.Mapping; diff --git a/System.Data.Entity/System/Data/EntitySqlException.cs b/System.Data.Entity/System/Data/EntitySqlException.cs index d9a0c3b24..006f09519 100644 --- a/System.Data.Entity/System/Data/EntitySqlException.cs +++ b/System.Data.Entity/System/Data/EntitySqlException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data diff --git a/System.Data.Entity/System/Data/InternalMappingException.cs b/System.Data.Entity/System/Data/InternalMappingException.cs index 0626e41a0..22f12f72e 100644 --- a/System.Data.Entity/System/Data/InternalMappingException.cs +++ b/System.Data.Entity/System/Data/InternalMappingException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/InvalidCommandTreeException.cs b/System.Data.Entity/System/Data/InvalidCommandTreeException.cs index 42e6cf01a..c07883463 100644 --- a/System.Data.Entity/System/Data/InvalidCommandTreeException.cs +++ b/System.Data.Entity/System/Data/InvalidCommandTreeException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data diff --git a/System.Data.Entity/System/Data/Mapping/BaseMetadataMappingVisitor.cs b/System.Data.Entity/System/Data/Mapping/BaseMetadataMappingVisitor.cs index 44b985c6c..52c82e3c7 100644 --- a/System.Data.Entity/System/Data/Mapping/BaseMetadataMappingVisitor.cs +++ b/System.Data.Entity/System/Data/Mapping/BaseMetadataMappingVisitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/DefaultObjectMappingItemCollection.cs b/System.Data.Entity/System/Data/Mapping/DefaultObjectMappingItemCollection.cs index cc0286ea6..e57eacff7 100644 --- a/System.Data.Entity/System/Data/Mapping/DefaultObjectMappingItemCollection.cs +++ b/System.Data.Entity/System/Data/Mapping/DefaultObjectMappingItemCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping { diff --git a/System.Data.Entity/System/Data/Mapping/EntityViewContainer.cs b/System.Data.Entity/System/Data/Mapping/EntityViewContainer.cs index 080a4486d..5d4e87e27 100644 --- a/System.Data.Entity/System/Data/Mapping/EntityViewContainer.cs +++ b/System.Data.Entity/System/Data/Mapping/EntityViewContainer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/EntityViewGenerationAttribute.cs b/System.Data.Entity/System/Data/Mapping/EntityViewGenerationAttribute.cs index d6caaa76c..5e6c8a3f8 100644 --- a/System.Data.Entity/System/Data/Mapping/EntityViewGenerationAttribute.cs +++ b/System.Data.Entity/System/Data/Mapping/EntityViewGenerationAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/FunctionImportMapping.ReturnTypeRenameMapping.cs b/System.Data.Entity/System/Data/Mapping/FunctionImportMapping.ReturnTypeRenameMapping.cs index 1b9cf0e5d..18bffc41d 100644 --- a/System.Data.Entity/System/Data/Mapping/FunctionImportMapping.ReturnTypeRenameMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/FunctionImportMapping.ReturnTypeRenameMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/FunctionImportMapping.cs b/System.Data.Entity/System/Data/Mapping/FunctionImportMapping.cs index 610975820..6c3a297b6 100644 --- a/System.Data.Entity/System/Data/Mapping/FunctionImportMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/FunctionImportMapping.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft // @backupOwner willa //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/FunctionImportMappingComposable.cs b/System.Data.Entity/System/Data/Mapping/FunctionImportMappingComposable.cs index f0507d294..7e278377f 100644 --- a/System.Data.Entity/System/Data/Mapping/FunctionImportMappingComposable.cs +++ b/System.Data.Entity/System/Data/Mapping/FunctionImportMappingComposable.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft // @backupOwner willa //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/FunctionImportMappingNonComposable.cs b/System.Data.Entity/System/Data/Mapping/FunctionImportMappingNonComposable.cs index 88677a82a..a2c85076a 100644 --- a/System.Data.Entity/System/Data/Mapping/FunctionImportMappingNonComposable.cs +++ b/System.Data.Entity/System/Data/Mapping/FunctionImportMappingNonComposable.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft // @backupOwner willa //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/Mapping.cs b/System.Data.Entity/System/Data/Mapping/Mapping.cs index 17f4c59dc..b6d419b7b 100644 --- a/System.Data.Entity/System/Data/Mapping/Mapping.cs +++ b/System.Data.Entity/System/Data/Mapping/Mapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/Mapping/MappingItemCollection.cs b/System.Data.Entity/System/Data/Mapping/MappingItemCollection.cs index c03c1cd57..aa74a7c7e 100644 --- a/System.Data.Entity/System/Data/Mapping/MappingItemCollection.cs +++ b/System.Data.Entity/System/Data/Mapping/MappingItemCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping diff --git a/System.Data.Entity/System/Data/Mapping/MetadataMappingHasherVisitor.HashSourceBuilder.cs b/System.Data.Entity/System/Data/Mapping/MetadataMappingHasherVisitor.HashSourceBuilder.cs index d6f03a94a..6a9f710c2 100644 --- a/System.Data.Entity/System/Data/Mapping/MetadataMappingHasherVisitor.HashSourceBuilder.cs +++ b/System.Data.Entity/System/Data/Mapping/MetadataMappingHasherVisitor.HashSourceBuilder.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/MetadataMappingHasherVisitor.cs b/System.Data.Entity/System/Data/Mapping/MetadataMappingHasherVisitor.cs index 864c5b508..bd42445d1 100644 --- a/System.Data.Entity/System/Data/Mapping/MetadataMappingHasherVisitor.cs +++ b/System.Data.Entity/System/Data/Mapping/MetadataMappingHasherVisitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ObjectAssociationEndMapping.cs b/System.Data.Entity/System/Data/Mapping/ObjectAssociationEndMapping.cs index 1500adf78..694846f49 100644 --- a/System.Data.Entity/System/Data/Mapping/ObjectAssociationEndMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/ObjectAssociationEndMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/ObjectComplexPropertyMapping.cs b/System.Data.Entity/System/Data/Mapping/ObjectComplexPropertyMapping.cs index fd72adf2a..a2f034b38 100644 --- a/System.Data.Entity/System/Data/Mapping/ObjectComplexPropertyMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/ObjectComplexPropertyMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/ObjectMemberMapping.cs b/System.Data.Entity/System/Data/Mapping/ObjectMemberMapping.cs index c6e1ac215..02bb19864 100644 --- a/System.Data.Entity/System/Data/Mapping/ObjectMemberMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/ObjectMemberMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ObjectNavigationPropertyMapping.cs b/System.Data.Entity/System/Data/Mapping/ObjectNavigationPropertyMapping.cs index f77723f4c..09b9789d7 100644 --- a/System.Data.Entity/System/Data/Mapping/ObjectNavigationPropertyMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/ObjectNavigationPropertyMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ObjectPropertyMapping.cs b/System.Data.Entity/System/Data/Mapping/ObjectPropertyMapping.cs index c0a9472f9..61ff5df99 100644 --- a/System.Data.Entity/System/Data/Mapping/ObjectPropertyMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/ObjectPropertyMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ObjectTypeMapping.cs b/System.Data.Entity/System/Data/Mapping/ObjectTypeMapping.cs index ebe68f678..c0f7e7e40 100644 --- a/System.Data.Entity/System/Data/Mapping/ObjectTypeMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/ObjectTypeMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping { diff --git a/System.Data.Entity/System/Data/Mapping/StorageAssociationSetMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageAssociationSetMapping.cs index 577d30411..f2a4f7f28 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageAssociationSetMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageAssociationSetMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/StorageAssociationTypeMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageAssociationTypeMapping.cs index 391865cf6..8ef29bd37 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageAssociationTypeMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageAssociationTypeMapping.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], [....] +// @owner Microsoft, Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/StorageComplexPropertyMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageComplexPropertyMapping.cs index bcc504de8..afa203d18 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageComplexPropertyMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageComplexPropertyMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/StorageComplexTypeMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageComplexTypeMapping.cs index a8fe6a610..cefcdbf04 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageComplexTypeMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageComplexTypeMapping.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], [....] +// @owner Microsoft, Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/StorageConditionPropertyMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageConditionPropertyMapping.cs index d0ee0d38d..5bdf08056 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageConditionPropertyMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageConditionPropertyMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/StorageEndPropertyMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageEndPropertyMapping.cs index a9481990e..b9e1f19bc 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageEndPropertyMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageEndPropertyMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/StorageEntityContainerMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageEntityContainerMapping.cs index 65b8286e3..79082acd4 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageEntityContainerMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageEntityContainerMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/StorageEntitySetMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageEntitySetMapping.cs index 59d2e3812..c96d6f796 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageEntitySetMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageEntitySetMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/StorageEntityTypeMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageEntityTypeMapping.cs index 41575121e..6ed006dca 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageEntityTypeMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageEntityTypeMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/StorageMappingFragment.cs b/System.Data.Entity/System/Data/Mapping/StorageMappingFragment.cs index faa501be9..6c5a11d38 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageMappingFragment.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageMappingFragment.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/StorageMappingItemCollection.ViewDictionary.cs b/System.Data.Entity/System/Data/Mapping/StorageMappingItemCollection.ViewDictionary.cs index c7a1eb015..dcdbffffe 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageMappingItemCollection.ViewDictionary.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageMappingItemCollection.ViewDictionary.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/StorageMappingItemCollection.cs b/System.Data.Entity/System/Data/Mapping/StorageMappingItemCollection.cs index 3bb5addca..5dc038524 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageMappingItemCollection.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageMappingItemCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Concurrent; diff --git a/System.Data.Entity/System/Data/Mapping/StorageMappingItemLoader.cs b/System.Data.Entity/System/Data/Mapping/StorageMappingItemLoader.cs index e065c9ab9..2c808ecf2 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageMappingItemLoader.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageMappingItemLoader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections; diff --git a/System.Data.Entity/System/Data/Mapping/StorageModificationFunctionMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageModificationFunctionMapping.cs index 50e659c6b..32eb36cb7 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageModificationFunctionMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageModificationFunctionMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/StoragePropertyMapping.cs b/System.Data.Entity/System/Data/Mapping/StoragePropertyMapping.cs index 455de5020..b428ed32e 100644 --- a/System.Data.Entity/System/Data/Mapping/StoragePropertyMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StoragePropertyMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/StorageScalarPropertyMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageScalarPropertyMapping.cs index 84ed3c3e3..16b34ed9a 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageScalarPropertyMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageScalarPropertyMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Diagnostics; diff --git a/System.Data.Entity/System/Data/Mapping/StorageSetMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageSetMapping.cs index d281639e8..4da03bdda 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageSetMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageSetMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/StorageTypeMapping.cs b/System.Data.Entity/System/Data/Mapping/StorageTypeMapping.cs index 8d379b498..b5f07a835 100644 --- a/System.Data.Entity/System/Data/Mapping/StorageTypeMapping.cs +++ b/System.Data.Entity/System/Data/Mapping/StorageTypeMapping.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/AssociationSetMetadata.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/AssociationSetMetadata.cs index a3936e775..5037b183a 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/AssociationSetMetadata.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/AssociationSetMetadata.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/ChangeNode.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/ChangeNode.cs index 0008c3ea0..1eabff48f 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/ChangeNode.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/ChangeNode.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/CompositeKey.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/CompositeKey.cs index bb2195d49..b44dafdad 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/CompositeKey.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/CompositeKey.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.Utils; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/DynamicUpdateCommand.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/DynamicUpdateCommand.cs index 0318d9868..3e46e43dd 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/DynamicUpdateCommand.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/DynamicUpdateCommand.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/ExtractedStateEntry.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/ExtractedStateEntry.cs index 82a4dd8e5..aeac41b95 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/ExtractedStateEntry.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/ExtractedStateEntry.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/ExtractorMetadata.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/ExtractorMetadata.cs index 5f4cc16d3..9f7c93219 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/ExtractorMetadata.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/ExtractorMetadata.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.Update.Internal diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/FunctionMappingTranslator.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/FunctionMappingTranslator.cs index 5b4e5b7ad..38dfb65d0 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/FunctionMappingTranslator.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/FunctionMappingTranslator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.Update.Internal diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/FunctionUpdateCommand.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/FunctionUpdateCommand.cs index 8f5b8ae90..a735b2cba 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/FunctionUpdateCommand.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/FunctionUpdateCommand.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.Update.Internal diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/Graph.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/Graph.cs index 72db96c3f..984fdc727 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/Graph.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/Graph.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.Utils; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/KeyManager.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/KeyManager.cs index 3027ad55f..c742f977e 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/KeyManager.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/KeyManager.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.Evaluator.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.Evaluator.cs index eb4d369ac..0e43c6cad 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.Evaluator.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.Evaluator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.Update.Internal diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.ExtentPlaceholderCreator.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.ExtentPlaceholderCreator.cs index 578920ab5..a45bf47ee 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.ExtentPlaceholderCreator.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.ExtentPlaceholderCreator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.Update.Internal diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.JoinPredicateVisitor.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.JoinPredicateVisitor.cs index 48daf01bc..c8845f555 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.JoinPredicateVisitor.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.JoinPredicateVisitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.SubstitutingCloneVisitor.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.SubstitutingCloneVisitor.cs index cc924cef2..f4fa3a2a0 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.SubstitutingCloneVisitor.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.SubstitutingCloneVisitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.cs index e8af9fc11..30ad18fab 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.JoinPropagator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.cs index 799d01892..56ad4f943 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/Propagator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.Update.Internal diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/PropagatorResult.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/PropagatorResult.cs index 44b503576..4cf4b5252 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/PropagatorResult.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/PropagatorResult.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/RecordConverter.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/RecordConverter.cs index 81ff164b6..e6dfbe7ae 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/RecordConverter.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/RecordConverter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.Update.Internal diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/RelationshipConstraintValidator.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/RelationshipConstraintValidator.cs index e1e72226d..aa5e72d1d 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/RelationshipConstraintValidator.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/RelationshipConstraintValidator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.Update.Internal diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/SourceInterpreter.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/SourceInterpreter.cs index 9718ca9fe..245956fb0 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/SourceInterpreter.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/SourceInterpreter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/TableChangeProcessor.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/TableChangeProcessor.cs index 4567d472c..3acae097f 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/TableChangeProcessor.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/TableChangeProcessor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.Update.Internal diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/UndirectedGraph.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/UndirectedGraph.cs index 055dcffd4..0d0e47133 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/UndirectedGraph.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/UndirectedGraph.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.Utils; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCommand.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCommand.cs index 2aa865a3b..4de147195 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCommand.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCommand.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCommandOrderer.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCommandOrderer.cs index 001046534..79ed22c37 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCommandOrderer.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCommandOrderer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.Update.Internal diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCompiler.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCompiler.cs index 97eb4d5b0..925fd2017 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCompiler.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateCompiler.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- // For the purposes of the update compiler, the member name fully describes the member diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateExpressionVisitor.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateExpressionVisitor.cs index f5643a33b..9260ac826 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateExpressionVisitor.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateExpressionVisitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.Update.Internal diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateTranslator.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateTranslator.cs index ca37def4e..73d15d4f5 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateTranslator.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/UpdateTranslator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/Update/Internal/ViewLoader.cs b/System.Data.Entity/System/Data/Mapping/Update/Internal/ViewLoader.cs index 98564d69d..487d6c24d 100644 --- a/System.Data.Entity/System/Data/Mapping/Update/Internal/ViewLoader.cs +++ b/System.Data.Entity/System/Data/Mapping/Update/Internal/ViewLoader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/BasicViewGenerator.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/BasicViewGenerator.cs index 180d906b6..e62348521 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/BasicViewGenerator.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/BasicViewGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration @@ -131,7 +131,7 @@ internal CellTreeNode GroupByRightExtent(CellTreeNode rootNode) foreach (LeafCellTreeNode childNode in rootNode.Children) { // A cell may contain P, P.PA -- we return P - // CHANGE_[....]_FEATURE_COMPOSITION Need to fix for composition!! + // CHANGE_Microsoft_FEATURE_COMPOSITION Need to fix for composition!! EntitySetBase extent = childNode.LeftCellWrapper.RightCellQuery.Extent; // relation or extent to group by Debug.Assert(extent != null, "Each cell must have a right extent"); diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellCreator.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellCreator.cs index c046b6313..e58f58fd6 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellCreator.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellCreator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.Utils; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellPartitioner.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellPartitioner.cs index 5d0c913ee..e4e322dc8 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellPartitioner.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellPartitioner.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellTreeSimplifier.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellTreeSimplifier.cs index 38b12707c..a842a88a7 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellTreeSimplifier.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CellTreeSimplifier.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.Utils; @@ -277,7 +277,7 @@ private static Set GetCommonGrandChildren(List n } // effects: Given a list of node, produces a new list in which all // leaf nodes of the same extent are adjacent to each other. Non-leaf - // nodes are also adjacent to each other. CHANGE_[....]_IMPROVE: Merge with GroupByRightExtent + // nodes are also adjacent to each other. CHANGE_Microsoft_IMPROVE: Merge with GroupByRightExtent private static List GroupLeafChildrenByExtent(List nodes) { // Keep track of leaf cells for each extent diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/ConfigViewGenerator.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/ConfigViewGenerator.cs index 47c59a98a..f771247ae 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/ConfigViewGenerator.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/ConfigViewGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.Utils; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/AliasedSlot.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/AliasedSlot.cs index 6bb05a2b6..499b17c26 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/AliasedSlot.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/AliasedSlot.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Linq; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/BooleanProjectedSlot.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/BooleanProjectedSlot.cs index 79a030baf..113e28387 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/BooleanProjectedSlot.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/BooleanProjectedSlot.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Mapping.ViewGeneration.Structures; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CaseCqlBlock.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CaseCqlBlock.cs index 950e3e963..e8ba88d0a 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CaseCqlBlock.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CaseCqlBlock.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Mapping.ViewGeneration.Structures; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlBlock.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlBlock.cs index 98164a94b..7c4eba699 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlBlock.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlBlock.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Linq; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlIdentifiers.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlIdentifiers.cs index 9c7734fb8..c4db94301 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlIdentifiers.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlIdentifiers.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlWriter.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlWriter.cs index 81fc02884..429ed1b1f 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlWriter.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/CqlWriter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Text.RegularExpressions; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/ExtentCqlBlock.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/ExtentCqlBlock.cs index f85ee2359..c4a679140 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/ExtentCqlBlock.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/ExtentCqlBlock.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Text; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/JoinCqlBlock.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/JoinCqlBlock.cs index 45c0a5f07..408f2a90b 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/JoinCqlBlock.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/JoinCqlBlock.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/SlotInfo.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/SlotInfo.cs index eb2afc5c0..3d33ff07f 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/SlotInfo.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/SlotInfo.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/UnionCqlBlock.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/UnionCqlBlock.cs index 2c7b8c23f..95dffb4d6 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/UnionCqlBlock.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGeneration/UnionCqlBlock.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGenerator.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGenerator.cs index 00988416f..37005f747 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGenerator.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/CqlGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/DiscriminatorMap.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/DiscriminatorMap.cs index 0c7848e3f..5abadcbd1 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/DiscriminatorMap.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/DiscriminatorMap.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/GeneratedView.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/GeneratedView.cs index 3c2c331ce..bec352a06 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/GeneratedView.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/GeneratedView.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQuery.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQuery.cs index 934e2018a..6c94e5038 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQuery.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQuery.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQueryKB.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQueryKB.cs index cffda30fd..ae6ec4120 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQueryKB.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQueryKB.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQueryProcessor.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQueryProcessor.cs index 01754ba8c..f13c6dc47 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQueryProcessor.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/FragmentQueryProcessor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/QueryRewriter.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/QueryRewriter.cs index d209d9f80..60fc38179 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/QueryRewriter.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/QueryRewriter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.QueryRewriting diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingPass.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingPass.cs index 860db188a..ae9abeb5c 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingPass.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingPass.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingProcessor.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingProcessor.cs index df892676b..41c4e1dd9 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingProcessor.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingProcessor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingSimplifier.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingSimplifier.cs index 55d91edbd..4a28e458c 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingSimplifier.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingSimplifier.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingValidator.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingValidator.cs index 4f1d21f57..588dfe0f4 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingValidator.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RewritingValidator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.Validation diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RoleBoolean.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RoleBoolean.cs index 8a1ae2c20..2f944c42f 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RoleBoolean.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/RoleBoolean.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.Structures diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/Tile.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/Tile.cs index 8d490f590..c949b5681 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/Tile.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/QueryRewriting/Tile.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolExpression.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolExpression.cs index c44639280..3fd29a627 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolExpression.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolExpression.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; @@ -366,7 +366,7 @@ internal BoolExpression RemapBool(Dictionary remap) // effects: Given a list of bools, returns a list of boolean expressions where each // boolean in bools has been ANDed with conjunct - // CHANGE_[....]_IMPROVE: replace with lambda pattern + // CHANGE_Microsoft_IMPROVE: replace with lambda pattern internal static List AddConjunctionToBools(List bools, BoolExpression conjunct) { diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolExpressionVisitors.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolExpressionVisitors.cs index fc4c19680..ade70afbb 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolExpressionVisitors.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolExpressionVisitors.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolLiteral.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolLiteral.cs index babeaa62f..64fdf5372 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolLiteral.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/BoolLiteral.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CaseStatement.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CaseStatement.cs index 1c1251178..6e6e4d40d 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CaseStatement.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CaseStatement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CaseStatementProjectedSlot.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CaseStatementProjectedSlot.cs index ee74e3a1b..8cdc34aed 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CaseStatementProjectedSlot.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CaseStatementProjectedSlot.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Mapping.ViewGeneration.CqlGeneration; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Cell.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Cell.cs index 8fa4646bf..d7bc34322 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Cell.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Cell.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.Utils; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellIdBoolean.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellIdBoolean.cs index 251f86b8e..97740718c 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellIdBoolean.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellIdBoolean.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.Structures diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellLabel.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellLabel.cs index 4cc45bfd8..bf02ac8aa 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellLabel.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellLabel.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellQuery.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellQuery.cs index 43f8b6814..3ed84c612 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellQuery.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellQuery.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellTreeNode.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellTreeNode.cs index 6bce7b75e..ecb925ac2 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellTreeNode.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellTreeNode.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.Structures diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellTreeNodeVisitors.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellTreeNodeVisitors.cs index 2c78985a0..351a94165 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellTreeNodeVisitors.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/CellTreeNodeVisitors.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Constant.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Constant.cs index a77b8a4ab..c90fbb668 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Constant.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Constant.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.Structures diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ConstantProjectedSlot.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ConstantProjectedSlot.cs index 93a14b964..4c9c27cbd 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ConstantProjectedSlot.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ConstantProjectedSlot.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Mapping.ViewGeneration.CqlGeneration; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Domain.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Domain.cs index 244c548fc..57b4f8fab 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Domain.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Domain.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; @@ -177,7 +177,7 @@ private static CellConstantSet DeriveDomainFromType(EdmType type, EdmItemCollect // effect: returns the default value for the member // if the member is nullable and has no default, changes default value to CellConstant.NULL and returns true // if the mebmer is not nullable and has no default, returns false - // CHANGE_[....]_FEATURE_DEFAULT_VALUES: return the right default once metadata supports it + // CHANGE_Microsoft_FEATURE_DEFAULT_VALUES: return the right default once metadata supports it internal static bool TryGetDefaultValueForMemberPath(MemberPath memberPath, out Constant defaultConstant) { object defaultValue = memberPath.DefaultValue; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ErrorLog.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ErrorLog.cs index 6b312d1ee..ba65fe75c 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ErrorLog.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ErrorLog.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.Structures diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/LeafCellTreeNode.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/LeafCellTreeNode.cs index bf49103be..5b37f45fc 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/LeafCellTreeNode.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/LeafCellTreeNode.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/LeftCellWrapper.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/LeftCellWrapper.cs index 66778f774..a67833981 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/LeftCellWrapper.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/LeftCellWrapper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberDomainMap.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberDomainMap.cs index 83dbe8c00..47e31c66e 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberDomainMap.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberDomainMap.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.Structures diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberMaps.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberMaps.cs index 3fed309b1..5ecce1d31 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberMaps.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberMaps.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberPath.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberPath.cs index ad0dff468..ba48a1389 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberPath.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberPath.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberProjectedSlot.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberProjectedSlot.cs index a58b37712..b17ce971f 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberProjectedSlot.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberProjectedSlot.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberProjectionIndex.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberProjectionIndex.cs index b508995fe..d36c26c23 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberProjectionIndex.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberProjectionIndex.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberRestriction.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberRestriction.cs index 797e1e675..fc63a2926 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberRestriction.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/MemberRestriction.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/NegatedConstant.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/NegatedConstant.cs index fa8f05cfa..9c671fe6b 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/NegatedConstant.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/NegatedConstant.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.Structures diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/OpCellTreeNode.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/OpCellTreeNode.cs index 362e9ff84..231b1563c 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/OpCellTreeNode.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/OpCellTreeNode.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ProjectedSlot.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ProjectedSlot.cs index 5fda4c615..48e2157c2 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ProjectedSlot.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ProjectedSlot.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.Structures diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/QualifiedCellIdBoolean.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/QualifiedCellIdBoolean.cs index b9800cf93..8ad476f87 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/QualifiedCellIdBoolean.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/QualifiedCellIdBoolean.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ScalarConstant.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ScalarConstant.cs index a7219d6e2..dca95d825 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ScalarConstant.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ScalarConstant.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Text; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ScalarRestriction.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ScalarRestriction.cs index 722aa09c7..59fa8a68f 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ScalarRestriction.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/ScalarRestriction.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/TypeConstant.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/TypeConstant.cs index 6dd961fd2..703f81096 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/TypeConstant.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/TypeConstant.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Text; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/TypeRestriction.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/TypeRestriction.cs index c4cb20d73..a17ef9ea3 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/TypeRestriction.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/TypeRestriction.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/WithStatement.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/WithStatement.cs index d609a2fe7..2d262cf77 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/WithStatement.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/WithStatement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Utils/ExceptionHelpers.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Utils/ExceptionHelpers.cs index 8166c317f..fffdf5ad1 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Utils/ExceptionHelpers.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Utils/ExceptionHelpers.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Text; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Utils/ExternalCalls.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Utils/ExternalCalls.cs index befe9b356..5fb40d871 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Utils/ExternalCalls.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Utils/ExternalCalls.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/BasicCellRelation.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/BasicCellRelation.cs index 366035326..fbd9c76e8 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/BasicCellRelation.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/BasicCellRelation.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved.Bharani1729 // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; @@ -88,7 +88,7 @@ private void PopulateKeyConstraintsForRelationshipSet(BasicSchemaConstraints con { AssociationSet relationshipSet = m_cellQuery.Extent as AssociationSet; // Gather all members of all keys - // CHANGE_[....]_FEATURE_KEYS: assume that an Entity has exactly one key. Otherwise we + // CHANGE_Microsoft_FEATURE_KEYS: assume that an Entity has exactly one key. Otherwise we // have to take a cross-product of all keys // Keep track of all the key members for the association in a set diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/BasicKeyConstraint.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/BasicKeyConstraint.cs index b52c62ee4..299fe131d 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/BasicKeyConstraint.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/BasicKeyConstraint.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/CellRelation.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/CellRelation.cs index 1824b2900..ac9c66cb6 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/CellRelation.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/CellRelation.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ErrorPatternMatcher.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ErrorPatternMatcher.cs index 918b7ff0d..b57ab576f 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ErrorPatternMatcher.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ErrorPatternMatcher.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ExtentKey.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ExtentKey.cs index eceb6063e..a89bf8271 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ExtentKey.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ExtentKey.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- @@ -49,7 +49,7 @@ internal IEnumerable KeyFields // -- prefix is prepended to the entity's key fields to get the full memberpath internal static List GetKeysForEntityType(MemberPath prefix, EntityType entityType) { - // CHANGE_[....]_MULTIPLE_KEYS: currently there is a single key only. Need to support + // CHANGE_Microsoft_MULTIPLE_KEYS: currently there is a single key only. Need to support // keys inside complex types + unique keys ExtentKey key = GetPrimaryKeyForEntityType(prefix, entityType); diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ForeignConstraint.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ForeignConstraint.cs index b4cbd3202..28c9c71a9 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ForeignConstraint.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ForeignConstraint.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/KeyConstraint.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/KeyConstraint.cs index 7de844253..e9de9dcdb 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/KeyConstraint.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/KeyConstraint.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.Utils; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/SchemaConstraints.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/SchemaConstraints.cs index a3eb207a5..8e43ff8f0 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/SchemaConstraints.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/SchemaConstraints.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewCellRelation.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewCellRelation.cs index be91192de..dc4799b9a 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewCellRelation.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewCellRelation.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; @@ -62,7 +62,7 @@ internal Cell Cell // null if it does not find the slot in the left or right side of the viewrelation internal ViewCellSlot LookupViewSlot(MemberProjectedSlot slot) { - // CHANGE_[....]_IMPROVE: We could have a dictionary to speed this up + // CHANGE_Microsoft_IMPROVE: We could have a dictionary to speed this up foreach (ViewCellSlot viewSlot in m_slots) { // If the left or right slots are equal, return the viewSlot diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewCellSlot.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewCellSlot.cs index 9b9fe6921..fea993596 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewCellSlot.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewCellSlot.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.Validation diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewKeyConstraint.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewKeyConstraint.cs index 704c122b1..a8898c241 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewKeyConstraint.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validation/ViewKeyConstraint.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration.Validation diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validator.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validator.cs index a8b380e66..497a193d4 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validator.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/Validator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewGenResults.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewGenResults.cs index 1061c52a5..a0348faf7 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewGenResults.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewGenResults.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.Utils; diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewGenerator.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewGenerator.cs index 8c5618e7a..96d9d83e9 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewGenerator.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; @@ -492,7 +492,7 @@ private static KeyToListMap GroupCellsByExtent(IEnumerable< { // Partition cells by extent -- extent is the top node in - // the tree. Even for compositions for now? CHANGE_[....]_FEATURE_COMPOSITION + // the tree. Even for compositions for now? CHANGE_Microsoft_FEATURE_COMPOSITION KeyToListMap extentCellMap = new KeyToListMap(EqualityComparer.Default); foreach (Cell cell in cells) diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewgenContext.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewgenContext.cs index 50bb0142b..b23ecf6a9 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewgenContext.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewgenContext.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping.ViewGeneration diff --git a/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewgenGatekeeper.cs b/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewgenGatekeeper.cs index f7a1d4113..20bf0b8be 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewgenGatekeeper.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewGeneration/ViewgenGatekeeper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Mapping/ViewValidator.cs b/System.Data.Entity/System/Data/Mapping/ViewValidator.cs index 2ab3c302c..cce9f4315 100644 --- a/System.Data.Entity/System/Data/Mapping/ViewValidator.cs +++ b/System.Data.Entity/System/Data/Mapping/ViewValidator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Mapping diff --git a/System.Data.Entity/System/Data/MappingException.cs b/System.Data.Entity/System/Data/MappingException.cs index 4c8e9d1c5..0cd23d838 100644 --- a/System.Data.Entity/System/Data/MappingException.cs +++ b/System.Data.Entity/System/Data/MappingException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data diff --git a/System.Data.Entity/System/Data/Metadata/AspProxy.cs b/System.Data.Entity/System/Data/Metadata/AspProxy.cs index cf39195f0..440497527 100644 --- a/System.Data.Entity/System/Data/Metadata/AspProxy.cs +++ b/System.Data.Entity/System/Data/Metadata/AspProxy.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/CacheForPrimitiveTypes.cs b/System.Data.Entity/System/Data/Metadata/CacheForPrimitiveTypes.cs index 100159b7c..cc3c04e0c 100644 --- a/System.Data.Entity/System/Data/Metadata/CacheForPrimitiveTypes.cs +++ b/System.Data.Entity/System/Data/Metadata/CacheForPrimitiveTypes.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/ClrPerspective.cs b/System.Data.Entity/System/Data/Metadata/ClrPerspective.cs index 708896590..96cb27bb7 100644 --- a/System.Data.Entity/System/Data/Metadata/ClrPerspective.cs +++ b/System.Data.Entity/System/Data/Metadata/ClrPerspective.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/Converter.cs b/System.Data.Entity/System/Data/Metadata/Converter.cs index eb4e61ec3..40d2b765e 100644 --- a/System.Data.Entity/System/Data/Metadata/Converter.cs +++ b/System.Data.Entity/System/Data/Metadata/Converter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/CustomAssemblyResolver.cs b/System.Data.Entity/System/Data/Metadata/CustomAssemblyResolver.cs index 2ed13e505..608bdd56c 100644 --- a/System.Data.Entity/System/Data/Metadata/CustomAssemblyResolver.cs +++ b/System.Data.Entity/System/Data/Metadata/CustomAssemblyResolver.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm { diff --git a/System.Data.Entity/System/Data/Metadata/DefaultAssemblyResolver.cs b/System.Data.Entity/System/Data/Metadata/DefaultAssemblyResolver.cs index a5abcab9c..134045fee 100644 --- a/System.Data.Entity/System/Data/Metadata/DefaultAssemblyResolver.cs +++ b/System.Data.Entity/System/Data/Metadata/DefaultAssemblyResolver.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Reflection; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/AssociationEndMember.cs b/System.Data.Entity/System/Data/Metadata/Edm/AssociationEndMember.cs index 48490fa5e..33511243f 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/AssociationEndMember.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/AssociationEndMember.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/AssociationSet.cs b/System.Data.Entity/System/Data/Metadata/Edm/AssociationSet.cs index e0d165556..64df1f868 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/AssociationSet.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/AssociationSet.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/AssociationSetEnd.cs b/System.Data.Entity/System/Data/Metadata/Edm/AssociationSetEnd.cs index 3fe246c32..b6c5cbd43 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/AssociationSetEnd.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/AssociationSetEnd.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/AssociationType.cs b/System.Data.Entity/System/Data/Metadata/Edm/AssociationType.cs index bc7283105..f12462b1c 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/AssociationType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/AssociationType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/CollectionType.cs b/System.Data.Entity/System/Data/Metadata/Edm/CollectionType.cs index 27f49ab65..debab7686 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/CollectionType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/CollectionType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/ComplexType.cs b/System.Data.Entity/System/Data/Metadata/Edm/ComplexType.cs index b3aa9751c..ad0fe21a1 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/ComplexType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/ComplexType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common; using System.Threading; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/Documentation.cs b/System.Data.Entity/System/Data/Metadata/Edm/Documentation.cs index 38f6d3d35..c036a9c0e 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/Documentation.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/Documentation.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EdmConstants.cs b/System.Data.Entity/System/Data/Metadata/Edm/EdmConstants.cs index 45ce070b2..b85a830d4 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EdmConstants.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EdmConstants.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EdmFunction.cs b/System.Data.Entity/System/Data/Metadata/Edm/EdmFunction.cs index a9c0b1672..29632cdfb 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EdmFunction.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EdmFunction.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EdmMember.cs b/System.Data.Entity/System/Data/Metadata/Edm/EdmMember.cs index 2a5f5c8d8..e04b01429 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EdmMember.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EdmMember.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EdmProperty.cs b/System.Data.Entity/System/Data/Metadata/Edm/EdmProperty.cs index 0d42381f4..b1529dde6 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EdmProperty.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EdmProperty.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EdmType.cs b/System.Data.Entity/System/Data/Metadata/Edm/EdmType.cs index 39a25ab74..c324b5475 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EdmType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EdmType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common; using System.Globalization; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EntityContainer.cs b/System.Data.Entity/System/Data/Metadata/Edm/EntityContainer.cs index e04b365e3..a51c2f59c 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EntityContainer.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EntityContainer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EntitySet.cs b/System.Data.Entity/System/Data/Metadata/Edm/EntitySet.cs index d22fccf9b..500c7b269 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EntitySet.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EntitySet.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EntitySetBase.cs b/System.Data.Entity/System/Data/Metadata/Edm/EntitySetBase.cs index 0679dfe8a..8b09606a6 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EntitySetBase.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EntitySetBase.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EntitySetBaseCollection.cs b/System.Data.Entity/System/Data/Metadata/Edm/EntitySetBaseCollection.cs index 72ba6079d..e0a884a84 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EntitySetBaseCollection.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EntitySetBaseCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EntityType.cs b/System.Data.Entity/System/Data/Metadata/Edm/EntityType.cs index 65f780409..60d95712d 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EntityType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EntityType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EntityTypeBase.cs b/System.Data.Entity/System/Data/Metadata/Edm/EntityTypeBase.cs index d3776b976..da5951871 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EntityTypeBase.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EntityTypeBase.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm { @@ -80,7 +80,7 @@ internal string[] KeyMemberNames } _keyMemberNames = keyNames; } - Debug.Assert(_keyMemberNames.Length == this.KeyMembers.Count, "This list is out of [....] with the key members count. This property was called before all the keymembers were added"); + Debug.Assert(_keyMemberNames.Length == this.KeyMembers.Count, "This list is out of sync with the key members count. This property was called before all the keymembers were added"); return _keyMemberNames; } } diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EnumMember.cs b/System.Data.Entity/System/Data/Metadata/Edm/EnumMember.cs index da510a866..ef089ea63 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EnumMember.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EnumMember.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/EnumType.cs b/System.Data.Entity/System/Data/Metadata/Edm/EnumType.cs index 29488511a..1c4df323c 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/EnumType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/EnumType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/Edm/Facet.cs b/System.Data.Entity/System/Data/Metadata/Edm/Facet.cs index 5e985eb5a..af7f75517 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/Facet.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/Facet.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/Edm/FacetDescription.cs b/System.Data.Entity/System/Data/Metadata/Edm/FacetDescription.cs index 3bb0c373d..4a8670c27 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/FacetDescription.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/FacetDescription.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/FacetValueContainer.cs b/System.Data.Entity/System/Data/Metadata/Edm/FacetValueContainer.cs index ef7173e62..d87d9a593 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/FacetValueContainer.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/FacetValueContainer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/FacetValues.cs b/System.Data.Entity/System/Data/Metadata/Edm/FacetValues.cs index 93cba7cd8..25cf2a8c4 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/FacetValues.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/FacetValues.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/FilteredReadOnlyMetadataCollection.cs b/System.Data.Entity/System/Data/Metadata/Edm/FilteredReadOnlyMetadataCollection.cs index 6595c4602..a29f99ad9 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/FilteredReadOnlyMetadataCollection.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/FilteredReadOnlyMetadataCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/FunctionParameter.cs b/System.Data.Entity/System/Data/Metadata/Edm/FunctionParameter.cs index 005a5db56..326e416c8 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/FunctionParameter.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/FunctionParameter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/GlobalItem.cs b/System.Data.Entity/System/Data/Metadata/Edm/GlobalItem.cs index 1e1e1517d..4b768e481 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/GlobalItem.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/GlobalItem.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/ItemCollection.cs b/System.Data.Entity/System/Data/Metadata/Edm/ItemCollection.cs index d04aa0731..de0b94047 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/ItemCollection.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/ItemCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/Edm/LightweightCodeGenerator.cs b/System.Data.Entity/System/Data/Metadata/Edm/LightweightCodeGenerator.cs index fc0e9e2a5..cc60a7a0f 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/LightweightCodeGenerator.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/LightweightCodeGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects diff --git a/System.Data.Entity/System/Data/Metadata/Edm/MemberCollection.cs b/System.Data.Entity/System/Data/Metadata/Edm/MemberCollection.cs index c2f9cbd86..155f65559 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/MemberCollection.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/MemberCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/MetadataCollection.cs b/System.Data.Entity/System/Data/Metadata/Edm/MetadataCollection.cs index 36535c8a0..e62dd919b 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/MetadataCollection.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/MetadataCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; @@ -28,7 +28,7 @@ internal class MetadataCollection : IList where T : MetadataItem // The way the collection supports both case sensitive and insensitive search is that it maintains two lists: one list // for keep tracking of the order (the ordered list) and another list sorted case sensitively (the sorted list) by the // identity of the item. When a look up on ordinal is requested, the ordered list is used. When a look up on the name - // is requested, the sorted list is used. The two list must be kept in [....] for all update operations. For case + // is requested, the sorted list is used. The two list must be kept in sync for all update operations. For case // sensitive name lookup, the sorted list is searched. For case insensitive name lookup, a binary search is used on the // sorted list to find the match. diff --git a/System.Data.Entity/System/Data/Metadata/Edm/MetadataItem.cs b/System.Data.Entity/System/Data/Metadata/Edm/MetadataItem.cs index a99c0292b..04e93f764 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/MetadataItem.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/MetadataItem.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/MetadataItem_Static.cs b/System.Data.Entity/System/Data/Metadata/Edm/MetadataItem_Static.cs index 126c4b7a9..e8da22d70 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/MetadataItem_Static.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/MetadataItem_Static.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Data.Common; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/MetadataProperty.cs b/System.Data.Entity/System/Data/Metadata/Edm/MetadataProperty.cs index b8ac93d07..0fe365f08 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/MetadataProperty.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/MetadataProperty.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyAttribute.cs b/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyAttribute.cs index 471301f36..3e0684456 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyAttribute.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyCollection.cs b/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyCollection.cs index 6ae122150..b8119608c 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyCollection.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyvalue.cs b/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyvalue.cs index 26897499b..8fdb0eca6 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyvalue.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/MetadataPropertyvalue.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/NavigationProperty.cs b/System.Data.Entity/System/Data/Metadata/Edm/NavigationProperty.cs index 721725925..e8525f7cc 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/NavigationProperty.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/NavigationProperty.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Data.Common; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/NavigationPropertyAccessor.cs b/System.Data.Entity/System/Data/Metadata/Edm/NavigationPropertyAccessor.cs index 52a8949ac..d9e8da11d 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/NavigationPropertyAccessor.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/NavigationPropertyAccessor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/PrimitiveType.cs b/System.Data.Entity/System/Data/Metadata/Edm/PrimitiveType.cs index 5e644eb56..89ccf2a65 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/PrimitiveType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/PrimitiveType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Data.Common; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/Provider/ClrProviderManifest.cs b/System.Data.Entity/System/Data/Metadata/Edm/Provider/ClrProviderManifest.cs index 82627c485..126408018 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/Provider/ClrProviderManifest.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/Provider/ClrProviderManifest.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifest.cs b/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifest.cs index cb2f50ddb..372fabbca 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifest.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifest.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifestFunctionBuilder.cs b/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifestFunctionBuilder.cs index fbbf97d8c..69d4bf334 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifestFunctionBuilder.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifestFunctionBuilder.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifestSpatialFunctions.cs b/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifestSpatialFunctions.cs index 19fc7d196..b34b15786 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifestSpatialFunctions.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/Provider/EdmProviderManifestSpatialFunctions.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //-------------------------------------------------------------------------- // This file is automatically generated and should not be changed directly. // diff --git a/System.Data.Entity/System/Data/Metadata/Edm/ReadOnlyMetadataCollection.cs b/System.Data.Entity/System/Data/Metadata/Edm/ReadOnlyMetadataCollection.cs index 3f60afa59..cc964f3ee 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/ReadOnlyMetadataCollection.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/ReadOnlyMetadataCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/RefType.cs b/System.Data.Entity/System/Data/Metadata/Edm/RefType.cs index d33335f4e..8c8184cbb 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/RefType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/RefType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/ReferentialConstraint.cs b/System.Data.Entity/System/Data/Metadata/Edm/ReferentialConstraint.cs index 71295ba55..051d7bfea 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/ReferentialConstraint.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/ReferentialConstraint.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/RelationshipEndMember.cs b/System.Data.Entity/System/Data/Metadata/Edm/RelationshipEndMember.cs index 4a635d82d..81225a715 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/RelationshipEndMember.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/RelationshipEndMember.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/RelationshipSet.cs b/System.Data.Entity/System/Data/Metadata/Edm/RelationshipSet.cs index f4714eccf..39ba5e07a 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/RelationshipSet.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/RelationshipSet.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/RelationshipType.cs b/System.Data.Entity/System/Data/Metadata/Edm/RelationshipType.cs index 46c0107a6..1e3b04274 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/RelationshipType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/RelationshipType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/RowType.cs b/System.Data.Entity/System/Data/Metadata/Edm/RowType.cs index 0b954067d..3285477da 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/RowType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/RowType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/SafeLink.cs b/System.Data.Entity/System/Data/Metadata/Edm/SafeLink.cs index 22e4126b5..563a8b5d1 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/SafeLink.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/SafeLink.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //---------------------------------------------------------------------using System; using System.Collections.Generic; using System.Linq; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/SafeLinkCollection.cs b/System.Data.Entity/System/Data/Metadata/Edm/SafeLinkCollection.cs index 39a0c85d9..43b3fa00f 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/SafeLinkCollection.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/SafeLinkCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/SimpleType.cs b/System.Data.Entity/System/Data/Metadata/Edm/SimpleType.cs index 554cbcdc7..82c07fbd4 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/SimpleType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/SimpleType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/StructuralType.cs b/System.Data.Entity/System/Data/Metadata/Edm/StructuralType.cs index 66fe1c7e2..dea24673f 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/StructuralType.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/StructuralType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/Edm/TypeUsage.cs b/System.Data.Entity/System/Data/Metadata/Edm/TypeUsage.cs index 29308e0a4..308c2bc68 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/TypeUsage.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/TypeUsage.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/Edm/util.cs b/System.Data.Entity/System/Data/Metadata/Edm/util.cs index b54adc330..3ea3b7036 100644 --- a/System.Data.Entity/System/Data/Metadata/Edm/util.cs +++ b/System.Data.Entity/System/Data/Metadata/Edm/util.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/EdmError.cs b/System.Data.Entity/System/Data/Metadata/EdmError.cs index 883a09574..e2915eed0 100644 --- a/System.Data.Entity/System/Data/Metadata/EdmError.cs +++ b/System.Data.Entity/System/Data/Metadata/EdmError.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/EdmItemCollection.OcAssemblyCache.cs b/System.Data.Entity/System/Data/Metadata/EdmItemCollection.OcAssemblyCache.cs index b6cf23948..19f0082a3 100644 --- a/System.Data.Entity/System/Data/Metadata/EdmItemCollection.OcAssemblyCache.cs +++ b/System.Data.Entity/System/Data/Metadata/EdmItemCollection.OcAssemblyCache.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Reflection; diff --git a/System.Data.Entity/System/Data/Metadata/EdmItemCollection.cs b/System.Data.Entity/System/Data/Metadata/EdmItemCollection.cs index 570ad901c..ca1d2be40 100644 --- a/System.Data.Entity/System/Data/Metadata/EdmItemCollection.cs +++ b/System.Data.Entity/System/Data/Metadata/EdmItemCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm { diff --git a/System.Data.Entity/System/Data/Metadata/EdmItemError.cs b/System.Data.Entity/System/Data/Metadata/EdmItemError.cs index feee36878..c18d3a5ca 100644 --- a/System.Data.Entity/System/Data/Metadata/EdmItemError.cs +++ b/System.Data.Entity/System/Data/Metadata/EdmItemError.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/EdmSchemaError.cs b/System.Data.Entity/System/Data/Metadata/EdmSchemaError.cs index 7769c0938..e6a143183 100644 --- a/System.Data.Entity/System/Data/Metadata/EdmSchemaError.cs +++ b/System.Data.Entity/System/Data/Metadata/EdmSchemaError.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/EdmValidator.cs b/System.Data.Entity/System/Data/Metadata/EdmValidator.cs index 45822d9d4..9aca70f70 100644 --- a/System.Data.Entity/System/Data/Metadata/EdmValidator.cs +++ b/System.Data.Entity/System/Data/Metadata/EdmValidator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/Helper.cs b/System.Data.Entity/System/Data/Metadata/Helper.cs index 392270ccd..ac6358abf 100644 --- a/System.Data.Entity/System/Data/Metadata/Helper.cs +++ b/System.Data.Entity/System/Data/Metadata/Helper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/MappingMetadataHelper.cs b/System.Data.Entity/System/Data/Metadata/MappingMetadataHelper.cs index 80fefe077..38916861f 100644 --- a/System.Data.Entity/System/Data/Metadata/MappingMetadataHelper.cs +++ b/System.Data.Entity/System/Data/Metadata/MappingMetadataHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm { diff --git a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoader.cs b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoader.cs index d393a6b4d..215b129f8 100644 --- a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoader.cs +++ b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderComposite.cs b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderComposite.cs index 0338f5466..3f1a54b1f 100644 --- a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderComposite.cs +++ b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderComposite.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderCompositeFile.cs b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderCompositeFile.cs index f81c3bffd..77769e760 100644 --- a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderCompositeFile.cs +++ b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderCompositeFile.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderCompositeResource.cs b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderCompositeResource.cs index 959e6617f..344a60e79 100644 --- a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderCompositeResource.cs +++ b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderCompositeResource.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderFile.cs b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderFile.cs index 3fd746c44..ca04d7a87 100644 --- a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderFile.cs +++ b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderFile.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderResource.cs b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderResource.cs index 7b6927c64..419e2f1f0 100644 --- a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderResource.cs +++ b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderResource.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderXmlReaderWrapper.cs b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderXmlReaderWrapper.cs index 8624eb4bf..e83fa0c9a 100644 --- a/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderXmlReaderWrapper.cs +++ b/System.Data.Entity/System/Data/Metadata/MetadataArtifactLoaderXmlReaderWrapper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/MetadataCache.cs b/System.Data.Entity/System/Data/Metadata/MetadataCache.cs index d9701d510..340a26d7f 100644 --- a/System.Data.Entity/System/Data/Metadata/MetadataCache.cs +++ b/System.Data.Entity/System/Data/Metadata/MetadataCache.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/MetadataWorkspace.cs b/System.Data.Entity/System/Data/Metadata/MetadataWorkspace.cs index 065255828..831428fee 100644 --- a/System.Data.Entity/System/Data/Metadata/MetadataWorkspace.cs +++ b/System.Data.Entity/System/Data/Metadata/MetadataWorkspace.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/ModelPerspective.cs b/System.Data.Entity/System/Data/Metadata/ModelPerspective.cs index 855de302a..90cc7b12f 100644 --- a/System.Data.Entity/System/Data/Metadata/ModelPerspective.cs +++ b/System.Data.Entity/System/Data/Metadata/ModelPerspective.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/ObjectHelper.cs b/System.Data.Entity/System/Data/Metadata/ObjectHelper.cs index 6d966224d..abde1abf2 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectHelper.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Mapping; diff --git a/System.Data.Entity/System/Data/Metadata/ObjectItemCollection.cs b/System.Data.Entity/System/Data/Metadata/ObjectItemCollection.cs index ccbb10a43..2c79eb40d 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectItemCollection.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectItemCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/AssemblyCache.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/AssemblyCache.cs index 02d09f98b..1c8a8b9fe 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/AssemblyCache.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/AssemblyCache.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/AssemblyCacheEntry.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/AssemblyCacheEntry.cs index fdaab763c..b5c6ec4f6 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/AssemblyCacheEntry.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/AssemblyCacheEntry.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ImmutableAssemblyCacheEntry.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ImmutableAssemblyCacheEntry.cs index e6804614e..f21a47597 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ImmutableAssemblyCacheEntry.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ImmutableAssemblyCacheEntry.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/KnownAssembliesSet.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/KnownAssembliesSet.cs index 608f707ef..116233108 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/KnownAssembliesSet.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/KnownAssembliesSet.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/KnownAssemblyEntry.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/KnownAssemblyEntry.cs index 2a59d2d69..ca0b6bd37 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/KnownAssemblyEntry.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/KnownAssemblyEntry.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/LoadMessageLogger.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/LoadMessageLogger.cs index 911045164..e4501a214 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/LoadMessageLogger.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/LoadMessageLogger.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm { diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/LockedAssemblyCache.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/LockedAssemblyCache.cs index 43ef352db..a81ccee2c 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/LockedAssemblyCache.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/LockedAssemblyCache.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/MetadataAssemblyHelper.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/MetadataAssemblyHelper.cs index 7229c3b83..ebaad4ec1 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/MetadataAssemblyHelper.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/MetadataAssemblyHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Reflection; diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/MutableAssemblyCacheEntry.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/MutableAssemblyCacheEntry.cs index e17dcb220..f44d9d1d1 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/MutableAssemblyCacheEntry.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/MutableAssemblyCacheEntry.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemAssemblyLoader.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemAssemblyLoader.cs index a394eecea..bbadb7cc5 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemAssemblyLoader.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemAssemblyLoader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemAttributeAssemblyLoader.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemAttributeAssemblyLoader.cs index 610f1f067..c54f6bbd7 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemAttributeAssemblyLoader.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemAttributeAssemblyLoader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemCachedAssemblyLoader.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemCachedAssemblyLoader.cs index d1db7caeb..9cf8fae6e 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemCachedAssemblyLoader.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemCachedAssemblyLoader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemConventionAssemblyLoader.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemConventionAssemblyLoader.cs index d6f3c2dda..a336bab04 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemConventionAssemblyLoader.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemConventionAssemblyLoader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemLoadingSessionData.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemLoadingSessionData.cs index bfb63d99f..f033bc476 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemLoadingSessionData.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemLoadingSessionData.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Reflection; using System.Linq; diff --git a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemNoOpAssemblyLoader.cs b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemNoOpAssemblyLoader.cs index 87c4d7d3e..45a60e927 100644 --- a/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemNoOpAssemblyLoader.cs +++ b/System.Data.Entity/System/Data/Metadata/ObjectLayer/ObjectItemNoOpAssemblyLoader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Reflection; diff --git a/System.Data.Entity/System/Data/Metadata/Perspective.cs b/System.Data.Entity/System/Data/Metadata/Perspective.cs index b3834ecef..c8f6ff312 100644 --- a/System.Data.Entity/System/Data/Metadata/Perspective.cs +++ b/System.Data.Entity/System/Data/Metadata/Perspective.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Diagnostics; using System.Linq; diff --git a/System.Data.Entity/System/Data/Metadata/StoreItemCollection.Loader.cs b/System.Data.Entity/System/Data/Metadata/StoreItemCollection.Loader.cs index ede35e321..0583ffef5 100644 --- a/System.Data.Entity/System/Data/Metadata/StoreItemCollection.Loader.cs +++ b/System.Data.Entity/System/Data/Metadata/StoreItemCollection.Loader.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm { diff --git a/System.Data.Entity/System/Data/Metadata/StoreItemCollection.cs b/System.Data.Entity/System/Data/Metadata/StoreItemCollection.cs index 8d3db3692..585dfca18 100644 --- a/System.Data.Entity/System/Data/Metadata/StoreItemCollection.cs +++ b/System.Data.Entity/System/Data/Metadata/StoreItemCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm { diff --git a/System.Data.Entity/System/Data/Metadata/TargetPerspective.cs b/System.Data.Entity/System/Data/Metadata/TargetPerspective.cs index 372a6d867..4f52bfdd8 100644 --- a/System.Data.Entity/System/Data/Metadata/TargetPerspective.cs +++ b/System.Data.Entity/System/Data/Metadata/TargetPerspective.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Metadata.Edm diff --git a/System.Data.Entity/System/Data/Metadata/TypeHelpers.cs b/System.Data.Entity/System/Data/Metadata/TypeHelpers.cs index a3f8e6394..a08529d31 100644 --- a/System.Data.Entity/System/Data/Metadata/TypeHelpers.cs +++ b/System.Data.Entity/System/Data/Metadata/TypeHelpers.cs @@ -3,8 +3,8 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Common diff --git a/System.Data.Entity/System/Data/Metadata/TypeSemantics.cs b/System.Data.Entity/System/Data/Metadata/TypeSemantics.cs index 5142269ba..0c0df5560 100644 --- a/System.Data.Entity/System/Data/Metadata/TypeSemantics.cs +++ b/System.Data.Entity/System/Data/Metadata/TypeSemantics.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/MetadataException.cs b/System.Data.Entity/System/Data/MetadataException.cs index 67eafde4e..bd0cfb075 100644 --- a/System.Data.Entity/System/Data/MetadataException.cs +++ b/System.Data.Entity/System/Data/MetadataException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data diff --git a/System.Data.Entity/System/Data/ObjectNotFoundException.cs b/System.Data.Entity/System/Data/ObjectNotFoundException.cs index d0496ab15..9247b2e59 100644 --- a/System.Data.Entity/System/Data/ObjectNotFoundException.cs +++ b/System.Data.Entity/System/Data/ObjectNotFoundException.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], nkline +// @owner Microsoft, nkline //--------------------------------------------------------------------- namespace System.Data diff --git a/System.Data.Entity/System/Data/Objects/AdditionalEntityFunctions.cs b/System.Data.Entity/System/Data/Objects/AdditionalEntityFunctions.cs index 2ca2abe88..36c949997 100644 --- a/System.Data.Entity/System/Data/Objects/AdditionalEntityFunctions.cs +++ b/System.Data.Entity/System/Data/Objects/AdditionalEntityFunctions.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects { diff --git a/System.Data.Entity/System/Data/Objects/CompiledQuery.cs b/System.Data.Entity/System/Data/Objects/CompiledQuery.cs index 96f6bb6be..c3f31fb4b 100644 --- a/System.Data.Entity/System/Data/Objects/CompiledQuery.cs +++ b/System.Data.Entity/System/Data/Objects/CompiledQuery.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupowner [....] +// @owner Microsoft +// @backupowner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/ComplexObject.cs b/System.Data.Entity/System/Data/Objects/DataClasses/ComplexObject.cs index c63108a63..fd606f818 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/ComplexObject.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/ComplexObject.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data; using System.Diagnostics; diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EdmComplexPropertyAttribute.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EdmComplexPropertyAttribute.cs index 61a7498be..857cc0432 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EdmComplexPropertyAttribute.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EdmComplexPropertyAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EdmComplexTypeAttribute.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EdmComplexTypeAttribute.cs index 6f4d556f0..05f2fcc71 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EdmComplexTypeAttribute.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EdmComplexTypeAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EdmEntityTypeAttribute.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EdmEntityTypeAttribute.cs index 495c0fdee..79b9c4bc3 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EdmEntityTypeAttribute.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EdmEntityTypeAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EdmEnumTypeAttribute.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EdmEnumTypeAttribute.cs index 01e1acce1..208b57f3c 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EdmEnumTypeAttribute.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EdmEnumTypeAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EdmFunctionAttribute.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EdmFunctionAttribute.cs index af990b078..59029670e 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EdmFunctionAttribute.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EdmFunctionAttribute.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EdmPropertyAttribute.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EdmPropertyAttribute.cs index 0897a9d25..e9d288628 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EdmPropertyAttribute.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EdmPropertyAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EdmRelationshipNavigationPropertyAttribute.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EdmRelationshipNavigationPropertyAttribute.cs index e94eeb442..3ce546554 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EdmRelationshipNavigationPropertyAttribute.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EdmRelationshipNavigationPropertyAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EdmRelationshipRoleAttribute.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EdmRelationshipRoleAttribute.cs index fb36665f8..45694e622 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EdmRelationshipRoleAttribute.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EdmRelationshipRoleAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Metadata.Edm; //for RelationshipMultiplicity diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EdmScalarPropertyAttribute.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EdmScalarPropertyAttribute.cs index 13d23f82d..ddf8d9398 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EdmScalarPropertyAttribute.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EdmScalarPropertyAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EdmSchemaAttribute.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EdmSchemaAttribute.cs index eec9c4c9a..e52f33554 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EdmSchemaAttribute.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EdmSchemaAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EdmTypeAttribute.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EdmTypeAttribute.cs index 097fd72cb..cdac80497 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EdmTypeAttribute.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EdmTypeAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EntityCollection.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EntityCollection.cs index 0f1f0cc60..4b1da9fd4 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EntityCollection.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EntityCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EntityObject.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EntityObject.cs index 08e8dd69a..028698fe9 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EntityObject.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EntityObject.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data; using System.Diagnostics; diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EntityReference.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EntityReference.cs index 5a7b1c84e..48acf77e5 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EntityReference.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EntityReference.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/EntityReference_TResultType.cs b/System.Data.Entity/System/Data/Objects/DataClasses/EntityReference_TResultType.cs index c18e9638f..29b355682 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/EntityReference_TResultType.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/EntityReference_TResultType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/RelatedEnd.cs b/System.Data.Entity/System/Data/Objects/DataClasses/RelatedEnd.cs index e89a660d4..073c79de2 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/RelatedEnd.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/RelatedEnd.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipFixer.cs b/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipFixer.cs index 4621064d8..40b72aed2 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipFixer.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipFixer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipManager.cs b/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipManager.cs index 32c092397..dd3a40854 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipManager.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipManager.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.DataClasses { diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipNavigation.cs b/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipNavigation.cs index 66dcba0ec..82295b743 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipNavigation.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/RelationshipNavigation.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Objects/DataClasses/StructuralObject.cs b/System.Data.Entity/System/Data/Objects/DataClasses/StructuralObject.cs index 900af0333..acda94e3d 100644 --- a/System.Data.Entity/System/Data/Objects/DataClasses/StructuralObject.cs +++ b/System.Data.Entity/System/Data/Objects/DataClasses/StructuralObject.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data; using System.Diagnostics; diff --git a/System.Data.Entity/System/Data/Objects/DataRecordObjectView.cs b/System.Data.Entity/System/Data/Objects/DataRecordObjectView.cs index 5869bf86b..f00b88296 100644 --- a/System.Data.Entity/System/Data/Objects/DataRecordObjectView.cs +++ b/System.Data.Entity/System/Data/Objects/DataRecordObjectView.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections; @@ -63,8 +63,8 @@ internal DataRecordObjectView(IObjectViewData viewData, object eve /// /// The algorithm here is lifted from System.Windows.Forms.ListBindingHelper, /// from the GetTypedIndexer method. - /// The Entity Framework could not take a dependency on [....], - /// so we lifted the appropriate parts from the [....] code here. + /// The Entity Framework could not take a dependency on Microsoft, + /// so we lifted the appropriate parts from the Microsoft code here. /// Not the best, but much better than guessing as to what algorithm is proper for data binding. /// private static PropertyInfo GetTypedIndexer(Type type) @@ -106,8 +106,8 @@ private static PropertyInfo GetTypedIndexer(Type type) /// /// The algorithm here is lifted from System.Windows.Forms.ListBindingHelper, /// from the GetListItemType(object) method. - /// The Entity Framework could not take a dependency on [....], - /// so we lifted the appropriate parts from the [....] code here. + /// The Entity Framework could not take a dependency on Microsoft, + /// so we lifted the appropriate parts from the Microsoft code here. /// Not the best, but much better than guessing as to what algorithm is proper for data binding. /// private static Type GetListItemType(Type type) diff --git a/System.Data.Entity/System/Data/Objects/ELinq/BindingContext.cs b/System.Data.Entity/System/Data/Objects/ELinq/BindingContext.cs index eeb849f9b..5a3cb738b 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/BindingContext.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/BindingContext.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- using CqtExpression = System.Data.Common.CommandTrees.DbExpression; diff --git a/System.Data.Entity/System/Data/Objects/ELinq/CompiledELinqQueryState.cs b/System.Data.Entity/System/Data/Objects/ELinq/CompiledELinqQueryState.cs index 0b7aa97d3..d072e7c3b 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/CompiledELinqQueryState.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/CompiledELinqQueryState.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq diff --git a/System.Data.Entity/System/Data/Objects/ELinq/ELinqQueryState.cs b/System.Data.Entity/System/Data/Objects/ELinq/ELinqQueryState.cs index 6a68bcb8b..ec98b5bb6 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/ELinqQueryState.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/ELinqQueryState.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq diff --git a/System.Data.Entity/System/Data/Objects/ELinq/ExpressionConverter.cs b/System.Data.Entity/System/Data/Objects/ELinq/ExpressionConverter.cs index 95c65e884..424cc99fe 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/ExpressionConverter.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/ExpressionConverter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq diff --git a/System.Data.Entity/System/Data/Objects/ELinq/ExpressionVisitorHelpers.cs b/System.Data.Entity/System/Data/Objects/ELinq/ExpressionVisitorHelpers.cs index 3f0060f41..90853b143 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/ExpressionVisitorHelpers.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/ExpressionVisitorHelpers.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Linq.Expressions.Internal diff --git a/System.Data.Entity/System/Data/Objects/ELinq/Funcletizer.cs b/System.Data.Entity/System/Data/Objects/ELinq/Funcletizer.cs index 7b45f33dd..ab12b11cc 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/Funcletizer.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/Funcletizer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq diff --git a/System.Data.Entity/System/Data/Objects/ELinq/InitializerFacet.cs b/System.Data.Entity/System/Data/Objects/ELinq/InitializerFacet.cs index b6e7adc53..207b73973 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/InitializerFacet.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/InitializerFacet.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq diff --git a/System.Data.Entity/System/Data/Objects/ELinq/LinqExpressionNormalizer.cs b/System.Data.Entity/System/Data/Objects/ELinq/LinqExpressionNormalizer.cs index 1a2e9d353..e6042b498 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/LinqExpressionNormalizer.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/LinqExpressionNormalizer.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], [....] +// @owner Microsoft, Microsoft //--------------------------------------------------------------------- using System.Linq.Expressions; diff --git a/System.Data.Entity/System/Data/Objects/ELinq/MethodCallTranslator.cs b/System.Data.Entity/System/Data/Objects/ELinq/MethodCallTranslator.cs index 247357fb4..b0f2bbade 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/MethodCallTranslator.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/MethodCallTranslator.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], [....] +// @owner Microsoft, Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq diff --git a/System.Data.Entity/System/Data/Objects/ELinq/ObjectQueryProvider.cs b/System.Data.Entity/System/Data/Objects/ELinq/ObjectQueryProvider.cs index fafc18ce0..9999435a9 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/ObjectQueryProvider.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/ObjectQueryProvider.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq diff --git a/System.Data.Entity/System/Data/Objects/ELinq/OrderByLifter.cs b/System.Data.Entity/System/Data/Objects/ELinq/OrderByLifter.cs index e32e423a2..cf0ccb54b 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/OrderByLifter.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/OrderByLifter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq diff --git a/System.Data.Entity/System/Data/Objects/ELinq/ReflectionUtil.cs b/System.Data.Entity/System/Data/Objects/ELinq/ReflectionUtil.cs index 86559d6b4..95a9af21f 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/ReflectionUtil.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/ReflectionUtil.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- using System.Reflection; diff --git a/System.Data.Entity/System/Data/Objects/ELinq/SpatialMethodCallTranslator.cs b/System.Data.Entity/System/Data/Objects/ELinq/SpatialMethodCallTranslator.cs index 2eb958f02..cfcc26232 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/SpatialMethodCallTranslator.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/SpatialMethodCallTranslator.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //-------------------------------------------------------------------------- // This file is automatically generated and should not be changed directly. // diff --git a/System.Data.Entity/System/Data/Objects/ELinq/SpatialPropertyTranslator.cs b/System.Data.Entity/System/Data/Objects/ELinq/SpatialPropertyTranslator.cs index c16cee7d5..84dc51270 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/SpatialPropertyTranslator.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/SpatialPropertyTranslator.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //-------------------------------------------------------------------------- // This file is automatically generated and should not be changed directly. // diff --git a/System.Data.Entity/System/Data/Objects/ELinq/Translator.cs b/System.Data.Entity/System/Data/Objects/ELinq/Translator.cs index 53ae3be39..5a4f283f1 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/Translator.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/Translator.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....], [....] +// @owner Microsoft, Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq diff --git a/System.Data.Entity/System/Data/Objects/ELinq/TypeSystem.cs b/System.Data.Entity/System/Data/Objects/ELinq/TypeSystem.cs index 1d0e4a7f1..f7fbc08f6 100644 --- a/System.Data.Entity/System/Data/Objects/ELinq/TypeSystem.cs +++ b/System.Data.Entity/System/Data/Objects/ELinq/TypeSystem.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq diff --git a/System.Data.Entity/System/Data/Objects/EntityEntry.cs b/System.Data.Entity/System/Data/Objects/EntityEntry.cs index efeddc674..ef96bb424 100644 --- a/System.Data.Entity/System/Data/Objects/EntityEntry.cs +++ b/System.Data.Entity/System/Data/Objects/EntityEntry.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects { diff --git a/System.Data.Entity/System/Data/Objects/EntityFunctions.cs b/System.Data.Entity/System/Data/Objects/EntityFunctions.cs index 879f3af5c..51a6eea6a 100644 --- a/System.Data.Entity/System/Data/Objects/EntityFunctions.cs +++ b/System.Data.Entity/System/Data/Objects/EntityFunctions.cs @@ -10,8 +10,8 @@ // Changes to this file will be lost if the code is regenerated. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Objects/FieldDescriptor.cs b/System.Data.Entity/System/Data/Objects/FieldDescriptor.cs index fd5ef4e00..f2bb8cf6f 100644 --- a/System.Data.Entity/System/Data/Objects/FieldDescriptor.cs +++ b/System.Data.Entity/System/Data/Objects/FieldDescriptor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections; diff --git a/System.Data.Entity/System/Data/Objects/Internal/BaseEntityWrapper.cs b/System.Data.Entity/System/Data/Objects/Internal/BaseEntityWrapper.cs index 7c4e91ac3..8278f03a9 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/BaseEntityWrapper.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/BaseEntityWrapper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections; using System.Data.Objects.DataClasses; diff --git a/System.Data.Entity/System/Data/Objects/Internal/ComplexTypeMaterializer.cs b/System.Data.Entity/System/Data/Objects/Internal/ComplexTypeMaterializer.cs index 44f963f3a..d4916b2c5 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/ComplexTypeMaterializer.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/ComplexTypeMaterializer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/Objects/Internal/EntityProxyFactory.cs b/System.Data.Entity/System/Data/Objects/Internal/EntityProxyFactory.cs index 0de1b08a4..385cb5b23 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/EntityProxyFactory.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/EntityProxyFactory.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.Internal diff --git a/System.Data.Entity/System/Data/Objects/Internal/EntityProxyTypeInfo.cs b/System.Data.Entity/System/Data/Objects/Internal/EntityProxyTypeInfo.cs index a301deb03..67b9ce1f7 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/EntityProxyTypeInfo.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/EntityProxyTypeInfo.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.Internal diff --git a/System.Data.Entity/System/Data/Objects/Internal/EntitySqlQueryBuilder.cs b/System.Data.Entity/System/Data/Objects/Internal/EntitySqlQueryBuilder.cs index eb994d425..f757170e4 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/EntitySqlQueryBuilder.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/EntitySqlQueryBuilder.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.Internal diff --git a/System.Data.Entity/System/Data/Objects/Internal/EntitySqlQueryState.cs b/System.Data.Entity/System/Data/Objects/Internal/EntitySqlQueryState.cs index 63b4ca4e6..40d6b1f62 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/EntitySqlQueryState.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/EntitySqlQueryState.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects diff --git a/System.Data.Entity/System/Data/Objects/Internal/EntityWrapper.cs b/System.Data.Entity/System/Data/Objects/Internal/EntityWrapper.cs index 8f06e08b9..95f18d39a 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/EntityWrapper.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/EntityWrapper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections; using System.Data.Objects.DataClasses; diff --git a/System.Data.Entity/System/Data/Objects/Internal/EntityWrapperFactory.cs b/System.Data.Entity/System/Data/Objects/Internal/EntityWrapperFactory.cs index bfbb201b7..a337615de 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/EntityWrapperFactory.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/EntityWrapperFactory.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Objects.DataClasses; using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/Objects/Internal/LazyLoadBehavior.cs b/System.Data.Entity/System/Data/Objects/Internal/LazyLoadBehavior.cs index 06276f934..6806c05cd 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/LazyLoadBehavior.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/LazyLoadBehavior.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Objects/Internal/LightweightEntityWrapper.cs b/System.Data.Entity/System/Data/Objects/Internal/LightweightEntityWrapper.cs index 76cae2fa8..874b4c0d0 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/LightweightEntityWrapper.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/LightweightEntityWrapper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections; using System.Data.Objects.DataClasses; diff --git a/System.Data.Entity/System/Data/Objects/Internal/NullEntityWrapper.cs b/System.Data.Entity/System/Data/Objects/Internal/NullEntityWrapper.cs index 0273238b7..9590660d0 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/NullEntityWrapper.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/NullEntityWrapper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.Internal { diff --git a/System.Data.Entity/System/Data/Objects/Internal/ObjectFullSpanRewriter.cs b/System.Data.Entity/System/Data/Objects/Internal/ObjectFullSpanRewriter.cs index d8a4c861e..2d54ed02c 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/ObjectFullSpanRewriter.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/ObjectFullSpanRewriter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupowner [....] +// @owner Microsoft +// @backupowner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.Internal diff --git a/System.Data.Entity/System/Data/Objects/Internal/ObjectQueryExecutionPlan.cs b/System.Data.Entity/System/Data/Objects/Internal/ObjectQueryExecutionPlan.cs index 78f35d033..43ca97936 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/ObjectQueryExecutionPlan.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/ObjectQueryExecutionPlan.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.Internal diff --git a/System.Data.Entity/System/Data/Objects/Internal/ObjectQueryState.cs b/System.Data.Entity/System/Data/Objects/Internal/ObjectQueryState.cs index 06d5d0841..8c958ea14 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/ObjectQueryState.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/ObjectQueryState.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects.Internal diff --git a/System.Data.Entity/System/Data/Objects/Internal/ObjectSpanRewriter.cs b/System.Data.Entity/System/Data/Objects/Internal/ObjectSpanRewriter.cs index 3dcb85b7c..2469adc8b 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/ObjectSpanRewriter.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/ObjectSpanRewriter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupowner [....] +// @owner Microsoft +// @backupowner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Objects/Internal/TransactionManager.cs b/System.Data.Entity/System/Data/Objects/Internal/TransactionManager.cs index 240963625..92352278e 100644 --- a/System.Data.Entity/System/Data/Objects/Internal/TransactionManager.cs +++ b/System.Data.Entity/System/Data/Objects/Internal/TransactionManager.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- // // Internal class used to manage ObjectStateManager's transactions for diff --git a/System.Data.Entity/System/Data/Objects/ObjectContext.cs b/System.Data.Entity/System/Data/Objects/ObjectContext.cs index df6204519..49b58de7c 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectContext.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectContext.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects @@ -3034,7 +3034,7 @@ public int ExecuteStoreCommand(string commandText, params object[] parameters) /// The query specified in the server's native query language. /// The parameter values to use for the query. /// An IEnumerable sequence of objects. - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] public ObjectResult ExecuteStoreQuery(string commandText, params object[] parameters) { return ExecuteStoreQueryInternal(commandText, null /*entitySetName*/, MergeOption.AppendOnly, parameters); @@ -3049,7 +3049,7 @@ public ObjectResult ExecuteStoreQuery(string commandText, pa /// The entity set in which results should be tracked. Null indicates there is no entity set. /// Merge option to use for entity results. /// The translated sequence of objects - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] public ObjectResult ExecuteStoreQuery(string commandText, string entitySetName, MergeOption mergeOption, params object[] parameters) { EntityUtil.CheckStringArgument(entitySetName, "entitySetName"); @@ -3106,7 +3106,7 @@ private ObjectResult ExecuteStoreQueryInternal(string comman /// The DbDataReader to translate /// Merge option to use for entity results. /// The translated sequence of objects - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] public ObjectResult Translate(DbDataReader reader) { // SQLBUDT 447285: Ensure the assembly containing the entity's CLR type @@ -3130,7 +3130,7 @@ public ObjectResult Translate(DbDataReader reader) /// The entity set in which results should be tracked. Null indicates there is no entity set. /// Merge option to use for entity results. /// The translated sequence of objects - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] public ObjectResult Translate(DbDataReader reader, string entitySetName, MergeOption mergeOption) { EntityUtil.CheckStringArgument(entitySetName, "entitySetName"); diff --git a/System.Data.Entity/System/Data/Objects/ObjectMaterializedEventArgs.cs b/System.Data.Entity/System/Data/Objects/ObjectMaterializedEventArgs.cs index 4b269fba2..26bd5a012 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectMaterializedEventArgs.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectMaterializedEventArgs.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Objects/ObjectParameter.cs b/System.Data.Entity/System/Data/Objects/ObjectParameter.cs index 2939ae7b9..4390811bc 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectParameter.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectParameter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupowner [....] +// @owner Microsoft +// @backupowner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects diff --git a/System.Data.Entity/System/Data/Objects/ObjectParameterCollection.cs b/System.Data.Entity/System/Data/Objects/ObjectParameterCollection.cs index bd314d2e1..7efb20d55 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectParameterCollection.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectParameterCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupowner [....] +// @owner Microsoft +// @backupowner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects diff --git a/System.Data.Entity/System/Data/Objects/ObjectQuery.cs b/System.Data.Entity/System/Data/Objects/ObjectQuery.cs index bd2868425..b8041ee41 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectQuery.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectQuery.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupowner [....] +// @owner Microsoft +// @backupowner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects diff --git a/System.Data.Entity/System/Data/Objects/ObjectQuery_EntitySqlExtensions.cs b/System.Data.Entity/System/Data/Objects/ObjectQuery_EntitySqlExtensions.cs index 36d85f3ee..10c751301 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectQuery_EntitySqlExtensions.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectQuery_EntitySqlExtensions.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupowner [....] +// @owner Microsoft +// @backupowner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects diff --git a/System.Data.Entity/System/Data/Objects/ObjectQuery_TResultType.cs b/System.Data.Entity/System/Data/Objects/ObjectQuery_TResultType.cs index bb459b661..e5acd60fe 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectQuery_TResultType.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectQuery_TResultType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupowner [....] +// @owner Microsoft +// @backupowner Microsoft //--------------------------------------------------------------------- using System.Collections; diff --git a/System.Data.Entity/System/Data/Objects/ObjectResult.cs b/System.Data.Entity/System/Data/Objects/ObjectResult.cs index 4b3bcb868..0c1197921 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectResult.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectResult.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupowner [....] +// @owner Microsoft +// @backupowner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects diff --git a/System.Data.Entity/System/Data/Objects/ObjectResult_TResultType.cs b/System.Data.Entity/System/Data/Objects/ObjectResult_TResultType.cs index 4b764e236..89643315a 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectResult_TResultType.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectResult_TResultType.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupowner [....] +// @owner Microsoft +// @backupowner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects diff --git a/System.Data.Entity/System/Data/Objects/ObjectSet.cs b/System.Data.Entity/System/Data/Objects/ObjectSet.cs index 94ffdbcab..3d5c4a02c 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectSet.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectSet.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- // ObjectSet is a wrapper around ObjectQuery and CUD diff --git a/System.Data.Entity/System/Data/Objects/ObjectStateEntry.cs b/System.Data.Entity/System/Data/Objects/ObjectStateEntry.cs index 388559d75..5d069e2ba 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectStateEntry.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectStateEntry.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Data.Common; diff --git a/System.Data.Entity/System/Data/Objects/ObjectStateEntryBaseUpdatableDataRecord.cs b/System.Data.Entity/System/Data/Objects/ObjectStateEntryBaseUpdatableDataRecord.cs index 72e6a8ce1..3006ec920 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectStateEntryBaseUpdatableDataRecord.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectStateEntryBaseUpdatableDataRecord.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.ComponentModel; diff --git a/System.Data.Entity/System/Data/Objects/ObjectStateEntryDbDataRecord.cs b/System.Data.Entity/System/Data/Objects/ObjectStateEntryDbDataRecord.cs index cda0af00f..5b763db4a 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectStateEntryDbDataRecord.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectStateEntryDbDataRecord.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Objects/ObjectStateEntryDbUpdatableDataRecord.cs b/System.Data.Entity/System/Data/Objects/ObjectStateEntryDbUpdatableDataRecord.cs index 08a0551c5..768828d89 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectStateEntryDbUpdatableDataRecord.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectStateEntryDbUpdatableDataRecord.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.ComponentModel; diff --git a/System.Data.Entity/System/Data/Objects/ObjectStateEntryOriginalDbUpdatableDataRecord.cs b/System.Data.Entity/System/Data/Objects/ObjectStateEntryOriginalDbUpdatableDataRecord.cs index 56c4c0f8a..e16a62b70 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectStateEntryOriginalDbUpdatableDataRecord.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectStateEntryOriginalDbUpdatableDataRecord.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.ComponentModel; diff --git a/System.Data.Entity/System/Data/Objects/ObjectStateManager.cs b/System.Data.Entity/System/Data/Objects/ObjectStateManager.cs index 9657c208b..842891518 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectStateManager.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectStateManager.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects @@ -2131,7 +2131,7 @@ private void ResetEntityKey(EntityEntry entry, EntityKey value) _inRelationshipFixup = false; } - // Keeping the entity and entry keys in [....]. + // Keeping the entity and entry keys in sync. entry.EntityKey = value; //Internally, entry.EntityKey asserts that entry._entityKey and entityWithKey.EntityKey are equal. @@ -3553,7 +3553,7 @@ private void PerformDelete(IList entries) reference.IsForeignKey && reference.IsDependentEndOfReferentialConstraint(checkIdentifying: false)) { - // Ensure that the cached FK value on the reference is in [....] because it is possible that we + // Ensure that the cached FK value on the reference is in sync because it is possible that we // didn't take any actions above that would cause this to be set. reference.SetCachedForeignKey(ForeignKeyFactory.CreateKeyFromForeignKeyValues(entry, reference), entry); } diff --git a/System.Data.Entity/System/Data/Objects/ObjectStateManagerMetadata.cs b/System.Data.Entity/System/Data/Objects/ObjectStateManagerMetadata.cs index 2f078289b..81e861695 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectStateManagerMetadata.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectStateManagerMetadata.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Objects/ObjectView.cs b/System.Data.Entity/System/Data/Objects/ObjectView.cs index acd5c3aa2..0adbd0b50 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectView.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectView.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections; diff --git a/System.Data.Entity/System/Data/Objects/ObjectViewEntityCollectionData.cs b/System.Data.Entity/System/Data/Objects/ObjectViewEntityCollectionData.cs index de89b3a48..0f91fb37d 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectViewEntityCollectionData.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectViewEntityCollectionData.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Objects/ObjectViewFactory.cs b/System.Data.Entity/System/Data/Objects/ObjectViewFactory.cs index 9c803f7bd..94bed62f1 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectViewFactory.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectViewFactory.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections; diff --git a/System.Data.Entity/System/Data/Objects/ObjectViewListener.cs b/System.Data.Entity/System/Data/Objects/ObjectViewListener.cs index 326ca561b..f26e293c8 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectViewListener.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectViewListener.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections; diff --git a/System.Data.Entity/System/Data/Objects/ObjectViewQueryResultData.cs b/System.Data.Entity/System/Data/Objects/ObjectViewQueryResultData.cs index 1f1eb2958..dd79ce434 100644 --- a/System.Data.Entity/System/Data/Objects/ObjectViewQueryResultData.cs +++ b/System.Data.Entity/System/Data/Objects/ObjectViewQueryResultData.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections; diff --git a/System.Data.Entity/System/Data/Objects/ProxyDataContractResolver.cs b/System.Data.Entity/System/Data/Objects/ProxyDataContractResolver.cs index 251a18ed5..4435cbc82 100644 --- a/System.Data.Entity/System/Data/Objects/ProxyDataContractResolver.cs +++ b/System.Data.Entity/System/Data/Objects/ProxyDataContractResolver.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Objects/RelationshipEntry.cs b/System.Data.Entity/System/Data/Objects/RelationshipEntry.cs index d3a7e9418..de19216f6 100644 --- a/System.Data.Entity/System/Data/Objects/RelationshipEntry.cs +++ b/System.Data.Entity/System/Data/Objects/RelationshipEntry.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects { diff --git a/System.Data.Entity/System/Data/Objects/RelationshipWrapper.cs b/System.Data.Entity/System/Data/Objects/RelationshipWrapper.cs index e3f4a297f..2aa42ba86 100644 --- a/System.Data.Entity/System/Data/Objects/RelationshipWrapper.cs +++ b/System.Data.Entity/System/Data/Objects/RelationshipWrapper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Objects/Span.cs b/System.Data.Entity/System/Data/Objects/Span.cs index c74e95d95..28482f31e 100644 --- a/System.Data.Entity/System/Data/Objects/Span.cs +++ b/System.Data.Entity/System/Data/Objects/Span.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Objects diff --git a/System.Data.Entity/System/Data/Objects/SpanIndex.cs b/System.Data.Entity/System/Data/Objects/SpanIndex.cs index 921eed602..151f06a22 100644 --- a/System.Data.Entity/System/Data/Objects/SpanIndex.cs +++ b/System.Data.Entity/System/Data/Objects/SpanIndex.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupowner [....] +// @owner Microsoft +// @backupowner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Objects/SqlClient/SqlFunctions.cs b/System.Data.Entity/System/Data/Objects/SqlClient/SqlFunctions.cs index d5745f568..0d9a53bd2 100644 --- a/System.Data.Entity/System/Data/Objects/SqlClient/SqlFunctions.cs +++ b/System.Data.Entity/System/Data/Objects/SqlClient/SqlFunctions.cs @@ -10,8 +10,8 @@ // Changes to this file will be lost if the code is regenerated. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Objects/SqlClient/SqlSpatialFunctions.cs b/System.Data.Entity/System/Data/Objects/SqlClient/SqlSpatialFunctions.cs index 3dd9e3aad..1c1dd30bb 100644 --- a/System.Data.Entity/System/Data/Objects/SqlClient/SqlSpatialFunctions.cs +++ b/System.Data.Entity/System/Data/Objects/SqlClient/SqlSpatialFunctions.cs @@ -10,8 +10,8 @@ // Changes to this file will be lost if the code is regenerated. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/OptimisticConcurrencyException.cs b/System.Data.Entity/System/Data/OptimisticConcurrencyException.cs index 6a38eb00c..9a911e5d2 100644 --- a/System.Data.Entity/System/Data/OptimisticConcurrencyException.cs +++ b/System.Data.Entity/System/Data/OptimisticConcurrencyException.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- namespace System.Data diff --git a/System.Data.Entity/System/Data/PropertyConstraintException.cs b/System.Data.Entity/System/Data/PropertyConstraintException.cs index 034e96170..ff231df5a 100644 --- a/System.Data.Entity/System/Data/PropertyConstraintException.cs +++ b/System.Data.Entity/System/Data/PropertyConstraintException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- diff --git a/System.Data.Entity/System/Data/ProviderIncompatibleException.cs b/System.Data.Entity/System/Data/ProviderIncompatibleException.cs index f15b3a5ed..8b3a5dad1 100644 --- a/System.Data.Entity/System/Data/ProviderIncompatibleException.cs +++ b/System.Data.Entity/System/Data/ProviderIncompatibleException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/AncillaryOps.cs b/System.Data.Entity/System/Data/Query/InternalTrees/AncillaryOps.cs index e2f4c3ad4..624c6db17 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/AncillaryOps.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/AncillaryOps.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMap.cs b/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMap.cs index 5616d7744..541441845 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMap.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMap.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapCopier.cs b/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapCopier.cs index edc63cc51..723aeae7f 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapCopier.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapCopier.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapFactory.cs b/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapFactory.cs index 7ba71b132..b000d40e8 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapFactory.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapVisitor.cs b/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapVisitor.cs index 5f717d4cd..1c95e226b 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapVisitor.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/ColumnMapVisitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Query.InternalTrees diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/Command.cs b/System.Data.Entity/System/Data/Query/InternalTrees/Command.cs index 7f16a5a68..0dabf7fa1 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/Command.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/Command.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/Dump.cs b/System.Data.Entity/System/Data/Query/InternalTrees/Dump.cs index a7fecfd71..8933a9946 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/Dump.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/Dump.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/ExplicitDiscriminatorMap.cs b/System.Data.Entity/System/Data/Query/InternalTrees/ExplicitDiscriminatorMap.cs index 9376a4d3e..594d9d4e6 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/ExplicitDiscriminatorMap.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/ExplicitDiscriminatorMap.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/Metadata.cs b/System.Data.Entity/System/Data/Query/InternalTrees/Metadata.cs index acb8bc50b..5ee20c008 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/Metadata.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/Metadata.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/NodeCounter.cs b/System.Data.Entity/System/Data/Query/InternalTrees/NodeCounter.cs index 77690a6ad..5261c4858 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/NodeCounter.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/NodeCounter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/NodeInfo.cs b/System.Data.Entity/System/Data/Query/InternalTrees/NodeInfo.cs index c169ff2f1..0043eb94b 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/NodeInfo.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/NodeInfo.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/Nodes.cs b/System.Data.Entity/System/Data/Query/InternalTrees/Nodes.cs index 639678818..d8c3bcc4a 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/Nodes.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/Nodes.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/OpCopier.cs b/System.Data.Entity/System/Data/Query/InternalTrees/OpCopier.cs index d083bf8e4..864ae4f80 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/OpCopier.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/OpCopier.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- // Interesting cases: Unnest diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/Ops.cs b/System.Data.Entity/System/Data/Query/InternalTrees/Ops.cs index 5f2ef19de..ffa517fde 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/Ops.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/Ops.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Query.InternalTrees diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/PhysicalOps.cs b/System.Data.Entity/System/Data/Query/InternalTrees/PhysicalOps.cs index 4a6c55295..932a39e14 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/PhysicalOps.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/PhysicalOps.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/RelOps.cs b/System.Data.Entity/System/Data/Query/InternalTrees/RelOps.cs index 2f69f2fe6..4e513fd7c 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/RelOps.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/RelOps.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/RelPropertyHelper.cs b/System.Data.Entity/System/Data/Query/InternalTrees/RelPropertyHelper.cs index 75ff85423..de5fb678f 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/RelPropertyHelper.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/RelPropertyHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/Rule.cs b/System.Data.Entity/System/Data/Query/InternalTrees/Rule.cs index b75f77f8b..b766b729d 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/Rule.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/Rule.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/RulePatternOps.cs b/System.Data.Entity/System/Data/Query/InternalTrees/RulePatternOps.cs index add95f189..ec10161a8 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/RulePatternOps.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/RulePatternOps.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/RuleProcessor.cs b/System.Data.Entity/System/Data/Query/InternalTrees/RuleProcessor.cs index 98e344496..2d43a1cb7 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/RuleProcessor.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/RuleProcessor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/ScalarOps.cs b/System.Data.Entity/System/Data/Query/InternalTrees/ScalarOps.cs index f02af32dc..c9c554ad6 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/ScalarOps.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/ScalarOps.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/Vars.cs b/System.Data.Entity/System/Data/Query/InternalTrees/Vars.cs index b9f865f5e..de6ed1425 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/Vars.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/Vars.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/InternalTrees/Visitors.cs b/System.Data.Entity/System/Data/Query/InternalTrees/Visitors.cs index 6dc5c0f5f..73d0a5de3 100644 --- a/System.Data.Entity/System/Data/Query/InternalTrees/Visitors.cs +++ b/System.Data.Entity/System/Data/Query/InternalTrees/Visitors.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Query.InternalTrees diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/AggregatePushdown.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/AggregatePushdown.cs index 9bf364d3b..db69808fa 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/AggregatePushdown.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/AggregatePushdown.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/CTreeGenerator.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/CTreeGenerator.cs index 62aa38cec..98e9d1d3b 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/CTreeGenerator.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/CTreeGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- //using System.Diagnostics; // Please use PlanCompiler.Assert instead of Debug.Assert in this class... @@ -1047,7 +1047,7 @@ public override DbExpression Visit(CastOp op, Node n) /// public override DbExpression Visit(SoftCastOp op, Node n) { - // [....] 9/21/06 - temporarily removing check here + // Microsoft 9/21/06 - temporarily removing check here // because the assert wrongly fails in some cases where the types are promotable, // but the facets are not. Put this back when that issue is solved. // diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/CodeGen.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/CodeGen.cs index 6d762ddef..2d8ad0d32 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/CodeGen.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/CodeGen.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/ColumnMapProcessor.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/ColumnMapProcessor.cs index e32537304..d2d6aa35c 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/ColumnMapProcessor.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/ColumnMapProcessor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/ColumnMapTranslator.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/ColumnMapTranslator.cs index a6b1ad761..793729bde 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/ColumnMapTranslator.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/ColumnMapTranslator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/CommandPlan.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/CommandPlan.cs index 3cbfa654f..afafe6188 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/CommandPlan.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/CommandPlan.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/ConstraintManager.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/ConstraintManager.cs index 70c0f09db..483fd2d00 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/ConstraintManager.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/ConstraintManager.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/ITreeGenerator.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/ITreeGenerator.cs index a32447777..6998a5568 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/ITreeGenerator.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/ITreeGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- //using System.Diagnostics; // Please use PlanCompiler.Assert instead of Debug.Assert in this class... diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/JoinElimination.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/JoinElimination.cs index f157f9cf3..82daa4395 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/JoinElimination.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/JoinElimination.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/JoinGraph.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/JoinGraph.cs index 170d81de8..fe5e6dbd5 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/JoinGraph.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/JoinGraph.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/KeyPullup.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/KeyPullup.cs index 976c8adc1..7a39349c2 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/KeyPullup.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/KeyPullup.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/NestPullup.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/NestPullup.cs index 41b2629eb..875f213c4 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/NestPullup.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/NestPullup.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; @@ -2161,7 +2161,7 @@ private Node ConvertToSingleStreamNest(Node nestNode, Dictionary KeyVec drivingNodeKeys = Command.PullupKeys(drivingNode); if (drivingNodeKeys.NoKeys) { - // [....]: In this case we used to wrap drivingNode into a projection that would also project Edm.NewGuid() thus giving us a synthetic key. + // Microsoft: In this case we used to wrap drivingNode into a projection that would also project Edm.NewGuid() thus giving us a synthetic key. // This solution did not work however due to a bug in SQL Server that allowed pulling non-deterministic functions above joins and applies, thus // producing incorrect results. SQL Server bug was filed in "sqlbuvsts01\Sql Server" database as #725272. // The only known path how we can get a keyless drivingNode is if diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/NominalTypeEliminator.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/NominalTypeEliminator.cs index 5cdb77d54..1b248fc59 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/NominalTypeEliminator.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/NominalTypeEliminator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/Normalizer.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/Normalizer.cs index f41d761c7..f780e6b3c 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/Normalizer.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/Normalizer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/PlanCompiler.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/PlanCompiler.cs index 32bdecec2..f58f7ff54 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/PlanCompiler.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/PlanCompiler.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/PlanCompilerUtil.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/PlanCompilerUtil.cs index 4a92d1bbd..7a3f91e64 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/PlanCompilerUtil.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/PlanCompilerUtil.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/PreProcessor.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/PreProcessor.cs index b3a359ed1..412249a1b 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/PreProcessor.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/PreProcessor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- //using System.Diagnostics; // Please use PlanCompiler.Assert instead of Debug.Assert in this class... diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/Predicate.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/Predicate.cs index f977e3a03..39bbeb37e 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/Predicate.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/Predicate.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/ProjectionPruner.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/ProjectionPruner.cs index 9c91918b7..412494ef0 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/ProjectionPruner.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/ProjectionPruner.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/PropertyPushdownHelper.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/PropertyPushdownHelper.cs index 32bcd16df..c45c29b82 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/PropertyPushdownHelper.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/PropertyPushdownHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/PropertyRef.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/PropertyRef.cs index f23a813a3..103296c73 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/PropertyRef.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/PropertyRef.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/ProviderCommandInfoUtils.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/ProviderCommandInfoUtils.cs index 4d81cb045..1e1978f87 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/ProviderCommandInfoUtils.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/ProviderCommandInfoUtils.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/StructuredTypeInfo.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/StructuredTypeInfo.cs index 149274a41..688911b9b 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/StructuredTypeInfo.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/StructuredTypeInfo.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/SubqueryTrackingVisitor.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/SubqueryTrackingVisitor.cs index 6ec1d822c..437a0cc3e 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/SubqueryTrackingVisitor.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/SubqueryTrackingVisitor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/TransformationRules.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/TransformationRules.cs index 99ace7694..947bb1ef3 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/TransformationRules.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/TransformationRules.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/TypeInfo.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/TypeInfo.cs index b76210602..d87b08c64 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/TypeInfo.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/TypeInfo.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/TypeUtils.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/TypeUtils.cs index c0bc872b5..daf8c53a8 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/TypeUtils.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/TypeUtils.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/VarInfo.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/VarInfo.cs index a3c7575f3..b207bd75b 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/VarInfo.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/VarInfo.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/VarRefManager.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/VarRefManager.cs index cea3d2d86..a996bbc08 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/VarRefManager.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/VarRefManager.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/PlanCompiler/VarRemapper.cs b/System.Data.Entity/System/Data/Query/PlanCompiler/VarRemapper.cs index e700c5416..df62621b5 100644 --- a/System.Data.Entity/System/Data/Query/PlanCompiler/VarRemapper.cs +++ b/System.Data.Entity/System/Data/Query/PlanCompiler/VarRemapper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/Query/ResultAssembly/BridgeDataReader.cs b/System.Data.Entity/System/Data/Query/ResultAssembly/BridgeDataReader.cs index 0e2c6696e..1fb083d05 100644 --- a/System.Data.Entity/System/Data/Query/ResultAssembly/BridgeDataReader.cs +++ b/System.Data.Entity/System/Data/Query/ResultAssembly/BridgeDataReader.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Query.ResultAssembly { diff --git a/System.Data.Entity/System/Data/Query/ResultAssembly/BridgeDataRecord.cs b/System.Data.Entity/System/Data/Query/ResultAssembly/BridgeDataRecord.cs index 2e8af6ba6..997a26479 100644 --- a/System.Data.Entity/System/Data/Query/ResultAssembly/BridgeDataRecord.cs +++ b/System.Data.Entity/System/Data/Query/ResultAssembly/BridgeDataRecord.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Query.ResultAssembly { diff --git a/System.Data.Entity/System/Data/Spatial/DbGeography.cs b/System.Data.Entity/System/Data/Spatial/DbGeography.cs index 43a680f7b..37ed063d3 100644 --- a/System.Data.Entity/System/Data/Spatial/DbGeography.cs +++ b/System.Data.Entity/System/Data/Spatial/DbGeography.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Data.Common.Internal; diff --git a/System.Data.Entity/System/Data/Spatial/DbGeographyWellKnownValue.cs b/System.Data.Entity/System/Data/Spatial/DbGeographyWellKnownValue.cs index 575afd3e3..38cab49fe 100644 --- a/System.Data.Entity/System/Data/Spatial/DbGeographyWellKnownValue.cs +++ b/System.Data.Entity/System/Data/Spatial/DbGeographyWellKnownValue.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Runtime.Serialization; diff --git a/System.Data.Entity/System/Data/Spatial/DbGeometry.cs b/System.Data.Entity/System/Data/Spatial/DbGeometry.cs index 53b79d8ac..8dd321698 100644 --- a/System.Data.Entity/System/Data/Spatial/DbGeometry.cs +++ b/System.Data.Entity/System/Data/Spatial/DbGeometry.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Data.Common.Internal; diff --git a/System.Data.Entity/System/Data/Spatial/DbGeometryWellKnownValue.cs b/System.Data.Entity/System/Data/Spatial/DbGeometryWellKnownValue.cs index ec64ff979..411faca56 100644 --- a/System.Data.Entity/System/Data/Spatial/DbGeometryWellKnownValue.cs +++ b/System.Data.Entity/System/Data/Spatial/DbGeometryWellKnownValue.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Runtime.Serialization; diff --git a/System.Data.Entity/System/Data/Spatial/DbSpatialServices.cs b/System.Data.Entity/System/Data/Spatial/DbSpatialServices.cs index e248ee0ca..2650b3e44 100644 --- a/System.Data.Entity/System/Data/Spatial/DbSpatialServices.cs +++ b/System.Data.Entity/System/Data/Spatial/DbSpatialServices.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Data.Common.Utils; diff --git a/System.Data.Entity/System/Data/Spatial/DefaultSpatialServices.cs b/System.Data.Entity/System/Data/Spatial/DefaultSpatialServices.cs index 0552d5a0a..70768b841 100644 --- a/System.Data.Entity/System/Data/Spatial/DefaultSpatialServices.cs +++ b/System.Data.Entity/System/Data/Spatial/DefaultSpatialServices.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Data.Common.Internal; diff --git a/System.Data.Entity/System/Data/Spatial/ExtensionMethods.cs b/System.Data.Entity/System/Data/Spatial/ExtensionMethods.cs index 010b131af..47f885566 100644 --- a/System.Data.Entity/System/Data/Spatial/ExtensionMethods.cs +++ b/System.Data.Entity/System/Data/Spatial/ExtensionMethods.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Data.Spatial.Internal; diff --git a/System.Data.Entity/System/Data/Spatial/Internal/SpatialExceptions.cs b/System.Data.Entity/System/Data/Spatial/Internal/SpatialExceptions.cs index bd7744137..2a9a718bb 100644 --- a/System.Data.Entity/System/Data/Spatial/Internal/SpatialExceptions.cs +++ b/System.Data.Entity/System/Data/Spatial/Internal/SpatialExceptions.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.Spatial.Internal diff --git a/System.Data.Entity/System/Data/Spatial/SpatialHelpers.cs b/System.Data.Entity/System/Data/Spatial/SpatialHelpers.cs index df940de75..af25ebd1a 100644 --- a/System.Data.Entity/System/Data/Spatial/SpatialHelpers.cs +++ b/System.Data.Entity/System/Data/Spatial/SpatialHelpers.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; using System.Data.Metadata.Edm; diff --git a/System.Data.Entity/System/Data/SqlClient/IDbSpatialValue.cs b/System.Data.Entity/System/Data/SqlClient/IDbSpatialValue.cs index 9334ccfa3..ab7dd297c 100644 --- a/System.Data.Entity/System/Data/SqlClient/IDbSpatialValue.cs +++ b/System.Data.Entity/System/Data/SqlClient/IDbSpatialValue.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Data.Spatial; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/DmlSqlGenerator.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/DmlSqlGenerator.cs index b17cc1734..204292f95 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/DmlSqlGenerator.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/DmlSqlGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.SqlClient.SqlGen diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/JoinSymbol.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/JoinSymbol.cs index 1d60e4299..75d807857 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/JoinSymbol.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/JoinSymbol.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/OptionalColumn.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/OptionalColumn.cs index b2c88e582..9670a2365 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/OptionalColumn.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/OptionalColumn.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/Sql8ConformanceChecker.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/Sql8ConformanceChecker.cs index 9b6d3bc90..ce48bf2d0 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/Sql8ConformanceChecker.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/Sql8ConformanceChecker.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.SqlClient.SqlGen diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/Sql8ExpressionRewriter.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/Sql8ExpressionRewriter.cs index 1fa8b4ca6..f5493efc8 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/Sql8ExpressionRewriter.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/Sql8ExpressionRewriter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlBuilder.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlBuilder.cs index c680a0dc1..f4ffc565d 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlBuilder.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlBuilder.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlFunctionCallHandler.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlFunctionCallHandler.cs index f749d5cf2..2fb8259d8 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlFunctionCallHandler.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlFunctionCallHandler.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.SqlClient.SqlGen diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlGenerator.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlGenerator.cs index b09cca657..2547d7bd2 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlGenerator.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlGenerator.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.SqlClient.SqlGen @@ -2495,7 +2495,7 @@ public override ISqlFragment Visit(DbSkipExpression e) //Create the resulting statement //See CreateNewSelectStatement, it is very similar - //Future Enhancement ([....]): Refactor to avoid duplication with CreateNewSelectStatement if we + //Future Enhancement (Microsoft): Refactor to avoid duplication with CreateNewSelectStatement if we // don't switch to using ExtensionExpression here SqlSelectStatement result = new SqlSelectStatement(); result.From.Append("( "); diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlSelectClauseBuilder.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlSelectClauseBuilder.cs index 8c3b203bd..83d2b2479 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlSelectClauseBuilder.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlSelectClauseBuilder.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlSelectStatement.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlSelectStatement.cs index d44940d8d..3893137a5 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlSelectStatement.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlSelectStatement.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlWriter.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlWriter.cs index f8e4e2f06..439738387 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlWriter.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/SqlWriter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/Symbol.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/Symbol.cs index f5e8f20b3..5257812e0 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/Symbol.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/Symbol.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolPair.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolPair.cs index 5624db4cb..b1684aa77 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolPair.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolPair.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolTable.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolTable.cs index b47c8e69f..3cf8d038d 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolTable.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolTable.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolUsageManager.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolUsageManager.cs index d0572b75e..7f9152076 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolUsageManager.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/SymbolUsageManager.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] +// @owner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlGen/TopClause.cs b/System.Data.Entity/System/Data/SqlClient/SqlGen/TopClause.cs index 5bd2c195a..e09e2252f 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlGen/TopClause.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlGen/TopClause.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlProviderManifest.cs b/System.Data.Entity/System/Data/SqlClient/SqlProviderManifest.cs index 3a0a4d3d0..2553a4a33 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlProviderManifest.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlProviderManifest.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlProviderServices.cs b/System.Data.Entity/System/Data/SqlClient/SqlProviderServices.cs index aa28e6af8..a917faa6c 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlProviderServices.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlProviderServices.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data.Entity/System/Data/SqlClient/SqlProviderUtilities.cs b/System.Data.Entity/System/Data/SqlClient/SqlProviderUtilities.cs index 283abf3e6..425b97d10 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlProviderUtilities.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlProviderUtilities.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlSpatialDataReader.cs b/System.Data.Entity/System/Data/SqlClient/SqlSpatialDataReader.cs index 607dd1e24..ef7b9c6a1 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlSpatialDataReader.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlSpatialDataReader.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Data.Common.Utils; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlSpatialServices.Generated.cs b/System.Data.Entity/System/Data/SqlClient/SqlSpatialServices.Generated.cs index 4007c8146..6d749c83a 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlSpatialServices.Generated.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlSpatialServices.Generated.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //-------------------------------------------------------------------------- // This file is automatically generated and should not be changed directly. // diff --git a/System.Data.Entity/System/Data/SqlClient/SqlSpatialServices.cs b/System.Data.Entity/System/Data/SqlClient/SqlSpatialServices.cs index cd5a2dec0..d9e787050 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlSpatialServices.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlSpatialServices.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlTypesAssembly.cs b/System.Data.Entity/System/Data/SqlClient/SqlTypesAssembly.cs index ee3eff1e5..c9213bb25 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlTypesAssembly.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlTypesAssembly.cs @@ -4,7 +4,7 @@ // // // @owner willa -// @backupOwner [....] +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.Entity/System/Data/SqlClient/SqlVersion.cs b/System.Data.Entity/System/Data/SqlClient/SqlVersion.cs index 360a25990..e9fc500e2 100644 --- a/System.Data.Entity/System/Data/SqlClient/SqlVersion.cs +++ b/System.Data.Entity/System/Data/SqlClient/SqlVersion.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.SqlClient diff --git a/System.Data.Entity/System/Data/UpdateException.cs b/System.Data.Entity/System/Data/UpdateException.cs index 7a1698868..739893c67 100644 --- a/System.Data.Entity/System/Data/UpdateException.cs +++ b/System.Data.Entity/System/Data/UpdateException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data diff --git a/System.Data.Entity/Util/AppSettings.cs b/System.Data.Entity/Util/AppSettings.cs index 9877ddace..2617ed2df 100644 --- a/System.Data.Entity/Util/AppSettings.cs +++ b/System.Data.Entity/Util/AppSettings.cs @@ -4,7 +4,7 @@ // // // @owner daobando -// @backupOwner [....] +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Specialized; diff --git a/System.Data.Linq/ChangeConflicts.cs b/System.Data.Linq/ChangeConflicts.cs index 815335272..5ce354335 100644 --- a/System.Data.Linq/ChangeConflicts.cs +++ b/System.Data.Linq/ChangeConflicts.cs @@ -279,7 +279,7 @@ public void Resolve(RefreshMode refreshMode, bool autoResolveDeletes) { private void ResolveDelete() { Debug.Assert(this.IsDeleted); // If the user is attempting to update an entity that no longer exists - // in the database, we first need to [....] the delete into the local cache. + // in the database, we first need to sync the delete into the local cache. if (!trackedObject.IsDeleted) { trackedObject.ConvertToDeleted(); } @@ -287,7 +287,7 @@ private void ResolveDelete() { // As the object have been deleted, it needs to leave the cache this.Session.Context.Services.RemoveCachedObjectLike(trackedObject.Type, trackedObject.Original); - // Now that our cache is in [....], we accept the changes + // Now that our cache is in sync, we accept the changes this.trackedObject.AcceptChanges(); this.isResolved = true; } diff --git a/System.Data.Linq/ChangeDirector.cs b/System.Data.Linq/ChangeDirector.cs index 96fc7db3b..74f9bf151 100644 --- a/System.Data.Linq/ChangeDirector.cs +++ b/System.Data.Linq/ChangeDirector.cs @@ -45,14 +45,14 @@ private enum UpdateType { Insert, Update, Delete }; private enum AutoSyncBehavior { ApplyNewAutoSync, RollbackSavedValues } DataContext context; - [SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Justification="[....]: FxCop bug Dev10:423110 -- List> is not supposed to be flagged as a violation.")] + [SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Justification="Microsoft: FxCop bug Dev10:423110 -- List> is not supposed to be flagged as a violation.")] List> syncRollbackItems; internal StandardChangeDirector(DataContext context) { this.context = context; } - [SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Justification="[....]: FxCop bug Dev10:423110 -- List> is not supposed to be flagged as a violation.")] + [SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Justification="Microsoft: FxCop bug Dev10:423110 -- List> is not supposed to be flagged as a violation.")] private List> SyncRollbackItems { get { if (syncRollbackItems == null) { @@ -89,7 +89,7 @@ internal override int DynamicInsert(TrackedObject item) { IEnumerable facts = (IEnumerable)this.context.Provider.Execute(cmd).ReturnValue; object[] syncResults = (object[])facts.FirstOrDefault(); if (syncResults != null) { - // [....] any auto gen or computed members + // sync any auto gen or computed members AutoSyncMembers(syncResults, item, UpdateType.Insert, AutoSyncBehavior.ApplyNewAutoSync); return 1; } @@ -142,7 +142,7 @@ internal override int DynamicUpdate(TrackedObject item) { IEnumerable facts = (IEnumerable)this.context.Provider.Execute(cmd).ReturnValue; object[] syncResults = (object[])facts.FirstOrDefault(); if (syncResults != null) { - // [....] any auto gen or computed members + // sync any auto gen or computed members AutoSyncMembers(syncResults, item, UpdateType.Update, AutoSyncBehavior.ApplyNewAutoSync); return 1; } @@ -204,7 +204,7 @@ internal override void AppendDeleteText(TrackedObject item, StringBuilder append } } - [SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Justification="[....]: FxCop bug Dev10:423110 -- List> is not supposed to be flagged as a violation.")] + [SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Justification="Microsoft: FxCop bug Dev10:423110 -- List> is not supposed to be flagged as a violation.")] internal override void RollbackAutoSync() { // Rolls back any AutoSync values that may have been set already // Those values are no longer valid since the transaction will be rolled back on the server @@ -222,7 +222,7 @@ internal override void RollbackAutoSync() { } } - [SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Justification="[....]: FxCop bug Dev10:423110 -- List> is not supposed to be flagged as a violation.")] + [SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Justification="Microsoft: FxCop bug Dev10:423110 -- List> is not supposed to be flagged as a violation.")] internal override void ClearAutoSyncRollback() { this.syncRollbackItems = null; } @@ -260,7 +260,7 @@ private Expression CreateAutoSync(List membersToSync, Expression private static List GetAutoSyncMembers(MetaType metaType, UpdateType updateType) { List membersToSync = new List(); foreach (MetaDataMember metaMember in metaType.PersistentDataMembers.OrderBy(m => m.Ordinal)) { - // add all auto generated members for the specified update type to the auto-[....] list + // add all auto generated members for the specified update type to the auto-sync list if ((updateType == UpdateType.Insert && metaMember.AutoSync == AutoSync.OnInsert) || (updateType == UpdateType.Update && metaMember.AutoSync == AutoSync.OnUpdate) || metaMember.AutoSync == AutoSync.Always) { @@ -272,14 +272,14 @@ private static List GetAutoSyncMembers(MetaType metaType, Update /// /// Synchronize the specified item by copying in data from the specified results. - /// Used to [....] members after successful insert or update, but also used to rollback to previous values if a failure + /// Used to sync members after successful insert or update, but also used to rollback to previous values if a failure /// occurs on other entities in the same SubmitChanges batch. /// /// - /// If AutoSyncBehavior.ApplyNewAutoSync, the current value of the property is saved before the [....] occurs. This is used for normal synchronization after a successful update/insert. - /// Otherwise, the current value is not saved. This is used for rollback operations when something in the SubmitChanges batch failed, rendering the previously-[....]'d values invalid. + /// If AutoSyncBehavior.ApplyNewAutoSync, the current value of the property is saved before the sync occurs. This is used for normal synchronization after a successful update/insert. + /// Otherwise, the current value is not saved. This is used for rollback operations when something in the SubmitChanges batch failed, rendering the previously-sync'd values invalid. /// - [SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Justification="[....]: FxCop bug Dev10:423110 -- List> is not supposed to be flagged as a violation.")] + [SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Justification="Microsoft: FxCop bug Dev10:423110 -- List> is not supposed to be flagged as a violation.")] private void AutoSyncMembers(object[] syncResults, TrackedObject item, UpdateType updateType, AutoSyncBehavior autoSyncBehavior) { System.Diagnostics.Debug.Assert(item != null); System.Diagnostics.Debug.Assert(item.IsNew || item.IsPossiblyModified, "AutoSyncMembers should only be called for new and modified objects."); diff --git a/System.Data.Linq/ChangeProcessor.cs b/System.Data.Linq/ChangeProcessor.cs index 4eaa79b5a..0affa3cb6 100644 --- a/System.Data.Linq/ChangeProcessor.cs +++ b/System.Data.Linq/ChangeProcessor.cs @@ -115,9 +115,9 @@ internal void SubmitChanges(ConflictMode failureMode) { // if we have accumulated any failed updates, throw the exception now if (conflicts.Count > 0) { - // First we need to rollback any value that have already been auto-[....]'d, since the values are no longer valid on the server + // First we need to rollback any value that have already been auto-sync'd, since the values are no longer valid on the server changeDirector.RollbackAutoSync(); - // Also rollback any dependent items that were [....]'d, since their parent values may have been rolled back + // Also rollback any dependent items that were sync'd, since their parent values may have been rolled back foreach (TrackedObject syncDependentItem in syncDependentItems) { Debug.Assert(syncDependentItem.IsNew || syncDependentItem.IsPossiblyModified, "SynchDependent data should only be rolled back for new and modified objects."); syncDependentItem.SynchDependentData(); diff --git a/System.Data.Linq/ChangeTracker.cs b/System.Data.Linq/ChangeTracker.cs index 76d80426b..4e850afa9 100644 --- a/System.Data.Linq/ChangeTracker.cs +++ b/System.Data.Linq/ChangeTracker.cs @@ -560,7 +560,7 @@ internal void StartTracking() { } } - // Return value indicates whether or not any data was actually [....]'d + // Return value indicates whether or not any data was actually sync'd internal override bool SynchDependentData() { bool valueWasSet = false; diff --git a/System.Data.Linq/CompiledQuery.cs b/System.Data.Linq/CompiledQuery.cs index 275883b02..ee789b785 100644 --- a/System.Data.Linq/CompiledQuery.cs +++ b/System.Data.Linq/CompiledQuery.cs @@ -31,7 +31,7 @@ public LambdaExpression Expression { get { return this.query; } } - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "[....]: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")] + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Microsoft: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")] public static Func Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -44,7 +44,7 @@ public static Func Compile(Expression Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -57,7 +57,7 @@ public static Func Compile(Express } } - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "[....]: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")] + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Microsoft: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")] public static Func Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -70,7 +70,7 @@ public static Func Compile Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -83,7 +83,7 @@ public static Func Compile Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -96,7 +96,7 @@ public static Func Compile Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -109,7 +109,7 @@ public static Func Compile Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -122,7 +122,7 @@ public static Func Com } } - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "[....]: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")] + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Microsoft: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")] public static Func Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -135,7 +135,7 @@ public static Func Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -148,7 +148,7 @@ public static Func Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -161,7 +161,7 @@ public static Func Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -174,7 +174,7 @@ public static Func Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -187,7 +187,7 @@ public static Func Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -200,7 +200,7 @@ public static Func Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -213,7 +213,7 @@ public static Func Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); @@ -226,7 +226,7 @@ public static Func Compile(Expression> query) where TArg0 : DataContext { if (query == null) { Error.ArgumentNull("query"); diff --git a/System.Data.Linq/DataContext.cs b/System.Data.Linq/DataContext.cs index 5d7fb47e7..822c6ea1b 100644 --- a/System.Data.Linq/DataContext.cs +++ b/System.Data.Linq/DataContext.cs @@ -352,7 +352,7 @@ internal void CheckInSubmitChanges() { /// The type of the entity objects. In case of a persistent hierarchy /// the entity specified must be the base type of the hierarchy. /// - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] public Table GetTable() where TEntity : class { CheckDispose(); MetaTable metaTable = this.services.Model.GetTable(typeof(TEntity)); @@ -483,7 +483,7 @@ public void SubmitChanges() { /// You can override this method to implement common conflict resolution behaviors. /// /// Determines how SubmitChanges handles conflicts. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "[....]: In the middle of attempting to rollback a transaction, outer transaction is thrown.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Microsoft: In the middle of attempting to rollback a transaction, outer transaction is thrown.")] public virtual void SubmitChanges(ConflictMode failureMode) { CheckDispose(); CheckNotInSubmitChanges(); @@ -718,7 +718,7 @@ public int ExecuteCommand(string command, params object[] parameters) { /// The query specified in the server's native query language. /// The parameter values to use for the query. /// An IEnumerable sequence of objects. - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] public IEnumerable ExecuteQuery(string query, params object[] parameters) { CheckDispose(); if (query == null) { @@ -786,7 +786,7 @@ internal protected IExecuteResult ExecuteMethodCall(object instance, MethodInfo /// The reflection MethodInfo for the method to invoke. /// The parameters for the method call. /// The returned query object - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] internal protected IQueryable CreateMethodCallQuery(object instance, MethodInfo methodInfo, params object[] parameters) { CheckDispose(); if (instance == null) { @@ -884,7 +884,7 @@ internal protected void ExecuteDynamicDelete(object entity) { /// The element type of the resulting sequence /// The DbDataReader to translate /// The translated sequence of objects - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] public IEnumerable Translate(DbDataReader reader) { CheckDispose(); return (IEnumerable)this.Translate(typeof(TResult), reader); @@ -999,7 +999,7 @@ public interface ITable : IQueryable /// ITable is the common interface for DataContext tables. It can be used as the source /// of a dynamic/runtime-generated query. /// - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification="[....]: Meant to represent a database table which is delayed loaded and doesn't provide collection semantics.")] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification="Microsoft: Meant to represent a database table which is delayed loaded and doesn't provide collection semantics.")] public interface ITable : IQueryable { /// /// The DataContext containing this Table. @@ -1102,7 +1102,7 @@ public interface ITable : IQueryable { /// persisted in the database. Use it as a source of queries and to add/insert and remove/delete entities. /// /// - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification="[....]: Meant to represent a database table which is delayed loaded and doesn't provide collection semantics.")] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification="Microsoft: Meant to represent a database table which is delayed loaded and doesn't provide collection semantics.")] public sealed class Table : IQueryable, IQueryProvider, IEnumerable, IQueryable, IEnumerable, ITable, IListSource, ITable where TEntity : class { DataContext context; @@ -1156,7 +1156,7 @@ IQueryable IQueryProvider.CreateQuery(Expression expression) { return (IQueryable)Activator.CreateInstance(dqType, new object[] { this.context, expression }); } - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] IQueryable IQueryProvider.CreateQuery(Expression expression) { if (expression == null) { throw Error.ArgumentNull("expression"); @@ -1171,7 +1171,7 @@ object IQueryProvider.Execute(Expression expression) { return this.context.Provider.Execute(expression).ReturnValue; } - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] TResult IQueryProvider.Execute(Expression expression) { return (TResult)this.context.Provider.Execute(expression).ReturnValue; } @@ -1680,7 +1680,7 @@ public override string ToString() { } } - [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes", Justification = "[....]: Types are never compared to each other. When comparisons happen it is against the entities that are represented by these constructs.")] + [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes", Justification = "Microsoft: Types are never compared to each other. When comparisons happen it is against the entities that are represented by these constructs.")] public struct ModifiedMemberInfo { MemberInfo member; object current; diff --git a/System.Data.Linq/DataShape.cs b/System.Data.Linq/DataShape.cs index e46bb6ee1..9993d417b 100644 --- a/System.Data.Linq/DataShape.cs +++ b/System.Data.Linq/DataShape.cs @@ -17,8 +17,8 @@ sealed public class DataLoadOptions { /// /// Describe a property that is automatically loaded when the containing instance is loaded /// - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "[....]: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")] - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "[....]: Need to provide static typing.")] + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Microsoft: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")] + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Microsoft: Need to provide static typing.")] public void LoadWith(Expression> expression) { if (expression == null) { throw Error.ArgumentNull("expression"); @@ -41,8 +41,8 @@ public void LoadWith(LambdaExpression expression) { /// /// Place a subquery on the given association. /// - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "[....]: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")] - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "[....]: Need to provide static typing.")] + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Microsoft: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")] + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Microsoft: Need to provide static typing.")] public void AssociateWith(Expression> expression) { if (expression == null) { throw Error.ArgumentNull("expression"); diff --git a/System.Data.Linq/DbConvert.cs b/System.Data.Linq/DbConvert.cs index 03af1adc4..7d21b20de 100644 --- a/System.Data.Linq/DbConvert.cs +++ b/System.Data.Linq/DbConvert.cs @@ -15,12 +15,12 @@ namespace System.Data.Linq { public static class DBConvert { private static Type[] StringArg = new Type[] { typeof(string) }; - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] public static T ChangeType(object value) { return (T)ChangeType(value, typeof(T)); } - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "[....]: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Microsoft: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] public static object ChangeType(object value, Type type) { if (value == null) diff --git a/System.Data.Linq/Mapping/MetaModel.cs b/System.Data.Linq/Mapping/MetaModel.cs index d07e222ba..68b69b3de 100644 --- a/System.Data.Linq/Mapping/MetaModel.cs +++ b/System.Data.Linq/Mapping/MetaModel.cs @@ -501,7 +501,7 @@ public abstract class MetaAccessor { /// /// The instance to set the value into. /// The value to set. - [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="[....]: Needs to handle classes and structs.")] + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Microsoft: Needs to handle classes and structs.")] [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", Justification="Unknown reason.")] public abstract void SetBoxedValue(ref object instance, object value); /// diff --git a/System.Data.Linq/Provider/IProvider.cs b/System.Data.Linq/Provider/IProvider.cs index 56eccaa93..98438415b 100644 --- a/System.Data.Linq/Provider/IProvider.cs +++ b/System.Data.Linq/Provider/IProvider.cs @@ -140,8 +140,8 @@ internal static class DataManipulation { /// /// /// - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "[....]: The method is being used to represent a method signature")] - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "resultSelector", Justification = "[....]: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "Microsoft: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "resultSelector", Justification = "Microsoft: The method is being used to represent a method signature")] public static TResult Insert(TEntity item, Func resultSelector) { throw new NotImplementedException(); } @@ -152,7 +152,7 @@ public static TResult Insert(TEntity item, Func /// /// - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "[....]: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "Microsoft: The method is being used to represent a method signature")] public static int Insert(TEntity item) { throw new NotImplementedException(); } @@ -166,9 +166,9 @@ public static int Insert(TEntity item) { /// /// /// - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "[....]: The method is being used to represent a method signature")] - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "check", Justification = "[....]: The method is being used to represent a method signature")] - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "resultSelector", Justification = "[....]: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "Microsoft: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "check", Justification = "Microsoft: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "resultSelector", Justification = "Microsoft: The method is being used to represent a method signature")] public static TResult Update(TEntity item, Func check, Func resultSelector) { throw new NotImplementedException(); } @@ -181,8 +181,8 @@ public static TResult Update(TEntity item, Func /// /// /// - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "[....]: The method is being used to represent a method signature")] - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "resultSelector", Justification = "[....]: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "Microsoft: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "resultSelector", Justification = "Microsoft: The method is being used to represent a method signature")] public static TResult Update(TEntity item, Func resultSelector) { throw new NotImplementedException(); } @@ -194,8 +194,8 @@ public static TResult Update(TEntity item, Func /// /// - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "[....]: The method is being used to represent a method signature")] - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "check", Justification = "[....]: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "Microsoft: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "check", Justification = "Microsoft: The method is being used to represent a method signature")] public static int Update(TEntity item, Func check) { throw new NotImplementedException(); } @@ -206,7 +206,7 @@ public static int Update(TEntity item, Func check) { /// /// /// - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "[....]: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "Microsoft: The method is being used to represent a method signature")] public static int Update(TEntity item) { throw new NotImplementedException(); } @@ -218,8 +218,8 @@ public static int Update(TEntity item) { /// /// /// - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "[....]: The method is being used to represent a method signature")] - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "check", Justification = "[....]: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "Microsoft: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "check", Justification = "Microsoft: The method is being used to represent a method signature")] public static int Delete(TEntity item, Func check) { throw new NotImplementedException(); } @@ -230,7 +230,7 @@ public static int Delete(TEntity item, Func check) { /// /// /// - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "[....]: The method is being used to represent a method signature")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "item", Justification = "Microsoft: The method is being used to represent a method signature")] public static int Delete(TEntity item) { throw new NotImplementedException(); } diff --git a/System.Data.Linq/SqlClient/Common/SqlVisitor.cs b/System.Data.Linq/SqlClient/Common/SqlVisitor.cs index 9f35835e4..87d874585 100644 --- a/System.Data.Linq/SqlClient/Common/SqlVisitor.cs +++ b/System.Data.Linq/SqlClient/Common/SqlVisitor.cs @@ -9,7 +9,7 @@ internal abstract class SqlVisitor { int nDepth; // Visit a SqlNode - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification="[....]: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification="Microsoft: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] internal virtual SqlNode Visit(SqlNode node) { diff --git a/System.Data.Linq/SqlClient/Query/Funcletizer.cs b/System.Data.Linq/SqlClient/Query/Funcletizer.cs index 57d09b761..50ccc2c6d 100644 --- a/System.Data.Linq/SqlClient/Query/Funcletizer.cs +++ b/System.Data.Linq/SqlClient/Query/Funcletizer.cs @@ -142,7 +142,7 @@ internal ExpressionVisitor() { } [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "[....]: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Microsoft: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] internal virtual Expression Visit(Expression exp) { if (exp == null) return exp; diff --git a/System.Data.Linq/SqlClient/Query/QueryConverter.cs b/System.Data.Linq/SqlClient/Query/QueryConverter.cs index 55ae51ee9..a9135481d 100644 --- a/System.Data.Linq/SqlClient/Query/QueryConverter.cs +++ b/System.Data.Linq/SqlClient/Query/QueryConverter.cs @@ -143,7 +143,7 @@ internal SqlNode ConvertInner(Expression node, Expression dominantExpression) { return result; } - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "[....]: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Microsoft: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] private SqlNode VisitInner(Expression node) { if (node == null) return null; diff --git a/System.Data.Linq/SqlClient/Query/SqlBinder.cs b/System.Data.Linq/SqlClient/Query/SqlBinder.cs index 26645270a..6d5c6e615 100644 --- a/System.Data.Linq/SqlClient/Query/SqlBinder.cs +++ b/System.Data.Linq/SqlClient/Query/SqlBinder.cs @@ -1266,7 +1266,7 @@ internal SqlExpression ConvertToExpression(SqlNode node) { throw Error.UnexpectedNode(node.NodeType); } - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "[....]: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Microsoft: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] internal SqlExpression ConvertToFetchedExpression(SqlNode node) { diff --git a/System.Data.Linq/SqlClient/Query/SqlComparer.cs b/System.Data.Linq/SqlClient/Query/SqlComparer.cs index 06a76c701..d70c0becb 100644 --- a/System.Data.Linq/SqlClient/Query/SqlComparer.cs +++ b/System.Data.Linq/SqlClient/Query/SqlComparer.cs @@ -13,7 +13,7 @@ internal class SqlComparer { internal SqlComparer() { } - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "[....]: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Microsoft: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] diff --git a/System.Data.Linq/SqlClient/Query/SqlDeflator.cs b/System.Data.Linq/SqlClient/Query/SqlDeflator.cs index b290c007c..ed4f0e66e 100644 --- a/System.Data.Linq/SqlClient/Query/SqlDeflator.cs +++ b/System.Data.Linq/SqlClient/Query/SqlDeflator.cs @@ -236,7 +236,7 @@ internal override SqlSelect VisitSelect(SqlSelect select) { return select; } - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification="[....]: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification="Microsoft: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] private void CheckJoinCondition(SqlExpression expr) { switch (expr.NodeType) { case SqlNodeType.And: { diff --git a/System.Data.Linq/SqlClient/Query/SqlFlattener.cs b/System.Data.Linq/SqlClient/Query/SqlFlattener.cs index 9b7d7de01..9717a97a0 100644 --- a/System.Data.Linq/SqlClient/Query/SqlFlattener.cs +++ b/System.Data.Linq/SqlClient/Query/SqlFlattener.cs @@ -20,7 +20,7 @@ internal SqlNode Flatten(SqlNode node) { } class Visitor : SqlVisitor { - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "[....]: part of our standard visitor pattern")] + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "Microsoft: part of our standard visitor pattern")] SqlFactory sql; SqlColumnizer columnizer; bool isTopLevel; diff --git a/System.Data.Linq/SqlClient/Query/SqlMethodCallConverter.cs b/System.Data.Linq/SqlClient/Query/SqlMethodCallConverter.cs index ddbca5a93..79be6fe37 100644 --- a/System.Data.Linq/SqlClient/Query/SqlMethodCallConverter.cs +++ b/System.Data.Linq/SqlClient/Query/SqlMethodCallConverter.cs @@ -939,7 +939,7 @@ internal override SqlExpression VisitMethodCall(SqlMethodCall mc) { //Recognized pattern has set return value so return if (returnValue != null) { - // Assert here to verify that actual translation stays in [....] with + // Assert here to verify that actual translation stays in sync with // method support logic Debug.Assert(GetMethodSupport(mc) == MethodSupport.Method); return returnValue; @@ -973,7 +973,7 @@ internal override SqlExpression VisitMethodCall(SqlMethodCall mc) { returnValue = TranslateDateTimeOffsetInstanceMethod(mc); } if (returnValue != null) { - // Assert here to verify that actual translation stays in [....] with + // Assert here to verify that actual translation stays in sync with // method support logic Debug.Assert(GetMethodSupport(mc) == MethodSupport.Method); return returnValue; @@ -2159,7 +2159,7 @@ private SqlExpression TranslateMathMethod(SqlMethodCall mc) { throw GetMethodSupportException(mc); } - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "[....]: These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Microsoft: These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] internal override SqlNode VisitMember(SqlMember m) { SqlExpression exp = this.VisitExpression(m.Expression); MemberInfo member = m.Member; diff --git a/System.Data.Linq/SqlClient/Reader/ObjectReaderCompiler.cs b/System.Data.Linq/SqlClient/Reader/ObjectReaderCompiler.cs index 44139f927..70507c245 100644 --- a/System.Data.Linq/SqlClient/Reader/ObjectReaderCompiler.cs +++ b/System.Data.Linq/SqlClient/Reader/ObjectReaderCompiler.cs @@ -35,18 +35,18 @@ namespace Implementation { [SuppressMessage("Microsoft.Design", "CA1012:AbstractTypesShouldNotHaveConstructors", Justification = "Unknown reason.")] public abstract class ObjectMaterializer where TDataReader : DbDataReader { // These are public fields rather than properties for access speed - [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "[....]: This is a public type that is not intended for public use.")] + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "Microsoft: This is a public type that is not intended for public use.")] public int[] Ordinals; [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Globals", Justification = "Spelling is correct.")] - [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "[....]: This is a public type that is not intended for public use.")] + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "Microsoft: This is a public type that is not intended for public use.")] public object[] Globals; - [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "[....]: This is a public type that is not intended for public use.")] + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "Microsoft: This is a public type that is not intended for public use.")] public object[] Locals; - [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "[....]: This is a public type that is not intended for public use.")] + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "Microsoft: This is a public type that is not intended for public use.")] public object[] Arguments; - [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "[....]: This is a public type that is not intended for public use.")] + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "Microsoft: This is a public type that is not intended for public use.")] public TDataReader DataReader; - [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "[....]: This is a public type that is not intended for public use.")] + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "Microsoft: This is a public type that is not intended for public use.")] public DbDataReader BufferReader; public ObjectMaterializer() { @@ -57,16 +57,16 @@ public ObjectMaterializer() { public abstract void SendEntityMaterialized(int globalMetaType, object instance); public abstract IEnumerable ExecuteSubQuery(int iSubQuery, object[] args); - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] public abstract IEnumerable GetLinkSource(int globalLink, int localFactory, object[] keyValues); - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] public abstract IEnumerable GetNestedLinkSource(int globalLink, int localFactory, object instance); public abstract bool Read(); public abstract bool CanDeferLoad { get; } [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Justification = "xiaoruda: The method has to be static because it's used in our generated code and there is no instance of the type.")] - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")] public static IEnumerable Convert(IEnumerable source) { foreach (object value in source) { yield return DBConvert.ChangeType(value); @@ -717,7 +717,7 @@ private Type Generate(SqlNode node) { return this.Generate(node, null); } - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "[....]: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Microsoft: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] private Type Generate(SqlNode node, LocalBuilder locInstance) { #if DEBUG @@ -2212,7 +2212,7 @@ private void GenerateLoadMember(MemberInfo mi) { } } - [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", Justification = "[....]: The variable tc for which the rule fires is used in both a Debug.Assert and in a switch statement")] + [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", Justification = "Microsoft: The variable tc for which the rule fires is used in both a Debug.Assert and in a switch statement")] private void GenerateArrayAssign(Type type) { // This method was copied out of the expression compiler codebase. // Since DLINQ doesn't currently consume array indexers most of this @@ -2263,7 +2263,7 @@ private void GenerateArrayAssign(Type type) { } } - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "address", Justification = "[....]: See comments in source. Usage commented out to improve code coverage test")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "address", Justification = "Microsoft: See comments in source. Usage commented out to improve code coverage test")] private Type GenerateArrayAccess(Type type, bool address) { // This method was copied out of the expression compiler codebase. // Since DLINQ doesn't currently consume array indexers most of this @@ -2517,7 +2517,7 @@ internal bool IsBuffered { get { return this.BufferReader != null; } } - [SuppressMessage("Microsoft.Globalization", "CA1306:SetLocaleForDataTypes", Justification = "[....]: Used only as a buffer and never used for string comparison.")] + [SuppressMessage("Microsoft.Globalization", "CA1306:SetLocaleForDataTypes", Justification = "Microsoft: Used only as a buffer and never used for string comparison.")] internal void Buffer() { if (this.BufferReader == null && (this.hasCurrentRow || !this.hasRead)) { if (this.session.IsBuffered) { @@ -2801,7 +2801,7 @@ public bool IsBuffered { get { return this.buffer != null; } } - [SuppressMessage("Microsoft.Globalization", "CA1306:SetLocaleForDataTypes", Justification = "[....]: Used only as a buffer and never used for string comparison.")] + [SuppressMessage("Microsoft.Globalization", "CA1306:SetLocaleForDataTypes", Justification = "Microsoft: Used only as a buffer and never used for string comparison.")] public void Buffer() { if (this.buffer == null) { if (this.currentReader != null && !this.currentReader.IsBuffered) { diff --git a/System.Data.Linq/SqlClient/SqlMethods.cs b/System.Data.Linq/SqlClient/SqlMethods.cs index e11bca1e8..da3696d31 100644 --- a/System.Data.Linq/SqlClient/SqlMethods.cs +++ b/System.Data.Linq/SqlClient/SqlMethods.cs @@ -562,8 +562,8 @@ public static int DateDiffNanosecond(DateTimeOffset startDate, DateTimeOffset en /// The string that is to be matched. /// The pattern which may involve wildcards %,_,[,],^. /// true if there is a match. - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "pattern", Justification = "[....]: Method is a placeholder for a server-side method.")] - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "matchExpression", Justification = "[....]: Method is a placeholder for a server-side method.")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "pattern", Justification = "Microsoft: Method is a placeholder for a server-side method.")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "matchExpression", Justification = "Microsoft: Method is a placeholder for a server-side method.")] public static bool Like(string matchExpression, string pattern) { throw Error.SqlMethodOnlyForSql(MethodInfo.GetCurrentMethod()); } @@ -576,9 +576,9 @@ public static bool Like(string matchExpression, string pattern) { /// The pattern which may involve wildcards %,_,[,],^. /// The escape character to use in front of %,_,[,],^ if they are not used as wildcards. /// true if there is a match. - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "pattern", Justification = "[....]: Method is a placeholder for a server-side method.")] - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "matchExpression", Justification = "[....]: Method is a placeholder for a server-side method.")] - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "escapeCharacter", Justification = "[....]: Method is a placeholder for a server-side method.")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "pattern", Justification = "Microsoft: Method is a placeholder for a server-side method.")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "matchExpression", Justification = "Microsoft: Method is a placeholder for a server-side method.")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "escapeCharacter", Justification = "Microsoft: Method is a placeholder for a server-side method.")] public static bool Like(string matchExpression, string pattern, char escapeCharacter) { throw Error.SqlMethodOnlyForSql(MethodInfo.GetCurrentMethod()); } @@ -591,7 +591,7 @@ public static bool Like(string matchExpression, string pattern, char escapeChara /// /// The string to take the length of. /// length of the string - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value", Justification = "[....]: Method is a placeholder for a server-side method.")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value", Justification = "Microsoft: Method is a placeholder for a server-side method.")] internal static int RawLength(string value) { throw Error.SqlMethodOnlyForSql(MethodInfo.GetCurrentMethod()); } @@ -602,7 +602,7 @@ internal static int RawLength(string value) { /// /// The byte array to take the length of. /// length of the array - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value", Justification = "[....]: Method is a placeholder for a server-side method.")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value", Justification = "Microsoft: Method is a placeholder for a server-side method.")] internal static int RawLength(byte[] value) { throw Error.SqlMethodOnlyForSql(MethodInfo.GetCurrentMethod()); } @@ -613,7 +613,7 @@ internal static int RawLength(byte[] value) { /// /// The Binary value to take the length of. /// length of the Binary - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value", Justification = "[....]: Method is a placeholder for a server-side method.")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value", Justification = "Microsoft: Method is a placeholder for a server-side method.")] internal static int RawLength(Binary value) { throw Error.SqlMethodOnlyForSql(MethodInfo.GetCurrentMethod()); } diff --git a/System.Data.Linq/SqlClient/SqlProvider.cs b/System.Data.Linq/SqlClient/SqlProvider.cs index f3dce0d1c..437759cb9 100644 --- a/System.Data.Linq/SqlClient/SqlProvider.cs +++ b/System.Data.Linq/SqlClient/SqlProvider.cs @@ -738,7 +738,7 @@ void IProvider.DeleteDatabase() { } } - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification="[....]: Code needs to return false regarless of exception.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification="Microsoft: Code needs to return false regarless of exception.")] [ResourceExposure(ResourceScope.None)] // Exposure is via other methods that set dbName. [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] // File.Exists method call. bool IProvider.DatabaseExists() { @@ -1779,7 +1779,7 @@ class ExecuteResult : IExecuteResult, IDisposable { IObjectReaderSession session; int iReturnParameter = -1; object value; - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "[....]: used in an assert in ReturnValue.set")] + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "Microsoft: used in an assert in ReturnValue.set")] bool useReturnValue; bool isDisposed; diff --git a/System.Data.Linq/SqlClient/SqlTypeSystemProvider.cs b/System.Data.Linq/SqlClient/SqlTypeSystemProvider.cs index 06bb4d3af..f71e86597 100644 --- a/System.Data.Linq/SqlClient/SqlTypeSystemProvider.cs +++ b/System.Data.Linq/SqlClient/SqlTypeSystemProvider.cs @@ -1316,7 +1316,7 @@ internal override ProviderType ChangeTypeFamilyTo(ProviderType type, ProviderTyp } } - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "[....]: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Microsoft: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] internal override ProviderType GetBestType(ProviderType typeA, ProviderType typeB) { // first determine the type precedence SqlType bestType = (SqlType)(typeA.ComparePrecedenceTo(typeB) > 0 ? typeA : typeB); diff --git a/System.Data.Linq/Types.cs b/System.Data.Linq/Types.cs index c6d89a010..d132e20d5 100644 --- a/System.Data.Linq/Types.cs +++ b/System.Data.Linq/Types.cs @@ -17,7 +17,7 @@ internal static class SourceState { internal static readonly IEnumerable Assigned = (IEnumerable)new T[] { }; } - [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes", Justification = "[....]: Types are never compared to each other. When comparisons happen it is against the entities that are represented by these constructs.")] + [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes", Justification = "Microsoft: Types are never compared to each other. When comparisons happen it is against the entities that are represented by these constructs.")] public struct Link { T underlyingValue; IEnumerable source; @@ -80,7 +80,7 @@ public T Value { } } - [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes", Justification="[....]: Types are never compared to each other. When comparisons happen it is against the entities that are represented by these constructs.")] + [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes", Justification="Microsoft: Types are never compared to each other. When comparisons happen it is against the entities that are represented by these constructs.")] public struct EntityRef where TEntity : class { IEnumerable source; @@ -146,7 +146,7 @@ internal TEntity UnderlyingValue { } } - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification="[....]: Naming chosen to represent a different concept from a collection because it is delayed loaded.")] + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification="Microsoft: Naming chosen to represent a different concept from a collection because it is delayed loaded.")] public sealed class EntitySet : IList, IList, IListSource where TEntity : class { IEnumerable source; @@ -213,7 +213,7 @@ public TEntity this[int index] { } } - [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Justification = "[....]: Naming the parameter entity makes it more discoverable because it is clear what type of data should be added to this collection.")] + [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Justification = "Microsoft: Naming the parameter entity makes it more discoverable because it is clear what type of data should be added to this collection.")] public void Add(TEntity entity) { if (entity == null) { throw Error.ArgumentNull("entity"); @@ -279,7 +279,7 @@ public void Clear() { OnListChanged(ListChangedType.Reset, 0); } - [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Justification = "[....]: Naming the parameter entity makes it more discoverable because it is clear what type of data should be added to this collection.")] + [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Justification = "Microsoft: Naming the parameter entity makes it more discoverable because it is clear what type of data should be added to this collection.")] public bool Contains(TEntity entity) { return IndexOf(entity) >= 0; } @@ -311,13 +311,13 @@ IEnumerator IEnumerable.GetEnumerator() { } } - [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Justification = "[....]: Naming the parameter entity makes it more discoverable because it is clear what type of data should be added to this collection.")] + [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Justification = "Microsoft: Naming the parameter entity makes it more discoverable because it is clear what type of data should be added to this collection.")] public int IndexOf(TEntity entity) { Load(); return entities.IndexOf(entity); } - [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "1#", Justification = "[....]: Naming the parameter entity makes it more discoverable because it is clear what type of data should be added to this collection.")] + [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "1#", Justification = "Microsoft: Naming the parameter entity makes it more discoverable because it is clear what type of data should be added to this collection.")] public void Insert(int index, TEntity entity) { Load(); if (index < 0 || index > Count) @@ -406,7 +406,7 @@ private void OnModified() { isModified = true; } - [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Justification = "[....]: Naming the parameter entity makes it more discoverable because it is clear what type of data should be added to this collection.")] + [SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Justification = "Microsoft: Naming the parameter entity makes it more discoverable because it is clear what type of data should be added to this collection.")] public bool Remove(TEntity entity) { if (entity == null || entity == onRemoveEntity) return false; CheckModify(); @@ -758,7 +758,7 @@ public T Current { } } - [SuppressMessage("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces", Justification = "[....]: The name clearly describes function and the namespace is under a DLinq namespace which will make the distinction clear.")] + [SuppressMessage("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces", Justification = "Microsoft: The name clearly describes function and the namespace is under a DLinq namespace which will make the distinction clear.")] [DataContract] [Serializable] public sealed class Binary : IEquatable { diff --git a/System.Data.Linq/misc/SecurityUtils.cs b/System.Data.Linq/misc/SecurityUtils.cs index 76e02fafb..159dedbb6 100644 --- a/System.Data.Linq/misc/SecurityUtils.cs +++ b/System.Data.Linq/misc/SecurityUtils.cs @@ -8,11 +8,11 @@ */ -#if WINFORMS_NAMESPACE +#if Microsoft_NAMESPACE namespace System.Windows.Forms #elif DRAWING_NAMESPACE namespace System.Drawing -#elif WINFORMS_PUBLIC_GRAPHICS_LIBRARY +#elif Microsoft_PUBLIC_GRAPHICS_LIBRARY namespace System.Internal #elif SYSTEM_NAMESPACE namespace System @@ -127,7 +127,7 @@ internal static object SecureCreateInstance(Type type, object[] args, bool allow return Activator.CreateInstance(type, flags, null, args, null); } -#if (!WINFORMS_NAMESPACE) +#if (!Microsoft_NAMESPACE) /// /// This helper method provides safe access to Activator.CreateInstance. diff --git a/System.Data.SqlXml/System/Xml/Xsl/IlGen/GenerateHelper.cs b/System.Data.SqlXml/System/Xml/Xsl/IlGen/GenerateHelper.cs index 6490ddfb9..393358762 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/IlGen/GenerateHelper.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/IlGen/GenerateHelper.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Globalization; diff --git a/System.Data.SqlXml/System/Xml/Xsl/IlGen/IteratorDescriptor.cs b/System.Data.SqlXml/System/Xml/Xsl/IlGen/IteratorDescriptor.cs index c99ee63ec..3f284be5a 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/IlGen/IteratorDescriptor.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/IlGen/IteratorDescriptor.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/IlGen/OptimizerPatterns.cs b/System.Data.SqlXml/System/Xml/Xsl/IlGen/OptimizerPatterns.cs index 85589508b..064edcd75 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/IlGen/OptimizerPatterns.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/IlGen/OptimizerPatterns.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/IlGen/StaticDataManager.cs b/System.Data.SqlXml/System/Xml/Xsl/IlGen/StaticDataManager.cs index 366f26d8d..c04cebf1e 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/IlGen/StaticDataManager.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/IlGen/StaticDataManager.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/IlGen/TailCallAnalyzer.cs b/System.Data.SqlXml/System/Xml/Xsl/IlGen/TailCallAnalyzer.cs index 343293ebb..86ab9c3a2 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/IlGen/TailCallAnalyzer.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/IlGen/TailCallAnalyzer.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILAnnotation.cs b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILAnnotation.cs index d029da0d7..5c339d4f0 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILAnnotation.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILAnnotation.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Reflection; diff --git a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs index c2c530141..26daac8b9 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILModule.cs b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILModule.cs index 2df1e23e2..e47912e44 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILModule.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILModule.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs index f671178fc..821617173 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlILOptimizerVisitor.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlIlTypeHelper.cs b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlIlTypeHelper.cs index 90b2c09d0..3bb04f749 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlIlTypeHelper.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlIlTypeHelper.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlIlVisitor.cs b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlIlVisitor.cs index 786be8983..f33d6a9c5 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlIlVisitor.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/IlGen/XmlIlVisitor.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/ListBase.cs b/System.Data.SqlXml/System/Xml/Xsl/ListBase.cs index dbabda6f9..9e9364891 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/ListBase.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/ListBase.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Pair.cs b/System.Data.SqlXml/System/Xml/Xsl/Pair.cs index 4cc21c06a..46a8ad5e5 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Pair.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Pair.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilBinary.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilBinary.cs index 1121c090b..c1982324c 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilBinary.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilBinary.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilChoice.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilChoice.cs index b9645a0c1..25139afcd 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilChoice.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilChoice.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilCloneVisitor.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilCloneVisitor.cs index 12da6caa4..540ef9b57 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilCloneVisitor.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilCloneVisitor.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilDataSource.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilDataSource.cs index 49f29d1d4..ae4964e2c 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilDataSource.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilDataSource.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilExpression.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilExpression.cs index f2050d46d..08aacbff0 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilExpression.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilExpression.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilFactory.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilFactory.cs index 743ae9829..8d941c659 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilFactory.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilFactory.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilFunction.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilFunction.cs index c08b149dc..6cbfabcc8 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilFunction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilFunction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvoke.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvoke.cs index a99d6b5ed..4d8970b40 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvoke.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvoke.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvokeEarlyBound.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvokeEarlyBound.cs index 4acb8d3e5..4a8807191 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvokeEarlyBound.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvokeEarlyBound.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvokeLateBound.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvokeLateBound.cs index 57ffa6189..33b9dd55c 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvokeLateBound.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilInvokeLateBound.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilIterator.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilIterator.cs index 04e1cdb89..51eafb533 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilIterator.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilIterator.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilList.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilList.cs index 8ac1d26c9..63f885868 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilList.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilList.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilLiteral.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilLiteral.cs index b20c678d8..ac2480a4a 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilLiteral.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilLiteral.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilLoop.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilLoop.cs index 73702017f..aeb4e0274 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilLoop.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilLoop.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilName.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilName.cs index 1558795a5..7387507ce 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilName.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilName.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilNode.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilNode.cs index 40201b071..6eefb53f2 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilNode.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilNode.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilParameter.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilParameter.cs index 357800ea0..3fdcf6c02 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilParameter.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilParameter.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilPatternFactory.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilPatternFactory.cs index 5798d4c33..28cdbe335 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilPatternFactory.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilPatternFactory.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilPatternVisitor.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilPatternVisitor.cs index 4b86398a2..bdd237a48 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilPatternVisitor.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilPatternVisitor.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilReference.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilReference.cs index bf28cf11f..f06089201 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilReference.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilReference.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilReplaceVisitor.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilReplaceVisitor.cs index e33515460..3c422a891 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilReplaceVisitor.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilReplaceVisitor.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilScopedVisitor.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilScopedVisitor.cs index a3bcfd59d..556a6d331 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilScopedVisitor.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilScopedVisitor.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilSortKey.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilSortKey.cs index a7d76b242..c4b8b9211 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilSortKey.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilSortKey.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilStrConcat.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilStrConcat.cs index 011075c45..173955974 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilStrConcat.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilStrConcat.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTargetType.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTargetType.cs index ae27ad547..de1bcc1e6 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTargetType.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTargetType.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTernary.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTernary.cs index 317891a50..493f12eaf 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTernary.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTernary.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTypeChecker.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTypeChecker.cs index 850c4c8d8..0d10556e9 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTypeChecker.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilTypeChecker.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilUnary.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilUnary.cs index 4980715ef..4d1fbed67 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilUnary.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilUnary.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilValidationVisitor.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilValidationVisitor.cs index 678bf547f..9ebe9a2dc 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilValidationVisitor.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilValidationVisitor.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilVisitor.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilVisitor.cs index ce86057f3..5e5b5543e 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilVisitor.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilVisitor.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilXmlReader.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilXmlReader.cs index 5a53a3e95..eebd0d843 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilXmlReader.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilXmlReader.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilXmlWriter.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilXmlWriter.cs index 83253ea5a..e53c663f9 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/QilXmlWriter.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/QilXmlWriter.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/SubstitutionList.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/SubstitutionList.cs index 223e5fbaf..32868e6a1 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/SubstitutionList.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/SubstitutionList.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QIL/WhitespaceRule.cs b/System.Data.SqlXml/System/Xml/Xsl/QIL/WhitespaceRule.cs index ca7ed1811..914f12963 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QIL/WhitespaceRule.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QIL/WhitespaceRule.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/QueryReaderSettings.cs b/System.Data.SqlXml/System/Xml/Xsl/QueryReaderSettings.cs index d8ed8752b..26cd3fc5d 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/QueryReaderSettings.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/QueryReaderSettings.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/ContentIterators.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/ContentIterators.cs index e13600336..02b7678ee 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/ContentIterators.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/ContentIterators.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/DecimalFormatter.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/DecimalFormatter.cs index 0662261d1..43f6ee629 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/DecimalFormatter.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/DecimalFormatter.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/DocumentOrderComparer.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/DocumentOrderComparer.cs index 07abd470b..0d074a55d 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/DocumentOrderComparer.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/DocumentOrderComparer.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/DodSequenceMerge.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/DodSequenceMerge.cs index 39928a7b4..89d230005 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/DodSequenceMerge.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/DodSequenceMerge.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs index e6e31f979..790cf9977 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/NumberFormatter.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/NumberFormatter.cs index 2aef5b0da..500a168de 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/NumberFormatter.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/NumberFormatter.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/RtfNavigator.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/RtfNavigator.cs index f31249e16..42e3c1960 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/RtfNavigator.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/RtfNavigator.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Threading; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/SetIterators.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/SetIterators.cs index 62a4e8592..dbf8c20c8 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/SetIterators.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/SetIterators.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/SiblingIterators.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/SiblingIterators.cs index d48459e9e..06c38ce39 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/SiblingIterators.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/SiblingIterators.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/StringConcat.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/StringConcat.cs index 6b41ec7c6..b20f293db 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/StringConcat.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/StringConcat.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/TreeIterators.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/TreeIterators.cs index a3cdf4903..05afae41b 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/TreeIterators.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/TreeIterators.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.ComponentModel; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/WhitespaceRuleLookup.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/WhitespaceRuleLookup.cs index 3aa9ab535..5a7dea1a3 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/WhitespaceRuleLookup.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/WhitespaceRuleLookup.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/WhitespaceRuleReader.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/WhitespaceRuleReader.cs index 4668e1522..17207a418 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/WhitespaceRuleReader.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/WhitespaceRuleReader.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.IO; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlAggregates.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlAggregates.cs index 902ffdf86..7c4d0394b 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlAggregates.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlAggregates.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlAttributeCache.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlAttributeCache.cs index 6f39cb3e4..c35eb8fc2 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlAttributeCache.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlAttributeCache.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.Runtime { diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlCollation.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlCollation.cs index 956c2a654..e06f6d902 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlCollation.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlCollation.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlExtensionFunction.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlExtensionFunction.cs index d51ded1fa..0425c8e83 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlExtensionFunction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlExtensionFunction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlILIndex.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlILIndex.cs index f03904573..679637e17 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlILIndex.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlILIndex.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlILStorageConverter.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlILStorageConverter.cs index 222ec5c05..ad7f029ed 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlILStorageConverter.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlILStorageConverter.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlIterators.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlIterators.cs index 24e3a96a8..d5f189c21 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlIterators.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlIterators.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlNavigatorFilter.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlNavigatorFilter.cs index 6b8eb8264..2e91ddc8a 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlNavigatorFilter.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlNavigatorFilter.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Xml; using System.Xml.XPath; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlNavigatorStack.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlNavigatorStack.cs index 214b75582..ab5d5cdc8 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlNavigatorStack.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlNavigatorStack.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryContext.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryContext.cs index ca621b66b..644bfa8c2 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryContext.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryContext.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryOutput.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryOutput.cs index 6fd3ce9e5..275b9e2bc 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryOutput.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryOutput.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; using System.ComponentModel; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryRuntime.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryRuntime.cs index 782a2e12c..15d5db990 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryRuntime.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryRuntime.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.IO; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQuerySequence.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQuerySequence.cs index 2c01291b6..727040cd6 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQuerySequence.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQuerySequence.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryStaticData.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryStaticData.cs index b3bae005f..7ca2d40b9 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryStaticData.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlQueryStaticData.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlRawWriterWrapper.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlRawWriterWrapper.cs index c8766cfd0..f08e0effe 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlRawWriterWrapper.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlRawWriterWrapper.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.IO; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSequenceWriter.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSequenceWriter.cs index f5538b75e..1b974e927 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSequenceWriter.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSequenceWriter.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSortKey.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSortKey.cs index 772ffd6b4..793d287c5 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSortKey.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSortKey.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSortKeyAccumulator.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSortKeyAccumulator.cs index 3516c6724..d1f241b3a 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSortKeyAccumulator.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XmlSortKeyAccumulator.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XslNumber.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XslNumber.cs index 343dd36d7..631232ac8 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XslNumber.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XslNumber.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltConvert.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltConvert.cs index 885ccaca9..93752e860 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltConvert.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltConvert.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltFunctions.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltFunctions.cs index 473cef5a4..032279a4b 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltFunctions.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltFunctions.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.IO; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltLibrary.cs b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltLibrary.cs index 6f9b8236b..0f148d6ee 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltLibrary.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Runtime/XsltLibrary.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Specialized; diff --git a/System.Data.SqlXml/System/Xml/Xsl/SourceLineInfo.cs b/System.Data.SqlXml/System/Xml/Xsl/SourceLineInfo.cs index 0e6659090..46f24679d 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/SourceLineInfo.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/SourceLineInfo.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathBuilder.cs b/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathBuilder.cs index b2ef65f8c..6a4814e2d 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathBuilder.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathBuilder.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathCompileException.cs b/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathCompileException.cs index 570a32cf4..81e25627a 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathCompileException.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathCompileException.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Runtime.Serialization; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathParser.cs b/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathParser.cs index 516775489..7b6b55429 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathParser.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathParser.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathQilFactory.cs b/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathQilFactory.cs index 6afc15b2f..1bfc27441 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathQilFactory.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathQilFactory.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathScanner.cs b/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathScanner.cs index 996dbaa4e..11f966e07 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathScanner.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XPath/XPathScanner.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft // http://www.w3.org/TR/xpath#exprlex //------------------------------------------------------------------------------ diff --git a/System.Data.SqlXml/System/Xml/Xsl/XPathConvert.cs b/System.Data.SqlXml/System/Xml/Xsl/XPathConvert.cs index 5d2c9671e..a9255f970 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XPathConvert.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XPathConvert.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ /** diff --git a/System.Data.SqlXml/System/Xml/Xsl/XmlILCommand.cs b/System.Data.SqlXml/System/Xml/Xsl/XmlILCommand.cs index 684b75fea..f0117615d 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XmlILCommand.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XmlILCommand.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft // http://webdata/xml/specs/querylowlevel.xml //------------------------------------------------------------------------------ diff --git a/System.Data.SqlXml/System/Xml/Xsl/XmlIlGenerator.cs b/System.Data.SqlXml/System/Xml/Xsl/XmlIlGenerator.cs index 4075e22a2..5952f556b 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XmlIlGenerator.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XmlIlGenerator.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XmlQualifiedNameTest.cs b/System.Data.SqlXml/System/Xml/Xsl/XmlQualifiedNameTest.cs index 394d5273a..d82d7ad71 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XmlQualifiedNameTest.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XmlQualifiedNameTest.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XmlQueryCardinality.cs b/System.Data.SqlXml/System/Xml/Xsl/XmlQueryCardinality.cs index 7c6554630..c8131e706 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XmlQueryCardinality.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XmlQueryCardinality.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XmlQueryType.cs b/System.Data.SqlXml/System/Xml/Xsl/XmlQueryType.cs index 4e7c0eb74..84692be81 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XmlQueryType.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XmlQueryType.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XmlQueryTypeFactory.cs b/System.Data.SqlXml/System/Xml/Xsl/XmlQueryTypeFactory.cs index 14cd425cb..2548bb2d5 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XmlQueryTypeFactory.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XmlQueryTypeFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XslException.cs b/System.Data.SqlXml/System/Xml/Xsl/XslException.cs index 2462fc6a6..1a896ddb1 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XslException.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XslException.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.CodeDom.Compiler; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/Compiler.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/Compiler.cs index 624f7b9d0..68fb7af2a 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/Compiler.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/Compiler.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.CodeDom.Compiler; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/CompilerScopeManager.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/CompilerScopeManager.cs index c8bd252ef..4704df6db 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/CompilerScopeManager.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/CompilerScopeManager.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/Focus.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/Focus.cs index d93962dbb..a110803de 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/Focus.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/Focus.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/InvokeGenerator.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/InvokeGenerator.cs index 0f82b468e..a323e01e8 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/InvokeGenerator.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/InvokeGenerator.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/KeyMatchBuilder.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/KeyMatchBuilder.cs index 404e153ae..4417d0be0 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/KeyMatchBuilder.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/KeyMatchBuilder.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/Keywords.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/Keywords.cs index 66d1532a1..0ab7f5dcd 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/Keywords.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/Keywords.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/MatcherBuilder.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/MatcherBuilder.cs index 70f110b6f..22715a247 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/MatcherBuilder.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/MatcherBuilder.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/OutputScopeManager.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/OutputScopeManager.cs index 4bdfe9285..07506f558 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/OutputScopeManager.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/OutputScopeManager.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilGenerator.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilGenerator.cs index d29bc0ca3..f73f9ab58 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilGenerator.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilGenerator.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft // http://www.w3.org/TR/xslt.html // http://www.w3.org/TR/xslt20/ //------------------------------------------------------------------------------ diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs index 7f0d17f22..2f606d8cf 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilStrConcatenator.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilStrConcatenator.cs index ba2c0dc22..fe1f4dd31 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilStrConcatenator.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/QilStrConcatenator.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; using System.Xml; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/Scripts.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/Scripts.cs index a5ea461c0..86a5392f9 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/Scripts.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/Scripts.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft // http://devdiv/Documents/Whidbey/CLR/CurrentSpecs/BCL/CodeDom%20Activation.doc //------------------------------------------------------------------------------ @@ -301,7 +301,7 @@ private Assembly CompileAssembly(List scriptsForLang) { // If GenerateInMemory == true, then CodeDom loads the compiled assembly using Assembly.Load(byte[]) // instead of Assembly.Load(AssemblyName). That means the assembly will be loaded in the anonymous - // context (http://blogs.msdn.com/[....]/archive/2003/05/29/57143.aspx), and its dependencies can only + // context (http://blogs.msdn.com/Microsoft/archive/2003/05/29/57143.aspx), and its dependencies can only // be loaded from the Load context or using AssemblyResolve event. However we want to use the LoadFrom // context to preload all dependencies specified by , so we turn off // GenerateInMemory here. diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/Stylesheet.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/Stylesheet.cs index d2b5a731c..96f094bd7 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/Stylesheet.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/Stylesheet.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs index 8143836c4..efad6709d 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XPathPatternParser.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XPathPatternParser.cs index ad786e07f..4a88b7656 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XPathPatternParser.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XPathPatternParser.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslAst.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslAst.cs index 758047cef..b1dc09df0 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslAst.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslAst.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Text; diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslAstAnalyzer.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslAstAnalyzer.cs index e94a5891a..87f96419f 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslAstAnalyzer.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslAstAnalyzer.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Globalization; @@ -668,7 +668,7 @@ private XslFlags ProcessVarPar(VarPar node) { if (node.Select != null) { if (node.Content.Count != 0) { // In case of incorrect stylesheet, variable or parameter may have both a 'select' attribute and non-empty content - // NOTE: This code must be in [....] with recovery logic in QilGenerator + // NOTE: This code must be in sync with recovery logic in QilGenerator result = xpathAnalyzer.Analyze(node.Select) | VisitChildren(node) | XslFlags.AnyType; typeDonor = null; } else { diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslVisitor.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslVisitor.cs index 5311a8321..28c95f3a3 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslVisitor.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XslVisitor.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.Xslt { diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltInput.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltInput.cs index 931285174..b50961a43 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltInput.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltInput.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ //#define XSLT2 diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltLoader.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltLoader.cs index 1bf0ee63a..c2037e36f 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltLoader.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltLoader.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ //#define XSLT2 diff --git a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltQilFactory.cs b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltQilFactory.cs index 4fcca15bf..78e9e6db9 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltQilFactory.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/Xslt/XsltQilFactory.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Action.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Action.cs index ead808b5f..31c38905c 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Action.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Action.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ActionFrame.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ActionFrame.cs index 21f5fb062..d76ef0996 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ActionFrame.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ActionFrame.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ApplyImportsAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ApplyImportsAction.cs index fada5fa30..db9430ed1 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ApplyImportsAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ApplyImportsAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ApplyTemplatesAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ApplyTemplatesAction.cs index a81dd223f..0cecb4220 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ApplyTemplatesAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ApplyTemplatesAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AttributeAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AttributeAction.cs index f85ccb333..c26a03b44 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AttributeAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AttributeAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AttributeSetAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AttributeSetAction.cs index c227f0287..ede0aef75 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AttributeSetAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AttributeSetAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Avt.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Avt.cs index 6b2cdcac8..282c31f4b 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Avt.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Avt.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AvtEvent.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AvtEvent.cs index f88243faf..687eaad3e 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AvtEvent.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/AvtEvent.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/BeginEvent.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/BeginEvent.cs index 2cf53f05f..95ca244b9 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/BeginEvent.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/BeginEvent.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/BuilderInfo.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/BuilderInfo.cs index 20886ec8c..3f0644ff7 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/BuilderInfo.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/BuilderInfo.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CallTemplateAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CallTemplateAction.cs index b21604d00..70354f28d 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CallTemplateAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CallTemplateAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ChooseAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ChooseAction.cs index 0bc970758..85cc21906 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ChooseAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ChooseAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CommentAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CommentAction.cs index 32dabbf8b..67c7503bf 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CommentAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CommentAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CompiledAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CompiledAction.cs index 51ae00815..c6476fe60 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CompiledAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CompiledAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Compiler.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Compiler.cs index 1af4378a4..437bb1ef9 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Compiler.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Compiler.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ContainerAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ContainerAction.cs index 7fd963341..c197c1c44 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ContainerAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ContainerAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyAction.cs index 12f1ed03f..cb7d325be 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyAttributesAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyAttributesAction.cs index 47f8d3cd6..ed717e944 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyAttributesAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyAttributesAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyCodeAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyCodeAction.cs index 073e16956..b46cf13de 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyCodeAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyCodeAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyNamespacesAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyNamespacesAction.cs index b3e3e34ab..cebaadebf 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyNamespacesAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyNamespacesAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyNodesetAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyNodesetAction.cs index 3d9a487a5..4c7457f01 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyNodesetAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyNodesetAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyOfAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyOfAction.cs index 5207f98bd..ed5e721af 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyOfAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/CopyOfAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/DbgCompiler.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/DbgCompiler.cs index 8190e5578..c39c6d2b7 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/DbgCompiler.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/DbgCompiler.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/DocumentScope.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/DocumentScope.cs index 610897581..8a47aa826 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/DocumentScope.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/DocumentScope.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ElementAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ElementAction.cs index 0df55f379..26ff1bc9f 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ElementAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ElementAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/EndEvent.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/EndEvent.cs index 266f2177a..70f1c8d33 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/EndEvent.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/EndEvent.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Event.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Event.cs index d97f6440d..62b638fe0 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Event.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Event.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ForeachAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ForeachAction.cs index a932cab37..bc12dbe72 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ForeachAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ForeachAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/HtmlProps.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/HtmlProps.cs index 81eac3d35..e60a2f880 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/HtmlProps.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/HtmlProps.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/IfAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/IfAction.cs index c224c0661..71001f3a2 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/IfAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/IfAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/InputScope.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/InputScope.cs index 39236053d..66b85807e 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/InputScope.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/InputScope.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/InputScopeManager.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/InputScopeManager.cs index b1c1afae2..2cbbdc32f 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/InputScopeManager.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/InputScopeManager.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/MessageAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/MessageAction.cs index e2807e7fb..d8da70f8c 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/MessageAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/MessageAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NamespaceDecl.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NamespaceDecl.cs index 71dab6766..9329cbfef 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NamespaceDecl.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NamespaceDecl.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NamespaceEvent.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NamespaceEvent.cs index 1420c525b..eeeeb6faf 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NamespaceEvent.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NamespaceEvent.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NavigatorInput.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NavigatorInput.cs index 563aaf5f2..ce6688e4d 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NavigatorInput.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NavigatorInput.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NavigatorOutput.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NavigatorOutput.cs index d722905f1..f29c63dd6 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NavigatorOutput.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NavigatorOutput.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NewInstructionAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NewInstructionAction.cs index 5f84c647b..53769e706 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NewInstructionAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NewInstructionAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NumberAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NumberAction.cs index 553b74574..85038e93b 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NumberAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/NumberAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { @@ -417,7 +417,7 @@ private XPathNodeType BasicNodeType(XPathNodeType type) { } } - // [....]: perf. + // Microsoft: perf. // for each call to xsl:number Format() will build new NumberingFormat object. // in case of no AVTs we can build this object at compile time and reuse it on execution time. // even partial step in this d---- will be usefull (when cFormats == 0) diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutKeywords.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutKeywords.cs index dadea9c70..266ce0038 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutKeywords.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutKeywords.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutputScope.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutputScope.cs index 7de7e8bfb..e27e57e04 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutputScope.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutputScope.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutputScopeManager.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutputScopeManager.cs index dfefae839..a5e152603 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutputScopeManager.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/OutputScopeManager.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/PrefixQname.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/PrefixQname.cs index 062f765e9..ed1beb49e 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/PrefixQname.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/PrefixQname.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ProcessingInstructionAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ProcessingInstructionAction.cs index 40a5ae886..4bcf3d01a 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ProcessingInstructionAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ProcessingInstructionAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Processor.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Processor.cs index 740dc7db7..9a86ec723 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Processor.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Processor.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ReaderOutput.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ReaderOutput.cs index b8f45d089..4829e224d 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ReaderOutput.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ReaderOutput.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/RecordBuilder.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/RecordBuilder.cs index 1ca009325..ff1e8bb68 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/RecordBuilder.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/RecordBuilder.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/RootAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/RootAction.cs index f1fc2fcf3..72cc4990b 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/RootAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/RootAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/SequentialOutput.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/SequentialOutput.cs index 1f3765247..11ada9cad 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/SequentialOutput.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/SequentialOutput.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/SortAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/SortAction.cs index 7eac8559c..deebec192 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/SortAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/SortAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/StateMachine.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/StateMachine.cs index bf0e413c9..a8c602bb2 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/StateMachine.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/StateMachine.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/StringOutput.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/StringOutput.cs index 4a1f20f78..b4c69f80c 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/StringOutput.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/StringOutput.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Stylesheet.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Stylesheet.cs index 9cc9876d6..0bf9d41df 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Stylesheet.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Stylesheet.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateAction.cs index b4eedce6b..f728fec60 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateBaseAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateBaseAction.cs index bdd82f3b8..3ac17a2dd 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateBaseAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateBaseAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateLookupAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateLookupAction.cs index d8168cbd6..063d58991 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateLookupAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TemplateLookupAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Templatemanager.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Templatemanager.cs index b54551b6c..36811a5b4 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Templatemanager.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/Templatemanager.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextAction.cs index d7b207870..f93e6025e 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextEvent.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextEvent.cs index 7f57aaa93..480f72fcb 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextEvent.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextEvent.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextOnlyOutput.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextOnlyOutput.cs index cf608ab72..e4a18741d 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextOnlyOutput.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextOnlyOutput.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextOutput.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextOutput.cs index ca039a174..2fa2cb546 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextOutput.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TextOutput.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TheQuery.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TheQuery.cs index 206b6dbd5..08238b490 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TheQuery.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/TheQuery.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/UseAttributesetsAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/UseAttributesetsAction.cs index fbc238812..6d1838f9e 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/UseAttributesetsAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/UseAttributesetsAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ValueOfAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ValueOfAction.cs index d0fc7e3b7..ac4d48f69 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ValueOfAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/ValueOfAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/VariableAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/VariableAction.cs index 95f606353..e57a25999 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/VariableAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/VariableAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/WithParamAction.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/WithParamAction.cs index 175d2409f..c02c45ea8 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/WithParamAction.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/WithParamAction.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/WriterOutput.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/WriterOutput.cs index 3778c9dc2..57a02cfa1 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/WriterOutput.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/WriterOutput.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/XsltCompileContext.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/XsltCompileContext.cs index a6c74c175..6e7a9a33b 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/XsltCompileContext.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/XsltCompileContext.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { @@ -467,7 +467,7 @@ public static XPathResultType GetXPathType(Type type) { if (typeof(XPathNodeIterator).IsAssignableFrom(type)) { return XPathResultType.NodeSet; } - // [....]: It be better to check that type is realy object and otherwise return XPathResultType.Error + // Microsoft: It be better to check that type is realy object and otherwise return XPathResultType.Error return XPathResultType.Any; case TypeCode.DateTime : return XPathResultType.Error; diff --git a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/XsltOutput.cs b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/XsltOutput.cs index 45197e4c2..0df2f0ab5 100644 --- a/System.Data.SqlXml/System/Xml/Xsl/XsltOld/XsltOutput.cs +++ b/System.Data.SqlXml/System/Xml/Xsl/XsltOld/XsltOutput.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml.Xsl.XsltOld { diff --git a/System.Data/Microsoft/SqlServer/Server/MemoryRecordBuffer.cs b/System.Data/Microsoft/SqlServer/Server/MemoryRecordBuffer.cs index 1a7317d87..54c1f5b04 100644 --- a/System.Data/Microsoft/SqlServer/Server/MemoryRecordBuffer.cs +++ b/System.Data/Microsoft/SqlServer/Server/MemoryRecordBuffer.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/MetadataUtilsSmi.cs b/System.Data/Microsoft/SqlServer/Server/MetadataUtilsSmi.cs index 2a267bd12..776bc2cfc 100644 --- a/System.Data/Microsoft/SqlServer/Server/MetadataUtilsSmi.cs +++ b/System.Data/Microsoft/SqlServer/Server/MetadataUtilsSmi.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiConnection.cs b/System.Data/Microsoft/SqlServer/Server/SmiConnection.cs index 593b27447..7907a61aa 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiConnection.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiConnection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiContext.cs b/System.Data/Microsoft/SqlServer/Server/SmiContext.cs index 413e2a2cf..5c500135f 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiContext.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiContext.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiContextFactory.cs b/System.Data/Microsoft/SqlServer/Server/SmiContextFactory.cs index 7554c9393..df636c295 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiContextFactory.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiContextFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiEventSink.cs b/System.Data/Microsoft/SqlServer/Server/SmiEventSink.cs index c7d2556b1..4c2822539 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiEventSink.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiEventSink.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiEventSink_Default.cs b/System.Data/Microsoft/SqlServer/Server/SmiEventSink_Default.cs index 089ced09e..8a0dfdae5 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiEventSink_Default.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiEventSink_Default.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiEventSink_DeferedProcessing.cs b/System.Data/Microsoft/SqlServer/Server/SmiEventSink_DeferedProcessing.cs index 624a6dfa1..80f1b99bb 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiEventSink_DeferedProcessing.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiEventSink_DeferedProcessing.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiEventStream.cs b/System.Data/Microsoft/SqlServer/Server/SmiEventStream.cs index baaeda5c0..9daeb29c4 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiEventStream.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiEventStream.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiGettersStream.cs b/System.Data/Microsoft/SqlServer/Server/SmiGettersStream.cs index c904b107b..f81df2468 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiGettersStream.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiGettersStream.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiMetaData.cs b/System.Data/Microsoft/SqlServer/Server/SmiMetaData.cs index ed861e021..49b2e68c1 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiMetaData.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiMetaData.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiMetaDataProperty.cs b/System.Data/Microsoft/SqlServer/Server/SmiMetaDataProperty.cs index b4fc70fd1..1ea6845ef 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiMetaDataProperty.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiMetaDataProperty.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiRecordBuffer.cs b/System.Data/Microsoft/SqlServer/Server/SmiRecordBuffer.cs index 822183327..3be8d9974 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiRecordBuffer.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiRecordBuffer.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiRequestExecutor.cs b/System.Data/Microsoft/SqlServer/Server/SmiRequestExecutor.cs index 4bf089f22..947907293 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiRequestExecutor.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiRequestExecutor.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiSettersStream.cs b/System.Data/Microsoft/SqlServer/Server/SmiSettersStream.cs index c32aa7f27..95428f6d8 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiSettersStream.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiSettersStream.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SmiTypedGetterSetter.cs b/System.Data/Microsoft/SqlServer/Server/SmiTypedGetterSetter.cs index ca6a630fd..14a25627a 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiTypedGetterSetter.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiTypedGetterSetter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ diff --git a/System.Data/Microsoft/SqlServer/Server/SmiXetterAccessMap.cs b/System.Data/Microsoft/SqlServer/Server/SmiXetterAccessMap.cs index 075099219..d782ff587 100644 --- a/System.Data/Microsoft/SqlServer/Server/SmiXetterAccessMap.cs +++ b/System.Data/Microsoft/SqlServer/Server/SmiXetterAccessMap.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SqlDataRecord.cs b/System.Data/Microsoft/SqlServer/Server/SqlDataRecord.cs index 9bb16a1e5..eba515f8e 100644 --- a/System.Data/Microsoft/SqlServer/Server/SqlDataRecord.cs +++ b/System.Data/Microsoft/SqlServer/Server/SqlDataRecord.cs @@ -2,10 +2,10 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SqlRecordBuffer.cs b/System.Data/Microsoft/SqlServer/Server/SqlRecordBuffer.cs index b719507e8..2882b8fe9 100644 --- a/System.Data/Microsoft/SqlServer/Server/SqlRecordBuffer.cs +++ b/System.Data/Microsoft/SqlServer/Server/SqlRecordBuffer.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/SqlTriggerContext.cs b/System.Data/Microsoft/SqlServer/Server/SqlTriggerContext.cs index 4ab4a259e..f89c1a83b 100644 --- a/System.Data/Microsoft/SqlServer/Server/SqlTriggerContext.cs +++ b/System.Data/Microsoft/SqlServer/Server/SqlTriggerContext.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft // daltodov //------------------------------------------------------------------------------ diff --git a/System.Data/Microsoft/SqlServer/Server/ValueUtilsSmi.cs b/System.Data/Microsoft/SqlServer/Server/ValueUtilsSmi.cs index 6d9b8cbe2..b2a867c59 100644 --- a/System.Data/Microsoft/SqlServer/Server/ValueUtilsSmi.cs +++ b/System.Data/Microsoft/SqlServer/Server/ValueUtilsSmi.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/Microsoft/SqlServer/Server/sqlcontext.cs b/System.Data/Microsoft/SqlServer/Server/sqlcontext.cs index 0696bedbb..5634702a7 100644 --- a/System.Data/Microsoft/SqlServer/Server/sqlcontext.cs +++ b/System.Data/Microsoft/SqlServer/Server/sqlcontext.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft // daltodov //------------------------------------------------------------------------------ diff --git a/System.Data/Microsoft/SqlServer/Server/sqlpipe.cs b/System.Data/Microsoft/SqlServer/Server/sqlpipe.cs index d1b39923f..a8abcbd16 100644 --- a/System.Data/Microsoft/SqlServer/Server/sqlpipe.cs +++ b/System.Data/Microsoft/SqlServer/Server/sqlpipe.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft // daltodov //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/BaseCollection.cs b/System.Data/System/Data/BaseCollection.cs index af0bc90ef..90a3c41bf 100644 --- a/System.Data/System/Data/BaseCollection.cs +++ b/System.Data/System/Data/BaseCollection.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/CodeGen/StrongTypingException.cs b/System.Data/System/Data/CodeGen/StrongTypingException.cs index 62eb1dcc3..1141adebe 100644 --- a/System.Data/System/Data/CodeGen/StrongTypingException.cs +++ b/System.Data/System/Data/CodeGen/StrongTypingException.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/CodeGen/datacache.cs b/System.Data/System/Data/CodeGen/datacache.cs index 26f3d320a..dc0705b26 100644 --- a/System.Data/System/Data/CodeGen/datacache.cs +++ b/System.Data/System/Data/CodeGen/datacache.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -351,7 +351,7 @@ private CodeTypeDeclaration CreateTypedTable(DataTable table) { } dataTableClass.Members.Add(constructor); - //\\ internal DataTableClass(DataTable table) : base(table.TableName) { // [....] : Assuming incoming table always associated with DataSet + //\\ internal DataTableClass(DataTable table) : base(table.TableName) { // Microsoft : Assuming incoming table always associated with DataSet //\\ if (table.CaseSensitive != table.DataSet.CaseSensitive) //\\ this.CaseSensitive = table.CaseSensitive; //\\ if (table.Locale.ToString() != table.DataSet.Locale.ToString()) diff --git a/System.Data/System/Data/ColumnTypeConverter.cs b/System.Data/System/Data/ColumnTypeConverter.cs index 69df720e1..c3fb2cbdf 100644 --- a/System.Data/System/Data/ColumnTypeConverter.cs +++ b/System.Data/System/Data/ColumnTypeConverter.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ /* diff --git a/System.Data/System/Data/Common/ActivityCorrelator.cs b/System.Data/System/Data/Common/ActivityCorrelator.cs index 4fc17b4eb..e40cbc2c5 100644 --- a/System.Data/System/Data/Common/ActivityCorrelator.cs +++ b/System.Data/System/Data/Common/ActivityCorrelator.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common diff --git a/System.Data/System/Data/Common/AdapterUtil.cs b/System.Data/System/Data/Common/AdapterUtil.cs index b2fd8d6fd..89bada172 100644 --- a/System.Data/System/Data/Common/AdapterUtil.cs +++ b/System.Data/System/Data/Common/AdapterUtil.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { @@ -1845,7 +1845,8 @@ static internal Exception InvalidArgumentValue(string methodName) { internal const int DefaultCommandTimeout = 30; internal const int DefaultConnectionTimeout = DbConnectionStringDefaults.ConnectTimeout; internal const float FailoverTimeoutStep = 0.08F; // fraction of timeout to use for fast failover connections - internal const int FirstTransparentAttemptTimeout = 500; // The first login attempt in Transparent network IP Resolution + internal const float FailoverTimeoutStepForTnir = 0.125F; // Fraction of timeout to use in case of Transparent Network IP resolution. + internal const int MinimumTimeoutForTnirMs = 500; // The first login attempt in Transparent network IP Resolution // security issue, don't rely upon static public readonly values - AS/URT 109635 static internal readonly String StrEmpty = ""; // String.Empty @@ -1996,7 +1997,7 @@ static internal string BuildQuotedString(string quotePrefix, string quoteSuffix, return resultString.ToString(); } - private static readonly string hexDigits = "0123456789abcdef"; + private const string hexDigits = "0123456789abcdef"; static internal byte[] ByteArrayFromString(string hexString, string dataTypeName) { if ((hexString.Length & 0x1) != 0) { @@ -2533,5 +2534,42 @@ static internal Version GetAssemblyVersion() { return _systemDataVersion; } + + static internal readonly string[] AzureSqlServerEndpoints = {Res.GetString(Res.AZURESQL_GenericEndpoint), + Res.GetString(Res.AZURESQL_GermanEndpoint), + Res.GetString(Res.AZURESQL_UsGovEndpoint), + Res.GetString(Res.AZURESQL_ChinaEndpoint)}; + + // This method assumes dataSource parameter is in TCP connection string format. + static internal bool IsAzureSqlServerEndpoint(string dataSource) + { + // remove server port + int i = dataSource.LastIndexOf(','); + if (i >= 0) + { + dataSource = dataSource.Substring(0, i); + } + + // check for the instance name + i = dataSource.LastIndexOf('\\'); + if (i >= 0) + { + dataSource = dataSource.Substring(0, i); + } + + // trim redundant whitespaces + dataSource = dataSource.Trim(); + + // check if servername end with any azure endpoints + for (i = 0; i < AzureSqlServerEndpoints.Length; i++) + { + if (dataSource.EndsWith(AzureSqlServerEndpoints[i], StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } } } diff --git a/System.Data/System/Data/Common/BigIntegerStorage.cs b/System.Data/System/Data/Common/BigIntegerStorage.cs index d3544903d..e26e96596 100644 --- a/System.Data/System/Data/Common/BigIntegerStorage.cs +++ b/System.Data/System/Data/Common/BigIntegerStorage.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/BooleanStorage.cs b/System.Data/System/Data/Common/BooleanStorage.cs index de174a86b..cc64c9506 100644 --- a/System.Data/System/Data/Common/BooleanStorage.cs +++ b/System.Data/System/Data/Common/BooleanStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/ByteStorage.cs b/System.Data/System/Data/Common/ByteStorage.cs index 12a9df123..d41d1576b 100644 --- a/System.Data/System/Data/Common/ByteStorage.cs +++ b/System.Data/System/Data/Common/ByteStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/CharStorage.cs b/System.Data/System/Data/Common/CharStorage.cs index b03c0df2c..f1baf809a 100644 --- a/System.Data/System/Data/Common/CharStorage.cs +++ b/System.Data/System/Data/Common/CharStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DBCommand.cs b/System.Data/System/Data/Common/DBCommand.cs index 3a2e01b26..cc4399fe3 100644 --- a/System.Data/System/Data/Common/DBCommand.cs +++ b/System.Data/System/Data/Common/DBCommand.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DBCommandBuilder.cs b/System.Data/System/Data/Common/DBCommandBuilder.cs index 9744b25b2..4205f9599 100644 --- a/System.Data/System/Data/Common/DBCommandBuilder.cs +++ b/System.Data/System/Data/Common/DBCommandBuilder.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DBConnection.cs b/System.Data/System/Data/Common/DBConnection.cs index e9967e0c0..52f045005 100644 --- a/System.Data/System/Data/Common/DBConnection.cs +++ b/System.Data/System/Data/Common/DBConnection.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DBConnectionString.cs b/System.Data/System/Data/Common/DBConnectionString.cs index ed7b7b4c5..42e1b6bb1 100644 --- a/System.Data/System/Data/Common/DBConnectionString.cs +++ b/System.Data/System/Data/Common/DBConnectionString.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { @@ -251,7 +251,7 @@ internal DBConnectionString Intersect(DBConnectionString entry) { //Debug.WriteLine("14/15/16 this AllowOnly and entry AllowOnly but no restrictions"); } - // verify _hasPassword & _parsetable are in [....] between Everett/Whidbey + // verify _hasPassword & _parsetable are in sync between Everett/Whidbey Debug.Assert(!_hasPassword || ContainsKey(KEY.Password) || ContainsKey(KEY.Pwd), "OnDeserialized password mismatch this"); Debug.Assert(null == entry || !entry._hasPassword || entry.ContainsKey(KEY.Password) || entry.ContainsKey(KEY.Pwd), "OnDeserialized password mismatch entry"); diff --git a/System.Data/System/Data/Common/DBDataPermission.cs b/System.Data/System/Data/Common/DBDataPermission.cs index 46c2906ef..ed6140309 100644 --- a/System.Data/System/Data/Common/DBDataPermission.cs +++ b/System.Data/System/Data/Common/DBDataPermission.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DBDataPermissionAttribute.cs b/System.Data/System/Data/Common/DBDataPermissionAttribute.cs index 0d22095d6..518e2c521 100644 --- a/System.Data/System/Data/Common/DBDataPermissionAttribute.cs +++ b/System.Data/System/Data/Common/DBDataPermissionAttribute.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DBParameter.cs b/System.Data/System/Data/Common/DBParameter.cs index be9208922..4a0ba3574 100644 --- a/System.Data/System/Data/Common/DBParameter.cs +++ b/System.Data/System/Data/Common/DBParameter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DBSchemaRow.cs b/System.Data/System/Data/Common/DBSchemaRow.cs index 06cf3ac14..25850cffe 100644 --- a/System.Data/System/Data/Common/DBSchemaRow.cs +++ b/System.Data/System/Data/Common/DBSchemaRow.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DBSchemaTable.cs b/System.Data/System/Data/Common/DBSchemaTable.cs index 8a548a5fa..c6c891727 100644 --- a/System.Data/System/Data/Common/DBSchemaTable.cs +++ b/System.Data/System/Data/Common/DBSchemaTable.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DataAdapter.cs b/System.Data/System/Data/Common/DataAdapter.cs index 1dbda9747..e36220920 100644 --- a/System.Data/System/Data/Common/DataAdapter.cs +++ b/System.Data/System/Data/Common/DataAdapter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DataColumnMapping.cs b/System.Data/System/Data/Common/DataColumnMapping.cs index acaf957c5..f6a843e2c 100644 --- a/System.Data/System/Data/Common/DataColumnMapping.cs +++ b/System.Data/System/Data/Common/DataColumnMapping.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DataColumnMappingCollection.cs b/System.Data/System/Data/Common/DataColumnMappingCollection.cs index 615616092..b37e75603 100644 --- a/System.Data/System/Data/Common/DataColumnMappingCollection.cs +++ b/System.Data/System/Data/Common/DataColumnMappingCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DataRecordInternal.cs b/System.Data/System/Data/Common/DataRecordInternal.cs index 9c8a7d31e..659db8d52 100644 --- a/System.Data/System/Data/Common/DataRecordInternal.cs +++ b/System.Data/System/Data/Common/DataRecordInternal.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DataStorage.cs b/System.Data/System/Data/Common/DataStorage.cs index 69087c233..cf66ff06e 100644 --- a/System.Data/System/Data/Common/DataStorage.cs +++ b/System.Data/System/Data/Common/DataStorage.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DataTableMapping.cs b/System.Data/System/Data/Common/DataTableMapping.cs index 96567755f..bbb0276ca 100644 --- a/System.Data/System/Data/Common/DataTableMapping.cs +++ b/System.Data/System/Data/Common/DataTableMapping.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DataTableMappingCollection.cs b/System.Data/System/Data/Common/DataTableMappingCollection.cs index 9ef089404..a235804a3 100644 --- a/System.Data/System/Data/Common/DataTableMappingCollection.cs +++ b/System.Data/System/Data/Common/DataTableMappingCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DateTimeOffsetStorage.cs b/System.Data/System/Data/Common/DateTimeOffsetStorage.cs index b92e6fc6f..457dc17f2 100644 --- a/System.Data/System/Data/Common/DateTimeOffsetStorage.cs +++ b/System.Data/System/Data/Common/DateTimeOffsetStorage.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DateTimeStorage.cs b/System.Data/System/Data/Common/DateTimeStorage.cs index cce489890..4ff7014c5 100644 --- a/System.Data/System/Data/Common/DateTimeStorage.cs +++ b/System.Data/System/Data/Common/DateTimeStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbConnectionOptions.cs b/System.Data/System/Data/Common/DbConnectionOptions.cs index 11257cc6d..43b8e22a3 100644 --- a/System.Data/System/Data/Common/DbConnectionOptions.cs +++ b/System.Data/System/Data/Common/DbConnectionOptions.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbConnectionPoolKey.cs b/System.Data/System/Data/Common/DbConnectionPoolKey.cs index 9142ef6dd..6ab3ddbb1 100644 --- a/System.Data/System/Data/Common/DbConnectionPoolKey.cs +++ b/System.Data/System/Data/Common/DbConnectionPoolKey.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common diff --git a/System.Data/System/Data/Common/DbConnectionStringBuilder.cs b/System.Data/System/Data/Common/DbConnectionStringBuilder.cs index 780bd97c9..42755929e 100644 --- a/System.Data/System/Data/Common/DbConnectionStringBuilder.cs +++ b/System.Data/System/Data/Common/DbConnectionStringBuilder.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbConnectionStringCommon.cs b/System.Data/System/Data/Common/DbConnectionStringCommon.cs index 24be05dfc..6327c29e8 100644 --- a/System.Data/System/Data/Common/DbConnectionStringCommon.cs +++ b/System.Data/System/Data/Common/DbConnectionStringCommon.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Common/DbDataAdapter.cs b/System.Data/System/Data/Common/DbDataAdapter.cs index 2db823111..0950ab8f2 100644 --- a/System.Data/System/Data/Common/DbDataAdapter.cs +++ b/System.Data/System/Data/Common/DbDataAdapter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbDataReader.cs b/System.Data/System/Data/Common/DbDataReader.cs index abee96850..c4c8318d0 100644 --- a/System.Data/System/Data/Common/DbDataReader.cs +++ b/System.Data/System/Data/Common/DbDataReader.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbDataSourceEnumerator.cs b/System.Data/System/Data/Common/DbDataSourceEnumerator.cs index 8b2f5d6e1..4071a35a8 100644 --- a/System.Data/System/Data/Common/DbDataSourceEnumerator.cs +++ b/System.Data/System/Data/Common/DbDataSourceEnumerator.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbException.cs b/System.Data/System/Data/Common/DbException.cs index f11303762..0a912d552 100644 --- a/System.Data/System/Data/Common/DbException.cs +++ b/System.Data/System/Data/Common/DbException.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbParameterCollection.cs b/System.Data/System/Data/Common/DbParameterCollection.cs index b4e5bb234..2f400cca1 100644 --- a/System.Data/System/Data/Common/DbParameterCollection.cs +++ b/System.Data/System/Data/Common/DbParameterCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbProviderConfigurationHandler.cs b/System.Data/System/Data/Common/DbProviderConfigurationHandler.cs index 6411c47e8..92ec37fcd 100644 --- a/System.Data/System/Data/Common/DbProviderConfigurationHandler.cs +++ b/System.Data/System/Data/Common/DbProviderConfigurationHandler.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbProviderFactories.cs b/System.Data/System/Data/Common/DbProviderFactories.cs index 7490e8ac3..9d3253620 100644 --- a/System.Data/System/Data/Common/DbProviderFactories.cs +++ b/System.Data/System/Data/Common/DbProviderFactories.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbProviderFactoriesConfigurationHandler.cs b/System.Data/System/Data/Common/DbProviderFactoriesConfigurationHandler.cs index 505e734ce..56d1a7188 100644 --- a/System.Data/System/Data/Common/DbProviderFactoriesConfigurationHandler.cs +++ b/System.Data/System/Data/Common/DbProviderFactoriesConfigurationHandler.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbProviderFactory.cs b/System.Data/System/Data/Common/DbProviderFactory.cs index 4235679cc..f0c8fd478 100644 --- a/System.Data/System/Data/Common/DbProviderFactory.cs +++ b/System.Data/System/Data/Common/DbProviderFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Common/DbProviderSpecificTypePropertyAttribute.cs b/System.Data/System/Data/Common/DbProviderSpecificTypePropertyAttribute.cs index a213939a2..1f13d32d6 100644 --- a/System.Data/System/Data/Common/DbProviderSpecificTypePropertyAttribute.cs +++ b/System.Data/System/Data/Common/DbProviderSpecificTypePropertyAttribute.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DbTransaction.cs b/System.Data/System/Data/Common/DbTransaction.cs index 467e740f8..8a3ae9046 100644 --- a/System.Data/System/Data/Common/DbTransaction.cs +++ b/System.Data/System/Data/Common/DbTransaction.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DecimalStorage.cs b/System.Data/System/Data/Common/DecimalStorage.cs index b9f8f6784..b8aeda1b8 100644 --- a/System.Data/System/Data/Common/DecimalStorage.cs +++ b/System.Data/System/Data/Common/DecimalStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/DoubleStorage.cs b/System.Data/System/Data/Common/DoubleStorage.cs index 15af90c02..b11514c7d 100644 --- a/System.Data/System/Data/Common/DoubleStorage.cs +++ b/System.Data/System/Data/Common/DoubleStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/FieldNameLookup.cs b/System.Data/System/Data/Common/FieldNameLookup.cs index 41df2b1aa..5ae728795 100644 --- a/System.Data/System/Data/Common/FieldNameLookup.cs +++ b/System.Data/System/Data/Common/FieldNameLookup.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/Common/GreenMethods.cs b/System.Data/System/Data/Common/GreenMethods.cs index 8aff41ed3..ced5a58d8 100644 --- a/System.Data/System/Data/Common/GreenMethods.cs +++ b/System.Data/System/Data/Common/GreenMethods.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Common/HandlerBase.cs b/System.Data/System/Data/Common/HandlerBase.cs index 99945fe78..3762aa488 100644 --- a/System.Data/System/Data/Common/HandlerBase.cs +++ b/System.Data/System/Data/Common/HandlerBase.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/Int16Storage.cs b/System.Data/System/Data/Common/Int16Storage.cs index 8d1d0b2a0..0c62a2043 100644 --- a/System.Data/System/Data/Common/Int16Storage.cs +++ b/System.Data/System/Data/Common/Int16Storage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/Int32Storage.cs b/System.Data/System/Data/Common/Int32Storage.cs index 870bd1093..1a59d7e12 100644 --- a/System.Data/System/Data/Common/Int32Storage.cs +++ b/System.Data/System/Data/Common/Int32Storage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/Int64Storage.cs b/System.Data/System/Data/Common/Int64Storage.cs index f50062992..26a81b6fa 100644 --- a/System.Data/System/Data/Common/Int64Storage.cs +++ b/System.Data/System/Data/Common/Int64Storage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/MultipartIdentifier.cs b/System.Data/System/Data/Common/MultipartIdentifier.cs index 531dfa1df..a2a077043 100644 --- a/System.Data/System/Data/Common/MultipartIdentifier.cs +++ b/System.Data/System/Data/Common/MultipartIdentifier.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/NameValuePair.cs b/System.Data/System/Data/Common/NameValuePair.cs index bcf188908..f0b7cdc17 100644 --- a/System.Data/System/Data/Common/NameValuePair.cs +++ b/System.Data/System/Data/Common/NameValuePair.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/NameValuePermission.cs b/System.Data/System/Data/Common/NameValuePermission.cs index 9f705d256..f2088dba9 100644 --- a/System.Data/System/Data/Common/NameValuePermission.cs +++ b/System.Data/System/Data/Common/NameValuePermission.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/ObjectStorage.cs b/System.Data/System/Data/Common/ObjectStorage.cs index f4c90546b..eb3a09d9c 100644 --- a/System.Data/System/Data/Common/ObjectStorage.cs +++ b/System.Data/System/Data/Common/ObjectStorage.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/RowUpdatedEventArgs.cs b/System.Data/System/Data/Common/RowUpdatedEventArgs.cs index 04af7fa7e..132952ed7 100644 --- a/System.Data/System/Data/Common/RowUpdatedEventArgs.cs +++ b/System.Data/System/Data/Common/RowUpdatedEventArgs.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/RowUpdatingEventArgs.cs b/System.Data/System/Data/Common/RowUpdatingEventArgs.cs index 1f6c6918c..50c8c0492 100644 --- a/System.Data/System/Data/Common/RowUpdatingEventArgs.cs +++ b/System.Data/System/Data/Common/RowUpdatingEventArgs.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SByteStorage.cs b/System.Data/System/Data/Common/SByteStorage.cs index 0ef3d5edb..66b546597 100644 --- a/System.Data/System/Data/Common/SByteStorage.cs +++ b/System.Data/System/Data/Common/SByteStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLConvert.cs b/System.Data/System/Data/Common/SQLConvert.cs index 4c1b691fc..19b823a39 100644 --- a/System.Data/System/Data/Common/SQLConvert.cs +++ b/System.Data/System/Data/Common/SQLConvert.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLBinaryStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQLBinaryStorage.cs index 752435570..33d7466b1 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLBinaryStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLBinaryStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLByteStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQLByteStorage.cs index d8f70c87a..45382a0d3 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLByteStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLByteStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLBytesStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQLBytesStorage.cs index da7d794b7..b4ce97d90 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLBytesStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLBytesStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLCharsStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQLCharsStorage.cs index c8af7abb4..79e094e2c 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLCharsStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLCharsStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLDateTimeStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQLDateTimeStorage.cs index 60753ae43..96a18718a 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLDateTimeStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLDateTimeStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLDecimalStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQLDecimalStorage.cs index e6a92bf1b..c451931a0 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLDecimalStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLDecimalStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLDoubleStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQLDoubleStorage.cs index 8833b829f..3062b3edb 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLDoubleStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLDoubleStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLGuidStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQLGuidStorage.cs index 79c818060..0c4f3a3dd 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLGuidStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLGuidStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLInt16Storage.cs b/System.Data/System/Data/Common/SQLTypes/SQLInt16Storage.cs index aff67bae5..9168c4d61 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLInt16Storage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLInt16Storage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLInt32Storage.cs b/System.Data/System/Data/Common/SQLTypes/SQLInt32Storage.cs index 4a31af610..f4c94d5e4 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLInt32Storage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLInt32Storage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLInt64Storage.cs b/System.Data/System/Data/Common/SQLTypes/SQLInt64Storage.cs index eb608d338..06720cb35 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLInt64Storage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLInt64Storage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLMoneyStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQLMoneyStorage.cs index fc4a344a3..184c9bccd 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLMoneyStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLMoneyStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLSingleStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQLSingleStorage.cs index d6c69725e..56cc3e690 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLSingleStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLSingleStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQLStringStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQLStringStorage.cs index 7201b55c5..0e4611fbe 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQLStringStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQLStringStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SQlBooleanStorage.cs b/System.Data/System/Data/Common/SQLTypes/SQlBooleanStorage.cs index 53fd2a92a..c0b0dac31 100644 --- a/System.Data/System/Data/Common/SQLTypes/SQlBooleanStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SQlBooleanStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SqlUDTStorage.cs b/System.Data/System/Data/Common/SQLTypes/SqlUDTStorage.cs index 1637442fe..f2a8c84a1 100644 --- a/System.Data/System/Data/Common/SQLTypes/SqlUDTStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SqlUDTStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SQLTypes/SqlXmlStorage.cs b/System.Data/System/Data/Common/SQLTypes/SqlXmlStorage.cs index be6cc6e52..8f3a03926 100644 --- a/System.Data/System/Data/Common/SQLTypes/SqlXmlStorage.cs +++ b/System.Data/System/Data/Common/SQLTypes/SqlXmlStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SafeNativeMethods.cs b/System.Data/System/Data/Common/SafeNativeMethods.cs index 5f8bf6d36..5e1c0ffc3 100644 --- a/System.Data/System/Data/Common/SafeNativeMethods.cs +++ b/System.Data/System/Data/Common/SafeNativeMethods.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Common/SchemaTableColumn.cs b/System.Data/System/Data/Common/SchemaTableColumn.cs index 69df0612c..3995656fb 100644 --- a/System.Data/System/Data/Common/SchemaTableColumn.cs +++ b/System.Data/System/Data/Common/SchemaTableColumn.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SchemaTableOptionalColumn.cs b/System.Data/System/Data/Common/SchemaTableOptionalColumn.cs index 80a961919..c4ab9bc5a 100644 --- a/System.Data/System/Data/Common/SchemaTableOptionalColumn.cs +++ b/System.Data/System/Data/Common/SchemaTableOptionalColumn.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/SingleStorage.cs b/System.Data/System/Data/Common/SingleStorage.cs index 1f1c8b451..2379ea758 100644 --- a/System.Data/System/Data/Common/SingleStorage.cs +++ b/System.Data/System/Data/Common/SingleStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/StringStorage.cs b/System.Data/System/Data/Common/StringStorage.cs index 7125e5d85..2885f9b9a 100644 --- a/System.Data/System/Data/Common/StringStorage.cs +++ b/System.Data/System/Data/Common/StringStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/System.Data_BID.cs b/System.Data/System/Data/Common/System.Data_BID.cs index 8cff81a5d..d70b1c6c0 100644 --- a/System.Data/System/Data/Common/System.Data_BID.cs +++ b/System.Data/System/Data/Common/System.Data_BID.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //----------------------------------------------------------------------------------------------- using System; diff --git a/System.Data/System/Data/Common/TimeSpanStorage.cs b/System.Data/System/Data/Common/TimeSpanStorage.cs index bf931fc47..b46bf5fb2 100644 --- a/System.Data/System/Data/Common/TimeSpanStorage.cs +++ b/System.Data/System/Data/Common/TimeSpanStorage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/UInt16Storage.cs b/System.Data/System/Data/Common/UInt16Storage.cs index 5bafd626b..06320a1b7 100644 --- a/System.Data/System/Data/Common/UInt16Storage.cs +++ b/System.Data/System/Data/Common/UInt16Storage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { @@ -15,7 +15,7 @@ namespace System.Data.Common { internal sealed class UInt16Storage : DataStorage { - private static readonly UInt16 defaultValue = UInt16.MinValue; + private const UInt16 defaultValue = UInt16.MinValue; private UInt16[] values; diff --git a/System.Data/System/Data/Common/UInt32Storage.cs b/System.Data/System/Data/Common/UInt32Storage.cs index d2701c49d..69cb7ef12 100644 --- a/System.Data/System/Data/Common/UInt32Storage.cs +++ b/System.Data/System/Data/Common/UInt32Storage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { @@ -15,7 +15,7 @@ namespace System.Data.Common { internal sealed class UInt32Storage : DataStorage { - private static readonly UInt32 defaultValue = UInt32.MinValue; + private const UInt32 defaultValue = UInt32.MinValue; private UInt32[] values; diff --git a/System.Data/System/Data/Common/UInt64Storage.cs b/System.Data/System/Data/Common/UInt64Storage.cs index 1242f279c..b5e6f7b1b 100644 --- a/System.Data/System/Data/Common/UInt64Storage.cs +++ b/System.Data/System/Data/Common/UInt64Storage.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { @@ -15,7 +15,7 @@ namespace System.Data.Common { internal sealed class UInt64Storage : DataStorage { - private static readonly UInt64 defaultValue = UInt64.MinValue; + private const UInt64 defaultValue = UInt64.MinValue; private UInt64[] values; diff --git a/System.Data/System/Data/Common/UnsafeNativeMethods.cs b/System.Data/System/Data/Common/UnsafeNativeMethods.cs index 47a1abb70..5a595c9ef 100644 --- a/System.Data/System/Data/Common/UnsafeNativeMethods.cs +++ b/System.Data/System/Data/Common/UnsafeNativeMethods.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Common/dbdatarecord.cs b/System.Data/System/Data/Common/dbdatarecord.cs index 7c140b1af..2f56981aa 100644 --- a/System.Data/System/Data/Common/dbdatarecord.cs +++ b/System.Data/System/Data/Common/dbdatarecord.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Common/dbenumerator.cs b/System.Data/System/Data/Common/dbenumerator.cs index 758d60629..5377586b7 100644 --- a/System.Data/System/Data/Common/dbenumerator.cs +++ b/System.Data/System/Data/Common/dbenumerator.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/Constraint.cs b/System.Data/System/Data/Constraint.cs index ff25eb8f6..0d9bd2e24 100644 --- a/System.Data/System/Data/Constraint.cs +++ b/System.Data/System/Data/Constraint.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/ConstraintCollection.cs b/System.Data/System/Data/ConstraintCollection.cs index 357723bae..a38733788 100644 --- a/System.Data/System/Data/ConstraintCollection.cs +++ b/System.Data/System/Data/ConstraintCollection.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/ConstraintConverter.cs b/System.Data/System/Data/ConstraintConverter.cs index 176866fa5..1564f89dd 100644 --- a/System.Data/System/Data/ConstraintConverter.cs +++ b/System.Data/System/Data/ConstraintConverter.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/ConstraintEnumerator.cs b/System.Data/System/Data/ConstraintEnumerator.cs index 72c20a474..8e4c2b991 100644 --- a/System.Data/System/Data/ConstraintEnumerator.cs +++ b/System.Data/System/Data/ConstraintEnumerator.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DBConcurrencyException.cs b/System.Data/System/Data/DBConcurrencyException.cs index a7724df44..5197faec7 100644 --- a/System.Data/System/Data/DBConcurrencyException.cs +++ b/System.Data/System/Data/DBConcurrencyException.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataColumn.cs b/System.Data/System/Data/DataColumn.cs index cacc19d4e..6c308bf2a 100644 --- a/System.Data/System/Data/DataColumn.cs +++ b/System.Data/System/Data/DataColumn.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataColumnChangeEvent.cs b/System.Data/System/Data/DataColumnChangeEvent.cs index 080d166c7..2c05d2f25 100644 --- a/System.Data/System/Data/DataColumnChangeEvent.cs +++ b/System.Data/System/Data/DataColumnChangeEvent.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataColumnCollection.cs b/System.Data/System/Data/DataColumnCollection.cs index 4a8f8119c..d486143a9 100644 --- a/System.Data/System/Data/DataColumnCollection.cs +++ b/System.Data/System/Data/DataColumnCollection.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataColumnPropertyDescriptor.cs b/System.Data/System/Data/DataColumnPropertyDescriptor.cs index 48d581f57..e99ccf43b 100644 --- a/System.Data/System/Data/DataColumnPropertyDescriptor.cs +++ b/System.Data/System/Data/DataColumnPropertyDescriptor.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataError.cs b/System.Data/System/Data/DataError.cs index ca3cae694..5cd3c8022 100644 --- a/System.Data/System/Data/DataError.cs +++ b/System.Data/System/Data/DataError.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataException.cs b/System.Data/System/Data/DataException.cs index f8de1c1bf..50f42cbe7 100644 --- a/System.Data/System/Data/DataException.cs +++ b/System.Data/System/Data/DataException.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -13,7 +13,7 @@ namespace System.Data { using System.Globalization; using System.Runtime.Serialization; - // [....]: This functions are major point of localization. + // Microsoft: This functions are major point of localization. // We need to have a rules to enforce consistency there. // The dangerous point there are the string arguments of the exported (internal) methods. // This string can be argument, table or constraint name but never text of exception itself. diff --git a/System.Data/System/Data/DataKey.cs b/System.Data/System/Data/DataKey.cs index a5f4cb57a..6581279d4 100644 --- a/System.Data/System/Data/DataKey.cs +++ b/System.Data/System/Data/DataKey.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataRelation.cs b/System.Data/System/Data/DataRelation.cs index 3838ca9ad..e63034c11 100644 --- a/System.Data/System/Data/DataRelation.cs +++ b/System.Data/System/Data/DataRelation.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ /***************************************************************************************************** diff --git a/System.Data/System/Data/DataRelationCollection.cs b/System.Data/System/Data/DataRelationCollection.cs index baec5ee44..44a1d6d2b 100644 --- a/System.Data/System/Data/DataRelationCollection.cs +++ b/System.Data/System/Data/DataRelationCollection.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -250,7 +250,7 @@ public virtual void Clear() { OnCollectionChanging(RefreshEventArgs); for (int i = count - 1; i >= 0; i--) { inTransition = this[i]; - RemoveCore(inTransition); // [....] : No need to go for try catch here and this will surely not throw any exception + RemoveCore(inTransition); // Microsoft : No need to go for try catch here and this will surely not throw any exception } OnCollectionChanged(RefreshEventArgs); inTransition = null; diff --git a/System.Data/System/Data/DataRelationPropertyDescriptor.cs b/System.Data/System/Data/DataRelationPropertyDescriptor.cs index c80abf5a9..b3885050e 100644 --- a/System.Data/System/Data/DataRelationPropertyDescriptor.cs +++ b/System.Data/System/Data/DataRelationPropertyDescriptor.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataRow.cs b/System.Data/System/Data/DataRow.cs index 557f5e448..acfadee90 100644 --- a/System.Data/System/Data/DataRow.cs +++ b/System.Data/System/Data/DataRow.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataRowChangeEvent.cs b/System.Data/System/Data/DataRowChangeEvent.cs index 444f93602..01a56d236 100644 --- a/System.Data/System/Data/DataRowChangeEvent.cs +++ b/System.Data/System/Data/DataRowChangeEvent.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataRowCollection.cs b/System.Data/System/Data/DataRowCollection.cs index 81d040e42..dbed8bf40 100644 --- a/System.Data/System/Data/DataRowCollection.cs +++ b/System.Data/System/Data/DataRowCollection.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataRowView.cs b/System.Data/System/Data/DataRowView.cs index 64eb89f9a..059764563 100644 --- a/System.Data/System/Data/DataRowView.cs +++ b/System.Data/System/Data/DataRowView.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataSet.cs b/System.Data/System/Data/DataSet.cs index b9f0af4ca..5984670e2 100644 --- a/System.Data/System/Data/DataSet.cs +++ b/System.Data/System/Data/DataSet.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -1104,7 +1104,7 @@ public virtual DataSet Clone() { try { DataSet ds = (DataSet)Activator.CreateInstance(this.GetType(), true); - if (ds.Tables.Count > 0) // [....] : To clean up all the schema in strong typed dataset. + if (ds.Tables.Count > 0) // Microsoft : To clean up all the schema in strong typed dataset. ds.Reset(); //copy some original dataset properties @@ -3086,7 +3086,7 @@ internal bool ValidateLocaleConstraint() { } } - // [....]: may be better to rewrite this as nonrecursive? + // Microsoft: may be better to rewrite this as nonrecursive? internal DataTable FindTable(DataTable baseTable, PropertyDescriptor[] props, int propStart) { if (props.Length < propStart + 1) return baseTable; diff --git a/System.Data/System/Data/DataSysAttribute.cs b/System.Data/System/Data/DataSysAttribute.cs index c0763fca7..6022e8f8b 100644 --- a/System.Data/System/Data/DataSysAttribute.cs +++ b/System.Data/System/Data/DataSysAttribute.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ /* diff --git a/System.Data/System/Data/DataTable.cs b/System.Data/System/Data/DataTable.cs index 24673fa5c..6c841445c 100644 --- a/System.Data/System/Data/DataTable.cs +++ b/System.Data/System/Data/DataTable.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -1893,7 +1893,7 @@ virtual public void EndInit() { } } } - fInitInProgress = false; // [....] : 77890. It is must that we set off this flag after calling FinishInitxxx(); + fInitInProgress = false; // Microsoft : 77890. It is must that we set off this flag after calling FinishInitxxx(); if (delayedSetPrimaryKey != null) { PrimaryKey = delayedSetPrimaryKey; delayedSetPrimaryKey = null; @@ -2150,7 +2150,7 @@ internal DataTable Clone(DataSet cloneDS) { Bid.ScopeEnter(out hscp, " %d#, cloneDS=%d\n", ObjectID, (cloneDS != null) ? cloneDS.ObjectID : 0); try { DataTable clone = CreateInstance(); - if (clone.Columns.Count > 0) // [....] : To clean up all the schema in strong typed dataset. + if (clone.Columns.Count > 0) // Microsoft : To clean up all the schema in strong typed dataset. clone.Reset(); return CloneTo(clone, cloneDS, false); } @@ -2225,8 +2225,8 @@ private DataTable CloneTo(DataTable clone, DataSet cloneDS, bool skipExpressionC clone._caseSensitiveUserSet = _caseSensitiveUserSet; clone.displayExpression = displayExpression; - clone.typeName = typeName; //[....] - clone.repeatableElement = repeatableElement; //[....] + clone.typeName = typeName; //Microsoft + clone.repeatableElement = repeatableElement; //Microsoft clone.MinimumCapacity = MinimumCapacity; clone.RemotingFormat = RemotingFormat; // clone.SerializeHierarchy = SerializeHierarchy; @@ -5541,8 +5541,8 @@ internal XmlReadMode ReadXml(XmlReader reader, XmlReadMode mode, bool denyResolv throw ExceptionBuilder.DataTableInferenceNotSupported(); } - // [....] xmlload.InferSchema(xdoc, null); - // [....] xmlload.LoadData(xdoc); + // Microsoft xmlload.InferSchema(xdoc, null); + // Microsoft xmlload.LoadData(xdoc); } } RestoreConstraint(originalEnforceConstraint); diff --git a/System.Data/System/Data/DataTableClearEvent.cs b/System.Data/System/Data/DataTableClearEvent.cs index a942a9336..302330291 100644 --- a/System.Data/System/Data/DataTableClearEvent.cs +++ b/System.Data/System/Data/DataTableClearEvent.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataTableCollection.cs b/System.Data/System/Data/DataTableCollection.cs index abe20b7f9..b42df0df4 100644 --- a/System.Data/System/Data/DataTableCollection.cs +++ b/System.Data/System/Data/DataTableCollection.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataTableNewRowEvent.cs b/System.Data/System/Data/DataTableNewRowEvent.cs index bfd0fcd7a..db994c7c2 100644 --- a/System.Data/System/Data/DataTableNewRowEvent.cs +++ b/System.Data/System/Data/DataTableNewRowEvent.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataTablePropertyDescriptor.cs b/System.Data/System/Data/DataTablePropertyDescriptor.cs index a5ffd176b..3d9f30c63 100644 --- a/System.Data/System/Data/DataTablePropertyDescriptor.cs +++ b/System.Data/System/Data/DataTablePropertyDescriptor.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataTableReader.cs b/System.Data/System/Data/DataTableReader.cs index 90d9af9f0..475e6f721 100644 --- a/System.Data/System/Data/DataTableReader.cs +++ b/System.Data/System/Data/DataTableReader.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataTableReaderListener.cs b/System.Data/System/Data/DataTableReaderListener.cs index 66b1c720d..545909a4f 100644 --- a/System.Data/System/Data/DataTableReaderListener.cs +++ b/System.Data/System/Data/DataTableReaderListener.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataTableTypeConverter.cs b/System.Data/System/Data/DataTableTypeConverter.cs index b5a9ed888..dc1425682 100644 --- a/System.Data/System/Data/DataTableTypeConverter.cs +++ b/System.Data/System/Data/DataTableTypeConverter.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataView.cs b/System.Data/System/Data/DataView.cs index fb93c55a2..69c0ce2b6 100644 --- a/System.Data/System/Data/DataView.cs +++ b/System.Data/System/Data/DataView.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -166,7 +166,7 @@ public DataView(DataTable table, String RowFilter, string Sort, DataViewRowState /// /// Allow construction of DataView with and /// - /// This is a copy of the other DataView ctor and needs to be kept in [....] + /// This is a copy of the other DataView ctor and needs to be kept in sync internal DataView(DataTable table, System.Predicate predicate, System.Comparison comparison, DataViewRowState RowState) { GC.SuppressFinalize(this); Bid.Trace(" %d#, table=%d, RowState=%d{ds.DataViewRowState}\n", @@ -1294,7 +1294,7 @@ protected virtual void IndexListChanged(object sender, ListChangedEventArgs e) { if (ListChangedType.Reset != e.ListChangedType) { OnListChanged(e); } - if (addNewRow != null && index.RecordCount == 0) { // [....] : 83032 Clear the newly added row as the underlying index is reset. + if (addNewRow != null && index.RecordCount == 0) { // Microsoft : 83032 Clear the newly added row as the underlying index is reset. FinishAddNew(false); } if (ListChangedType.Reset == e.ListChangedType) { @@ -1511,7 +1511,7 @@ internal void SetDataViewManager(DataViewManager dataViewManager) { dataViewManager.nViews++; DataViewSetting dataViewSetting = dataViewManager.DataViewSettings[table]; try { - // [....]: check that we will not do unnesasary operation here if dataViewSetting.Sort == this.Sort ... + // Microsoft: check that we will not do unnesasary operation here if dataViewSetting.Sort == this.Sort ... applyDefaultSort = dataViewSetting.ApplyDefaultSort; DataExpression newFilter = new DataExpression(table, dataViewSetting.RowFilter); SetIndex(dataViewSetting.Sort, dataViewSetting.RowStateFilter, newFilter); diff --git a/System.Data/System/Data/DataViewListener.cs b/System.Data/System/Data/DataViewListener.cs index 32fb4fbf6..0821be330 100644 --- a/System.Data/System/Data/DataViewListener.cs +++ b/System.Data/System/Data/DataViewListener.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataViewManager.cs b/System.Data/System/Data/DataViewManager.cs index f597b87e8..29d032803 100644 --- a/System.Data/System/Data/DataViewManager.cs +++ b/System.Data/System/Data/DataViewManager.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -300,7 +300,7 @@ string IBindingList.GetListName(PropertyDescriptor[] listAccessors) { } */ - // [....]: GetListName and GetItemProperties almost the same in DataView and DataViewManager + // Microsoft: GetListName and GetItemProperties almost the same in DataView and DataViewManager string System.ComponentModel.ITypedList.GetListName(PropertyDescriptor[] listAccessors) { DataSet dataSet = DataSet; if (dataSet == null) diff --git a/System.Data/System/Data/DataViewManagerListItemTypeDescriptor.cs b/System.Data/System/Data/DataViewManagerListItemTypeDescriptor.cs index 60d96cc86..b9ed419b4 100644 --- a/System.Data/System/Data/DataViewManagerListItemTypeDescriptor.cs +++ b/System.Data/System/Data/DataViewManagerListItemTypeDescriptor.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataViewSetting.cs b/System.Data/System/Data/DataViewSetting.cs index d2d4b86f4..1072ce263 100644 --- a/System.Data/System/Data/DataViewSetting.cs +++ b/System.Data/System/Data/DataViewSetting.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DataViewSettingCollection.cs b/System.Data/System/Data/DataViewSettingCollection.cs index fc91e196b..cbdfa92f2 100644 --- a/System.Data/System/Data/DataViewSettingCollection.cs +++ b/System.Data/System/Data/DataViewSettingCollection.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/DefaultValueTypeConverter.cs b/System.Data/System/Data/DefaultValueTypeConverter.cs index 092a27b24..977867402 100644 --- a/System.Data/System/Data/DefaultValueTypeConverter.cs +++ b/System.Data/System/Data/DefaultValueTypeConverter.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ /* diff --git a/System.Data/System/Data/FillErrorEventArgs.cs b/System.Data/System/Data/FillErrorEventArgs.cs index ea0f9b7d9..83c581a83 100644 --- a/System.Data/System/Data/FillErrorEventArgs.cs +++ b/System.Data/System/Data/FillErrorEventArgs.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { // MDAC 59437 diff --git a/System.Data/System/Data/Filter/AggregateNode.cs b/System.Data/System/Data/Filter/AggregateNode.cs index 0515908cc..2fe5c8136 100644 --- a/System.Data/System/Data/Filter/AggregateNode.cs +++ b/System.Data/System/Data/Filter/AggregateNode.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Filter/BinaryNode.cs b/System.Data/System/Data/Filter/BinaryNode.cs index 1e2691c82..808ad9007 100644 --- a/System.Data/System/Data/Filter/BinaryNode.cs +++ b/System.Data/System/Data/Filter/BinaryNode.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Filter/ConstNode.cs b/System.Data/System/Data/Filter/ConstNode.cs index 3d3215329..ae40e2269 100644 --- a/System.Data/System/Data/Filter/ConstNode.cs +++ b/System.Data/System/Data/Filter/ConstNode.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Filter/DataExpression.cs b/System.Data/System/Data/Filter/DataExpression.cs index 2a13366e5..a61417462 100644 --- a/System.Data/System/Data/Filter/DataExpression.cs +++ b/System.Data/System/Data/Filter/DataExpression.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Filter/ExpressionNode.cs b/System.Data/System/Data/Filter/ExpressionNode.cs index bbd59d3c8..049e98aa8 100644 --- a/System.Data/System/Data/Filter/ExpressionNode.cs +++ b/System.Data/System/Data/Filter/ExpressionNode.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Filter/ExpressionParser.cs b/System.Data/System/Data/Filter/ExpressionParser.cs index 0cbd98ec9..c040e8e4f 100644 --- a/System.Data/System/Data/Filter/ExpressionParser.cs +++ b/System.Data/System/Data/Filter/ExpressionParser.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Filter/FilterException.cs b/System.Data/System/Data/Filter/FilterException.cs index 643744062..11165c62e 100644 --- a/System.Data/System/Data/Filter/FilterException.cs +++ b/System.Data/System/Data/Filter/FilterException.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Filter/FunctionNode.cs b/System.Data/System/Data/Filter/FunctionNode.cs index 97580e2d9..7d53c4934 100644 --- a/System.Data/System/Data/Filter/FunctionNode.cs +++ b/System.Data/System/Data/Filter/FunctionNode.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Filter/LookupNode.cs b/System.Data/System/Data/Filter/LookupNode.cs index 3b75a801c..896122d70 100644 --- a/System.Data/System/Data/Filter/LookupNode.cs +++ b/System.Data/System/Data/Filter/LookupNode.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -92,7 +92,7 @@ internal override object Eval(DataRow row, DataRowVersion version) { if (parent == null) return DBNull.Value; - return parent[column, parent.HasVersion(version) ? version : DataRowVersion.Current]; // [....] : Bug 76154 + return parent[column, parent.HasVersion(version) ? version : DataRowVersion.Current]; // Microsoft : Bug 76154 } internal override object Eval(int[] recordNos) { diff --git a/System.Data/System/Data/Filter/NameNode.cs b/System.Data/System/Data/Filter/NameNode.cs index 4ec71c0e7..efc3b139e 100644 --- a/System.Data/System/Data/Filter/NameNode.cs +++ b/System.Data/System/Data/Filter/NameNode.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Filter/Operators.cs b/System.Data/System/Data/Filter/Operators.cs index ef806e204..863a0c0f0 100644 --- a/System.Data/System/Data/Filter/Operators.cs +++ b/System.Data/System/Data/Filter/Operators.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Filter/UnaryNode.cs b/System.Data/System/Data/Filter/UnaryNode.cs index 21f4fec0c..2bc957117 100644 --- a/System.Data/System/Data/Filter/UnaryNode.cs +++ b/System.Data/System/Data/Filter/UnaryNode.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Filter/ZeroOpNode.cs b/System.Data/System/Data/Filter/ZeroOpNode.cs index e9c0ad4fa..21e318aa4 100644 --- a/System.Data/System/Data/Filter/ZeroOpNode.cs +++ b/System.Data/System/Data/Filter/ZeroOpNode.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/ForeignKeyConstraint.cs b/System.Data/System/Data/ForeignKeyConstraint.cs index 5afa2ecbd..26350a8bf 100644 --- a/System.Data/System/Data/ForeignKeyConstraint.cs +++ b/System.Data/System/Data/ForeignKeyConstraint.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/MergeFailedEvent.cs b/System.Data/System/Data/MergeFailedEvent.cs index 880119a67..3de377905 100644 --- a/System.Data/System/Data/MergeFailedEvent.cs +++ b/System.Data/System/Data/MergeFailedEvent.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Merger.cs b/System.Data/System/Data/Merger.cs index 091a03a2a..0d01c4987 100644 --- a/System.Data/System/Data/Merger.cs +++ b/System.Data/System/Data/Merger.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/Odbc/DbDataRecord.cs b/System.Data/System/Data/Odbc/DbDataRecord.cs index ac00f0d0e..ea81451b6 100644 --- a/System.Data/System/Data/Odbc/DbDataRecord.cs +++ b/System.Data/System/Data/Odbc/DbDataRecord.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/Odbc32.cs b/System.Data/System/Data/Odbc/Odbc32.cs index 63a7a6e29..4fddaba87 100644 --- a/System.Data/System/Data/Odbc/Odbc32.cs +++ b/System.Data/System/Data/Odbc/Odbc32.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/Odbc/OdbcCommand.cs b/System.Data/System/Data/Odbc/OdbcCommand.cs index a5b4cbdf0..2c1f531f2 100644 --- a/System.Data/System/Data/Odbc/OdbcCommand.cs +++ b/System.Data/System/Data/Odbc/OdbcCommand.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcCommandBuilder.cs b/System.Data/System/Data/Odbc/OdbcCommandBuilder.cs index 955c786fd..e94f58756 100644 --- a/System.Data/System/Data/Odbc/OdbcCommandBuilder.cs +++ b/System.Data/System/Data/Odbc/OdbcCommandBuilder.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcConnection.cs b/System.Data/System/Data/Odbc/OdbcConnection.cs index bf56cc81f..7a35ef87c 100644 --- a/System.Data/System/Data/Odbc/OdbcConnection.cs +++ b/System.Data/System/Data/Odbc/OdbcConnection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcConnectionFactory.cs b/System.Data/System/Data/Odbc/OdbcConnectionFactory.cs index 956635682..e72fc109f 100644 --- a/System.Data/System/Data/Odbc/OdbcConnectionFactory.cs +++ b/System.Data/System/Data/Odbc/OdbcConnectionFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Odbc diff --git a/System.Data/System/Data/Odbc/OdbcConnectionHandle.cs b/System.Data/System/Data/Odbc/OdbcConnectionHandle.cs index fc645f7e7..fd0b3598c 100644 --- a/System.Data/System/Data/Odbc/OdbcConnectionHandle.cs +++ b/System.Data/System/Data/Odbc/OdbcConnectionHandle.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcConnectionOpen.cs b/System.Data/System/Data/Odbc/OdbcConnectionOpen.cs index cbfb7691d..42c134450 100644 --- a/System.Data/System/Data/Odbc/OdbcConnectionOpen.cs +++ b/System.Data/System/Data/Odbc/OdbcConnectionOpen.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcConnectionPoolProviderInfo.cs b/System.Data/System/Data/Odbc/OdbcConnectionPoolProviderInfo.cs index b631eabdb..a48d5d741 100644 --- a/System.Data/System/Data/Odbc/OdbcConnectionPoolProviderInfo.cs +++ b/System.Data/System/Data/Odbc/OdbcConnectionPoolProviderInfo.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Odbc diff --git a/System.Data/System/Data/Odbc/OdbcConnectionString.cs b/System.Data/System/Data/Odbc/OdbcConnectionString.cs index 821449546..f9d7a4654 100644 --- a/System.Data/System/Data/Odbc/OdbcConnectionString.cs +++ b/System.Data/System/Data/Odbc/OdbcConnectionString.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Odbc { diff --git a/System.Data/System/Data/Odbc/OdbcConnectionStringbuilder.cs b/System.Data/System/Data/Odbc/OdbcConnectionStringbuilder.cs index 224cf9984..13193c544 100644 --- a/System.Data/System/Data/Odbc/OdbcConnectionStringbuilder.cs +++ b/System.Data/System/Data/Odbc/OdbcConnectionStringbuilder.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcDataAdapter.cs b/System.Data/System/Data/Odbc/OdbcDataAdapter.cs index c05c0b67f..b3bbbe129 100644 --- a/System.Data/System/Data/Odbc/OdbcDataAdapter.cs +++ b/System.Data/System/Data/Odbc/OdbcDataAdapter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcDataReader.cs b/System.Data/System/Data/Odbc/OdbcDataReader.cs index 2428b5e49..b361a55d0 100644 --- a/System.Data/System/Data/Odbc/OdbcDataReader.cs +++ b/System.Data/System/Data/Odbc/OdbcDataReader.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcEnvironment.cs b/System.Data/System/Data/Odbc/OdbcEnvironment.cs index 86685f8d2..e2f228c21 100644 --- a/System.Data/System/Data/Odbc/OdbcEnvironment.cs +++ b/System.Data/System/Data/Odbc/OdbcEnvironment.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcEnvironmentHandle.cs b/System.Data/System/Data/Odbc/OdbcEnvironmentHandle.cs index a01fa82c9..78d9cb709 100644 --- a/System.Data/System/Data/Odbc/OdbcEnvironmentHandle.cs +++ b/System.Data/System/Data/Odbc/OdbcEnvironmentHandle.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcError.cs b/System.Data/System/Data/Odbc/OdbcError.cs index 08fbed4a1..2a1c94411 100644 --- a/System.Data/System/Data/Odbc/OdbcError.cs +++ b/System.Data/System/Data/Odbc/OdbcError.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcErrorCollection.cs b/System.Data/System/Data/Odbc/OdbcErrorCollection.cs index 1358b94a3..00f464349 100644 --- a/System.Data/System/Data/Odbc/OdbcErrorCollection.cs +++ b/System.Data/System/Data/Odbc/OdbcErrorCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Odbc { diff --git a/System.Data/System/Data/Odbc/OdbcException.cs b/System.Data/System/Data/Odbc/OdbcException.cs index ef8ebabb0..a852637eb 100644 --- a/System.Data/System/Data/Odbc/OdbcException.cs +++ b/System.Data/System/Data/Odbc/OdbcException.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcFactory.cs b/System.Data/System/Data/Odbc/OdbcFactory.cs index 4637f0924..da89d9bac 100644 --- a/System.Data/System/Data/Odbc/OdbcFactory.cs +++ b/System.Data/System/Data/Odbc/OdbcFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcHandle.cs b/System.Data/System/Data/Odbc/OdbcHandle.cs index cf4362005..f4deea79f 100644 --- a/System.Data/System/Data/Odbc/OdbcHandle.cs +++ b/System.Data/System/Data/Odbc/OdbcHandle.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcInfoMessageEvent.cs b/System.Data/System/Data/Odbc/OdbcInfoMessageEvent.cs index 18ea6b2f8..fed1a56fc 100644 --- a/System.Data/System/Data/Odbc/OdbcInfoMessageEvent.cs +++ b/System.Data/System/Data/Odbc/OdbcInfoMessageEvent.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcParameter.cs b/System.Data/System/Data/Odbc/OdbcParameter.cs index 013a65cb2..d9a23bb2a 100644 --- a/System.Data/System/Data/Odbc/OdbcParameter.cs +++ b/System.Data/System/Data/Odbc/OdbcParameter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ @@ -326,11 +326,11 @@ private int GetColumnSize(object value, int offset, int ordinal) { // the following code causes failure against SQL 6.5 // ERROR [HY104] [Microsoft][ODBC SQL Server Driver]Invalid precision value // - // the code causes failure if it is NOT there (remark added by [....]) + // the code causes failure if it is NOT there (remark added by Microsoft) // it causes failure with jet if it is there // // MDAC 76227: Code is required for japanese client/server tests. - // If this causes regressions with Jet please doc here including bug#. ([....]) + // If this causes regressions with Jet please doc here including bug#. (Microsoft) // if ((ODBC32.SQL_TYPE.CHAR == _bindtype._sql_type) || (ODBC32.SQL_TYPE.VARCHAR == _bindtype._sql_type) diff --git a/System.Data/System/Data/Odbc/OdbcParameterCollection.cs b/System.Data/System/Data/Odbc/OdbcParameterCollection.cs index 8231d988d..feb30a5f5 100644 --- a/System.Data/System/Data/Odbc/OdbcParameterCollection.cs +++ b/System.Data/System/Data/Odbc/OdbcParameterCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Odbc { diff --git a/System.Data/System/Data/Odbc/OdbcPermission.cs b/System.Data/System/Data/Odbc/OdbcPermission.cs index b173351f6..d1560e285 100644 --- a/System.Data/System/Data/Odbc/OdbcPermission.cs +++ b/System.Data/System/Data/Odbc/OdbcPermission.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Odbc { diff --git a/System.Data/System/Data/Odbc/OdbcReferenceCollection.cs b/System.Data/System/Data/Odbc/OdbcReferenceCollection.cs index a6e6c1422..16636e5d2 100644 --- a/System.Data/System/Data/Odbc/OdbcReferenceCollection.cs +++ b/System.Data/System/Data/Odbc/OdbcReferenceCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcRowUpdatingEvent.cs b/System.Data/System/Data/Odbc/OdbcRowUpdatingEvent.cs index 1f33d71ae..7e36ad5e1 100644 --- a/System.Data/System/Data/Odbc/OdbcRowUpdatingEvent.cs +++ b/System.Data/System/Data/Odbc/OdbcRowUpdatingEvent.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcStatementHandle.cs b/System.Data/System/Data/Odbc/OdbcStatementHandle.cs index 04d1157b7..9000d8ea8 100644 --- a/System.Data/System/Data/Odbc/OdbcStatementHandle.cs +++ b/System.Data/System/Data/Odbc/OdbcStatementHandle.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcTransaction.cs b/System.Data/System/Data/Odbc/OdbcTransaction.cs index 610dfdb7c..25dbd7179 100644 --- a/System.Data/System/Data/Odbc/OdbcTransaction.cs +++ b/System.Data/System/Data/Odbc/OdbcTransaction.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/OdbcUtils.cs b/System.Data/System/Data/Odbc/OdbcUtils.cs index 5c6f11ad1..b5d23b8aa 100644 --- a/System.Data/System/Data/Odbc/OdbcUtils.cs +++ b/System.Data/System/Data/Odbc/OdbcUtils.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Odbc/odbcmetadatacollectionnames.cs b/System.Data/System/Data/Odbc/odbcmetadatacollectionnames.cs index ab10d4aa0..a7cafce8a 100644 --- a/System.Data/System/Data/Odbc/odbcmetadatacollectionnames.cs +++ b/System.Data/System/Data/Odbc/odbcmetadatacollectionnames.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Odbc { diff --git a/System.Data/System/Data/Odbc/odbcmetadatacolumnnames.cs b/System.Data/System/Data/Odbc/odbcmetadatacolumnnames.cs index 513cf0f35..bbd591fb1 100644 --- a/System.Data/System/Data/Odbc/odbcmetadatacolumnnames.cs +++ b/System.Data/System/Data/Odbc/odbcmetadatacolumnnames.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Odbc { diff --git a/System.Data/System/Data/Odbc/odbcmetadatafactory.cs b/System.Data/System/Data/Odbc/odbcmetadatafactory.cs index 87281ad3b..01ffbf81c 100644 --- a/System.Data/System/Data/Odbc/odbcmetadatafactory.cs +++ b/System.Data/System/Data/Odbc/odbcmetadatafactory.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// [....] -// [....] +// Microsoft +// Microsoft // //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/OleDb/ColumnBinding.cs b/System.Data/System/Data/OleDb/ColumnBinding.cs index 05a211e2c..89b83e35c 100644 --- a/System.Data/System/Data/OleDb/ColumnBinding.cs +++ b/System.Data/System/Data/OleDb/ColumnBinding.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/DBBindings.cs b/System.Data/System/Data/OleDb/DBBindings.cs index 60350f468..4b802a209 100644 --- a/System.Data/System/Data/OleDb/DBBindings.cs +++ b/System.Data/System/Data/OleDb/DBBindings.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/DBPropSet.cs b/System.Data/System/Data/OleDb/DBPropSet.cs index 7157e6c7e..f6128fcf3 100644 --- a/System.Data/System/Data/OleDb/DBPropSet.cs +++ b/System.Data/System/Data/OleDb/DBPropSet.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/OleDb/OLEDB_Enum.cs b/System.Data/System/Data/OleDb/OLEDB_Enum.cs index 40d7250e0..9eaa3c0e0 100644 --- a/System.Data/System/Data/OleDb/OLEDB_Enum.cs +++ b/System.Data/System/Data/OleDb/OLEDB_Enum.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OLEDB_Util.cs b/System.Data/System/Data/OleDb/OLEDB_Util.cs index 66c7ead9d..9a5c4818b 100644 --- a/System.Data/System/Data/OleDb/OLEDB_Util.cs +++ b/System.Data/System/Data/OleDb/OLEDB_Util.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbCommand.cs b/System.Data/System/Data/OleDb/OleDbCommand.cs index a835d94e7..34c26ef0f 100644 --- a/System.Data/System/Data/OleDb/OleDbCommand.cs +++ b/System.Data/System/Data/OleDb/OleDbCommand.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbCommandBuilder.cs b/System.Data/System/Data/OleDb/OleDbCommandBuilder.cs index f7e15dd4f..7e6b55777 100644 --- a/System.Data/System/Data/OleDb/OleDbCommandBuilder.cs +++ b/System.Data/System/Data/OleDb/OleDbCommandBuilder.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbConnection.cs b/System.Data/System/Data/OleDb/OleDbConnection.cs index b721af209..251146a92 100644 --- a/System.Data/System/Data/OleDb/OleDbConnection.cs +++ b/System.Data/System/Data/OleDb/OleDbConnection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbConnectionFactory.cs b/System.Data/System/Data/OleDb/OleDbConnectionFactory.cs index 81a539608..28815c855 100644 --- a/System.Data/System/Data/OleDb/OleDbConnectionFactory.cs +++ b/System.Data/System/Data/OleDb/OleDbConnectionFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb diff --git a/System.Data/System/Data/OleDb/OleDbConnectionInternal.cs b/System.Data/System/Data/OleDb/OleDbConnectionInternal.cs index 83b463ed4..67e120b14 100644 --- a/System.Data/System/Data/OleDb/OleDbConnectionInternal.cs +++ b/System.Data/System/Data/OleDb/OleDbConnectionInternal.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbConnectionPoolGroupProviderInfo.cs b/System.Data/System/Data/OleDb/OleDbConnectionPoolGroupProviderInfo.cs index 88200afba..6c48b2565 100644 --- a/System.Data/System/Data/OleDb/OleDbConnectionPoolGroupProviderInfo.cs +++ b/System.Data/System/Data/OleDb/OleDbConnectionPoolGroupProviderInfo.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb diff --git a/System.Data/System/Data/OleDb/OleDbDataAdapter.cs b/System.Data/System/Data/OleDb/OleDbDataAdapter.cs index c1301ded6..f9e2e640c 100644 --- a/System.Data/System/Data/OleDb/OleDbDataAdapter.cs +++ b/System.Data/System/Data/OleDb/OleDbDataAdapter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/OleDb/OleDbDataReader.cs b/System.Data/System/Data/OleDb/OleDbDataReader.cs index 16a4393ed..55fdaa58b 100644 --- a/System.Data/System/Data/OleDb/OleDbDataReader.cs +++ b/System.Data/System/Data/OleDb/OleDbDataReader.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { @@ -1168,7 +1168,7 @@ static internal OleDbException NextResults(UnsafeNativeMethods.IMultipleResults static private void NextResultsInfinite() { // MDAC 72738 Bid.Trace(" System.Data.OleDb.OleDbDataReader: 2000 IMultipleResult.GetResult(NULL, DBRESULTFLAG_DEFAULT, IID_NULL, NULL, NULL) iterations with 0 records affected. Stopping suspect infinite loop. To work-around try using ExecuteReader() and iterating through results with NextResult().\n"); - // [....]'s suggestion is that we debug assert so that users will learn of MSOLAP's misbehavior and not call ExecuteNonQuery + // Microsoft's suggestion is that we debug assert so that users will learn of MSOLAP's misbehavior and not call ExecuteNonQuery Debug.Assert(false, " System.Data.OleDb.OleDbDataReader: 2000 IMultipleResult.GetResult(NULL, DBRESULTFLAG_DEFAULT, IID_NULL, NULL, NULL) iterations with 0 records affected. Stopping suspect infinite loop. To work-around try using ExecuteReader() and iterating through results with NextResult().\n"); } diff --git a/System.Data/System/Data/OleDb/OleDbEnumerator.cs b/System.Data/System/Data/OleDb/OleDbEnumerator.cs index 25b0e2765..fdd83b9c0 100644 --- a/System.Data/System/Data/OleDb/OleDbEnumerator.cs +++ b/System.Data/System/Data/OleDb/OleDbEnumerator.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbError.cs b/System.Data/System/Data/OleDb/OleDbError.cs index 7bd40b391..c46ab4271 100644 --- a/System.Data/System/Data/OleDb/OleDbError.cs +++ b/System.Data/System/Data/OleDb/OleDbError.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbErrorCollection.cs b/System.Data/System/Data/OleDb/OleDbErrorCollection.cs index c2e0e14f9..a7410a8e3 100644 --- a/System.Data/System/Data/OleDb/OleDbErrorCollection.cs +++ b/System.Data/System/Data/OleDb/OleDbErrorCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbException.cs b/System.Data/System/Data/OleDb/OleDbException.cs index b34faca19..1b310bb8b 100644 --- a/System.Data/System/Data/OleDb/OleDbException.cs +++ b/System.Data/System/Data/OleDb/OleDbException.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbFactory.cs b/System.Data/System/Data/OleDb/OleDbFactory.cs index a89770234..190c0019d 100644 --- a/System.Data/System/Data/OleDb/OleDbFactory.cs +++ b/System.Data/System/Data/OleDb/OleDbFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/OleDb/OleDbInfoMessageEvent.cs b/System.Data/System/Data/OleDb/OleDbInfoMessageEvent.cs index 1af769a72..87936250c 100644 --- a/System.Data/System/Data/OleDb/OleDbInfoMessageEvent.cs +++ b/System.Data/System/Data/OleDb/OleDbInfoMessageEvent.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbMetaDataFactory.cs b/System.Data/System/Data/OleDb/OleDbMetaDataFactory.cs index 99651fe5e..7189c9f86 100644 --- a/System.Data/System/Data/OleDb/OleDbMetaDataFactory.cs +++ b/System.Data/System/Data/OleDb/OleDbMetaDataFactory.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// [....] +// Microsoft // Mugunm // //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/OleDb/OleDbParameter.cs b/System.Data/System/Data/OleDb/OleDbParameter.cs index 745436693..ad824e1a7 100644 --- a/System.Data/System/Data/OleDb/OleDbParameter.cs +++ b/System.Data/System/Data/OleDb/OleDbParameter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbParameterCollection.cs b/System.Data/System/Data/OleDb/OleDbParameterCollection.cs index 2ab175f7c..40a210715 100644 --- a/System.Data/System/Data/OleDb/OleDbParameterCollection.cs +++ b/System.Data/System/Data/OleDb/OleDbParameterCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbPermission.cs b/System.Data/System/Data/OleDb/OleDbPermission.cs index d7ca1aa88..a1a313100 100644 --- a/System.Data/System/Data/OleDb/OleDbPermission.cs +++ b/System.Data/System/Data/OleDb/OleDbPermission.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbPropertySetGuid.cs b/System.Data/System/Data/OleDb/OleDbPropertySetGuid.cs index 75e6fae13..4be4655a8 100644 --- a/System.Data/System/Data/OleDb/OleDbPropertySetGuid.cs +++ b/System.Data/System/Data/OleDb/OleDbPropertySetGuid.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbReferenceCollection.cs b/System.Data/System/Data/OleDb/OleDbReferenceCollection.cs index 45f347b78..ad3750c95 100644 --- a/System.Data/System/Data/OleDb/OleDbReferenceCollection.cs +++ b/System.Data/System/Data/OleDb/OleDbReferenceCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbRowUpdatedEvent.cs b/System.Data/System/Data/OleDb/OleDbRowUpdatedEvent.cs index d4c3ccf53..043e585d0 100644 --- a/System.Data/System/Data/OleDb/OleDbRowUpdatedEvent.cs +++ b/System.Data/System/Data/OleDb/OleDbRowUpdatedEvent.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbRowUpdatingEvent.cs b/System.Data/System/Data/OleDb/OleDbRowUpdatingEvent.cs index ea1d58df0..4b20a71e3 100644 --- a/System.Data/System/Data/OleDb/OleDbRowUpdatingEvent.cs +++ b/System.Data/System/Data/OleDb/OleDbRowUpdatingEvent.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbSchemaGuid.cs b/System.Data/System/Data/OleDb/OleDbSchemaGuid.cs index eb0b45c11..69bac32ad 100644 --- a/System.Data/System/Data/OleDb/OleDbSchemaGuid.cs +++ b/System.Data/System/Data/OleDb/OleDbSchemaGuid.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbStruct.cs b/System.Data/System/Data/OleDb/OleDbStruct.cs index 49f83271b..8683055b5 100644 --- a/System.Data/System/Data/OleDb/OleDbStruct.cs +++ b/System.Data/System/Data/OleDb/OleDbStruct.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbTransaction.cs b/System.Data/System/Data/OleDb/OleDbTransaction.cs index a5653b5a7..14881edbc 100644 --- a/System.Data/System/Data/OleDb/OleDbTransaction.cs +++ b/System.Data/System/Data/OleDb/OleDbTransaction.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OleDbWrapper.cs b/System.Data/System/Data/OleDb/OleDbWrapper.cs index c4a71c071..433d6d499 100644 --- a/System.Data/System/Data/OleDb/OleDbWrapper.cs +++ b/System.Data/System/Data/OleDb/OleDbWrapper.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/OledbConnectionStringbuilder.cs b/System.Data/System/Data/OleDb/OledbConnectionStringbuilder.cs index bb021752e..9b9eb1717 100644 --- a/System.Data/System/Data/OleDb/OledbConnectionStringbuilder.cs +++ b/System.Data/System/Data/OleDb/OledbConnectionStringbuilder.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/OleDb/PropertyIDSet.cs b/System.Data/System/Data/OleDb/PropertyIDSet.cs index 92d8e4bfb..048b30508 100644 --- a/System.Data/System/Data/OleDb/PropertyIDSet.cs +++ b/System.Data/System/Data/OleDb/PropertyIDSet.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/OleDb/PropertyInfoSet.cs b/System.Data/System/Data/OleDb/PropertyInfoSet.cs index fb15d85b3..8f0bbf887 100644 --- a/System.Data/System/Data/OleDb/PropertyInfoSet.cs +++ b/System.Data/System/Data/OleDb/PropertyInfoSet.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/OleDb/RowBinding.cs b/System.Data/System/Data/OleDb/RowBinding.cs index eb93e1ae3..71b80127a 100644 --- a/System.Data/System/Data/OleDb/RowBinding.cs +++ b/System.Data/System/Data/OleDb/RowBinding.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/SafeHandles.cs b/System.Data/System/Data/OleDb/SafeHandles.cs index 39e1958f5..1351f3b11 100644 --- a/System.Data/System/Data/OleDb/SafeHandles.cs +++ b/System.Data/System/Data/OleDb/SafeHandles.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/oledbconnectionstring.cs b/System.Data/System/Data/OleDb/oledbconnectionstring.cs index bb12e5de7..e1406cfc2 100644 --- a/System.Data/System/Data/OleDb/oledbconnectionstring.cs +++ b/System.Data/System/Data/OleDb/oledbconnectionstring.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/oledbmetadatacollectionnames.cs b/System.Data/System/Data/OleDb/oledbmetadatacollectionnames.cs index 629e25ab9..9c0600b28 100644 --- a/System.Data/System/Data/OleDb/oledbmetadatacollectionnames.cs +++ b/System.Data/System/Data/OleDb/oledbmetadatacollectionnames.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OleDb/oledbmetadatacolumnnames.cs b/System.Data/System/Data/OleDb/oledbmetadatacolumnnames.cs index 3e2606325..741e79769 100644 --- a/System.Data/System/Data/OleDb/oledbmetadatacolumnnames.cs +++ b/System.Data/System/Data/OleDb/oledbmetadatacolumnnames.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.OleDb { diff --git a/System.Data/System/Data/OperationAbortedException.cs b/System.Data/System/Data/OperationAbortedException.cs index 539b0e3c1..3eda086c7 100644 --- a/System.Data/System/Data/OperationAbortedException.cs +++ b/System.Data/System/Data/OperationAbortedException.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/PrimaryKeyTypeConverter.cs b/System.Data/System/Data/PrimaryKeyTypeConverter.cs index 431f2ba83..b57494291 100644 --- a/System.Data/System/Data/PrimaryKeyTypeConverter.cs +++ b/System.Data/System/Data/PrimaryKeyTypeConverter.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/PropertyCollection.cs b/System.Data/System/Data/PropertyCollection.cs index 0b014fd3a..e0532236d 100644 --- a/System.Data/System/Data/PropertyCollection.cs +++ b/System.Data/System/Data/PropertyCollection.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/ProviderBase/DataReaderContainer.cs b/System.Data/System/Data/ProviderBase/DataReaderContainer.cs index b6864fb8d..181017f55 100644 --- a/System.Data/System/Data/ProviderBase/DataReaderContainer.cs +++ b/System.Data/System/Data/ProviderBase/DataReaderContainer.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/ProviderBase/DbBuffer.cs b/System.Data/System/Data/ProviderBase/DbBuffer.cs index 82c4df382..390d8cd51 100644 --- a/System.Data/System/Data/ProviderBase/DbBuffer.cs +++ b/System.Data/System/Data/ProviderBase/DbBuffer.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase diff --git a/System.Data/System/Data/ProviderBase/DbConnectionClosed.cs b/System.Data/System/Data/ProviderBase/DbConnectionClosed.cs index fee86a2e3..a47c0532b 100644 --- a/System.Data/System/Data/ProviderBase/DbConnectionClosed.cs +++ b/System.Data/System/Data/ProviderBase/DbConnectionClosed.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/ProviderBase/DbConnectionFactory.cs b/System.Data/System/Data/ProviderBase/DbConnectionFactory.cs index c9fe482c8..64032e8a2 100644 --- a/System.Data/System/Data/ProviderBase/DbConnectionFactory.cs +++ b/System.Data/System/Data/ProviderBase/DbConnectionFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/ProviderBase/DbConnectionHelper.cs b/System.Data/System/Data/ProviderBase/DbConnectionHelper.cs index 0e5622882..9765041e3 100644 --- a/System.Data/System/Data/ProviderBase/DbConnectionHelper.cs +++ b/System.Data/System/Data/ProviderBase/DbConnectionHelper.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace NAMESPACE { diff --git a/System.Data/System/Data/ProviderBase/DbConnectionInternal.cs b/System.Data/System/Data/ProviderBase/DbConnectionInternal.cs index 73541107c..bfab42509 100644 --- a/System.Data/System/Data/ProviderBase/DbConnectionInternal.cs +++ b/System.Data/System/Data/ProviderBase/DbConnectionInternal.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { @@ -58,7 +58,7 @@ internal abstract class DbConnectionInternal { // V1.1.3300 private SysTx.Transaction _enlistedTransactionOriginal; #if DEBUG - private int _activateCount; // debug only counter to verify activate/deactivates are in [....]. + private int _activateCount; // debug only counter to verify activate/deactivates are in sync. #endif //DEBUG protected DbConnectionInternal() : this(ConnectionState.Open, true, false) { // V1.1.3300 @@ -323,7 +323,7 @@ abstract public string ServerVersion { get; } - // this should be abstract but untill it is added to all the providers virtual will have to do [....] + // this should be abstract but untill it is added to all the providers virtual will have to do Microsoft virtual public string ServerVersionNormalized { get{ throw ADP.NotSupported(); diff --git a/System.Data/System/Data/ProviderBase/DbConnectionPool.cs b/System.Data/System/Data/ProviderBase/DbConnectionPool.cs index f9fcefa74..dc74b1581 100644 --- a/System.Data/System/Data/ProviderBase/DbConnectionPool.cs +++ b/System.Data/System/Data/ProviderBase/DbConnectionPool.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { @@ -749,40 +749,6 @@ private Timer CreateCleanupTimer() { return (new Timer(new TimerCallback(this.CleanupCallback), null, _cleanupWait, _cleanupWait)); } - private static readonly string[] AzureSqlServerEndpoints = {Res.GetString(Res.AZURESQL_GenericEndpoint), - Res.GetString(Res.AZURESQL_GermanEndpoint), - Res.GetString(Res.AZURESQL_UsGovEndpoint), - Res.GetString(Res.AZURESQL_ChinaEndpoint) }; - private static bool IsAzureSqlServerEndpoint(string dataSource) - { - // remove server port - var i = dataSource.LastIndexOf(','); - if (i >= 0) - { - dataSource = dataSource.Substring(0, i); - } - - // check for the instance name - i = dataSource.LastIndexOf('\\'); - if (i >= 0) - { - dataSource = dataSource.Substring(0, i); - } - - // trim redundant whitespaces - dataSource = dataSource.Trim(); - - // check if servername end with any azure endpoints - for (i = 0; i < AzureSqlServerEndpoints.Length; i++) - { - if (dataSource.EndsWith(AzureSqlServerEndpoints[i], StringComparison.OrdinalIgnoreCase)) - { - return true; - } - } - return false; - } - private bool IsBlockingPeriodEnabled() { var poolGroupConnectionOptions = _connectionPoolGroup.ConnectionOptions as SqlConnectionString; @@ -797,7 +763,7 @@ private bool IsBlockingPeriodEnabled() { case PoolBlockingPeriod.Auto: { - if (IsAzureSqlServerEndpoint(poolGroupConnectionOptions.DataSource)) + if (ADP.IsAzureSqlServerEndpoint(poolGroupConnectionOptions.DataSource)) { return false; // in Azure it will be Disabled } @@ -1228,7 +1194,7 @@ internal bool TryGetConnection(DbConnection owningObject, TaskCompletionSource // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/ProviderBase/DbConnectionPoolGroup.cs b/System.Data/System/Data/ProviderBase/DbConnectionPoolGroup.cs index 17fc317bb..31a5b968d 100644 --- a/System.Data/System/Data/ProviderBase/DbConnectionPoolGroup.cs +++ b/System.Data/System/Data/ProviderBase/DbConnectionPoolGroup.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs b/System.Data/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs index 32a8ebfb2..dfd1796b9 100644 --- a/System.Data/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs +++ b/System.Data/System/Data/ProviderBase/DbConnectionPoolGroupProviderInfo.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/ProviderBase/DbConnectionPoolIdentity.cs b/System.Data/System/Data/ProviderBase/DbConnectionPoolIdentity.cs index 330b89fba..34e8e00be 100644 --- a/System.Data/System/Data/ProviderBase/DbConnectionPoolIdentity.cs +++ b/System.Data/System/Data/ProviderBase/DbConnectionPoolIdentity.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/ProviderBase/DbConnectionPoolOptions.cs b/System.Data/System/Data/ProviderBase/DbConnectionPoolOptions.cs index fa3f82e55..33610b618 100644 --- a/System.Data/System/Data/ProviderBase/DbConnectionPoolOptions.cs +++ b/System.Data/System/Data/ProviderBase/DbConnectionPoolOptions.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/ProviderBase/DbMetaDataCollectionNames.cs b/System.Data/System/Data/ProviderBase/DbMetaDataCollectionNames.cs index 2408d5f4a..118800f7c 100644 --- a/System.Data/System/Data/ProviderBase/DbMetaDataCollectionNames.cs +++ b/System.Data/System/Data/ProviderBase/DbMetaDataCollectionNames.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/ProviderBase/DbMetaDataColumnNames.cs b/System.Data/System/Data/ProviderBase/DbMetaDataColumnNames.cs index c8237455e..6d12c9169 100644 --- a/System.Data/System/Data/ProviderBase/DbMetaDataColumnNames.cs +++ b/System.Data/System/Data/ProviderBase/DbMetaDataColumnNames.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Common { diff --git a/System.Data/System/Data/ProviderBase/DbMetaDataFactory.cs b/System.Data/System/Data/ProviderBase/DbMetaDataFactory.cs index 5267928dd..67025f4b5 100644 --- a/System.Data/System/Data/ProviderBase/DbMetaDataFactory.cs +++ b/System.Data/System/Data/ProviderBase/DbMetaDataFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/ProviderBase/DbParameterCollectionHelper.cs b/System.Data/System/Data/ProviderBase/DbParameterCollectionHelper.cs index 33266444b..d28d3414e 100644 --- a/System.Data/System/Data/ProviderBase/DbParameterCollectionHelper.cs +++ b/System.Data/System/Data/ProviderBase/DbParameterCollectionHelper.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace NAMESPACE diff --git a/System.Data/System/Data/ProviderBase/DbParameterHelper.cs b/System.Data/System/Data/ProviderBase/DbParameterHelper.cs index 7efd67b6a..b968d12dc 100644 --- a/System.Data/System/Data/ProviderBase/DbParameterHelper.cs +++ b/System.Data/System/Data/ProviderBase/DbParameterHelper.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace NAMESPACE { diff --git a/System.Data/System/Data/ProviderBase/DbReferenceCollection.cs b/System.Data/System/Data/ProviderBase/DbReferenceCollection.cs index 8a1baeec7..1f55090b4 100644 --- a/System.Data/System/Data/ProviderBase/DbReferenceCollection.cs +++ b/System.Data/System/Data/ProviderBase/DbReferenceCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/ProviderBase/SchemaMapping.cs b/System.Data/System/Data/ProviderBase/SchemaMapping.cs index 9c0e43513..0118a9a64 100644 --- a/System.Data/System/Data/ProviderBase/SchemaMapping.cs +++ b/System.Data/System/Data/ProviderBase/SchemaMapping.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/ProviderBase/TimeoutTimer.cs b/System.Data/System/Data/ProviderBase/TimeoutTimer.cs index 8c89bab8e..24172d3bd 100644 --- a/System.Data/System/Data/ProviderBase/TimeoutTimer.cs +++ b/System.Data/System/Data/ProviderBase/TimeoutTimer.cs @@ -5,8 +5,8 @@ // // Class used to manage timeouts in complex system operations. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase diff --git a/System.Data/System/Data/ProviderBase/WrappedIUnknown.cs b/System.Data/System/Data/ProviderBase/WrappedIUnknown.cs index 298ed6091..acd00a437 100644 --- a/System.Data/System/Data/ProviderBase/WrappedIUnknown.cs +++ b/System.Data/System/Data/ProviderBase/WrappedIUnknown.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.ProviderBase { diff --git a/System.Data/System/Data/Range.cs b/System.Data/System/Data/Range.cs index 790bf3055..6c3ea0a9c 100644 --- a/System.Data/System/Data/Range.cs +++ b/System.Data/System/Data/Range.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/RbTree.cs b/System.Data/System/Data/RbTree.cs index 4048974b9..57ab5bfa1 100644 --- a/System.Data/System/Data/RbTree.cs +++ b/System.Data/System/Data/RbTree.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ #if DEBUG diff --git a/System.Data/System/Data/RecordManager.cs b/System.Data/System/Data/RecordManager.cs index 106bfafe0..608f79c6f 100644 --- a/System.Data/System/Data/RecordManager.cs +++ b/System.Data/System/Data/RecordManager.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/RecordsAffectedEventArgs.cs b/System.Data/System/Data/RecordsAffectedEventArgs.cs index 9f2c8aef1..82322d961 100644 --- a/System.Data/System/Data/RecordsAffectedEventArgs.cs +++ b/System.Data/System/Data/RecordsAffectedEventArgs.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/RelatedView.cs b/System.Data/System/Data/RelatedView.cs index 7493a8b56..e1aed175a 100644 --- a/System.Data/System/Data/RelatedView.cs +++ b/System.Data/System/Data/RelatedView.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/RelationshipConverter.cs b/System.Data/System/Data/RelationshipConverter.cs index dbddce219..2fec1c69e 100644 --- a/System.Data/System/Data/RelationshipConverter.cs +++ b/System.Data/System/Data/RelationshipConverter.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/SQLTypes/SQLBinary.cs b/System.Data/System/Data/SQLTypes/SQLBinary.cs index 114fd109a..e9df08a60 100644 --- a/System.Data/System/Data/SQLTypes/SQLBinary.cs +++ b/System.Data/System/Data/SQLTypes/SQLBinary.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** diff --git a/System.Data/System/Data/SQLTypes/SQLBoolean.cs b/System.Data/System/Data/SQLTypes/SQLBoolean.cs index 300eb2914..21f2b3df4 100644 --- a/System.Data/System/Data/SQLTypes/SQLBoolean.cs +++ b/System.Data/System/Data/SQLTypes/SQLBoolean.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** diff --git a/System.Data/System/Data/SQLTypes/SQLByte.cs b/System.Data/System/Data/SQLTypes/SQLByte.cs index f72b2e843..3ae27040e 100644 --- a/System.Data/System/Data/SQLTypes/SQLByte.cs +++ b/System.Data/System/Data/SQLTypes/SQLByte.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** @@ -49,7 +49,7 @@ public struct SqlByte : INullable, IComparable, IXmlSerializable { private bool m_fNotNull; // false if null private byte m_value; - private static readonly int x_iBitNotByteMax = ~0xff; + private const int x_iBitNotByteMax = ~0xff; // constructor // construct a Null diff --git a/System.Data/System/Data/SQLTypes/SQLBytes.cs b/System.Data/System/Data/SQLTypes/SQLBytes.cs index 1c7dd76f4..5c77bc045 100644 --- a/System.Data/System/Data/SQLTypes/SQLBytes.cs +++ b/System.Data/System/Data/SQLTypes/SQLBytes.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** diff --git a/System.Data/System/Data/SQLTypes/SQLChars.cs b/System.Data/System/Data/SQLTypes/SQLChars.cs index 0bd0bd5d0..ea61e8404 100644 --- a/System.Data/System/Data/SQLTypes/SQLChars.cs +++ b/System.Data/System/Data/SQLTypes/SQLChars.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** diff --git a/System.Data/System/Data/SQLTypes/SQLDateTime.cs b/System.Data/System/Data/SQLTypes/SQLDateTime.cs index 6217081b9..666b2afc3 100644 --- a/System.Data/System/Data/SQLTypes/SQLDateTime.cs +++ b/System.Data/System/Data/SQLTypes/SQLDateTime.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** @@ -56,26 +56,26 @@ public struct SqlDateTime : INullable, IComparable, IXmlSerializable { // Constants // Number of (100ns) ticks per time unit - private static readonly double SQLTicksPerMillisecond = 0.3; - public static readonly int SQLTicksPerSecond = 300; - public static readonly int SQLTicksPerMinute = SQLTicksPerSecond * 60; - public static readonly int SQLTicksPerHour = SQLTicksPerMinute * 60; - private static readonly int SQLTicksPerDay = SQLTicksPerHour * 24; + private const double SQLTicksPerMillisecond = 0.3; + public static readonly int SQLTicksPerSecond = 300; + public static readonly int SQLTicksPerMinute = SQLTicksPerSecond * 60; + public static readonly int SQLTicksPerHour = SQLTicksPerMinute * 60; + private static readonly int SQLTicksPerDay = SQLTicksPerHour * 24; - private static readonly long TicksPerSecond = TimeSpan.TicksPerMillisecond * 1000; + private const long TicksPerSecond = TimeSpan.TicksPerMillisecond * 1000; private static readonly DateTime SQLBaseDate = new DateTime(1900, 1, 1); private static readonly long SQLBaseDateTicks = SQLBaseDate.Ticks; - private static readonly int MinYear = 1753; // Jan 1 1753 - private static readonly int MaxYear = 9999; // Dec 31 9999 + private const int MinYear = 1753; // Jan 1 1753 + private const int MaxYear = 9999; // Dec 31 9999 - private static readonly int MinDay = -53690; // Jan 1 1753 - private static readonly int MaxDay = 2958463; // Dec 31 9999 is this many days from Jan 1 1900 - private static readonly int MinTime = 0; // 00:00:0:000PM + private const int MinDay = -53690; // Jan 1 1753 + private const int MaxDay = 2958463; // Dec 31 9999 is this many days from Jan 1 1900 + private const int MinTime = 0; // 00:00:0:000PM private static readonly int MaxTime = SQLTicksPerDay - 1; // = 25919999, 11:59:59:997PM - private static readonly int DayBase = 693595; // Jan 1 1900 is this many days from Jan 1 0001 + private const int DayBase = 693595; // Jan 1 1900 is this many days from Jan 1 0001 private static readonly int[] DaysToMonth365 = new int[] { @@ -87,7 +87,7 @@ public struct SqlDateTime : INullable, IComparable, IXmlSerializable { private static readonly DateTime MaxDateTime = DateTime.MaxValue; private static readonly TimeSpan MinTimeSpan = MinDateTime.Subtract(SQLBaseDate); private static readonly TimeSpan MaxTimeSpan = MaxDateTime.Subtract(SQLBaseDate); - private static readonly String x_ISO8601_DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fff"; + private const String x_ISO8601_DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fff"; // These formats are valid styles in SQL Server (style 9, 12, 13, 14) // but couldn't be recognized by the default parse. Needs to call diff --git a/System.Data/System/Data/SQLTypes/SQLDecimal.cs b/System.Data/System/Data/SQLTypes/SQLDecimal.cs index a992e479e..db66e9680 100644 --- a/System.Data/System/Data/SQLTypes/SQLDecimal.cs +++ b/System.Data/System/Data/SQLTypes/SQLDecimal.cs @@ -3,9 +3,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** @@ -69,44 +69,44 @@ public struct SqlDecimal : INullable, IComparable, IXmlSerializable { internal UInt32 m_data3; internal UInt32 m_data4; - private static readonly byte NUMERIC_MAX_PRECISION = 38; // Maximum precision of numeric + private const byte NUMERIC_MAX_PRECISION = 38; // Maximum precision of numeric /// /// [To be supplied.] /// - public static readonly byte MaxPrecision = NUMERIC_MAX_PRECISION; // max SS precision + public static readonly byte MaxPrecision = NUMERIC_MAX_PRECISION; // max SS precision /// /// [To be supplied.] /// - public static readonly byte MaxScale = NUMERIC_MAX_PRECISION; // max SS scale + public static readonly byte MaxScale = NUMERIC_MAX_PRECISION; // max SS scale - private static readonly byte x_bNullMask = 1; // bit mask for null bit in m_bStatus - private static readonly byte x_bIsNull = 0; // is null - private static readonly byte x_bNotNull = 1; // is not null - private static readonly byte x_bReverseNullMask = unchecked((byte)~x_bNullMask); + private const byte x_bNullMask = 1; // bit mask for null bit in m_bStatus + private const byte x_bIsNull = 0; // is null + private const byte x_bNotNull = 1; // is not null + private const byte x_bReverseNullMask = unchecked((byte)~x_bNullMask); - private static readonly byte x_bSignMask = 2; // bit mask for sign bit in m_bStatus - private static readonly byte x_bPositive = 0; // is positive - private static readonly byte x_bNegative = 2; // is negative - private static readonly byte x_bReverseSignMask = unchecked((byte)~x_bSignMask); + private const byte x_bSignMask = 2; // bit mask for sign bit in m_bStatus + private const byte x_bPositive = 0; // is positive + private const byte x_bNegative = 2; // is negative + private const byte x_bReverseSignMask = unchecked((byte)~x_bSignMask); - private static readonly uint x_uiZero = (uint) 0; + private const uint x_uiZero = (uint) 0; - private static readonly int x_cNumeMax = 4; - private static readonly long x_lInt32Base = ((long)1) << 32; // 2**32 - private static readonly ulong x_ulInt32Base = ((ulong)1) << 32; // 2**32 - private static readonly ulong x_ulInt32BaseForMod = x_ulInt32Base - 1; // 2**32 - 1 (0xFFF...FF) + private const int x_cNumeMax = 4; + private const long x_lInt32Base = ((long)1) << 32; // 2**32 + private const ulong x_ulInt32Base = ((ulong)1) << 32; // 2**32 + private const ulong x_ulInt32BaseForMod = x_ulInt32Base - 1; // 2**32 - 1 (0xFFF...FF) - internal static readonly ulong x_llMax = Int64.MaxValue; // Max of Int64 + internal const ulong x_llMax = Int64.MaxValue; // Max of Int64 - private static readonly uint x_ulBase10 = 10; + private const uint x_ulBase10 = 10; - private static readonly double DUINT_BASE = (double)x_lInt32Base; // 2**32 - private static readonly double DUINT_BASE2 = DUINT_BASE * DUINT_BASE; // 2**64 - private static readonly double DUINT_BASE3 = DUINT_BASE2 * DUINT_BASE; // 2**96 - private static readonly double DMAX_NUME = 1.0e+38; // Max value of numeric - private static readonly uint DBL_DIG = 17; // Max decimal digits of double + private const double DUINT_BASE = (double)x_lInt32Base; // 2**32 + private const double DUINT_BASE2 = DUINT_BASE * DUINT_BASE; // 2**64 + private const double DUINT_BASE3 = DUINT_BASE2 * DUINT_BASE; // 2**96 + private const double DMAX_NUME = 1.0e+38; // Max value of numeric + private const uint DBL_DIG = 17; // Max decimal digits of double - private static readonly byte x_cNumeDivScaleMin = 6; // Minimum result scale of numeric division + private const byte x_cNumeDivScaleMin = 6; // Minimum result scale of numeric division // Array of multipliers for lAdjust and Ceiling/Floor. private static readonly uint[] x_rgulShiftBase = new uint[9] { @@ -1907,25 +1907,25 @@ private bool FGt10_38(uint[] rglData) { // Powers of ten (used by BGetPrecI4,BGetPrecI8) - private static readonly uint x_ulT1 = 10; - private static readonly uint x_ulT2 = 100; - private static readonly uint x_ulT3 = 1000; - private static readonly uint x_ulT4 = 10000; - private static readonly uint x_ulT5 = 100000; - private static readonly uint x_ulT6 = 1000000; - private static readonly uint x_ulT7 = 10000000; - private static readonly uint x_ulT8 = 100000000; - private static readonly uint x_ulT9 = 1000000000; - private static readonly ulong x_dwlT10 = 10000000000; - private static readonly ulong x_dwlT11 = 100000000000; - private static readonly ulong x_dwlT12 = 1000000000000; - private static readonly ulong x_dwlT13 = 10000000000000; - private static readonly ulong x_dwlT14 = 100000000000000; - private static readonly ulong x_dwlT15 = 1000000000000000; - private static readonly ulong x_dwlT16 = 10000000000000000; - private static readonly ulong x_dwlT17 = 100000000000000000; - private static readonly ulong x_dwlT18 = 1000000000000000000; - private static readonly ulong x_dwlT19 = 10000000000000000000; + private const uint x_ulT1 = 10; + private const uint x_ulT2 = 100; + private const uint x_ulT3 = 1000; + private const uint x_ulT4 = 10000; + private const uint x_ulT5 = 100000; + private const uint x_ulT6 = 1000000; + private const uint x_ulT7 = 10000000; + private const uint x_ulT8 = 100000000; + private const uint x_ulT9 = 1000000000; + private const ulong x_dwlT10 = 10000000000; + private const ulong x_dwlT11 = 100000000000; + private const ulong x_dwlT12 = 1000000000000; + private const ulong x_dwlT13 = 10000000000000; + private const ulong x_dwlT14 = 100000000000000; + private const ulong x_dwlT15 = 1000000000000000; + private const ulong x_dwlT16 = 10000000000000000; + private const ulong x_dwlT17 = 100000000000000000; + private const ulong x_dwlT18 = 1000000000000000000; + private const ulong x_dwlT19 = 10000000000000000000; //------------------------------------------------------------------ //BGetPrecI4 diff --git a/System.Data/System/Data/SQLTypes/SQLDouble.cs b/System.Data/System/Data/SQLTypes/SQLDouble.cs index 3aace9925..5e25a2fc0 100644 --- a/System.Data/System/Data/SQLTypes/SQLDouble.cs +++ b/System.Data/System/Data/SQLTypes/SQLDouble.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** diff --git a/System.Data/System/Data/SQLTypes/SQLFileStream.cs b/System.Data/System/Data/SQLTypes/SQLFileStream.cs index 3491985f9..1e69b843b 100644 --- a/System.Data/System/Data/SQLTypes/SQLFileStream.cs +++ b/System.Data/System/Data/SQLTypes/SQLFileStream.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; @@ -428,7 +428,7 @@ public override void WriteByte(byte value) // 2. GetFullPathName API of kernel32 does not accept paths with length (in chars) greater than 32766 // (32766 is actually Int16.MaxValue - 1, while (-1) is for NULL termination) // We must check for the lowest value between the the two - static private readonly int MaxWin32PathLength = Int16.MaxValue - 1; + private const int MaxWin32PathLength = Int16.MaxValue - 1; [ConditionalAttribute("DEBUG")] static private void AssertPathFormat(string path) diff --git a/System.Data/System/Data/SQLTypes/SQLGuid.cs b/System.Data/System/Data/SQLTypes/SQLGuid.cs index 46e62e844..e62e9ab1f 100644 --- a/System.Data/System/Data/SQLTypes/SQLGuid.cs +++ b/System.Data/System/Data/SQLTypes/SQLGuid.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** @@ -41,7 +41,7 @@ namespace System.Data.SqlTypes { [Serializable] [XmlSchemaProvider("GetXsdType")] public struct SqlGuid : INullable, IComparable, IXmlSerializable { - private static readonly int SizeOfGuid = 16; + private const int SizeOfGuid = 16; // Comparison orders. private static readonly int[] x_rgiGuidOrder = new int[16] diff --git a/System.Data/System/Data/SQLTypes/SQLInt16.cs b/System.Data/System/Data/SQLTypes/SQLInt16.cs index 276862274..1691de4bf 100644 --- a/System.Data/System/Data/SQLTypes/SQLInt16.cs +++ b/System.Data/System/Data/SQLTypes/SQLInt16.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** @@ -48,7 +48,7 @@ public struct SqlInt16 : INullable, IComparable, IXmlSerializable { private bool m_fNotNull; // false if null private short m_value; - private static readonly int O_MASKI2 = ~0x00007fff; + private const int O_MASKI2 = ~0x00007fff; // constructor // construct a Null diff --git a/System.Data/System/Data/SQLTypes/SQLInt32.cs b/System.Data/System/Data/SQLTypes/SQLInt32.cs index 70667a2d6..b97fe87c5 100644 --- a/System.Data/System/Data/SQLTypes/SQLInt32.cs +++ b/System.Data/System/Data/SQLTypes/SQLInt32.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** @@ -47,8 +47,8 @@ public struct SqlInt32 : INullable, IComparable, IXmlSerializable { private bool m_fNotNull; // false if null, the default ctor (plain 0) will make it Null private int m_value; - private static readonly long x_iIntMin = Int32.MinValue; // minimum (signed) int value - private static readonly long x_lBitNotIntMax = ~(long)(Int32.MaxValue); + private const long x_iIntMin = Int32.MinValue; // minimum (signed) int value + private const long x_lBitNotIntMax = ~(long)(Int32.MaxValue); // constructor // construct a Null diff --git a/System.Data/System/Data/SQLTypes/SQLInt64.cs b/System.Data/System/Data/SQLTypes/SQLInt64.cs index 523433c9b..60337ce30 100644 --- a/System.Data/System/Data/SQLTypes/SQLInt64.cs +++ b/System.Data/System/Data/SQLTypes/SQLInt64.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** @@ -47,8 +47,8 @@ public struct SqlInt64 : INullable, IComparable, IXmlSerializable { private bool m_fNotNull; // false if null private long m_value; - private static readonly long x_lLowIntMask = 0xffffffff; - private static readonly long x_lHighIntMask = unchecked((long)0xffffffff00000000); + private const long x_lLowIntMask = 0xffffffff; + private const long x_lHighIntMask = unchecked((long)0xffffffff00000000); // constructor diff --git a/System.Data/System/Data/SQLTypes/SQLMoney.cs b/System.Data/System/Data/SQLTypes/SQLMoney.cs index e64f46118..d40b0edff 100644 --- a/System.Data/System/Data/SQLTypes/SQLMoney.cs +++ b/System.Data/System/Data/SQLTypes/SQLMoney.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** @@ -52,12 +52,12 @@ public struct SqlMoney : INullable, IComparable, IXmlSerializable { private long m_value; // SQL Server stores money8 as ticks of 1/10000. - internal static readonly int x_iMoneyScale = 4; - private static readonly long x_lTickBase = 10000; - private static readonly double x_dTickBase = (double)x_lTickBase; + internal const int x_iMoneyScale = 4; + private const long x_lTickBase = 10000; + private const double x_dTickBase = (double)x_lTickBase; - private static readonly long MinLong = unchecked((long)0x8000000000000000L) / x_lTickBase; - private static readonly long MaxLong = 0x7FFFFFFFFFFFFFFFL / x_lTickBase; + private const long MinLong = unchecked((long)0x8000000000000000L) / x_lTickBase; + private const long MaxLong = 0x7FFFFFFFFFFFFFFFL / x_lTickBase; // constructor // construct a Null diff --git a/System.Data/System/Data/SQLTypes/SQLResource.cs b/System.Data/System/Data/SQLTypes/SQLResource.cs index 679bc8ff8..3ce29437d 100644 --- a/System.Data/System/Data/SQLTypes/SQLResource.cs +++ b/System.Data/System/Data/SQLTypes/SQLResource.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** diff --git a/System.Data/System/Data/SQLTypes/SQLSingle.cs b/System.Data/System/Data/SQLTypes/SQLSingle.cs index 5e7aa6869..124a7fe13 100644 --- a/System.Data/System/Data/SQLTypes/SQLSingle.cs +++ b/System.Data/System/Data/SQLTypes/SQLSingle.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** diff --git a/System.Data/System/Data/SQLTypes/SQLString.cs b/System.Data/System/Data/SQLTypes/SQLString.cs index 4bc110c4c..944dd6230 100644 --- a/System.Data/System/Data/SQLTypes/SQLString.cs +++ b/System.Data/System/Data/SQLTypes/SQLString.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** @@ -105,8 +105,8 @@ public struct SqlString : INullable, IComparable, IXmlSerializable { SqlCompareOptions.IgnoreNonSpace | SqlCompareOptions.IgnoreKanaType | SqlCompareOptions.BinarySort | SqlCompareOptions.BinarySort2; - internal static readonly int x_lcidUSEnglish = 0x00000409; - private static readonly int x_lcidBinary = 0x00008200; + internal const int x_lcidUSEnglish = 0x00000409; + private const int x_lcidBinary = 0x00008200; // constructor diff --git a/System.Data/System/Data/SQLTypes/SQLUtility.cs b/System.Data/System/Data/SQLTypes/SQLUtility.cs index 5a8e64811..253b85477 100644 --- a/System.Data/System/Data/SQLTypes/SQLUtility.cs +++ b/System.Data/System/Data/SQLTypes/SQLUtility.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** diff --git a/System.Data/System/Data/SQLTypes/SqlCharStream.cs b/System.Data/System/Data/SQLTypes/SqlCharStream.cs index 3d77065fc..e270bc00b 100644 --- a/System.Data/System/Data/SQLTypes/SqlCharStream.cs +++ b/System.Data/System/Data/SQLTypes/SqlCharStream.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // junfang -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** diff --git a/System.Data/System/Data/SQLTypes/SqlTypesSchemaImporter.cs b/System.Data/System/Data/SQLTypes/SqlTypesSchemaImporter.cs index 0d65de3b2..6b390b537 100644 --- a/System.Data/System/Data/SQLTypes/SqlTypesSchemaImporter.cs +++ b/System.Data/System/Data/SQLTypes/SqlTypesSchemaImporter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // dondu -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/SQLTypes/SqlXml.cs b/System.Data/System/Data/SQLTypes/SqlXml.cs index d05ed2c80..cab4fed08 100644 --- a/System.Data/System/Data/SQLTypes/SqlXml.cs +++ b/System.Data/System/Data/SQLTypes/SqlXml.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //************************************************************************** diff --git a/System.Data/System/Data/SQLTypes/UnsafeNativeMethods.cs b/System.Data/System/Data/SQLTypes/UnsafeNativeMethods.cs index c16394814..7c847edac 100644 --- a/System.Data/System/Data/SQLTypes/UnsafeNativeMethods.cs +++ b/System.Data/System/Data/SQLTypes/UnsafeNativeMethods.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Select.cs b/System.Data/System/Data/Select.cs index afac08872..118a08534 100644 --- a/System.Data/System/Data/Select.cs +++ b/System.Data/System/Data/Select.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -52,7 +52,7 @@ private bool IsSupportedOperator(int op) { return ((op >= Operators.EqualTo && op <= Operators.LessOrEqual) || op == Operators.Is || op == Operators.IsNot); } - // [....] : Gathers all linear expressions in to this.linearExpression and all binary expressions in to their respective candidate columns expressions + // Microsoft : Gathers all linear expressions in to this.linearExpression and all binary expressions in to their respective candidate columns expressions private void AnalyzeExpression(BinaryNode expr) { if (this.linearExpression == this.expression) return; @@ -355,7 +355,7 @@ private void CreateIndex() { matchedCandidates = 0; if (this.linearExpression != this.expression) { IndexField[] fields = index.IndexFields; - while (matchedCandidates < j) { // [....] : j = index.IndexDesc.Length + while (matchedCandidates < j) { // Microsoft : j = index.IndexDesc.Length ColumnInfo canColumn = candidateColumns[fields[matchedCandidates].Column.Ordinal]; if (canColumn == null || canColumn.expr == null) break; @@ -459,7 +459,7 @@ public DataRow[] SelectRows() { return table.NewRowArray(0); Range range; - if (matchedCandidates == 0) { // [....] : Either dont have rowFilter or only linear search expression + if (matchedCandidates == 0) { // Microsoft : Either dont have rowFilter or only linear search expression range = new Range(0, index.RecordCount-1); Debug.Assert(!needSorting, "What are we doing here if no real reuse of this index ?"); this.linearExpression = this.expression; diff --git a/System.Data/System/Data/Selection.cs b/System.Data/System/Data/Selection.cs index 6ef2dd1ea..cdb4f24e6 100644 --- a/System.Data/System/Data/Selection.cs +++ b/System.Data/System/Data/Selection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/SimpleType.cs b/System.Data/System/Data/SimpleType.cs index 13ecfc5b7..a1d995b60 100644 --- a/System.Data/System/Data/SimpleType.cs +++ b/System.Data/System/Data/SimpleType.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -38,7 +38,7 @@ internal sealed class SimpleType : ISerializable { string maxInclusive = ""; string minExclusive = ""; string minInclusive = ""; - //REMOVED: encoding due to [....] 2001 XDS changes + //REMOVED: encoding due to Microsoft 2001 XDS changes // internal string enumeration = ""; @@ -267,7 +267,7 @@ internal XmlNode ToNode(XmlDocument dc, Hashtable prefixes, bool inRemoting) { type.SetAttribute(Keywords.BASE, baseSimpleType.Name); } } - else { // [....] + else { // Microsoft type.SetAttribute(Keywords.BASE, baseSimpleType.Name); } } diff --git a/System.Data/System/Data/Sql/SqlDataSourceEnumerator.cs b/System.Data/System/Data/Sql/SqlDataSourceEnumerator.cs index 4d76cab09..e8a2f8f82 100644 --- a/System.Data/System/Data/Sql/SqlDataSourceEnumerator.cs +++ b/System.Data/System/Data/Sql/SqlDataSourceEnumerator.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Sql { diff --git a/System.Data/System/Data/Sql/SqlFacetAttribute.cs b/System.Data/System/Data/Sql/SqlFacetAttribute.cs index 7b56e9852..0d3fc92f4 100644 --- a/System.Data/System/Data/Sql/SqlFacetAttribute.cs +++ b/System.Data/System/Data/Sql/SqlFacetAttribute.cs @@ -3,12 +3,12 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // -// [....] -// [....] +// Microsoft +// Microsoft // daltudov -// [....] +// Microsoft // beysims -// [....] +// Microsoft // vadimt //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/Sql/SqlFunctionAttribute.cs b/System.Data/System/Data/Sql/SqlFunctionAttribute.cs index b1af7c807..c11a8f4ca 100644 --- a/System.Data/System/Data/Sql/SqlFunctionAttribute.cs +++ b/System.Data/System/Data/Sql/SqlFunctionAttribute.cs @@ -3,12 +3,12 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // -// [....] -// [....] +// Microsoft +// Microsoft // daltudov -// [....] +// Microsoft // beysims -// [....] +// Microsoft // vadimt //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/Sql/SqlGenericUtil.cs b/System.Data/System/Data/Sql/SqlGenericUtil.cs index db01b7ad5..e5a3b3907 100644 --- a/System.Data/System/Data/Sql/SqlGenericUtil.cs +++ b/System.Data/System/Data/Sql/SqlGenericUtil.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Sql { diff --git a/System.Data/System/Data/Sql/SqlMetaData.cs b/System.Data/System/Data/Sql/SqlMetaData.cs index d17f8b723..ea709ecc0 100644 --- a/System.Data/System/Data/Sql/SqlMetaData.cs +++ b/System.Data/System/Data/Sql/SqlMetaData.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/System/Data/Sql/SqlMethodAttribute.cs b/System.Data/System/Data/Sql/SqlMethodAttribute.cs index 66eee2f72..3203b1748 100644 --- a/System.Data/System/Data/Sql/SqlMethodAttribute.cs +++ b/System.Data/System/Data/Sql/SqlMethodAttribute.cs @@ -3,13 +3,13 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // -// [....] -// [....] +// Microsoft +// Microsoft // daltudov -// [....] +// Microsoft // beysims // junfang -// [....] +// Microsoft // vadimt //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/Sql/SqlNotificationRequest.cs b/System.Data/System/Data/Sql/SqlNotificationRequest.cs index 9b5149d52..986d8f5d6 100644 --- a/System.Data/System/Data/Sql/SqlNotificationRequest.cs +++ b/System.Data/System/Data/Sql/SqlNotificationRequest.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.Sql { diff --git a/System.Data/System/Data/Sql/SqlProcedureAttribute.cs b/System.Data/System/Data/Sql/SqlProcedureAttribute.cs index 8f28089cb..c88caeaea 100644 --- a/System.Data/System/Data/Sql/SqlProcedureAttribute.cs +++ b/System.Data/System/Data/Sql/SqlProcedureAttribute.cs @@ -3,12 +3,12 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // -// [....] -// [....] +// Microsoft +// Microsoft // daltudov -// [....] +// Microsoft // beysims -// [....] +// Microsoft // vadimt //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/Sql/SqlTriggerAttribute.cs b/System.Data/System/Data/Sql/SqlTriggerAttribute.cs index dbb72b83d..303687749 100644 --- a/System.Data/System/Data/Sql/SqlTriggerAttribute.cs +++ b/System.Data/System/Data/Sql/SqlTriggerAttribute.cs @@ -3,12 +3,12 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // -// [....] -// [....] +// Microsoft +// Microsoft // daltudov -// [....] +// Microsoft // beysims -// [....] +// Microsoft // vadimt //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/Sql/SqlUserDefinedAggregateAttribute.cs b/System.Data/System/Data/Sql/SqlUserDefinedAggregateAttribute.cs index 56ba4a976..f7c1307fd 100644 --- a/System.Data/System/Data/Sql/SqlUserDefinedAggregateAttribute.cs +++ b/System.Data/System/Data/Sql/SqlUserDefinedAggregateAttribute.cs @@ -3,15 +3,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // -// [....] -// [....] +// Microsoft +// Microsoft // daltudov -// [....] +// Microsoft // beysims -// [....] +// Microsoft // vadimt // venkar -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/System/Data/Sql/SqlUserDefinedTypeAttribute.cs b/System.Data/System/Data/Sql/SqlUserDefinedTypeAttribute.cs index 2684b82fe..8dddb2200 100644 --- a/System.Data/System/Data/Sql/SqlUserDefinedTypeAttribute.cs +++ b/System.Data/System/Data/Sql/SqlUserDefinedTypeAttribute.cs @@ -3,15 +3,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // -// [....] -// [....] +// Microsoft +// Microsoft // daltudov -// [....] +// Microsoft // beysims -// [....] +// Microsoft // vadimt // venkar -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/System/Data/Sql/invalidudtexception.cs b/System.Data/System/Data/Sql/invalidudtexception.cs index 56efbc86f..527832fdb 100644 --- a/System.Data/System/Data/Sql/invalidudtexception.cs +++ b/System.Data/System/Data/Sql/invalidudtexception.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/Sql/sqlnorm.cs b/System.Data/System/Data/Sql/sqlnorm.cs index 2be7f1237..e27d86b3f 100644 --- a/System.Data/System/Data/Sql/sqlnorm.cs +++ b/System.Data/System/Data/Sql/sqlnorm.cs @@ -3,14 +3,14 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // -// [....] -// [....] +// Microsoft +// Microsoft // daltudov -// [....] +// Microsoft // beysims -// [....] +// Microsoft // vadimt -// [....] +// Microsoft // venkar //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/Sql/sqlser.cs b/System.Data/System/Data/Sql/sqlser.cs index 579818e6e..e4a1cada1 100644 --- a/System.Data/System/Data/Sql/sqlser.cs +++ b/System.Data/System/Data/Sql/sqlser.cs @@ -3,15 +3,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // -// [....] -// [....] +// Microsoft +// Microsoft // daltudov -// [....] +// Microsoft // beysims -// [....] +// Microsoft // vadimt // venkar -// [....] +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/SqlClient/RowsCopiedEventArgs.cs b/System.Data/System/Data/SqlClient/RowsCopiedEventArgs.cs index 0a93882a2..cc294b157 100644 --- a/System.Data/System/Data/SqlClient/RowsCopiedEventArgs.cs +++ b/System.Data/System/Data/SqlClient/RowsCopiedEventArgs.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlBuffer.cs b/System.Data/System/Data/SqlClient/SqlBuffer.cs index f4dce919c..9c4084086 100644 --- a/System.Data/System/Data/SqlClient/SqlBuffer.cs +++ b/System.Data/System/Data/SqlClient/SqlBuffer.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlBulkCopy.cs b/System.Data/System/Data/SqlClient/SqlBulkCopy.cs index 2a4b96c02..f538fdfe0 100644 --- a/System.Data/System/Data/SqlClient/SqlBulkCopy.cs +++ b/System.Data/System/Data/SqlClient/SqlBulkCopy.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ // todo list: @@ -531,7 +531,7 @@ private string CreateInitialQuery() { } // Creates and then executes initial query to get information about the targettable - // When __isAsyncBulkCopy == false (i.e. it is [....] copy): out result contains the resulset. Returns null. + // When __isAsyncBulkCopy == false (i.e. it is Sync copy): out result contains the resulset. Returns null. // When __isAsyncBulkCopy == true (i.e. it is Async copy): This still uses the _parser.Run method synchronously and return Task. // We need to have a _parser.RunAsync to make it real async. private Task CreateAndExecuteInitialQueryAsync(out BulkCopySimpleResultSet result) { @@ -1067,7 +1067,7 @@ private object GetValueFromSourceRow(int destRowIndex, out bool isSqlType, out b // unified method to read a row from the current rowsource // When _isAsyncBulkCopy == true (i.e. async copy): returns Task when IDataReader is a DbDataReader, Null for others. - // When _isAsyncBulkCopy == false (i.e. [....] copy): returns null. Uses ReadFromRowSource to get the boolean value. + // When _isAsyncBulkCopy == false (i.e. sync copy): returns null. Uses ReadFromRowSource to get the boolean value. // "more" -- should be used by the caller only when the return value is null. private Task ReadFromRowSourceAsync(CancellationToken cts) { #if !PROJECTK @@ -2081,7 +2081,7 @@ private bool FireRowsCopiedEvent(long rowsCopied) { // Reads a cell and then writes it. // Read may block at this moment since there is no getValueAsync or DownStream async at this moment. // When _isAsyncBulkCopy == true: Write will return Task (when async method runs asynchronously) or Null (when async call actually ran synchronously) for performance. - // When _isAsyncBulkCopy == false: Writes are purely [....]. This method reutrn null at the end. + // When _isAsyncBulkCopy == false: Writes are purely sync. This method reutrn null at the end. // private Task ReadWriteColumnValueAsync(int col) { bool isSqlType; @@ -2392,7 +2392,7 @@ private Task CopyBatchesAsync(BulkCopySimpleResultSet internalResults, string up AsyncHelper.ContinueTask(commandTask, source, () => { Task continuedTask = CopyBatchesAsyncContinued(internalResults, updateBulkCommandText, cts, source); if (continuedTask == null) { - // Continuation finished [....], recall into CopyBatchesAsync to continue + // Continuation finished sync, recall into CopyBatchesAsync to continue CopyBatchesAsync(internalResults, updateBulkCommandText, cts, source); } }, _connection.GetOpenTdsConnection()); @@ -2443,7 +2443,7 @@ private Task CopyBatchesAsyncContinued(BulkCopySimpleResultSet internalResults, AsyncHelper.ContinueTask(task, source, () => { Task continuedTask = CopyBatchesAsyncContinuedOnSuccess(internalResults, updateBulkCommandText, cts, source); if (continuedTask == null) { - // Continuation finished [....], recall into CopyBatchesAsync to continue + // Continuation finished sync, recall into CopyBatchesAsync to continue CopyBatchesAsync(internalResults, updateBulkCommandText, cts, source); } }, _connection.GetOpenTdsConnection(), _ => CopyBatchesAsyncContinuedOnError(cleanupParser: false), () => CopyBatchesAsyncContinuedOnError(cleanupParser: true)); @@ -2586,7 +2586,7 @@ private void CleanUpStateObjectOnError() { // The continuation part of WriteToServerInternalRest. Executes when the initial query task is completed. (see, WriteToServerInternalRest). // It carries on the source which is passed from the WriteToServerInternalRest and performs SetResult when the entire copy is done. - // The carried on source may be null in case of [....] copy. So no need to SetResult at that time. + // The carried on source may be null in case of Sync copy. So no need to SetResult at that time. // It launches the copy operation. // private void WriteToServerInternalRestContinuedAsync(BulkCopySimpleResultSet internalResults, CancellationToken cts, TaskCompletionSource source) { @@ -2683,7 +2683,7 @@ private void WriteToServerInternalRestContinuedAsync(BulkCopySimpleResultSet int // Rest of the WriteToServerInternalAsync method. // It carries on the source from its caller WriteToServerInternal. - // source is null in case of [....] bcp. But valid in case of Async bcp. + // source is null in case of Sync bcp. But valid in case of Async bcp. // It calls the WriteToServerInternalRestContinuedAsync as a continuation of the initial query task. // private void WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletionSource source) { @@ -2793,7 +2793,7 @@ private void WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletio } } - // This returns Task for Async, Null for [....] + // This returns Task for Async, Null for Sync // private Task WriteToServerInternalAsync(CancellationToken ctoken) { TaskCompletionSource source = null; diff --git a/System.Data/System/Data/SqlClient/SqlBulkCopyColumnMapping.cs b/System.Data/System/Data/SqlClient/SqlBulkCopyColumnMapping.cs index d4166c2d9..16b85f3a2 100644 --- a/System.Data/System/Data/SqlClient/SqlBulkCopyColumnMapping.cs +++ b/System.Data/System/Data/SqlClient/SqlBulkCopyColumnMapping.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ // Todo: rename the file diff --git a/System.Data/System/Data/SqlClient/SqlBulkCopyColumnMappingCollection.cs b/System.Data/System/Data/SqlClient/SqlBulkCopyColumnMappingCollection.cs index ac37a1d92..d11c23c8c 100644 --- a/System.Data/System/Data/SqlClient/SqlBulkCopyColumnMappingCollection.cs +++ b/System.Data/System/Data/SqlClient/SqlBulkCopyColumnMappingCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ // todo: rename the file diff --git a/System.Data/System/Data/SqlClient/SqlCachedBuffer.cs b/System.Data/System/Data/SqlClient/SqlCachedBuffer.cs index 5e5e2c22d..ded56bee7 100644 --- a/System.Data/System/Data/SqlClient/SqlCachedBuffer.cs +++ b/System.Data/System/Data/SqlClient/SqlCachedBuffer.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlClientFactory.cs b/System.Data/System/Data/SqlClient/SqlClientFactory.cs index b42193a80..4763dd80d 100644 --- a/System.Data/System/Data/SqlClient/SqlClientFactory.cs +++ b/System.Data/System/Data/SqlClient/SqlClientFactory.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/SqlClient/SqlClientMetaDataCollectionNames.cs b/System.Data/System/Data/SqlClient/SqlClientMetaDataCollectionNames.cs index 46d0f0da5..01530e81b 100644 --- a/System.Data/System/Data/SqlClient/SqlClientMetaDataCollectionNames.cs +++ b/System.Data/System/Data/SqlClient/SqlClientMetaDataCollectionNames.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient{ diff --git a/System.Data/System/Data/SqlClient/SqlClientPermission.cs b/System.Data/System/Data/SqlClient/SqlClientPermission.cs index d668f1169..695b9adad 100644 --- a/System.Data/System/Data/SqlClient/SqlClientPermission.cs +++ b/System.Data/System/Data/SqlClient/SqlClientPermission.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlClientSymmetricKey.cs b/System.Data/System/Data/SqlClient/SqlClientSymmetricKey.cs index 501ed7c91..0481e480a 100644 --- a/System.Data/System/Data/SqlClient/SqlClientSymmetricKey.cs +++ b/System.Data/System/Data/SqlClient/SqlClientSymmetricKey.cs @@ -35,15 +35,9 @@ internal SqlClientSymmetricKey(byte[] rootKey) { } /// - /// Destructor that cleans up the key material. - /// This is a best effort approach since there are no guarantees around GC. + /// Empty destructor for binary back compat. /// ~SqlClientSymmetricKey() { - if (_rootKey != null) { - for (int i = 0; i < _rootKey.Length; i++) { - _rootKey[i] = 0; - } - } } /// diff --git a/System.Data/System/Data/SqlClient/SqlClientWrapperSmiStream.cs b/System.Data/System/Data/SqlClient/SqlClientWrapperSmiStream.cs index e4e984da9..32ef810a4 100644 --- a/System.Data/System/Data/SqlClient/SqlClientWrapperSmiStream.cs +++ b/System.Data/System/Data/SqlClient/SqlClientWrapperSmiStream.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/System/Data/SqlClient/SqlClientWrapperSmiStreamChars.cs b/System.Data/System/Data/SqlClient/SqlClientWrapperSmiStreamChars.cs index f5ae0f3df..1818a2e0c 100644 --- a/System.Data/System/Data/SqlClient/SqlClientWrapperSmiStreamChars.cs +++ b/System.Data/System/Data/SqlClient/SqlClientWrapperSmiStreamChars.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace Microsoft.SqlServer.Server { diff --git a/System.Data/System/Data/SqlClient/SqlColumnEncryptionCngProvider.cs b/System.Data/System/Data/SqlClient/SqlColumnEncryptionCngProvider.cs index aa4561ab3..6f6c3010f 100644 --- a/System.Data/System/Data/SqlClient/SqlColumnEncryptionCngProvider.cs +++ b/System.Data/System/Data/SqlClient/SqlColumnEncryptionCngProvider.cs @@ -37,7 +37,7 @@ public class SqlColumnEncryptionCngProvider : SqlColumnEncryptionKeyStoreProvide /// /// RSA_OAEP is the only algorithm supported for encrypting/decrypting column encryption keys using this provider. - /// For now, we are keeping all the providers in [....]. + /// For now, we are keeping all the providers in sync. /// private const string RSAEncryptionAlgorithmWithOAEP = @"RSA_OAEP"; diff --git a/System.Data/System/Data/SqlClient/SqlColumnEncryptionCspProvider.cs b/System.Data/System/Data/SqlClient/SqlColumnEncryptionCspProvider.cs index 19ac621b3..14e57082c 100644 --- a/System.Data/System/Data/SqlClient/SqlColumnEncryptionCspProvider.cs +++ b/System.Data/System/Data/SqlClient/SqlColumnEncryptionCspProvider.cs @@ -38,7 +38,7 @@ public class SqlColumnEncryptionCspProvider : SqlColumnEncryptionKeyStoreProvide /// /// RSA_OAEP is the only algorithm supported for encrypting/decrypting column encryption keys using this provider. - /// For now, we are keeping all the providers in [....]. + /// For now, we are keeping all the providers in sync. /// private const string RSAEncryptionAlgorithmWithOAEP = @"RSA_OAEP"; diff --git a/System.Data/System/Data/SqlClient/SqlCommand.cs b/System.Data/System/Data/SqlClient/SqlCommand.cs index 46a535370..5a3c6835c 100644 --- a/System.Data/System/Data/SqlClient/SqlCommand.cs +++ b/System.Data/System/Data/SqlClient/SqlCommand.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { @@ -500,7 +500,7 @@ private SqlCommand(SqlCommand from) : this() { // Clone } } - _activeConnection = value; // UNDONE: Designers need this setter. Should we block other scenarios? + _activeConnection = value; // Bid.Trace(" %d#, %d#\n", ObjectID, ((null != value) ? value.ObjectID : -1)); } @@ -1991,7 +1991,7 @@ public IAsyncResult BeginExecuteReader(AsyncCallback callback, object stateObjec } internal SqlDataReader ExecuteReader(CommandBehavior behavior, string method) { - SqlConnection.ExecutePermission.Demand(); // TODO: Need to move this to public methods... + SqlConnection.ExecutePermission.Demand(); // // Reset _pendingCancel upon entry into any Execute - used to synchronize state // between entry into Execute* API and the thread obtaining the stateObject. @@ -4032,7 +4032,7 @@ internal SqlDataReader RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior catch (SqlException ex) { // We only want to retry once, so don't retry if we are already in retry. // If we didn't use the cache, we don't want to retry. - // The async retried are handled separately, handle only [....] calls here. + // The async retried are handled separately, handle only sync calls here. if (inRetry || async || !usedCache) { throw; } @@ -4441,7 +4441,7 @@ private SqlDataReader RunExecuteReaderSmi( CommandBehavior cmdBehavior, RunBehav } if (null != eventStream) { - eventStream.Close( EventSink ); // UNDONE: should cancel instead! + eventStream.Close( EventSink ); // } if (requestExecutor != null) { diff --git a/System.Data/System/Data/SqlClient/SqlCommandBuilder.cs b/System.Data/System/Data/SqlClient/SqlCommandBuilder.cs index 476000e80..7563b0c08 100644 --- a/System.Data/System/Data/SqlClient/SqlCommandBuilder.cs +++ b/System.Data/System/Data/SqlClient/SqlCommandBuilder.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlCommandSet.cs b/System.Data/System/Data/SqlClient/SqlCommandSet.cs index b15a5353b..913a30f1c 100644 --- a/System.Data/System/Data/SqlClient/SqlCommandSet.cs +++ b/System.Data/System/Data/SqlClient/SqlCommandSet.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlConnection.cs b/System.Data/System/Data/SqlClient/SqlConnection.cs index af278effe..de80e6bd9 100644 --- a/System.Data/System/Data/SqlClient/SqlConnection.cs +++ b/System.Data/System/Data/SqlClient/SqlConnection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("System.Data.DataSetExtensions, PublicKey="+AssemblyRef.EcmaPublicKeyFull)] // DevDiv Bugs 92166 @@ -1700,7 +1700,7 @@ internal void OnError(SqlException exception, bool breakConnection, Action // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient diff --git a/System.Data/System/Data/SqlClient/SqlConnectionPoolGroupProviderInfo.cs b/System.Data/System/Data/SqlClient/SqlConnectionPoolGroupProviderInfo.cs index 044682c67..157865b45 100644 --- a/System.Data/System/Data/SqlClient/SqlConnectionPoolGroupProviderInfo.cs +++ b/System.Data/System/Data/SqlClient/SqlConnectionPoolGroupProviderInfo.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient diff --git a/System.Data/System/Data/SqlClient/SqlConnectionPoolKey.cs b/System.Data/System/Data/SqlClient/SqlConnectionPoolKey.cs index e3fb5a7dd..ccb98a2b8 100644 --- a/System.Data/System/Data/SqlClient/SqlConnectionPoolKey.cs +++ b/System.Data/System/Data/SqlClient/SqlConnectionPoolKey.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient diff --git a/System.Data/System/Data/SqlClient/SqlConnectionPoolProviderInfo.cs b/System.Data/System/Data/SqlClient/SqlConnectionPoolProviderInfo.cs index d5ff005e6..3f9e5ccee 100644 --- a/System.Data/System/Data/SqlClient/SqlConnectionPoolProviderInfo.cs +++ b/System.Data/System/Data/SqlClient/SqlConnectionPoolProviderInfo.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlConnectionString.cs b/System.Data/System/Data/SqlClient/SqlConnectionString.cs index 1dd74aec9..05e672bff 100644 --- a/System.Data/System/Data/SqlClient/SqlConnectionString.cs +++ b/System.Data/System/Data/SqlClient/SqlConnectionString.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlConnectionStringBuilder.cs b/System.Data/System/Data/SqlClient/SqlConnectionStringBuilder.cs index ae3c2b1e6..21ff4e0fa 100644 --- a/System.Data/System/Data/SqlClient/SqlConnectionStringBuilder.cs +++ b/System.Data/System/Data/SqlClient/SqlConnectionStringBuilder.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/SqlClient/SqlConnectionTimeoutErrorInternal.cs b/System.Data/System/Data/SqlClient/SqlConnectionTimeoutErrorInternal.cs index 0e799476b..f7e0ca2d2 100644 --- a/System.Data/System/Data/SqlClient/SqlConnectionTimeoutErrorInternal.cs +++ b/System.Data/System/Data/SqlClient/SqlConnectionTimeoutErrorInternal.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient diff --git a/System.Data/System/Data/SqlClient/SqlCredential.cs b/System.Data/System/Data/SqlClient/SqlCredential.cs index 874ac5cc3..091753c6f 100644 --- a/System.Data/System/Data/SqlClient/SqlCredential.cs +++ b/System.Data/System/Data/SqlClient/SqlCredential.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient diff --git a/System.Data/System/Data/SqlClient/SqlDataAdapter.cs b/System.Data/System/Data/SqlClient/SqlDataAdapter.cs index 11be2219a..b1f304cd7 100644 --- a/System.Data/System/Data/SqlClient/SqlDataAdapter.cs +++ b/System.Data/System/Data/SqlClient/SqlDataAdapter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlDataReader.cs b/System.Data/System/Data/SqlClient/SqlDataReader.cs index 8e04c4225..fcec91e6f 100644 --- a/System.Data/System/Data/SqlClient/SqlDataReader.cs +++ b/System.Data/System/Data/SqlClient/SqlDataReader.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { @@ -44,7 +44,7 @@ internal class SharedState { // parameters needed to execute cleanup from parser internal SharedState _sharedState = new SharedState(); - private TdsParser _parser; // TODO: Probably don't need this, since it's on the stateObj + private TdsParser _parser; // private TdsParserStateObject _stateObj; private SqlCommand _command; private SqlConnection _connection; @@ -1105,7 +1105,7 @@ virtual internal void CloseReaderFromConnection() { // CleanWire will do cleanup - so we don't really care about the snapshot CleanupAfterAsyncInvocationInternal(stateObj, resetNetworkPacketTaskSource: false); } - // Switch to [....] to prepare for cleanwire + // Switch to sync to prepare for cleanwire stateObj._syncOverAsync = true; // Remove owner (this will allow the stateObj to be disposed after the connection is closed) stateObj.RemoveOwner(); @@ -4355,7 +4355,7 @@ override public Task IsDBNullAsync(int i, CancellationToken cancellationTo return ADP.CreatedTaskWithCancellation(); } - // Shortcut - if we have enough data, then run [....] + // Shortcut - if we have enough data, then run sync try { if (WillHaveEnoughData(i, headerOnly: true)) { #if DEBUG @@ -4457,7 +4457,7 @@ override public Task GetFieldValueAsync(int i, CancellationToken cancellat return ADP.CreatedTaskWithCancellation(); } - // Shortcut - if we have enough data, then run [....] + // Shortcut - if we have enough data, then run sync try { if (WillHaveEnoughData(i)) { #if DEBUG @@ -4628,9 +4628,7 @@ private Task InvokeRetryable(Func> moreFunc, TaskCompletionS } if (task.IsCompleted) { - // If we've completed [....], then don't bother handling the TaskCompletionSource - we'll just return the completed task CompleteRetryable(task, source, objectToDispose); - return task; } else { task.ContinueWith((t) => CompleteRetryable(t, source, objectToDispose), TaskScheduler.Default); diff --git a/System.Data/System/Data/SqlClient/SqlDataReaderSmi.cs b/System.Data/System/Data/SqlClient/SqlDataReaderSmi.cs index 4a46f64b6..ded4479ff 100644 --- a/System.Data/System/Data/SqlClient/SqlDataReaderSmi.cs +++ b/System.Data/System/Data/SqlClient/SqlDataReaderSmi.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlDelegatedTransaction.cs b/System.Data/System/Data/SqlClient/SqlDelegatedTransaction.cs index 60edc0e40..63bae158d 100644 --- a/System.Data/System/Data/SqlClient/SqlDelegatedTransaction.cs +++ b/System.Data/System/Data/SqlClient/SqlDelegatedTransaction.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlDependency.cs b/System.Data/System/Data/SqlClient/SqlDependency.cs index fe13f0878..c27b94cd0 100644 --- a/System.Data/System/Data/SqlClient/SqlDependency.cs +++ b/System.Data/System/Data/SqlClient/SqlDependency.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlDependencyListener.cs b/System.Data/System/Data/SqlClient/SqlDependencyListener.cs index 9a11b63cb..656d0dd6d 100644 --- a/System.Data/System/Data/SqlClient/SqlDependencyListener.cs +++ b/System.Data/System/Data/SqlClient/SqlDependencyListener.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; @@ -151,7 +151,7 @@ internal SqlConnectionContainer(SqlConnectionContainerHashHelper hashHelper, str _conversationGuidParam = new SqlParameter("@p1", SqlDbType.UniqueIdentifier); _timeoutParam = new SqlParameter("@p2", SqlDbType.Int); - _timeoutParam.Value = 0; // Timeout set to 0 for initial [....] query. + _timeoutParam.Value = 0; // Timeout set to 0 for initial sync query. _com.Parameters.Add(_timeoutParam); setupCompleted = true; @@ -160,7 +160,7 @@ internal SqlConnectionContainer(SqlConnectionContainerHashHelper hashHelper, str // Create standard query. _receiveQuery = "WAITFOR(RECEIVE TOP (1) message_type_name, conversation_handle, cast(message_body AS XML) as message_body from " + _escapedQueueName + "), TIMEOUT @p2;"; - // Create queue, service, [....] query, and async query on user thread to ensure proper + // Create queue, service, sync query, and async query on user thread to ensure proper // init prior to return. if (useDefaults) { // Only create if user did not specify service & database. @@ -179,7 +179,7 @@ internal SqlConnectionContainer(SqlConnectionContainerHashHelper hashHelper, str // Query synchronously once to ensure everything is working correctly. // We want the exception to occur on start to immediately inform caller. SynchronouslyQueryServiceBrokerQueue(); - _timeoutParam.Value = _defaultWaitforTimeout; // [....] successful, extend timeout to 60 seconds. + _timeoutParam.Value = _defaultWaitforTimeout; // Sync successful, extend timeout to 60 seconds. AsynchronouslyQueryServiceBrokerQueue(); } catch (Exception e) { diff --git a/System.Data/System/Data/SqlClient/SqlDependencyUtils.cs b/System.Data/System/Data/SqlClient/SqlDependencyUtils.cs index ae91e9644..ccd6d84f7 100644 --- a/System.Data/System/Data/SqlClient/SqlDependencyUtils.cs +++ b/System.Data/System/Data/SqlClient/SqlDependencyUtils.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { @@ -179,7 +179,7 @@ internal string AddCommandEntry(string commandHash, SqlDependency dep) { { // this should not happen since _commandHashToNotificationId and _notificationIdToDependenciesHash are always // updated together - Debug.Assert(false, "_commandHashToNotificationId has entries that were removed from _notificationIdToDependenciesHash. Remember to keep them in [....]"); + Debug.Assert(false, "_commandHashToNotificationId has entries that were removed from _notificationIdToDependenciesHash. Remember to keep them in sync"); throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyCommandHashIsNotAssociatedWithNotification); } @@ -217,7 +217,7 @@ internal string AddCommandEntry(string commandHash, SqlDependency dep) { } - Debug.Assert(_notificationIdToDependenciesHash.Count == _commandHashToNotificationId.Count, "always keep these maps in [....]!"); + Debug.Assert(_notificationIdToDependenciesHash.Count == _commandHashToNotificationId.Count, "always keep these maps in sync!"); } } } @@ -402,7 +402,7 @@ private List LookupCommandEntryWithRemove(string notificationId) Bid.NotificationsTrace(" Entries NOT found in hashtable.\n"); } - Debug.Assert(_notificationIdToDependenciesHash.Count == _commandHashToNotificationId.Count, "always keep these maps in [....]!"); + Debug.Assert(_notificationIdToDependenciesHash.Count == _commandHashToNotificationId.Count, "always keep these maps in sync!"); } return entry; // DependencyList inherits from List @@ -436,7 +436,7 @@ private void RemoveDependencyFromCommandToDependenciesHash(SqlDependency depende // same SqlDependency can be associated with more than one command, so we have to continue till the end... } - Debug.Assert(commandHashesToRemove.Count == notificationIdsToRemove.Count, "maps should be kept in [....]"); + Debug.Assert(commandHashesToRemove.Count == notificationIdsToRemove.Count, "maps should be kept in sync"); for (int i = 0; i < notificationIdsToRemove.Count; i++ ) { // cleanup the entry outside of foreach // do it inside finally block to avoid ThreadAbort exception interrupt this operation @@ -448,7 +448,7 @@ private void RemoveDependencyFromCommandToDependenciesHash(SqlDependency depende } } - Debug.Assert(_notificationIdToDependenciesHash.Count == _commandHashToNotificationId.Count, "always keep these maps in [....]!"); + Debug.Assert(_notificationIdToDependenciesHash.Count == _commandHashToNotificationId.Count, "always keep these maps in sync!"); } } finally { diff --git a/System.Data/System/Data/SqlClient/SqlEnums.cs b/System.Data/System/Data/SqlClient/SqlEnums.cs index da0013b80..ea4a9a88b 100644 --- a/System.Data/System/Data/SqlClient/SqlEnums.cs +++ b/System.Data/System/Data/SqlClient/SqlEnums.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlError.cs b/System.Data/System/Data/SqlClient/SqlError.cs index 9b4d5ee36..e929e0eaf 100644 --- a/System.Data/System/Data/SqlClient/SqlError.cs +++ b/System.Data/System/Data/SqlClient/SqlError.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { @@ -16,7 +16,7 @@ namespace System.Data.SqlClient { public sealed class SqlError { // bug fix - MDAC 48965 - missing source of exception - // fixed by [....] + // fixed by Microsoft private string source = TdsEnums.SQL_PROVIDER_NAME; private int number; private byte state; @@ -61,7 +61,7 @@ public override string ToString() { } // bug fix - MDAC #48965 - missing source of exception - // fixed by [....] + // fixed by Microsoft public string Source { get { return this.source;} } diff --git a/System.Data/System/Data/SqlClient/SqlErrorCollection.cs b/System.Data/System/Data/SqlClient/SqlErrorCollection.cs index 143be5fa3..18ea5d808 100644 --- a/System.Data/System/Data/SqlClient/SqlErrorCollection.cs +++ b/System.Data/System/Data/SqlClient/SqlErrorCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlException.cs b/System.Data/System/Data/SqlClient/SqlException.cs index 2da09347a..72dab1c0a 100644 --- a/System.Data/System/Data/SqlClient/SqlException.cs +++ b/System.Data/System/Data/SqlClient/SqlException.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlInfoMessageEvent.cs b/System.Data/System/Data/SqlClient/SqlInfoMessageEvent.cs index 51e69e9dd..1e3eadb40 100644 --- a/System.Data/System/Data/SqlClient/SqlInfoMessageEvent.cs +++ b/System.Data/System/Data/SqlClient/SqlInfoMessageEvent.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlInternalConnection.cs b/System.Data/System/Data/SqlClient/SqlInternalConnection.cs index 6221416a1..3179c4849 100644 --- a/System.Data/System/Data/SqlClient/SqlInternalConnection.cs +++ b/System.Data/System/Data/SqlClient/SqlInternalConnection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient diff --git a/System.Data/System/Data/SqlClient/SqlInternalConnectionSmi.cs b/System.Data/System/Data/SqlClient/SqlInternalConnectionSmi.cs index 167727734..becb5962e 100644 --- a/System.Data/System/Data/SqlClient/SqlInternalConnectionSmi.cs +++ b/System.Data/System/Data/SqlClient/SqlInternalConnectionSmi.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlInternalConnectionTds.cs b/System.Data/System/Data/SqlClient/SqlInternalConnectionTds.cs index 376909b9a..a617acd95 100644 --- a/System.Data/System/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/System.Data/System/Data/SqlClient/SqlInternalConnectionTds.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient @@ -1428,16 +1428,21 @@ private void LoginNoFailover(ServerInfo serverInfo, string newPassword, SecureSt ResolveExtendedServerName(serverInfo, !redirectedUserInstance, connectionOptions); + Boolean disableTnir = ShouldDisableTnir(connectionOptions); + long timeoutUnitInterval = 0; - Boolean isParallel = connectionOptions.MultiSubnetFailover || connectionOptions.TransparentNetworkIPResolution; + Boolean isParallel = connectionOptions.MultiSubnetFailover || (connectionOptions.TransparentNetworkIPResolution && !disableTnir); + + if(isParallel) { + float failoverTimeoutStep = connectionOptions.MultiSubnetFailover ? ADP.FailoverTimeoutStep : ADP.FailoverTimeoutStepForTnir; // Determine unit interval if (timeout.IsInfinite) { - timeoutUnitInterval = checked((long)(ADP.FailoverTimeoutStep * (1000L * ADP.DefaultConnectionTimeout))); + timeoutUnitInterval = checked((long)(failoverTimeoutStep * (1000L * ADP.DefaultConnectionTimeout))); } else { - timeoutUnitInterval = checked((long)(ADP.FailoverTimeoutStep * timeout.MillisecondsRemaining)); + timeoutUnitInterval = checked((long)(failoverTimeoutStep * timeout.MillisecondsRemaining)); } } // Only three ways out of this loop: @@ -1451,15 +1456,31 @@ private void LoginNoFailover(ServerInfo serverInfo, string newPassword, SecureSt // back into the parser for the error cases. int attemptNumber = 0; TimeoutTimer intervalTimer = null; - TimeoutTimer firstTransparentAttemptTimeout = TimeoutTimer.StartMillisecondsTimeout(ADP.FirstTransparentAttemptTimeout); + TimeoutTimer attemptOneLoginTimeout = timeout; while(true) { + Boolean isFirstTransparentAttempt = connectionOptions.TransparentNetworkIPResolution && !disableTnir && attemptNumber == 1; + if(isParallel) { - attemptNumber++; + int multiplier = ++attemptNumber; + + if (connectionOptions.TransparentNetworkIPResolution) + { + // While connecting using TNIR the timeout multiplier should be increased to allow steps of 1,2,4 instead of 1,2,3. + // This will allow half the time out for the last connection attempt in case of Tnir. + multiplier = 1 << (attemptNumber - 1); + } // Set timeout for this attempt, but don't exceed original timer - long nextTimeoutInterval = checked(timeoutUnitInterval * attemptNumber); + long nextTimeoutInterval = checked(timeoutUnitInterval * multiplier); long milliseconds = timeout.MillisecondsRemaining; + + // If it is the first attempt at TNIR connection, then allow at least 500 ms for timeout. With the current failover step of 0.125 + // and Connection Time of < 4000 ms, the first attempt can be lower than 500 ms. + if (isFirstTransparentAttempt) + { + nextTimeoutInterval = Math.Max(ADP.MinimumTimeoutForTnirMs, nextTimeoutInterval); + } if (nextTimeoutInterval > milliseconds) { nextTimeoutInterval = milliseconds; } @@ -1478,15 +1499,9 @@ private void LoginNoFailover(ServerInfo serverInfo, string newPassword, SecureSt // - Boolean isFirstTransparentAttempt = connectionOptions.TransparentNetworkIPResolution && attemptNumber == 1; - - if(isFirstTransparentAttempt) { - attemptOneLoginTimeout = firstTransparentAttemptTimeout; - } - else { - if(isParallel) { - attemptOneLoginTimeout = intervalTimer; - } + + if(isParallel) { + attemptOneLoginTimeout = intervalTimer; } AttemptOneLogin( serverInfo, @@ -1494,7 +1509,8 @@ private void LoginNoFailover(ServerInfo serverInfo, string newPassword, SecureSt newSecurePassword, !isParallel, // ignore timeout for SniOpen call unless MSF , and TNIR attemptOneLoginTimeout, - isFirstTransparentAttempt:isFirstTransparentAttempt); + isFirstTransparentAttempt:isFirstTransparentAttempt, + disableTnir: disableTnir); if (connectionOptions.MultiSubnetFailover && null != ServerProvidedFailOverPartner) { // connection succeeded: trigger exception if server sends failover partner and MultiSubnetFailover is used. @@ -1594,6 +1610,21 @@ private void LoginNoFailover(ServerInfo serverInfo, string newPassword, SecureSt CurrentDataSource = originalServerInfo.UserServerName; } + private bool ShouldDisableTnir(SqlConnectionString connectionOptions) + { + Boolean isAzureEndPoint = ADP.IsAzureSqlServerEndpoint(connectionOptions.DataSource); + + Boolean isFedAuthEnabled = this._accessTokenInBytes != null || + connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryPassword || + connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryIntegrated; + + // Check if the user had explicitly specified the TNIR option in the connection string or the connection string builder. + // If the user has specified the option in the connection string explicitly, then we shouldn't disable TNIR. + bool isTnirExplicitlySpecifiedInConnectionOptions = connectionOptions.Parsetable[SqlConnectionString.KEY.TransparentNetworkIPResolution] != null; + + return isTnirExplicitlySpecifiedInConnectionOptions ? false : (isAzureEndPoint || isFedAuthEnabled); + } + // Attempt to login to a host that has a failover partner // // Connection & timeout sequence is @@ -1815,7 +1846,8 @@ private void ResolveExtendedServerName(ServerInfo serverInfo, bool aliasLookup, } // Common code path for making one attempt to establish a connection and log in to server. - private void AttemptOneLogin(ServerInfo serverInfo, string newPassword, SecureString newSecurePassword, bool ignoreSniOpenTimeout, TimeoutTimer timeout, bool withFailover = false, bool isFirstTransparentAttempt = true) { + private void AttemptOneLogin(ServerInfo serverInfo, string newPassword, SecureString newSecurePassword, bool ignoreSniOpenTimeout, TimeoutTimer timeout, bool withFailover = false, bool isFirstTransparentAttempt = true, bool disableTnir = false) + { if (Bid.AdvancedOn) { Bid.Trace(" %d#, timout=%I64d{msec}, server=", ObjectID, timeout.MillisecondsRemaining); Bid.PutStr(serverInfo.ExtendedServerName); @@ -1835,7 +1867,8 @@ private void AttemptOneLogin(ServerInfo serverInfo, string newPassword, SecureSt ConnectionOptions.IntegratedSecurity, withFailover, isFirstTransparentAttempt, - ConnectionOptions.Authentication); + ConnectionOptions.Authentication, + disableTnir); timeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.ConsumePreLoginHandshake); timeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.LoginBegin); diff --git a/System.Data/System/Data/SqlClient/SqlNotificationEventArgs.cs b/System.Data/System/Data/SqlClient/SqlNotificationEventArgs.cs index 89498fc18..590e7bfe3 100644 --- a/System.Data/System/Data/SqlClient/SqlNotificationEventArgs.cs +++ b/System.Data/System/Data/SqlClient/SqlNotificationEventArgs.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlParameter.cs b/System.Data/System/Data/SqlClient/SqlParameter.cs index 81274a6b8..37efcfd52 100644 --- a/System.Data/System/Data/SqlClient/SqlParameter.cs +++ b/System.Data/System/Data/SqlClient/SqlParameter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlParameterCollection.cs b/System.Data/System/Data/SqlClient/SqlParameterCollection.cs index 4367bc7a6..a89514591 100644 --- a/System.Data/System/Data/SqlClient/SqlParameterCollection.cs +++ b/System.Data/System/Data/SqlClient/SqlParameterCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlReferenceCollection.cs b/System.Data/System/Data/SqlClient/SqlReferenceCollection.cs index e26069f2d..c50e7ea4f 100644 --- a/System.Data/System/Data/SqlClient/SqlReferenceCollection.cs +++ b/System.Data/System/Data/SqlClient/SqlReferenceCollection.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Data/System/Data/SqlClient/SqlRowUpdatedEvent.cs b/System.Data/System/Data/SqlClient/SqlRowUpdatedEvent.cs index 75d370323..a0ff53b1f 100644 --- a/System.Data/System/Data/SqlClient/SqlRowUpdatedEvent.cs +++ b/System.Data/System/Data/SqlClient/SqlRowUpdatedEvent.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlRowUpdatingEvent.cs b/System.Data/System/Data/SqlClient/SqlRowUpdatingEvent.cs index 6d3bcd921..2233e9dff 100644 --- a/System.Data/System/Data/SqlClient/SqlRowUpdatingEvent.cs +++ b/System.Data/System/Data/SqlClient/SqlRowUpdatingEvent.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlSequentialTextReader.cs b/System.Data/System/Data/SqlClient/SqlSequentialTextReader.cs index d5e60712a..8236a519b 100644 --- a/System.Data/System/Data/SqlClient/SqlSequentialTextReader.cs +++ b/System.Data/System/Data/SqlClient/SqlSequentialTextReader.cs @@ -180,7 +180,7 @@ public override Task ReadAsync(char[] buffer, int index, int count) byteBufferUsed += bytesRead; } else { - // We need more data - setup the callback, and mark this as not completed [....] + // We need more data - setup the callback, and mark this as not completed sync completedSynchronously = false; getBytesTask.ContinueWith((t) => { diff --git a/System.Data/System/Data/SqlClient/SqlStatistics.cs b/System.Data/System/Data/SqlClient/SqlStatistics.cs index be518346a..688fe4f3d 100644 --- a/System.Data/System/Data/SqlClient/SqlStatistics.cs +++ b/System.Data/System/Data/SqlClient/SqlStatistics.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/SqlClient/SqlStream.cs b/System.Data/System/Data/SqlClient/SqlStream.cs index 6fa190091..d8a7753b3 100644 --- a/System.Data/System/Data/SqlClient/SqlStream.cs +++ b/System.Data/System/Data/SqlClient/SqlStream.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlTransaction.cs b/System.Data/System/Data/SqlClient/SqlTransaction.cs index ff02ce923..e7927edf1 100644 --- a/System.Data/System/Data/SqlClient/SqlTransaction.cs +++ b/System.Data/System/Data/SqlClient/SqlTransaction.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlUdtInfo.cs b/System.Data/System/Data/SqlClient/SqlUdtInfo.cs index cfde73a6f..a97f766bf 100644 --- a/System.Data/System/Data/SqlClient/SqlUdtInfo.cs +++ b/System.Data/System/Data/SqlClient/SqlUdtInfo.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/SqlUtil.cs b/System.Data/System/Data/SqlClient/SqlUtil.cs index 815a25efd..c472ff324 100644 --- a/System.Data/System/Data/SqlClient/SqlUtil.cs +++ b/System.Data/System/Data/SqlClient/SqlUtil.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/TdsEnums.cs b/System.Data/System/Data/SqlClient/TdsEnums.cs index 11e3cdd98..d0607ec2f 100644 --- a/System.Data/System/Data/SqlClient/TdsEnums.cs +++ b/System.Data/System/Data/SqlClient/TdsEnums.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/TdsParameterSetter.cs b/System.Data/System/Data/SqlClient/TdsParameterSetter.cs index 56a661fe1..18da7f153 100644 --- a/System.Data/System/Data/SqlClient/TdsParameterSetter.cs +++ b/System.Data/System/Data/SqlClient/TdsParameterSetter.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/TdsParser.cs b/System.Data/System/Data/SqlClient/TdsParser.cs index 8c2c8cc5d..3d3d95f3f 100644 --- a/System.Data/System/Data/SqlClient/TdsParser.cs +++ b/System.Data/System/Data/SqlClient/TdsParser.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { @@ -386,7 +386,8 @@ internal void Connect(ServerInfo serverInfo, bool integratedSecurity, bool withFailover, bool isFirstTransparentAttempt, - SqlAuthenticationMethod authType) { + SqlAuthenticationMethod authType, + bool disableTnir) { if (_state != TdsParserState.Closed) { Debug.Assert(false, "TdsParser.Connect called on non-closed connection!"); return; @@ -435,7 +436,7 @@ internal void Connect(ServerInfo serverInfo, bool fParallel = _connHandler.ConnectionOptions.MultiSubnetFailover; TransparentNetworkResolutionState transparentNetworkResolutionState; - if(_connHandler.ConnectionOptions.TransparentNetworkIPResolution) + if (_connHandler.ConnectionOptions.TransparentNetworkIPResolution && !disableTnir) { if(isFirstTransparentAttempt) transparentNetworkResolutionState = TransparentNetworkResolutionState.SequentialMode; @@ -7948,7 +7949,7 @@ internal Task TdsExecuteSQLBatch(string text, int timeout, SqlNotificationReques }, TaskScheduler.Default); } - // Finished [....] + // Finished sync return null; } catch (Exception e) { @@ -8773,7 +8774,7 @@ private void WriteSmiTypeInfo(MSS.SmiExtendedMetaData metaData, TdsParserStateOb case SqlDbType.Char: stateObj.WriteByte(TdsEnums.SQLBIGCHAR); WriteUnsignedShort(checked((ushort)(metaData.MaxLength)), stateObj); - WriteUnsignedInt(_defaultCollation.info, stateObj); // TODO: Use metadata's collation?? + WriteUnsignedInt(_defaultCollation.info, stateObj); // stateObj.WriteByte(_defaultCollation.sortId); break; case SqlDbType.DateTime: @@ -8805,13 +8806,13 @@ private void WriteSmiTypeInfo(MSS.SmiExtendedMetaData metaData, TdsParserStateOb case SqlDbType.NChar: stateObj.WriteByte(TdsEnums.SQLNCHAR); WriteUnsignedShort(checked((ushort)(metaData.MaxLength*2)), stateObj); - WriteUnsignedInt(_defaultCollation.info, stateObj); // TODO: Use metadata's collation?? + WriteUnsignedInt(_defaultCollation.info, stateObj); // stateObj.WriteByte(_defaultCollation.sortId); break; case SqlDbType.NText: stateObj.WriteByte(TdsEnums.SQLNVARCHAR); WriteUnsignedShort(unchecked((ushort)MSS.SmiMetaData.UnlimitedMaxLengthIndicator), stateObj); - WriteUnsignedInt(_defaultCollation.info, stateObj); // TODO: Use metadata's collation?? + WriteUnsignedInt(_defaultCollation.info, stateObj); // stateObj.WriteByte(_defaultCollation.sortId); break; case SqlDbType.NVarChar: @@ -8822,7 +8823,7 @@ private void WriteSmiTypeInfo(MSS.SmiExtendedMetaData metaData, TdsParserStateOb else { WriteUnsignedShort(checked((ushort)(metaData.MaxLength*2)), stateObj); } - WriteUnsignedInt(_defaultCollation.info, stateObj); // TODO: Use metadata's collation?? + WriteUnsignedInt(_defaultCollation.info, stateObj); // stateObj.WriteByte(_defaultCollation.sortId); break; case SqlDbType.Real: @@ -8848,7 +8849,7 @@ private void WriteSmiTypeInfo(MSS.SmiExtendedMetaData metaData, TdsParserStateOb case SqlDbType.Text: stateObj.WriteByte(TdsEnums.SQLBIGVARCHAR); WriteUnsignedShort(unchecked((ushort)MSS.SmiMetaData.UnlimitedMaxLengthIndicator), stateObj); - WriteUnsignedInt(_defaultCollation.info, stateObj); // TODO: Use metadata's collation?? + WriteUnsignedInt(_defaultCollation.info, stateObj); // stateObj.WriteByte(_defaultCollation.sortId); break; case SqlDbType.Timestamp: @@ -8866,7 +8867,7 @@ private void WriteSmiTypeInfo(MSS.SmiExtendedMetaData metaData, TdsParserStateOb case SqlDbType.VarChar: stateObj.WriteByte(TdsEnums.SQLBIGVARCHAR); WriteUnsignedShort(unchecked((ushort)metaData.MaxLength), stateObj); - WriteUnsignedInt(_defaultCollation.info, stateObj); // TODO: Use metadata's collation?? + WriteUnsignedInt(_defaultCollation.info, stateObj); // stateObj.WriteByte(_defaultCollation.sortId); break; case SqlDbType.Variant: @@ -9127,7 +9128,7 @@ internal void WriteCekTable (_SqlMetaDataSet metadataCollection, TdsParserStateO /// internal void WriteTceUserTypeAndTypeInfo(SqlMetaDataPriv mdPriv, TdsParserStateObject stateObj) { // Write the UserType (4 byte value) - WriteInt(0x0, stateObj); // TODO: fix this- timestamp columns have 0x50 value here + WriteInt(0x0, stateObj); // Debug.Assert(SqlDbType.Xml != mdPriv.type); Debug.Assert(SqlDbType.Udt != mdPriv.type); @@ -9233,7 +9234,7 @@ internal void WriteBulkCopyMetaData(_SqlMetaDataSet metadataCollection, int coun // todo: // for xml WriteTokenLength results in a no-op // discuss this with blaine ... - // ([....]) xml datatype does not have token length in its metadata. So it should be a noop. + // (Microsoft) xml datatype does not have token length in its metadata. So it should be a noop. switch (md.type) { case SqlDbType.Decimal: diff --git a/System.Data/System/Data/SqlClient/TdsParserHelperClasses.cs b/System.Data/System/Data/SqlClient/TdsParserHelperClasses.cs index 01322f319..7d2408a90 100644 --- a/System.Data/System/Data/SqlClient/TdsParserHelperClasses.cs +++ b/System.Data/System/Data/SqlClient/TdsParserHelperClasses.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/TdsParserSafeHandles.cs b/System.Data/System/Data/SqlClient/TdsParserSafeHandles.cs index 73286f199..c1a4d9406 100644 --- a/System.Data/System/Data/SqlClient/TdsParserSafeHandles.cs +++ b/System.Data/System/Data/SqlClient/TdsParserSafeHandles.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { @@ -150,7 +150,8 @@ internal SNIHandle( int transparentNetworkResolutionStateNo = (int)transparentNetworkResolutionState; _status = SNINativeMethodWrapper.SNIOpenSyncEx(myInfo, serverName, ref base.handle, - spnBuffer, instanceName, flushCache, fSync, timeout, fParallel, transparentNetworkResolutionStateNo, totalTimeout); + spnBuffer, instanceName, flushCache, fSync, timeout, fParallel, transparentNetworkResolutionStateNo, totalTimeout, + ADP.IsAzureSqlServerEndpoint(serverName)); } } diff --git a/System.Data/System/Data/SqlClient/TdsParserSessionPool.cs b/System.Data/System/Data/SqlClient/TdsParserSessionPool.cs index d60e9ecdc..cb4d9b10d 100644 --- a/System.Data/System/Data/SqlClient/TdsParserSessionPool.cs +++ b/System.Data/System/Data/SqlClient/TdsParserSessionPool.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/TdsParserStateObject.cs b/System.Data/System/Data/SqlClient/TdsParserStateObject.cs index 75e2a4b30..7a878152f 100644 --- a/System.Data/System/Data/SqlClient/TdsParserStateObject.cs +++ b/System.Data/System/Data/SqlClient/TdsParserStateObject.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { @@ -646,7 +646,7 @@ public void CheckSetResetConnectionState(UInt32 error, CallbackType callbackType // Should only be called for MARS - that is the only time we need to take // the ResetConnection lock! - // SQL BU DT 333026 - it was raised in a security review by [....] questioning whether + // SQL BU DT 333026 - it was raised in a security review by Microsoft questioning whether // we need to actually process the resulting packet (sp_reset ack or error) to know if the // reset actually succeeded. There was a concern that if the reset failed and we proceeded // there might be a security issue present. We have been assured by the server that if @@ -2046,7 +2046,7 @@ private void OnTimeout(object state) { TaskCompletionSource source = _networkPacketTaskSource; if (_parser.Connection.IsInPool) { - // Dev11 Bug 390048 : Timing issue between OnTimeout and ReadAsyncCallback results in SqlClient's packet parsing going out of [....] + // Dev11 Bug 390048 : Timing issue between OnTimeout and ReadAsyncCallback results in SqlClient's packet parsing going out of sync // We should never timeout if the connection is currently in the pool: the safest thing to do here is to doom the connection to avoid corruption Debug.Assert(_parser.Connection.IsConnectionDoomed, "Timeout occurred while the connection is in the pool"); _parser.State = TdsParserState.Broken; @@ -2150,7 +2150,7 @@ internal void ReadSni(TaskCompletionSource completion) { } // -1 == Infinite - // 0 == Already timed out (NOTE: To simulate the same behavior as [....] we will only timeout on 0 if we receive an IO Pending from SNI) + // 0 == Already timed out (NOTE: To simulate the same behavior as sync we will only timeout on 0 if we receive an IO Pending from SNI) // >0 == Actual timeout remaining int msecsRemaining = GetTimeoutRemaining(); if (msecsRemaining > 0) { @@ -2206,7 +2206,7 @@ internal void ReadSni(TaskCompletionSource completion) { ChangeNetworkPacketTimeout(0, Timeout.Infinite); } // DO NOT HANDLE PENDING READ HERE - which is TdsEnums.SNI_SUCCESS_IO_PENDING state. - // That is handled by user who initiated async read, or by ReadNetworkPacket which is [....] over async. + // That is handled by user who initiated async read, or by ReadNetworkPacket which is sync over async. } finally { if (readPacket != IntPtr.Zero) { @@ -3278,7 +3278,7 @@ internal bool HasErrorOrWarning { internal void AddError(SqlError error) { Debug.Assert(error != null, "Trying to add a null error"); - // Switch to [....] once we see an error + // Switch to sync once we see an error _syncOverAsync = true; lock (_errorAndWarningsLock) { @@ -3312,7 +3312,7 @@ internal int ErrorCount { internal void AddWarning(SqlError error) { Debug.Assert(error != null, "Trying to add a null error"); - // Switch to [....] once we see a warning + // Switch to sync once we see a warning _syncOverAsync = true; lock (_errorAndWarningsLock){ diff --git a/System.Data/System/Data/SqlClient/TdsParserStaticMethods.cs b/System.Data/System/Data/SqlClient/TdsParserStaticMethods.cs index 2f58d45a8..288e4eee4 100644 --- a/System.Data/System/Data/SqlClient/TdsParserStaticMethods.cs +++ b/System.Data/System/Data/SqlClient/TdsParserStaticMethods.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/TdsRecordBufferSetter.cs b/System.Data/System/Data/SqlClient/TdsRecordBufferSetter.cs index 406e2b7b6..7b856bb85 100644 --- a/System.Data/System/Data/SqlClient/TdsRecordBufferSetter.cs +++ b/System.Data/System/Data/SqlClient/TdsRecordBufferSetter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/SqlClient/TdsValueSetter.cs b/System.Data/System/Data/SqlClient/TdsValueSetter.cs index aef315de5..63e1dd4ed 100644 --- a/System.Data/System/Data/SqlClient/TdsValueSetter.cs +++ b/System.Data/System/Data/SqlClient/TdsValueSetter.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/SqlClient/assemblycache.cs b/System.Data/System/Data/SqlClient/assemblycache.cs index b843d5529..5fd69f054 100644 --- a/System.Data/System/Data/SqlClient/assemblycache.cs +++ b/System.Data/System/Data/SqlClient/assemblycache.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/SqlClient/sqlinternaltransaction.cs b/System.Data/System/Data/SqlClient/sqlinternaltransaction.cs index c717a8efc..e09e10f5a 100644 --- a/System.Data/System/Data/SqlClient/sqlinternaltransaction.cs +++ b/System.Data/System/Data/SqlClient/sqlinternaltransaction.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data.SqlClient { diff --git a/System.Data/System/Data/SqlClient/sqlmetadatafactory.cs b/System.Data/System/Data/SqlClient/sqlmetadatafactory.cs index 24cfe1c3e..f17f069a0 100644 --- a/System.Data/System/Data/SqlClient/sqlmetadatafactory.cs +++ b/System.Data/System/Data/SqlClient/sqlmetadatafactory.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// [....] +// Microsoft // Mugunm // //------------------------------------------------------------------------------ diff --git a/System.Data/System/Data/StateChangeEvent.cs b/System.Data/System/Data/StateChangeEvent.cs index 54d94f051..8bc08c548 100644 --- a/System.Data/System/Data/StateChangeEvent.cs +++ b/System.Data/System/Data/StateChangeEvent.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/UniqueConstraint.cs b/System.Data/System/Data/UniqueConstraint.cs index c097f9319..29c3d5a24 100644 --- a/System.Data/System/Data/UniqueConstraint.cs +++ b/System.Data/System/Data/UniqueConstraint.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/XDRSchema.cs b/System.Data/System/Data/XDRSchema.cs index 4c8a96208..fee6ab5be 100644 --- a/System.Data/System/Data/XDRSchema.cs +++ b/System.Data/System/Data/XDRSchema.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/XMLDiffLoader.cs b/System.Data/System/Data/XMLDiffLoader.cs index fc3ecb9f9..c240bd1ed 100644 --- a/System.Data/System/Data/XMLDiffLoader.cs +++ b/System.Data/System/Data/XMLDiffLoader.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/XMLSchema.cs b/System.Data/System/Data/XMLSchema.cs index 476e3b77c..1a53dce5f 100644 --- a/System.Data/System/Data/XMLSchema.cs +++ b/System.Data/System/Data/XMLSchema.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -1343,7 +1343,7 @@ internal DataTable InstantiateTable(XmlSchemaElement node, XmlSchemaComplexType table = _ds.Tables.GetTable(XmlConvert.DecodeName(typeName), _TableUri); // TOD: Do not do this fix // if (table == null && node.RefName.IsEmpty && !IsTopLevelElement(node) && _TableUri != null && _TableUri.Length > 0) { -// _TableUri = null; // it means form="qualified", so child element inherits namespace. [....] +// _TableUri = null; // it means form="qualified", so child element inherits namespace. Microsoft // } if (!FromInference || (FromInference && table == null)) @@ -1571,7 +1571,7 @@ public static Type XsdtoClr(string xsdTypeName) { new NameType("byte" , typeof(SByte) ), /* XSD Apr */ new NameType("date" , typeof(DateTime)), /* XSD Apr */ new NameType("dateTime" , typeof(DateTime)), /* XSD Apr */ - new NameType("decimal" , typeof(decimal) ), /* XSD 2001 [....] */ + new NameType("decimal" , typeof(decimal) ), /* XSD 2001 Microsoft */ new NameType("double" , typeof(double) ), /* XSD Apr */ new NameType("duration" , typeof(TimeSpan)), /* XSD Apr */ new NameType("float" , typeof(Single) ), /* XSD Apr */ @@ -2023,7 +2023,7 @@ internal void HandleAttributeColumn(XmlSchemaAttribute attrib, DataTable table, } - // XDR [....] change + // XDR Microsoft change string strDefault = (attrib.Use == XmlSchemaUse.Required) ? GetMsdataAttribute(attr, Keywords.MSD_DEFAULTVALUE) : attr.DefaultValue; if ((attr.Use == XmlSchemaUse.Optional) && (strDefault == null )) strDefault = attr.FixedValue; diff --git a/System.Data/System/Data/XmlDataLoader.cs b/System.Data/System/Data/XmlDataLoader.cs index 566e2581f..24733de45 100644 --- a/System.Data/System/Data/XmlDataLoader.cs +++ b/System.Data/System/Data/XmlDataLoader.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -313,7 +313,7 @@ internal void LoadData( XmlDocument xdoc ) { XmlElement e = xdoc.DocumentElement; DataTable topTable = (DataTable) nodeToSchemaMap.GetSchemaForNode(e, FIgnoreNamespace(e)); if (topTable != null) { - topRow = topTable.CreateEmptyRow(); //enzol perf + topRow = topTable.CreateEmptyRow(); //Microsoft perf nodeToRowMap[ e ] = topRow; // get all field values. diff --git a/System.Data/System/Data/XmlKeywords.cs b/System.Data/System/Data/XmlKeywords.cs index 674f812d5..4b288fb5f 100644 --- a/System.Data/System/Data/XmlKeywords.cs +++ b/System.Data/System/Data/XmlKeywords.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { diff --git a/System.Data/System/Data/XmlToDatasetMap.cs b/System.Data/System/Data/XmlToDatasetMap.cs index a1aab9cd5..7f46e7e6d 100644 --- a/System.Data/System/Data/XmlToDatasetMap.cs +++ b/System.Data/System/Data/XmlToDatasetMap.cs @@ -2,9 +2,9 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] -// [....] +// Microsoft +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -128,10 +128,10 @@ static internal bool IsMappedColumn(DataColumn c) { // Used to infere schema private TableSchemaInfo AddTableSchema(DataTable table, XmlNameTable nameTable) { - // [....]: Because in our case reader already read the document all names that we can meet in the + // Microsoft: Because in our case reader already read the document all names that we can meet in the // document already has an entry in NameTable. // If in future we will build identity map before reading XML we can replace Get() to Add() - // [....]: GetIdentity is called from two places: BuildIdentityMap() and LoadRows() + // Microsoft: GetIdentity is called from two places: BuildIdentityMap() and LoadRows() // First case deals with decoded names; Second one with encoded names. // We decided encoded names in first case (instead of decoding them in second) // because it save us time in LoadRows(). We have, as usual, more data them schemas @@ -148,10 +148,10 @@ private TableSchemaInfo AddTableSchema(DataTable table, XmlNameTable nameTable) } private TableSchemaInfo AddTableSchema(XmlNameTable nameTable, DataTable table) { - // [....]:This is the opposite of the previous function: + // Microsoft:This is the opposite of the previous function: // we populate the nametable so that the hash comparison can happen as // object comparison instead of strings. - // [....]: GetIdentity is called from two places: BuildIdentityMap() and LoadRows() + // Microsoft: GetIdentity is called from two places: BuildIdentityMap() and LoadRows() // First case deals with decoded names; Second one with encoded names. // We decided encoded names in first case (instead of decoding them in second) // because it save us time in LoadRows(). We have, as usual, more data them schemas diff --git a/System.Data/System/Data/xmlsaver.cs b/System.Data/System/Data/xmlsaver.cs index 2129d4762..a25f9b1de 100644 --- a/System.Data/System/Data/xmlsaver.cs +++ b/System.Data/System/Data/xmlsaver.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Data { @@ -153,7 +153,7 @@ internal void AddXdoProperty(PropertyDescriptor pd, Object instance, XmlElement if (propInst is PropertyCollection) { return; } - // [....]: perf: Why not have this as a table? + // Microsoft: perf: Why not have this as a table? // there are several xdo properties that equal to some xml attributes, we should not explicitly ouput them. if ( 0 == String.Compare(pd.Name, "Namespace" , StringComparison.Ordinal) || @@ -1093,7 +1093,7 @@ internal void HandleColumnType(DataColumn col, XmlDocument dc, XmlElement root, schNode.AppendChild(type); }else { #if DEBUG - // [....]: TO DO: replace the constructor with IsEqual(XmlElement) + // Microsoft: TO DO: replace the constructor with IsEqual(XmlElement) // Debug.Assert(col.SimpleType.IsEqual(new SimpleType(elmSimpeType)), "simpleTypes with the same name have to be the same: "+name); #endif } @@ -1288,7 +1288,7 @@ internal XmlElement HandleColumn(DataColumn col, XmlDocument dc, XmlElement sche minOccurs = (col.AllowDBNull) ? 0 : 1; - // [....] 2001 change + // Microsoft 2001 change if (col.ColumnMapping == MappingType.Attribute && minOccurs != 0) root.SetAttribute(Keywords.USE, Keywords.REQUIRED); diff --git a/System.Data/System/NewXml/BaseTreeIterator.cs b/System.Data/System/NewXml/BaseTreeIterator.cs index c06feef60..fa67c094a 100644 --- a/System.Data/System/NewXml/BaseTreeIterator.cs +++ b/System.Data/System/NewXml/BaseTreeIterator.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Data/System/NewXml/DataDocumentXPathNavigator.cs b/System.Data/System/NewXml/DataDocumentXPathNavigator.cs index 45420d2d2..d2e5280a5 100644 --- a/System.Data/System/NewXml/DataDocumentXPathNavigator.cs +++ b/System.Data/System/NewXml/DataDocumentXPathNavigator.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ #pragma warning disable 618 // ignore obsolete warning about XmlDataDocument namespace System.Xml { diff --git a/System.Data/System/NewXml/DataPointer.cs b/System.Data/System/NewXml/DataPointer.cs index e8f4f51e6..2b85cf142 100644 --- a/System.Data/System/NewXml/DataPointer.cs +++ b/System.Data/System/NewXml/DataPointer.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ #pragma warning disable 618 // ignore obsolete warning about XmlDataDocument namespace System.Xml { diff --git a/System.Data/System/NewXml/DataSetMappper.cs b/System.Data/System/NewXml/DataSetMappper.cs index 390bf5780..de28bbd11 100644 --- a/System.Data/System/NewXml/DataSetMappper.cs +++ b/System.Data/System/NewXml/DataSetMappper.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ #pragma warning disable 618 // ignore obsolete warning about XmlDataDocument namespace System.Xml { diff --git a/System.Data/System/NewXml/RegionIterator.cs b/System.Data/System/NewXml/RegionIterator.cs index de0c6882c..8e4b622ac 100644 --- a/System.Data/System/NewXml/RegionIterator.cs +++ b/System.Data/System/NewXml/RegionIterator.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ #pragma warning disable 618 // ignore obsolete warning about XmlDataDocument namespace System.Xml { diff --git a/System.Data/System/NewXml/TreeIterator.cs b/System.Data/System/NewXml/TreeIterator.cs index 5e90984a7..34099a111 100644 --- a/System.Data/System/NewXml/TreeIterator.cs +++ b/System.Data/System/NewXml/TreeIterator.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ #pragma warning disable 618 // ignore obsolete warning about XmlDataDocument namespace System.Xml { diff --git a/System.Data/System/NewXml/XPathNodePointer.cs b/System.Data/System/NewXml/XPathNodePointer.cs index 1af6e149a..4d772315a 100644 --- a/System.Data/System/NewXml/XPathNodePointer.cs +++ b/System.Data/System/NewXml/XPathNodePointer.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ #pragma warning disable 618 // ignore obsolete warning about XmlDataDocument namespace System.Xml { @@ -169,7 +169,7 @@ internal XPathNodeType NodeType { } } - //[....]: From CodeReview: Perf: We should have another array similar w/ + //Microsoft: From CodeReview: Perf: We should have another array similar w/ // xmlNodeType_To_XpathNodeType_Map that will return String.Empty for everything but the element and // attribute case. internal string LocalName { diff --git a/System.Data/System/NewXml/XmlBoundElement.cs b/System.Data/System/NewXml/XmlBoundElement.cs index 476facfa9..33f8307d3 100644 --- a/System.Data/System/NewXml/XmlBoundElement.cs +++ b/System.Data/System/NewXml/XmlBoundElement.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ #pragma warning disable 618 // ignore obsolete warning about XmlDataDocument namespace System.Xml { diff --git a/System.Data/System/NewXml/XmlDataDocument.cs b/System.Data/System/NewXml/XmlDataDocument.cs index c2b65001e..b2dc5d618 100644 --- a/System.Data/System/NewXml/XmlDataDocument.cs +++ b/System.Data/System/NewXml/XmlDataDocument.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ namespace System.Xml { using System; @@ -606,9 +606,9 @@ private void ForceFoliation( XmlBoundElement node, ElementState newState ) { DataRow row = node.Row; // create new attrs & elements for row - // For detached rows: we are in [....] w/ temp values - // For non-detached rows: we are in [....] w/ the current values - // For deleted rows: we never [....] + // For detached rows: we are in sync w/ temp values + // For non-detached rows: we are in sync w/ the current values + // For deleted rows: we never sync DataRowVersion rowVersion = ( row.RowState == DataRowState.Detached ) ? DataRowVersion.Proposed : DataRowVersion.Current; foreach( DataColumn col in row.Table.Columns ) { if ( !IsNotMapped(col) ) { @@ -1273,7 +1273,7 @@ private void OnColumnValueChanged( DataRow row, DataColumn col, XmlBoundElement if ( col.ColumnMapping == MappingType.SimpleContent && Convert.IsDBNull( value ) && !rowElement.IsFoliated ) ForceFoliation( rowElement, ElementState.WeakFoliation); else { - // no need to [....] if not foliated + // no need to sync if not foliated if ( !IsFoliated( rowElement ) ) { #if DEBUG // If the new value is null, we should be already foliated if there is a DataPointer that points to the column @@ -1433,7 +1433,7 @@ private void OnColumnChanged( object sender, DataColumnChangeEventArgs args ) { XmlBoundElement be = row.Element; Debug.Assert( be != null ); if ( be.IsFoliated ) { - // Need to [....] changes from ROM to DOM + // Need to sync changes from ROM to DOM OnColumnValueChanged( row, col, be ); } } @@ -1535,7 +1535,7 @@ DataColumn FindAssociatedParentColumn( DataRelation relation, DataColumn childCo // Change the childElement position in the tree to conform to the parent nested relationship in ROM private void OnNestedParentChange(DataRow child, XmlBoundElement childElement, DataColumn childCol) { Debug.Assert( child.Element == childElement && childElement.Row == child ); - // This function is (and s/b) called as a result of ROM changes, therefore XML changes done here should not be [....]-ed to ROM + // This function is (and s/b) called as a result of ROM changes, therefore XML changes done here should not be sync-ed to ROM Debug.Assert( ignoreXmlEvents == true ); #if DEBUG // In order to check that this move does not change the connected/disconnected state of the node @@ -1697,7 +1697,7 @@ private void OnNodeRemoved( object sender, XmlNodeChangedEventArgs args ) { OnNodeRemovedFromTree( node, oldParent ); } else { - // Removing from disconnected tree to disconnected tree: just [....] the old region + // Removing from disconnected tree to disconnected tree: just sync the old region OnNodeRemovedFromFragment( node, oldParent ); } } @@ -1742,7 +1742,7 @@ private void OnNodeRemovedFromFragment( XmlNode node, XmlNode oldParent ) { XmlBoundElement oldRowElem; if ( mapper.GetRegion( oldParent, out oldRowElem ) ) { - // [....] the old region if it is not deleted + // Sync the old region if it is not deleted DataRow row = oldRowElem.Row; // Since the old old region was disconnected, then the row can be only Deleted or Detached Debug.Assert( ! IsRowLive( row ) ); @@ -2171,7 +2171,7 @@ internal static void SetRowValueFromXmlText( DataRow row, DataColumn col, string private void SynchronizeRowFromRowElement( XmlBoundElement rowElement ) { SynchronizeRowFromRowElement( rowElement, null ); } - // [....] row fields w/ values from rowElem region. + // Sync row fields w/ values from rowElem region. // If rowElemList is != null, all subregions of rowElem are appended to it. private void SynchronizeRowFromRowElement( XmlBoundElement rowElement, ArrayList rowElemList ) { DataRow row = rowElement.Row; @@ -2402,7 +2402,7 @@ private void OnNodeInsertedInTree( XmlNode node ) { } } else { - // We only need to [....] the embedded sub-regions + // We only need to sync the embedded sub-regions TreeIterator iter = new TreeIterator( node ); for (bool fMore = iter.NextRowElement(); fMore; fMore = iter.NextRightRowElement() ) rowElemList.Add( iter.CurrentNode ); @@ -2588,7 +2588,7 @@ private void OnNonRowElementInsertedInFragment( XmlNode node, XmlBoundElement ro if ( row.RowState == DataRowState.Detached ) SynchronizeRowFromRowElementEx( rowElement, rowElemList ); - // Nothing to do if the row is deleted (there is no [....]-ing from XML to ROM for deleted rows) + // Nothing to do if the row is deleted (there is no sync-ing from XML to ROM for deleted rows) } private void SetNestedParentRegion( XmlBoundElement childRowElem ) { diff --git a/System.Data/System/NewXml/XmlDataImplementation.cs b/System.Data/System/NewXml/XmlDataImplementation.cs index ed253a35a..c3e983958 100644 --- a/System.Data/System/NewXml/XmlDataImplementation.cs +++ b/System.Data/System/NewXml/XmlDataImplementation.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft //------------------------------------------------------------------------------ #pragma warning disable 618 // ignore obsolete warning about XmlDataDocument namespace System.Xml { diff --git a/System.Data/bid/inc/cs/bidPrivateBase.cs b/System.Data/bid/inc/cs/bidPrivateBase.cs index 7687bafb6..95629d427 100644 --- a/System.Data/bid/inc/cs/bidPrivateBase.cs +++ b/System.Data/bid/inc/cs/bidPrivateBase.cs @@ -2,8 +2,8 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// [....] -// [....] +// Microsoft +// Microsoft // Last Modified: 6-November-2008 //----------------------------------------------------------------------------------------------- diff --git a/System.Data/system.data.txt b/System.Data/system.data.txt index ef72da356..c4d1f6099 100644 --- a/System.Data/system.data.txt +++ b/System.Data/system.data.txt @@ -6,10 +6,13 @@ ; NOTE: do not use \", use ' instead ; NOTE: Use # or ; for comments +; markash +; laled ; These are the managed resources for System.Data.dll. See ; ResourceManager documentation and the ResGen tool. +;; TODO: Remove Common Code stuff if we ever get Friend Assemblies to work ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; COMMON CODE STUFF ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -52,6 +55,12 @@ ADP_NonPooledOpenTimeout=Timeout attempting to open the connection. The time pe ADP_InvalidMixedUsageOfSecureAndClearCredential=Cannot use Credential with UserID, UID, Password, or PWD connection string keywords. ADP_InvalidMixedUsageOfSecureCredentialAndIntegratedSecurity=Cannot use Credential with Integrated Security connection string keyword. ADP_InvalidMixedUsageOfSecureCredentialAndContextConnection=Cannot use Credential with Context Connection keyword. +ADP_InvalidMixedUsageOfAccessTokenAndUserIDPassword=Cannot set the AccessToken property if 'UserID', 'UID', 'Password', or 'PWD' has been specified in connection string. +ADP_InvalidMixedUsageOfAccessTokenAndIntegratedSecurity=Cannot set the AccessToken property if the 'Integrated Security' connection string keyword has been set to 'true' or 'SSPI'. +ADP_InvalidMixedUsageOfAccessTokenAndContextConnection=Cannot set the AccessToken property with the 'Context Connection' keyword. +ADP_InvalidMixedUsageOfAccessTokenAndCredential=Cannot set the AccessToken property if the Credential property is already set. +ADP_InvalidMixedUsageOfCredentialAndAccessToken=Cannot set the Credential property if the AccessToken property is already set. +ADP_InvalidMixedUsageOfAccessTokenAndAuthentication=Cannot set the AccessToken property if 'Authentication' has been specified in the connection string. ADP_MustBeReadOnly={0} must be marked as read only. DataCategory_Data=Data DataCategory_StateChange=StateChange @@ -1082,6 +1091,11 @@ SQL_InvalidPacketSizeValue=Invalid 'Packet Size'. The value must be an integer SQL_NullEmptyTransactionName=Invalid transaction or invalid name for a point at which to save within the transaction. SQL_SnapshotNotSupported=The {0} enumeration value, {1}, is not supported by SQL Server 7.0 or SQL Server 2000. SQL_UserInstanceFailoverNotCompatible=User Instance and Failover are not compatible options. Please choose only one of the two in the connection string. +SQL_AuthenticationAndIntegratedSecurity=Cannot use 'Authentication' with 'Integrated Security'. +SQL_IntegratedWithUserIDAndPassword=Cannot use 'Authentication=Active Directory Integrated' with 'User ID', 'UID', 'Password' or 'PWD' connection string keywords. +SQL_SettingIntegratedWithCredential=Cannot use 'Authentication=Active Directory Integrated', if the Credential property has been set. +SQL_SettingCredentialWithIntegrated=Cannot set the Credential property if 'Authentication=Active Directory Integrated' has been specified in the connection string. + ; DataProviderException SQL_EncryptionNotSupportedByClient=The instance of SQL Server you attempted to connect to requires encryption but this machine does not support it. SQL_EncryptionNotSupportedByServer=The instance of SQL Server you attempted to connect to does not support encryption. @@ -1091,6 +1105,7 @@ SQL_CannotModifyPropertyAsyncOperationInProgress={0} cannot be changed while asy SQL_AsyncConnectionRequired=This command requires an asynchronous connection. Set \"Asynchronous Processing=true\" in the connection string. SQL_FatalTimeout=Timeout expired. The connection has been broken as a result. SQL_InstanceFailure=Instance failure. +SQL_CredentialsNotProvided=Either Credential or both 'User ID' and 'Password' (or 'UID' and 'PWD') connection string keywords must be specified, if 'Authentication={0}'. SQL_ChangePasswordArgumentMissing=The '{0}' argument must not be null or empty. SQL_ChangePasswordConflictsWithSSPI=ChangePassword can only be used with SQL authentication, not with integrated security. @@ -1098,6 +1113,8 @@ SQL_ChangePasswordUseOfUnallowedKey=The keyword '{0}' must not be specified in t SQL_UnknownSysTxIsolationLevel=Unrecognized System.Transactions.IsolationLevel enumeration value: {0}. SQL_InvalidPartnerConfiguration=Server {0}, database {1} is not configured for database mirroring. SQL_MarsUnsupportedOnConnection=The connection does not support MultipleActiveResultSets. +SQL_ADALFailure=Failed to authenticate the user {0} in Active Directory (Authentication={1}). +SQL_ADALInnerException=Error code 0x{0}; state {1} ;NotSupportedException SQL_ChangePasswordRequiresYukon=ChangePassword requires SQL Server 9.0 or later. @@ -1127,10 +1144,19 @@ SQL_ParameterTypeNameRequired=The {0} type parameter '{1}' must have a valid typ ;;; SQLServer.TDSParser ; InvalidOperationException +SQL_ADALInitializeError=Unable to load adalsql.dll (Authentication={0}). Error code: 0x{1}. For more information, see http://go.microsoft.com/fwlink/?LinkID=513072 SQL_InvalidInternalPacketSize=Invalid internal packet size: SQL_InvalidTDSVersion=The SQL Server instance returned an invalid or unsupported protocol version during login negotiation. SQL_InvalidTDSPacketSize=Invalid Packet Size. SQL_ParsingError=Internal connection fatal error. +SQL_ParsingErrorWithState=Internal connection fatal error. Error state: {0} +SQL_ParsingErrorValue=Internal connection fatal error. Error state: {0}, Value: {1} +SQL_ParsingErrorOffset=Internal connection fatal error. Error state: {0}, Offset: {1} +SQL_ParsingErrorFeatureId=Internal connection fatal error. Error state: {0}, Feature Id: {1} +SQL_ParsingErrorToken=Internal connection fatal error. Error state: {0}, Token : {1} +SQL_ParsingErrorLength=Internal connection fatal error. Error state: {0}, Length: {1} +SQL_ParsingErrorStatus=Internal connection fatal error. Error state: {0}, Status: {1} +SQL_ParsingErrorAuthLibraryType=Internal connection fatal error. Error state: {0}, Authentication Library Type: {1} SQL_ConnectionLockedForBcpEvent=The connection cannot be used because there is an ongoing operation that must be finished. SQL_SNIPacketAllocationFailure=Memory allocation for internal connection failed. ; OverflowException @@ -1214,6 +1240,10 @@ SQL_ConnectionDoomed=The requested operation cannot be completed because the con SQL_OpenResultCountExceeded=Open result count exceeded. ;;; +;;; Global Transactions +GT_Disabled=Global Transactions are not enabled for this Azure SQL Database. Please contact Azure SQL DB support for assistance. +GT_UnsupportedSysTxVersion=The System.Transactions.dll loaded does not support Global Transactions. Please upgrade to .NET 4.6.1 or later. + ;;; Merged Provider SQL_BatchedUpdatesNotAvailableOnContextConnection=Batching updates is not supported on the context connection. SQL_ContextAllowsLimitedKeywords=The only additional connection string keyword that may be used when requesting the context connection is the Type System Version keyword. @@ -1228,7 +1258,7 @@ SQL_UnexpectedSmiEvent=Unexpected server event: {0}. SQL_UserInstanceNotAvailableInProc=User instances are not allowed when running in the Sql Server process. SQL_ArgumentLengthMismatch=The length of '{0}' must match the length of '{1}'. SQL_InvalidSqlDbTypeWithOneAllowedType=The SqlDbType '{0}' is invalid for {1}. Only {2} is supported. -SQL_PipeErrorRequiresSendEnd=An error occurred with a prior row sent to the SqlPipe. SendResultsEnd must be called before anything else con be sent. +SQL_PipeErrorRequiresSendEnd=An error occurred with a prior row sent to the SqlPipe. SendResultsEnd must be called before anything else can be sent. SQL_TooManyValues=Too many values. SQL_StreamWriteNotSupported=The Stream does not support writing. SQL_StreamReadNotSupported=The Stream does not support reading. @@ -1373,6 +1403,7 @@ DbConnectionString_MaxPoolSize=The maximum number of connections allowed in the DbConnectionString_MinPoolSize=The minimum number of connections allowed in the pool. DbConnectionString_MultipleActiveResultSets=When true, multiple result sets can be returned and read from one connection. DbConnectionString_MultiSubnetFailover=If your application is connecting to a high-availability, disaster recovery (AlwaysOn) availability group (AG) on different subnets, MultiSubnetFailover=Yes configures SqlConnection to provide faster detection of and connection to the (currently) active server. +DbConnectionString_TransparentNetworkIPResolution=If your application connects to different networks, TransparentNetworkIPResolution=Yes configures SqlConnection to provide transparent connection resolution to the currently active server, independently of the network IP topology. DbConnectionString_NetworkLibrary=The network library used to establish a connection to an instance of SQL Server. DbConnectionString_PacketSize=Size in bytes of the network packets used to communicate with an instance of SQL Server. DbConnectionString_Password=Indicates the password to be used when connecting to the data source. @@ -1389,6 +1420,7 @@ DbConnectionString_ApplicationIntent=Declares the application workload type when ;DbConnectionString_Unicode=If true, the client supports Unicode functionality available in Oracle, or if false, is non-Unicode aware. DbConnectionString_ConnectRetryCount=Number of attempts to restore connection. DbConnectionString_ConnectRetryInterval=Delay between attempts to restore connection. +DbConnectionString_Authentication=Specifies the method of authenticating with SQL Server. ;;; ;;; DbConnection Property Descriptions ; COMMON CODE DbConnection_State=The ConnectionState indicating whether the connection is open or closed. @@ -1407,6 +1439,7 @@ OleDbConnection_DataSource=Current data source, 'Data Source=X' in the connectio OleDbConnection_Provider=Current OLE DB provider ProgID, 'Provider=X' in the connection string. OleDbConnection_ServerVersion=Version of the product accessed by the OLE DB Provider. +SqlConnection_AccessToken=Access token to use for authentication. SqlConnection_Asynchronous=State of connection, synchronous or asynchronous. 'Asynchronous Processing=x' in the connection string. SqlConnection_Replication=Information used to connect for replication. SqlConnection_ConnectionString=Information used to connect to a DataSource, such as 'Data Source=x;Initial Catalog=x;Integrated Security=SSPI'. @@ -1417,6 +1450,7 @@ SqlConnection_PacketSize=Network packet size, 'Packet Size=x' in the connection SqlConnection_ServerVersion=Version of the SQL Server accessed by the SqlConnection. SqlConnection_WorkstationId=Workstation Id, 'Workstation ID=x' in the connection string. SqlConnection_StatisticsEnabled=Collect statistics for this connection. +SqlConnection_CustomColumnEncryptionKeyStoreProviders=Custom column encryption key store providers. SqlConnection_ClientConnectionId=A guid to represent the physical connection. SqlConnection_Credential=User Id and secure password to use for authentication. ;;; @@ -1702,6 +1736,123 @@ LocalDB_MethodNotFound=Invalid SQLUserInstance.dll found at the location specifi LocalDB_UnobtainableMessage=Cannot obtain Local Database Runtime error message LocalDB_InvalidVersion=Local Database Runtime: Invalid instance version specification found in the configuration file. +;;; TCE +; CertificateStoreProvider error messages +TCE_InvalidKeyEncryptionAlgorithm=Invalid key encryption algorithm specified: '{0}'. Expected value: '{1}'. +TCE_InvalidKeyEncryptionAlgorithmSysErr=Internal error. Invalid key encryption algorithm specified: '{0}'. Expected value: '{1}'. +TCE_NullKeyEncryptionAlgorithm=Key encryption algorithm cannot be null. +TCE_NullKeyEncryptionAlgorithmSysErr=Internal error. Key encryption algorithm cannot be null. +TCE_EmptyColumnEncryptionKey=Empty column encryption key specified. +TCE_NullColumnEncryptionKey=Column encryption key cannot be null. +TCE_EmptyEncryptedColumnEncryptionKey=Internal error. Empty encrypted column encryption key specified. +TCE_NullEncryptedColumnEncryptionKey=Internal error. Encrypted column encryption key cannot be null. +TCE_LargeCertificatePathLength=Specified certificate path has {0} bytes, which exceeds maximum length of {1} bytes. +TCE_LargeCertificatePathLengthSysErr=Internal error. Specified certificate path has {0} bytes, which exceeds maximum length of {1} bytes. +TCE_NullCertificatePath=Certificate path cannot be null. Use the following format: {2}{2}, where is either '{0}' or '{1}'. +TCE_NullCertificatePathSysErr=Internal error. Certificate path cannot be null. Use the following format: {2}{2}, where is either '{0}' or '{1}'. +TCE_NullCspPath=Column master key path cannot be null. Use the following format for a key stored in a Microsoft cryptographic service provider (CSP): {0}. +TCE_NullCspPathSysErr=Internal error. Column master key path cannot be null. Use the following format for a key stored in a Microsoft cryptographic service provider (CSP): {0}. +TCE_NullCngPath=Column master key path cannot be null. Use the following format for a key stored in a Microsoft Cryptography API: Next Generation (CNG) provider: {0}. +TCE_NullCngPathSysErr=Internal error. Column master key path cannot be null. Use the following format for a key stored in a Microsoft Cryptography API: Next Generation (CNG) provider: {0}. +TCE_InvalidCertificatePath=Invalid certificate path: '{0}'. Use the following format: {3}{3}, where is either '{1}' or '{2}'. +TCE_InvalidCertificatePathSysErr=Internal error. Invalid certificate path: '{0}'. Use the following format: {3}{3}, where is either '{1}' or '{2}'. +TCE_InvalidCspPath=Invalid column master key path: '{0}'. Use the following format for a key stored in a Microsoft cryptographic service provider (CSP): {1}. +TCE_InvalidCspPathSysErr=Internal error. Invalid column master key path: '{0}'. Use the following format for a key stored in a Microsoft cryptographic service provider (CSP): {1}. +TCE_InvalidCngPath=Invalid column master key path: '{0}'. Use the following format for a key stored in a Microsoft Cryptography API: Next Generation (CNG) provider: {1}. +TCE_InvalidCngPathSysErr=Internal error. Invalid column master key path: '{0}'. Use the following format for a key stored in a Microsoft Cryptography API: Next Generation (CNG) provider: {1}. +TCE_InvalidCertificateLocation=Invalid certificate location '{0}' in certificate path '{1}'. Use the following format: {4}{4}, where is either '{2}' or '{3}'. +TCE_InvalidCertificateLocationSysErr=Internal error. Invalid certificate location '{0}' in certificate path '{1}'. Use the following format: {4}{4}, where is either '{2}' or '{3}'. +TCE_InvalidCertificateStore=Invalid certificate store '{0}' specified in certificate path '{1}'. Expected value: '{2}'. +TCE_InvalidCertificateStoreSysErr=Internal error. Invalid certificate store '{0}' specified in certificate path '{1}'. Expected value: '{2}'. +TCE_EmptyCertificateThumbprint=Empty certificate thumbprint specified in certificate path '{0}'. +TCE_EmptyCertificateThumbprintSysErr=Internal error. Empty certificate thumbprint specified in certificate path '{0}'. +TCE_EmptyCspName=Empty Microsoft cryptographic service provider (CSP) name specified in column master key path: '{0}'. Use the following format for a key stored in a Microsoft cryptographic service provider (CSP): {1}. +TCE_EmptyCspNameSysErr=Internal error. Empty Microsoft cryptographic service provider (CSP) name specified in column master key path: '{0}'. Use the following format for a key stored in a Microsoft cryptographic service provider (CSP): {1}. +TCE_EmptyCngName=Empty Microsoft Cryptography API: Next Generation (CNG) provider name specified in column master key path: '{0}'. Use the following format for a key stored in a Microsoft Cryptography API: Next Generation (CNG) provider: {1}. +TCE_EmptyCngNameSysErr=Internal error. Empty Microsoft Cryptography API: Next Generation (CNG) provider name specified in column master key path: '{0}'. Use the following format for a key stored in a Microsoft Cryptography API: Next Generation (CNG) provider: {1}. +TCE_EmptyCspKeyId=Empty key identifier specified in column master key path: '{0}'. Use the following format for a key stored in a Microsoft cryptographic service provider (CSP): {1}. +TCE_EmptyCspKeyIdSysErr=Internal error. Empty key identifier specified in column master key path: '{0}'. Use the following format for a key stored in a Microsoft cryptographic service provider (CSP): {1}. +TCE_EmptyCngKeyId=Empty key identifier specified in column master key path: '{0}'. Use the following format for a key stored in a Microsoft Cryptography API: Next Generation (CNG) provider: {1}. +TCE_EmptyCngKeyIdSysErr=Internal error. Empty key identifier specified in column master key path: '{0}'. Use the following format for a key stored in a Microsoft Cryptography API: Next Generation (CNG) provider: {1}. +TCE_InvalidCspName=Invalid Microsoft cryptographic service provider (CSP) name: '{0}'. Verify that the CSP provider name in column master key path: '{1}' is valid and installed on the machine. +TCE_InvalidCspNameSysErr=Internal error. Invalid Microsoft cryptographic service provider (CSP) name: '{0}'. Verify that the CSP provider name in column master key path: '{1}' is valid and installed on the machine. +TCE_InvalidCspKeyId=Invalid key identifier: '{0}'. Verify that the key identifier in column master key path: '{1}' is valid and exists in the CSP. +TCE_InvalidCspKeyIdSysErr=Internal error. Invalid key identifier: '{0}'. Verify that the key identifier in column master key path: '{1}' is valid and exists in the CSP. +TCE_InvalidCngKey=An error occurred while opening the Microsoft Cryptography API: Next Generation (CNG) key: '{0}'. Verify that the CNG provider name '{1}' is valid, installed on the machine, and the key '{2}' exists. +TCE_InvalidCngKeySysErr=Internal error. An error occurred while opening the Microsoft Cryptography API: Next Generation (CNG) key: '{0}'. Verify that the CNG provider name '{1}' is valid, installed on the machine, and the key '{2}' exists. +TCE_CertificateNotFound=Certificate with thumbprint '{0}' not found in certificate store '{1}' in certificate location '{2}'. +TCE_CertificateNotFoundSysErr=Certificate with thumbprint '{0}' not found in certificate store '{1}' in certificate location '{2}'. Verify the certificate path in the column master key definition in the database is correct, and the certificate has been imported correctly into the certificate location/store. +TCE_InvalidAlgorithmVersionInEncryptedCEK=Specified encrypted column encryption key contains an invalid encryption algorithm version '{0}'. Expected version is '{1}'. +TCE_InvalidCiphertextLengthInEncryptedCEK=The specified encrypted column encryption key's ciphertext length: {0} does not match the ciphertext length: {1} when using column master key (certificate) in '{2}'. The encrypted column encryption key may be corrupt, or the specified certificate path may be incorrect. +TCE_InvalidCiphertextLengthInEncryptedCEKCsp=The specified encrypted column encryption key's ciphertext length: {0} does not match the ciphertext length: {1} when using column master key (asymmetric key) in '{2}'. The encrypted column encryption key may be corrupt, or the specified Microsoft Cryptographic Service provider (CSP) path may be incorrect. +TCE_InvalidCiphertextLengthInEncryptedCEKCng=The specified encrypted column encryption key's ciphertext length: {0} does not match the ciphertext length: {1} when using column master key (asymmetric key) in '{2}'. The encrypted column encryption key may be corrupt, or the specified Microsoft Cryptography API: Next Generation (CNG) provider path may be incorrect. +TCE_InvalidSignatureInEncryptedCEK=The specified encrypted column encryption key's signature length: {0} does not match the signature length: {1} when using column master key (certificate) in '{2}'. The encrypted column encryption key may be corrupt, or the specified certificate path may be incorrect. +TCE_InvalidSignatureInEncryptedCEKCsp=The specified encrypted column encryption key's signature length: {0} does not match the signature length: {1} when using column master key (asymmetric key) in '{2}'. The encrypted column encryption key may be corrupt, or the specified Microsoft cryptographic service provider (CSP) path may be incorrect. +TCE_InvalidSignatureInEncryptedCEKCng=The specified encrypted column encryption key's signature length: {0} does not match the signature length: {1} when using column master key (asymmetric key) in '{2}'. The encrypted column encryption key may be corrupt, or the specified Microsoft Cryptography API: Next Generation (CNG) provider path may be incorrect. +TCE_InvalidCertificateSignature=The specified encrypted column encryption key signature does not match the signature computed with the column master key (certificate) in '{0}'. The encrypted column encryption key may be corrupt, or the specified path may be incorrect. +TCE_InvalidSignature=The specified encrypted column encryption key signature does not match the signature computed with the column master key (asymmetric key) in '{0}'. The encrypted column encryption key may be corrupt, or the specified path may be incorrect. +TCE_CertificateWithNoPrivateKey=Certificate specified in key path '{0}' does not have a private key to encrypt a column encryption key. Verify the certificate is imported correctly. +TCE_CertificateWithNoPrivateKeySysErr=Certificate specified in key path '{0}' does not have a private key to decrypt a column encryption key. Verify the certificate is imported correctly. + +; Cryptographic algorithms error messages +TCE_NullColumnEncryptionKeySysErr=Internal error. Column encryption key cannot be null. +TCE_InvalidKeySize=The column encryption key has been successfully decrypted but it's length: {1} does not match the length: {2} for algorithm '{0}'. Verify the encrypted value of the column encryption key in the database. +TCE_InvalidEncryptionType=Encryption type '{1}' specified for the column in the database is either invalid or corrupted. Valid encryption types for algorithm '{0}' are: {2}. +TCE_NullPlainText=Internal error. Plaintext value cannot be null. +TCE_VeryLargeCiphertext=Cannot encrypt. Encrypting resulted in {0} bytes of ciphertext which exceeds the maximum allowed limit of {1} bytes. The specified plaintext value is likely too large (plaintext size is: {2} bytes). +TCE_NullCipherText=Internal error. Ciphertext value cannot be null. +TCE_InvalidCipherTextSize=Specified ciphertext has an invalid size of {0} bytes, which is below the minimum {1} bytes required for decryption. +TCE_InvalidAlgorithmVersion=The specified ciphertext's encryption algorithm version '{0}' does not match the expected encryption algorithm version '{1}'. +TCE_InvalidAuthenticationTag=Specified ciphertext has an invalid authentication tag. +TCE_NullColumnEncryptionAlgorithm=Internal error. Encryption algorithm cannot be null. Valid algorithms are: {0}. + +; Errors from sp_describe_parameter_encryption +TCE_UnexpectedDescribeParamFormat=Internal error. The format of the resultset returned by {0} is invalid. One of the resultsets is missing. +TCE_InvalidEncryptionKeyOrdinal=Internal error. The referenced column encryption key ordinal '{1}' is missing in the encryption metadata returned by {0}. Max ordinal is '{2}'. +TCE_ParamEncryptionMetaDataMissing=Internal error. Metadata for parameter '{1}' in statement or procedure '{2}' is missing in resultset returned by {0}. +TCE_ProcEncryptionMetaDataMissing=Internal error. Metadata for parameters for command '{1}' in a batch is missing in the resultset returned by {0}. + +; Generic toplevel cryptofailures +TCE_ParamEncryptionFailed=Failed to encrypt parameter '{0}'. +TCE_ColumnDecryptionFailed=Failed to decrypt column '{0}'. +TCE_ParamDecryptionFailed=Failed to decrypt parameter '{0}'. + +; Query processing error messages +TCE_UnknownColumnEncryptionAlgorithm=Encryption algorithm '{0}' for the column in the database is either invalid or corrupted. Valid algorithms are: {1}. +TCE_UnknownColumnEncryptionAlgorithmId=Encryption algorithm id '{0}' for the column in the database is either invalid or corrupted. Valid encryption algorithm ids are: {1}. +TCE_UnsupportedNormalizationVersion=Normalization version '{0}' received from {2} is not supported. Valid normalization versions are: {1}. +TCE_UnrecognizedKeyStoreProviderName=Failed to decrypt a column encryption key. Invalid key store provider name: '{0}'. A key store provider name must denote either a system key store provider or a registered custom key store provider. Valid system key store provider names are: {1}. Valid (currently registered) custom key store provider names are: {2}. Please verify key store provider information in column master key definitions in the database, and verify all custom key store providers used in your application are registered properly. +TCE_KeyDecryptionFailedCertStore=Failed to decrypt a column encryption key using key store provider: '{0}'. The last 10 bytes of the encrypted column encryption key are: '{1}'. +TCE_UntrustedKeyPath=Column master key path '{0}' received from server '{1}' is not a trusted key path. +TCE_KeyDecryptionFailed=Failed to decrypt a column encryption key using key store provider: '{0}'. Verify the properties of the column encryption key and its column master key in your database. The last 10 bytes of the encrypted column encryption key are: '{1}'. +TCE_UnsupportedDatatype=Encryption and decryption of data type '{0}' is not supported. +TCE_DecryptionFailed=Decryption failed. The last 10 bytes of the encrypted column encryption key are: '{0}'. The first 10 bytes of ciphertext are: '{1}'. + +; TCE Generic errors +TCE_ParamInvalidForceColumnEncryptionSetting=Cannot set {0} for {3} '{1}' because encryption is not enabled for the statement or procedure '{2}'. +TCE_ParamUnExpectedEncryptionMetadata=Cannot execute statement or procedure '{1}' because {2} was set for {3} '{0}' and the database expects this parameter to be sent as plaintext. This may be due to a configuration error. + +; TCE specific SQL connection related error messages +TCE_NotSupportedByServer={0} instance in use does not support column encryption. + +; TCE specific SQL command/adapter related error messages +TCE_BatchedUpdateColumnEncryptionSettingMismatch={0} should be identical on all commands ({1}, {2}, {3}, {4}) when doing batch updates. +TCE_StreamNotSupportOnEncryptedColumn=Retrieving encrypted column '{0}' as a {1} is not supported. +TCE_SequentialAccessNotSupportedOnEncryptedColumn=Retrieving encrypted column '{0}' with {1} is not supported. + +; Provider Extensibility error messages +TCE_CanOnlyCallOnce=Key store providers cannot be set more than once. +TCE_NullCustomKeyStoreProviderDictionary=Column encryption key store provider dictionary cannot be null. Expecting a non-null value. +TCE_InvalidCustomKeyStoreProviderName=Invalid key store provider name '{0}'. '{1}' prefix is reserved for system key store providers. +TCE_NullProviderValue=Null reference specified for key store provider '{0}'. Expecting a non-null value. +TCE_EmptyProviderName=Invalid key store provider name specified. Key store provider names cannot be null or empty. + +; TCE Generic Property descriptions +TCE_SqlCommand_ColumnEncryptionSetting=Column encryption setting for the command. Overrides the connection level default. +TCE_DbConnectionString_ColumnEncryptionSetting=Default column encryption setting for all the commands on the connection. +TCE_SqlParameter_ForceColumnEncryption=Forces parameter to be encrypted before sending sensitive data to server. +TCE_SqlConnection_TrustedColumnMasterKeyPaths=Dictionary object containing SQL Server names and their trusted column master key paths. + ; Read-only routing error message SQLROR_RecursiveRoutingNotSupported=Two or more redirections have occurred. Only one redirection per login is allowed. SQLROR_FailoverNotSupported=Connecting to a mirrored SQL Server instance using the ApplicationIntent ReadOnly connection option is not supported. @@ -1719,3 +1870,18 @@ SQLCR_AllAttemptsFailed=The connection is broken and recovery is not possible. SQLCR_UnrecoverableServer=The connection is broken and recovery is not possible. The connection is marked by the server as unrecoverable. No attempt was made to restore the connection. SQLCR_UnrecoverableClient=The connection is broken and recovery is not possible. The connection is marked by the client driver as unrecoverable. No attempt was made to restore the connection. SQLCR_NoCRAckAtReconnection=The server did not acknowledge a recovery attempt, connection recovery is not possible. + +DbConnectionString_PoolBlockingPeriod=Defines the blocking period behavior for a connection pool. + +; Azure endpoints +AZURESQL_GenericEndpoint=.database.windows.net +AZURESQL_GermanEndpoint=.database.cloudapi.de +AZURESQL_UsGovEndpoint=.database.usgovcloudapi.net +AZURESQL_ChinaEndpoint=.database.chinacloudapi.cn + +; TCE Generic Property descriptions .Net 4.6.2 +TCE_SqlConnection_ColumnEncryptionQueryMetadataCacheEnabled=Defines whether query metadata caching is enabled. +TCE_SqlConnection_ColumnEncryptionKeyCacheTtl=Defines the time-to-live of entries in the column encryption key cache. + +;;; SQLServer.TDSParser .Net 4.6.2 +SQL_Timeout_Execution=Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding. \ No newline at end of file diff --git a/System.IdentityModel.Selectors/infocard/common/managed/InfoCardCryptoHelper.cs b/System.IdentityModel.Selectors/infocard/common/managed/InfoCardCryptoHelper.cs index 1e7281d0c..1a53c754f 100644 --- a/System.IdentityModel.Selectors/infocard/common/managed/InfoCardCryptoHelper.cs +++ b/System.IdentityModel.Selectors/infocard/common/managed/InfoCardCryptoHelper.cs @@ -8,7 +8,7 @@ namespace Microsoft.InfoCards using System.Security.Cryptography; using System.Security.Cryptography.Xml; - // copied from IdentityModel\CryptoHelper.cs and they need to be kept in [....]. After V1, we need to rethink how we can have + // copied from IdentityModel\CryptoHelper.cs and they need to be kept in sync. After V1, we need to rethink how we can have // a single place to ask this question. Perhaps even add it as an extensibility internal static class InfoCardCryptoHelper diff --git a/System.IdentityModel/System/AppContextDefaultValues.cs b/System.IdentityModel/System/AppContextDefaultValues.cs index e879cb1e2..6f66cdbc7 100644 --- a/System.IdentityModel/System/AppContextDefaultValues.cs +++ b/System.IdentityModel/System/AppContextDefaultValues.cs @@ -31,6 +31,11 @@ static partial void PopulateDefaultValuesPartial(string platformIdentifier, stri LocalAppContextSwitches.SetDefaultsLessOrEqual_46(); } + if (version <= 40602) + { + LocalAppContextSwitches.SetDefaultsLessOrEqual_462(); + } + break; } } diff --git a/System.IdentityModel/System/IdentityModel/Claims/Claim.cs b/System.IdentityModel/System/IdentityModel/Claims/Claim.cs index bc90eb0f2..f8a2a4bdf 100644 --- a/System.IdentityModel/System/IdentityModel/Claims/Claim.cs +++ b/System.IdentityModel/System/IdentityModel/Claims/Claim.cs @@ -17,7 +17,7 @@ namespace System.IdentityModel.Claims // --------------- ---------------- ------------------ // "File" "boot.ini" "Read" // "HairColor" "Brown" "PossessProperty" - // "UserName" "[....]" "PossessProperty" + // "UserName" "Microsoft" "PossessProperty" // "Service" "MailService" "Access" // "Operation" "ReadMail" "Invoke" // ClaimType: diff --git a/System.IdentityModel/System/IdentityModel/Claims/X509CertificateClaimSet.cs b/System.IdentityModel/System/IdentityModel/Claims/X509CertificateClaimSet.cs index 7561fffb9..cf6bf7762 100644 --- a/System.IdentityModel/System/IdentityModel/Claims/X509CertificateClaimSet.cs +++ b/System.IdentityModel/System/IdentityModel/Claims/X509CertificateClaimSet.cs @@ -192,7 +192,15 @@ IList InitializeClaimsCore() if (!string.IsNullOrEmpty(value)) claims.Add(Claim.CreateUriClaim(new Uri(value))); - RSA rsa = this.certificate.PublicKey.Key as RSA; + RSA rsa; + if (LocalAppContextSwitches.DisableCngCertificates) + { + rsa = this.certificate.PublicKey.Key as RSA; + } + else + { + rsa = CngLightup.GetRSAPublicKey(this.certificate); + } if (rsa != null) claims.Add(Claim.CreateRsaClaim(rsa)); diff --git a/System.IdentityModel/System/IdentityModel/CryptoHelper.cs b/System.IdentityModel/System/IdentityModel/CryptoHelper.cs index bfcc748bf..bfe9e6266 100644 --- a/System.IdentityModel/System/IdentityModel/CryptoHelper.cs +++ b/System.IdentityModel/System/IdentityModel/CryptoHelper.cs @@ -865,7 +865,7 @@ internal static bool IsAsymmetricAlgorithm(string algorithm) catch (InvalidOperationException) { algorithmObject = null; - // We ---- the exception and continue. + // We swallow the exception and continue. } if (algorithmObject != null) @@ -901,7 +901,7 @@ internal static bool IsSymmetricAlgorithm(string algorithm) catch (InvalidOperationException) { algorithmObject = null; - // We ---- the exception and continue. + // We swallow the exception and continue. } if (algorithmObject != null) { @@ -952,7 +952,7 @@ internal static bool IsSymmetricSupportedAlgorithm(string algorithm, int keySize } catch (InvalidOperationException) { - // We ---- the exception and continue. + // We swallow the exception and continue. } if (algorithmObject != null) { diff --git a/System.IdentityModel/System/IdentityModel/LocalAppContextSwitches.cs b/System.IdentityModel/System/IdentityModel/LocalAppContextSwitches.cs index b6bc82224..ccea9bbbc 100644 --- a/System.IdentityModel/System/IdentityModel/LocalAppContextSwitches.cs +++ b/System.IdentityModel/System/IdentityModel/LocalAppContextSwitches.cs @@ -2,6 +2,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------ +#pragma warning disable 0436 //Disable the type conflict warning for the types used by LocalAppContext framework (Quirking) namespace System.IdentityModel { using System; @@ -16,10 +17,12 @@ internal static class LocalAppContextSwitches private const string EnableCachedEmptyDefaultAuthorizationContextString = "Switch.System.IdentityModel.EnableCachedEmptyDefaultAuthorizationContext"; private const string DisableMultipleDNSEntriesInSANCertificateString = "Switch.System.IdentityModel.DisableMultipleDNSEntriesInSANCertificate"; private const string DisableUpdatingRsaProviderTypeString = "Switch.System.IdentityModel.DisableUpdatingRsaProviderType"; + private const string DisableCngCertificatesString = "Switch.System.IdentityModel.DisableCngCertificates"; private static int enableCachedEmptyDefaultAuthorizationContext; private static int disableMultipleDNSEntriesInSANCertificate; private static int disableUpdatingRsaProviderType; + private static int disableCngCertificatesString; public static bool EnableCachedEmptyDefaultAuthorizationContext { @@ -48,6 +51,15 @@ public static bool DisableUpdatingRsaProviderType } } + public static bool DisableCngCertificates + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return LocalAppContext.GetCachedSwitchValue(DisableCngCertificatesString, ref disableCngCertificatesString); + } + } + public static void SetDefaultsLessOrEqual_452() { #pragma warning disable BCL0012 @@ -61,6 +73,14 @@ public static void SetDefaultsLessOrEqual_46() #pragma warning disable BCL0012 // Define the switches that should be true for 4.6 or less, false for 4.6.1+. LocalAppContext.DefineSwitchDefault(DisableMultipleDNSEntriesInSANCertificateString, true); +#pragma warning restore BCL0012 + } + + public static void SetDefaultsLessOrEqual_462() + { +#pragma warning disable BCL0012 + // Define the switches that should be true for 4.6.2 or less, false for above 4.6.2. + LocalAppContext.DefineSwitchDefault(DisableCngCertificatesString, true); #pragma warning restore BCL0012 } } diff --git a/System.IdentityModel/System/IdentityModel/RsaEncryptionCookieTransform.cs b/System.IdentityModel/System/IdentityModel/RsaEncryptionCookieTransform.cs index 33cac6ffb..9ada52d4d 100644 --- a/System.IdentityModel/System/IdentityModel/RsaEncryptionCookieTransform.cs +++ b/System.IdentityModel/System/IdentityModel/RsaEncryptionCookieTransform.cs @@ -46,14 +46,14 @@ public class RsaEncryptionCookieTransform : CookieTransform /// /// The provided key will be used as the encryption and decryption key by default. /// When the key is null. - public RsaEncryptionCookieTransform( RSA key ) + public RsaEncryptionCookieTransform(RSA key) { - if ( null == key ) + if (null == key) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "key" ); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("key"); } _encryptionKey = key; - _decryptionKeys.Add( _encryptionKey ); + _decryptionKeys.Add(_encryptionKey); } /// @@ -63,14 +63,14 @@ public RsaEncryptionCookieTransform( RSA key ) /// When certificate is null. /// When the certificate has no private key. /// When the certificate's key is not RSA. - public RsaEncryptionCookieTransform( X509Certificate2 certificate ) + public RsaEncryptionCookieTransform(X509Certificate2 certificate) { - if ( null == certificate ) + if (null == certificate) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "certificate" ); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("certificate"); } - _encryptionKey = X509Util.EnsureAndGetPrivateRSAKey( certificate ); - _decryptionKeys.Add( _encryptionKey ); + _encryptionKey = X509Util.EnsureAndGetPrivateRSAKey(certificate); + _decryptionKeys.Add(_encryptionKey); } /// @@ -90,7 +90,7 @@ public virtual RSA EncryptionKey set { _encryptionKey = value; - _decryptionKeys = new List( new RSA[] { _encryptionKey }); + _decryptionKeys = new List(new RSA[] { _encryptionKey }); } } @@ -118,11 +118,11 @@ public string HashName get { return _hashName; } set { - using ( HashAlgorithm algorithm = CryptoHelper.CreateHashAlgorithm( value ) ) + using (HashAlgorithm algorithm = CryptoHelper.CreateHashAlgorithm(value)) { - if ( algorithm == null ) + if (algorithm == null) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( "value", SR.GetString( SR.ID6034, value ) ); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("value", SR.GetString(SR.ID6034, value)); } _hashName = value; } @@ -138,23 +138,23 @@ public string HashName /// The argument 'encoded' contains zero bytes. /// The platform does not support the requested algorithm. /// There are no decryption keys or none of the keys match. - public override byte[] Decode( byte[] encoded ) + public override byte[] Decode(byte[] encoded) { - if ( null == encoded ) + if (null == encoded) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "encoded" ); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encoded"); } - if ( 0 == encoded.Length ) + if (0 == encoded.Length) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( "encoded", SR.GetString( SR.ID6045 ) ); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("encoded", SR.GetString(SR.ID6045)); } ReadOnlyCollection decryptionKeys = DecryptionKeys; - if ( 0 == decryptionKeys.Count ) + if (0 == decryptionKeys.Count) { - throw DiagnosticUtility.ThrowHelperInvalidOperation( SR.GetString( SR.ID6039 ) ); + throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6039)); } byte[] encryptedKeyAndIV; @@ -162,50 +162,50 @@ public override byte[] Decode( byte[] encoded ) byte[] rsaHash; RSA rsaDecryptionKey = null; - using ( HashAlgorithm hash = CryptoHelper.CreateHashAlgorithm( _hashName ) ) + using (HashAlgorithm hash = CryptoHelper.CreateHashAlgorithm(_hashName)) { int hashSizeInBytes = hash.HashSize / 8; - using ( BinaryReader br = new BinaryReader( new MemoryStream( encoded ) ) ) + using (BinaryReader br = new BinaryReader(new MemoryStream(encoded))) { - rsaHash = br.ReadBytes( hashSizeInBytes ); + rsaHash = br.ReadBytes(hashSizeInBytes); int encryptedKeyAndIVSize = br.ReadInt32(); - if ( encryptedKeyAndIVSize < 0 ) + if (encryptedKeyAndIVSize < 0) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new FormatException( SR.GetString( SR.ID1006, encryptedKeyAndIVSize ) ) ); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1006, encryptedKeyAndIVSize))); } // // Enforce upper limit on key size to prevent large buffer allocation in br.ReadBytes() // - if ( encryptedKeyAndIVSize > encoded.Length ) + if (encryptedKeyAndIVSize > encoded.Length) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new FormatException( SR.GetString( SR.ID1007 ) ) ); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1007))); } - encryptedKeyAndIV = br.ReadBytes( encryptedKeyAndIVSize ); + encryptedKeyAndIV = br.ReadBytes(encryptedKeyAndIVSize); int encryptedDataSize = br.ReadInt32(); - if ( encryptedDataSize < 0 ) + if (encryptedDataSize < 0) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new FormatException( SR.GetString( SR.ID1008, encryptedDataSize ) ) ); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1008, encryptedDataSize))); } // // Enforce upper limit on data size to prevent large buffer allocation in br.ReadBytes() // - if ( encryptedDataSize > encoded.Length ) + if (encryptedDataSize > encoded.Length) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new FormatException( SR.GetString( SR.ID1009 ) ) ); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.ID1009))); } - encryptedData = br.ReadBytes( encryptedDataSize ); + encryptedData = br.ReadBytes(encryptedDataSize); } // // Find the decryption key matching the one in XML // - foreach ( RSA key in decryptionKeys ) + foreach (RSA key in decryptionKeys) { - byte[] hashedKey = hash.ComputeHash( Encoding.UTF8.GetBytes( key.ToXmlString( false ) ) ); - if ( CryptoHelper.IsEqual( hashedKey, rsaHash ) ) + byte[] hashedKey = hash.ComputeHash(Encoding.UTF8.GetBytes(key.ToXmlString(false))); + if (CryptoHelper.IsEqual(hashedKey, rsaHash)) { rsaDecryptionKey = key; break; @@ -213,19 +213,12 @@ public override byte[] Decode( byte[] encoded ) } } - if ( rsaDecryptionKey == null ) + if (rsaDecryptionKey == null) { - throw DiagnosticUtility.ThrowHelperInvalidOperation( SR.GetString( SR.ID6040 ) ); + throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6040)); } - RSACryptoServiceProvider rsaProvider = rsaDecryptionKey as RSACryptoServiceProvider; - - if ( rsaProvider == null ) - { - throw DiagnosticUtility.ThrowHelperInvalidOperation( SR.GetString( SR.ID6041 ) ); - } - - byte[] decryptedKeyAndIV = rsaProvider.Decrypt( encryptedKeyAndIV, true ); + byte[] decryptedKeyAndIV = CngLightup.OaepSha1Decrypt(rsaDecryptionKey, encryptedKeyAndIV); using (SymmetricAlgorithm symmetricAlgorithm = CryptoHelper.NewDefaultEncryption()) { @@ -265,35 +258,35 @@ public override byte[] Decode( byte[] encoded ) /// The argument 'value' contains zero bytes. /// The EncryptionKey is null. /// Encoded data - public override byte[] Encode( byte[] value ) + public override byte[] Encode(byte[] value) { - if ( null == value ) + if (null == value) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "value" ); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value"); } - if ( 0 == value.Length ) + if (0 == value.Length) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( "value", SR.GetString( SR.ID6044 ) ); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("value", SR.GetString(SR.ID6044)); } RSA encryptionKey = EncryptionKey; - if ( null == encryptionKey ) + if (null == encryptionKey) { - throw DiagnosticUtility.ThrowHelperInvalidOperation( SR.GetString( SR.ID6043 ) ); + throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6043)); } byte[] rsaHash; byte[] encryptedKeyAndIV; byte[] encryptedData; - using ( HashAlgorithm hash = CryptoHelper.CreateHashAlgorithm( _hashName ) ) + using (HashAlgorithm hash = CryptoHelper.CreateHashAlgorithm(_hashName)) { - rsaHash = hash.ComputeHash( Encoding.UTF8.GetBytes( encryptionKey.ToXmlString( false ) ) ); + rsaHash = hash.ComputeHash(Encoding.UTF8.GetBytes(encryptionKey.ToXmlString(false))); } - using ( SymmetricAlgorithm encryptionAlgorithm = CryptoHelper.NewDefaultEncryption() ) + using (SymmetricAlgorithm encryptionAlgorithm = CryptoHelper.NewDefaultEncryption()) { encryptionAlgorithm.GenerateIV(); encryptionAlgorithm.GenerateKey(); @@ -314,21 +307,21 @@ public override byte[] Encode( byte[] value ) // Concatenate the Key and IV in an attempt to avoid two minimum block lengths in the cookie // byte[] keyAndIV = new byte[encryptionAlgorithm.Key.Length + encryptionAlgorithm.IV.Length]; - Array.Copy( encryptionAlgorithm.Key, keyAndIV, encryptionAlgorithm.Key.Length ); - Array.Copy( encryptionAlgorithm.IV, 0, keyAndIV, encryptionAlgorithm.Key.Length, encryptionAlgorithm.IV.Length ); + Array.Copy(encryptionAlgorithm.Key, keyAndIV, encryptionAlgorithm.Key.Length); + Array.Copy(encryptionAlgorithm.IV, 0, keyAndIV, encryptionAlgorithm.Key.Length, encryptionAlgorithm.IV.Length); - encryptedKeyAndIV = provider.Encrypt( keyAndIV, true ); + encryptedKeyAndIV = CngLightup.OaepSha1Encrypt(encryptionKey, keyAndIV); } - using ( MemoryStream ms = new MemoryStream() ) + using (MemoryStream ms = new MemoryStream()) { - using ( BinaryWriter bw = new BinaryWriter( ms ) ) + using (BinaryWriter bw = new BinaryWriter(ms)) { - bw.Write( rsaHash ); - bw.Write( encryptedKeyAndIV.Length ); - bw.Write( encryptedKeyAndIV ); - bw.Write( encryptedData.Length ); - bw.Write( encryptedData ); + bw.Write(rsaHash); + bw.Write(encryptedKeyAndIV.Length); + bw.Write(encryptedKeyAndIV); + bw.Write(encryptedData.Length); + bw.Write(encryptedData); bw.Flush(); } diff --git a/System.IdentityModel/System/IdentityModel/RsaSignatureCookieTransform.cs b/System.IdentityModel/System/IdentityModel/RsaSignatureCookieTransform.cs index 566f8bd62..d5b7c5c3d 100644 --- a/System.IdentityModel/System/IdentityModel/RsaSignatureCookieTransform.cs +++ b/System.IdentityModel/System/IdentityModel/RsaSignatureCookieTransform.cs @@ -242,15 +242,18 @@ public override byte[] Encode(byte[] value) } RSA signingKey = SigningKey; + if (null == signingKey) + { + throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6042)); + } RSACryptoServiceProvider rsaCryptoServiceProvider = signingKey as RSACryptoServiceProvider; - - if (null == signingKey || null == rsaCryptoServiceProvider) + if (rsaCryptoServiceProvider == null && LocalAppContextSwitches.DisableCngCertificates) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6042)); } - if (rsaCryptoServiceProvider.PublicOnly) + if (rsaCryptoServiceProvider != null && rsaCryptoServiceProvider.PublicOnly) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID6046)); } diff --git a/System.IdentityModel/System/IdentityModel/SecurityUtils.cs b/System.IdentityModel/System/IdentityModel/SecurityUtils.cs index 7b2b9f189..297c9df09 100644 --- a/System.IdentityModel/System/IdentityModel/SecurityUtils.cs +++ b/System.IdentityModel/System/IdentityModel/SecurityUtils.cs @@ -28,7 +28,7 @@ static class SecurityUtils public const int WindowsVistaMajorNumber = 6; static IIdentity anonymousIdentity; - // these should be kept in [....] with IIS70 + // these should be kept in sync with IIS70 public const string AuthTypeNTLM = "NTLM"; public const string AuthTypeNegotiate = "Negotiate"; public const string AuthTypeKerberos = "Kerberos"; @@ -727,7 +727,7 @@ public static void DisposeIfNecessary(IDisposable obj) } /// - /// Internal helper class to help keep Kerberos and Spnego in [....]. + /// Internal helper class to help keep Kerberos and Spnego in sync. /// This code is shared by: /// System\IdentityModel\Tokens\KerberosReceiverSecurityToken.cs /// System\ServiceModel\Security\WindowsSspiNegotiation.cs @@ -736,7 +736,7 @@ public static void DisposeIfNecessary(IDisposable obj) internal class ExtendedProtectionPolicyHelper { // - // keep the defaults: _protectionScenario and _policyEnforcement, in [....] with: static class System.ServiceModel.Channel.ChannelBindingUtility + // keep the defaults: _protectionScenario and _policyEnforcement, in sync with: static class System.ServiceModel.Channel.ChannelBindingUtility // We can't access those defaults as IdentityModel cannot take a dependency on ServiceModel // static ExtendedProtectionPolicy disabledPolicy = new ExtendedProtectionPolicy(PolicyEnforcement.Never); @@ -893,11 +893,11 @@ public void CheckServiceBinding(SafeDeleteContext securityContext, string defaul } /// - /// Keep this in [....] with \System\ServiceModel\Channels\ChannelBindingUtility.cs + /// Keep this in sync with \System\ServiceModel\Channels\ChannelBindingUtility.cs /// public static ExtendedProtectionPolicy DefaultPolicy { // - //keep the default in [....] with : static class System.ServiceModel.Channels.ChannelBindingUtility + //keep the default in sync with : static class System.ServiceModel.Channels.ChannelBindingUtility //we can't use these defaults as IdentityModel cannot take a dependency on ServiceModel // diff --git a/System.IdentityModel/System/IdentityModel/SspiWrapper.cs b/System.IdentityModel/System/IdentityModel/SspiWrapper.cs index 9a885e93b..cf5e3d589 100644 --- a/System.IdentityModel/System/IdentityModel/SspiWrapper.cs +++ b/System.IdentityModel/System/IdentityModel/SspiWrapper.cs @@ -18,6 +18,9 @@ namespace System.IdentityModel internal enum SchProtocols { Zero = 0, + PctClient = 0x00000002, + PctServer = 0x00000001, + Pct = (PctClient | PctServer), Ssl2Client = 0x00000008, Ssl2Server = 0x00000004, Ssl2 = (Ssl2Client | Ssl2Server), @@ -28,6 +31,17 @@ internal enum SchProtocols TlsServer = 0x00000040, Tls = (TlsClient | TlsServer), Ssl3Tls = (Ssl3 | Tls), + Tls11Client = 0x00000200, + Tls11Server = 0x00000100, + Tls11 = (Tls11Client | Tls11Server), + Tls12Client = 0x00000800, + Tls12Server = 0x00000400, + Tls12 = (Tls12Client | Tls12Server), + UniClient = unchecked((int)0x80000000), + UniServer = 0x40000000, + Unified = (UniClient | UniServer), + ClientMask = (PctClient | Ssl2Client | Ssl3Client | TlsClient | Tls11Client | Tls12Client | UniClient), + ServerMask = (PctServer | Ssl2Server | Ssl3Server | TlsServer | Tls11Server | Tls12Server | UniServer) }; //From WinCrypt.h diff --git a/System.IdentityModel/System/IdentityModel/Tokens/Saml2SecurityTokenHandler.cs b/System.IdentityModel/System/IdentityModel/Tokens/Saml2SecurityTokenHandler.cs index 3911fb648..227968329 100644 --- a/System.IdentityModel/System/IdentityModel/Tokens/Saml2SecurityTokenHandler.cs +++ b/System.IdentityModel/System/IdentityModel/Tokens/Saml2SecurityTokenHandler.cs @@ -370,7 +370,7 @@ public override ReadOnlyCollection ValidateToken(SecurityToken t if (this.samlSecurityTokenRequirement.MapToWindows) { - // TFS: 153865, [....] WindowsIdentity does not set Authtype. I don't think that authtype should be set here anyway. + // TFS: 153865, Microsoft WindowsIdentity does not set Authtype. I don't think that authtype should be set here anyway. // The authtype will be S4U (kerberos) it doesn't really matter that the upn arrived in a SAML token. claimsIdentity = this.CreateWindowsIdentity(this.FindUpn(claimsIdentity)); diff --git a/System.IdentityModel/System/IdentityModel/Tokens/SamlSecurityTokenHandler.cs b/System.IdentityModel/System/IdentityModel/Tokens/SamlSecurityTokenHandler.cs index 3ee5369d3..0fbf94a87 100644 --- a/System.IdentityModel/System/IdentityModel/Tokens/SamlSecurityTokenHandler.cs +++ b/System.IdentityModel/System/IdentityModel/Tokens/SamlSecurityTokenHandler.cs @@ -1020,7 +1020,7 @@ public override ReadOnlyCollection ValidateToken(SecurityToken t if (_samlSecurityTokenRequirement.MapToWindows) { - // TFS: 153865, [....] WindowsIdentity does not set Authtype. I don't think that authtype should be set here anyway. + // TFS: 153865, Microsoft WindowsIdentity does not set Authtype. I don't think that authtype should be set here anyway. // The authtype will be S4U (kerberos) it doesn't really matter that the upn arrived in a SAML token. WindowsIdentity windowsIdentity = CreateWindowsIdentity(FindUpn(claimsIdentity)); diff --git a/System.IdentityModel/System/IdentityModel/Tokens/X509AsymmetricSecurityKey.cs b/System.IdentityModel/System/IdentityModel/Tokens/X509AsymmetricSecurityKey.cs index fb1918c6c..ab69fff48 100644 --- a/System.IdentityModel/System/IdentityModel/Tokens/X509AsymmetricSecurityKey.cs +++ b/System.IdentityModel/System/IdentityModel/Tokens/X509AsymmetricSecurityKey.cs @@ -14,7 +14,8 @@ public class X509AsymmetricSecurityKey : AsymmetricSecurityKey X509Certificate2 certificate; AsymmetricAlgorithm privateKey; bool privateKeyAvailabilityDetermined; - PublicKey publicKey; + AsymmetricAlgorithm publicKey; + bool publicKeyAvailabilityDetermined; object thisLock = new Object(); @@ -28,7 +29,7 @@ public X509AsymmetricSecurityKey(X509Certificate2 certificate) public override int KeySize { - get { return this.PublicKey.Key.KeySize; } + get { return this.PublicKey.KeySize; } } AsymmetricAlgorithm PrivateKey @@ -39,28 +40,67 @@ AsymmetricAlgorithm PrivateKey { lock (ThisLock) { - if (!this.privateKeyAvailabilityDetermined) + if (LocalAppContextSwitches.DisableCngCertificates) { this.privateKey = this.certificate.PrivateKey; - this.privateKeyAvailabilityDetermined = true; } + else + { + this.privateKey = CngLightup.GetRSAPrivateKey(this.certificate); + if (this.privateKey != null) + { + RSACryptoServiceProvider rsaCsp = this.privateKey as RSACryptoServiceProvider; + // ProviderType == 1 is PROV_RSA_FULL provider type that only supports SHA1. Change it to PROV_RSA_AES=24 that supports SHA2 also. + if (rsaCsp != null && rsaCsp.CspKeyContainerInfo.ProviderType == 1) + { + CspParameters csp = new CspParameters(); + csp.ProviderType = 24; + csp.KeyContainerName = rsaCsp.CspKeyContainerInfo.KeyContainerName; + csp.KeyNumber = (int)rsaCsp.CspKeyContainerInfo.KeyNumber; + if (rsaCsp.CspKeyContainerInfo.MachineKeyStore) + csp.Flags = CspProviderFlags.UseMachineKeyStore; + + csp.Flags |= CspProviderFlags.UseExistingKey; + this.privateKey = new RSACryptoServiceProvider(csp); + } + } + else + { + this.privateKey = CngLightup.GetDSAPrivateKey(this.certificate); + } + if (certificate.HasPrivateKey && this.privateKey == null) + DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.PrivateKeyNotSupported))); + } + this.privateKeyAvailabilityDetermined = true; } } return this.privateKey; } } - PublicKey PublicKey + AsymmetricAlgorithm PublicKey { get { - if (this.publicKey == null) + if (!this.publicKeyAvailabilityDetermined) { lock (ThisLock) { - if (this.publicKey == null) + if (!this.publicKeyAvailabilityDetermined) { - this.publicKey = this.certificate.PublicKey; + if (LocalAppContextSwitches.DisableCngCertificates) + { + this.publicKey = this.certificate.PublicKey.Key; + } + else + { + this.publicKey = CngLightup.GetRSAPublicKey(this.certificate); + if (this.publicKey == null) + this.publicKey = CngLightup.GetDSAPublicKey(this.certificate); + if (this.publicKey == null) + DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.PublicKeyNotSupported))); + } + this.publicKeyAvailabilityDetermined = true; } } } @@ -115,7 +155,7 @@ public override byte[] DecryptKey(string algorithm, byte[] keyData) public override byte[] EncryptKey(string algorithm, byte[] keyData) { // Ensure that we have an RSA algorithm object - RSA rsa = this.PublicKey.Key as RSA; + RSA rsa = this.PublicKey as RSA; if (rsa == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.PublicKeyNotRSA))); @@ -181,18 +221,18 @@ public override AsymmetricAlgorithm GetAsymmetricAlgorithm(string algorithm, boo switch (algorithm) { case SignedXml.XmlDsigDSAUrl: - if ((this.PublicKey.Key as DSA) != null) + if ((this.PublicKey as DSA) != null) { - return (this.PublicKey.Key as DSA); + return (this.PublicKey as DSA); } throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.AlgorithmAndPublicKeyMisMatch))); case SignedXml.XmlDsigRSASHA1Url: case SecurityAlgorithms.RsaSha256Signature: case EncryptedXml.XmlEncRSA15Url: case EncryptedXml.XmlEncRSAOAEPUrl: - if ((this.PublicKey.Key as RSA) != null) + if ((this.PublicKey as RSA) != null) { - return (this.PublicKey.Key as RSA); + return (this.PublicKey as RSA); } throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.AlgorithmAndPublicKeyMisMatch))); default: @@ -254,14 +294,14 @@ public override AsymmetricSignatureDeformatter GetSignatureDeformatter(string al { SignatureDescription description = algorithmObject as SignatureDescription; if (description != null) - return description.CreateDeformatter(this.PublicKey.Key); + return description.CreateDeformatter(this.PublicKey); try { AsymmetricSignatureDeformatter asymmetricSignatureDeformatter = algorithmObject as AsymmetricSignatureDeformatter; if (asymmetricSignatureDeformatter != null) { - asymmetricSignatureDeformatter.SetKey(this.PublicKey.Key); + asymmetricSignatureDeformatter.SetKey(this.PublicKey); return asymmetricSignatureDeformatter; } } @@ -279,7 +319,7 @@ public override AsymmetricSignatureDeformatter GetSignatureDeformatter(string al case SignedXml.XmlDsigDSAUrl: // Ensure that we have a DSA algorithm object. - DSA dsa = (this.PublicKey.Key as DSA); + DSA dsa = (this.PublicKey as DSA); if (dsa == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.PublicKeyNotDSA))); return new DSASignatureDeformatter(dsa); @@ -287,7 +327,7 @@ public override AsymmetricSignatureDeformatter GetSignatureDeformatter(string al case SignedXml.XmlDsigRSASHA1Url: case SecurityAlgorithms.RsaSha256Signature: // Ensure that we have an RSA algorithm object. - RSA rsa = (this.PublicKey.Key as RSA); + RSA rsa = (this.PublicKey as RSA); if (rsa == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.PublicKeyNotRSA))); return new RSAPKCS1SignatureDeformatter(rsa); @@ -456,13 +496,13 @@ public override bool IsSupportedAlgorithm(string algorithm) switch (algorithm) { case SignedXml.XmlDsigDSAUrl: - return (this.PublicKey.Key is DSA); + return (this.PublicKey is DSA); case SignedXml.XmlDsigRSASHA1Url: case SecurityAlgorithms.RsaSha256Signature: case EncryptedXml.XmlEncRSA15Url: case EncryptedXml.XmlEncRSAOAEPUrl: - return (this.PublicKey.Key is RSA); + return (this.PublicKey is RSA); default: return false; } diff --git a/System.IdentityModel/System/IdentityModel/X509Util.cs b/System.IdentityModel/System/IdentityModel/X509Util.cs index 965002cd3..7ede60624 100644 --- a/System.IdentityModel/System/IdentityModel/X509Util.cs +++ b/System.IdentityModel/System/IdentityModel/X509Util.cs @@ -32,18 +32,23 @@ internal static RSA EnsureAndGetPrivateRSAKey(X509Certificate2 certificate) } // Check for accessibility of private key - AsymmetricAlgorithm privateKey; + RSA rsa; try { - privateKey = certificate.PrivateKey; + if (LocalAppContextSwitches.DisableCngCertificates) + { + rsa = certificate.PrivateKey as RSA; + } + else + { + rsa = CngLightup.GetRSAPrivateKey(certificate); + } } catch (CryptographicException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ID1039, certificate.Thumbprint), e)); } - // Reject weird private key - RSA rsa = privateKey as RSA; if (rsa == null) { #pragma warning suppress 56526 // no validation necessary for value.Thumbprint @@ -223,13 +228,29 @@ public static IEnumerable GetClaimsFromCertificate(X509Certificate2 certi claimsCollection.Add(new Claim(ClaimTypes.Uri, value, ClaimValueTypes.String, issuer)); } - RSA rsa = certificate.PublicKey.Key as RSA; + RSA rsa; + if (LocalAppContextSwitches.DisableCngCertificates) + { + rsa = certificate.PublicKey.Key as RSA; + } + else + { + rsa = CngLightup.GetRSAPublicKey(certificate); + } if (rsa != null) { claimsCollection.Add(new Claim(ClaimTypes.Rsa, rsa.ToXmlString(false), ClaimValueTypes.RsaKeyValue, issuer)); } - DSA dsa = certificate.PublicKey.Key as DSA; + DSA dsa; + if (LocalAppContextSwitches.DisableCngCertificates) + { + dsa = certificate.PublicKey.Key as DSA; + } + else + { + dsa = CngLightup.GetDSAPublicKey(certificate); + } if (dsa != null) { claimsCollection.Add(new Claim(ClaimTypes.Dsa, dsa.ToXmlString(false), ClaimValueTypes.DsaKeyValue, issuer)); diff --git a/System.Net/net/PeerToPeer/Collaboration/ContactManager.cs b/System.Net/net/PeerToPeer/Collaboration/ContactManager.cs index de8d5aab8..0a863133e 100644 --- a/System.Net/net/PeerToPeer/Collaboration/ContactManager.cs +++ b/System.Net/net/PeerToPeer/Collaboration/ContactManager.cs @@ -1561,7 +1561,7 @@ private void CreateContactAsyncHelper(object state) object userToken = createAsyncState.UserToken; // - // Call the [....] version of createcontact + // Call the sync version of createcontact // try{ peerContact = CreateContact(peerNearMe); diff --git a/System.Net/net/PeerToPeer/Collaboration/PeerNearMe.cs b/System.Net/net/PeerToPeer/Collaboration/PeerNearMe.cs index 66fae79ab..b72b6f990 100644 --- a/System.Net/net/PeerToPeer/Collaboration/PeerNearMe.cs +++ b/System.Net/net/PeerToPeer/Collaboration/PeerNearMe.cs @@ -315,7 +315,7 @@ internal protected void InternalRefreshData(object state) if (exception != null){ // - // Throw exception for [....] but call callback for async with exception + // Throw exception for sync but call callback for async with exception // if (!isAsync) throw exception; @@ -328,7 +328,7 @@ internal protected void InternalRefreshData(object state) Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Found endpoint match in Request status changed."); // - // For async call the callback and for [....] just return + // For async call the callback and for sync just return // if (isAsync){ RefreshDataCompletedEventArgs args = new @@ -352,7 +352,7 @@ internal protected void InternalRefreshData(object state) // // Async case with exception fire callback here - // [....] would have already thrown this by now + // Sync would have already thrown this by now // if (exception != null){ RefreshDataCompletedEventArgs args = new diff --git a/System.Net/net/PeerToPeer/PeerName.cs b/System.Net/net/PeerToPeer/PeerName.cs index e4c8f05b9..b9502c116 100644 --- a/System.Net/net/PeerToPeer/PeerName.cs +++ b/System.Net/net/PeerToPeer/PeerName.cs @@ -433,7 +433,7 @@ public bool IsSecured /// I have considered using regular expressions. However, the regular expressions offer /// poor performance and or startup cost. Really there is no substiture for custom /// parsing logic. I decided to write this piece of code to parse the peername for now - /// - [....] 6/6/2005 + /// - Microsoft 6/6/2005 /// /// /// diff --git a/System.Net/net/PeerToPeer/PeerNameResolver.cs b/System.Net/net/PeerToPeer/PeerNameResolver.cs index 887280f92..62397d824 100644 --- a/System.Net/net/PeerToPeer/PeerNameResolver.cs +++ b/System.Net/net/PeerToPeer/PeerNameResolver.cs @@ -490,7 +490,7 @@ internal int TraceEventId /// - /// PeerNameResolver does [....] and async resolves. + /// PeerNameResolver does sync and async resolves. /// PeerNameResolver supports multiple outstanding async calls /// public class PeerNameResolver @@ -581,7 +581,7 @@ public PeerNameRecordCollection Resolve(PeerName peerName, int maxRecords) } /// - /// Implements [....] resolve of the PeerName in the cloud given + /// Implements sync resolve of the PeerName in the cloud given /// /// /// @@ -641,7 +641,7 @@ public PeerNameRecordCollection Resolve(PeerName peerName, Cloud cloud, int maxR //--------------------------------------------------------------- //Trace log //--------------------------------------------------------------- - Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "[....] Resolve called with PeerName: {0}, Cloud: {1}, MaxRecords {2}", peerName, cloud, maxRecords); + Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Sync Resolve called with PeerName: {0}, Cloud: {1}, MaxRecords {2}", peerName, cloud, maxRecords); SafePeerData shEndPointInfoArray; string NativeCloudName = cloud.InternalName; @@ -721,7 +721,7 @@ public PeerNameRecordCollection Resolve(PeerName peerName, Cloud cloud, int maxR shEndPointInfoArray.Dispose(); } } - Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "[....] Resolve returnig with PeerNameRecord count :{0}", PeerNameRecords.Count); + Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Sync Resolve returnig with PeerNameRecord count :{0}", PeerNameRecords.Count); return PeerNameRecords; } diff --git a/System.Numerics/System.Numerics.txt b/System.Numerics/System.Numerics.txt index f3827ec29..e834a8449 100644 --- a/System.Numerics/System.Numerics.txt +++ b/System.Numerics/System.Numerics.txt @@ -6,6 +6,7 @@ ; NOTE: do not use \", use ' instead ; NOTE: Use # or ; for comments + Argument_InvalidNumberStyles=An undefined NumberStyles value is being used. Argument_InvalidHexStyle=With the AllowHexSpecifier bit set in the enum bit field, the only other valid bits that can be combined into the enum value must be a subset of those in HexNumber. Argument_MustBeBigInt=The parameter must be a BigInteger. @@ -20,3 +21,8 @@ Overflow_Int64=Value was either too large or too small for an Int64. Overflow_UInt32=Value was either too large or too small for a UInt32. Overflow_UInt64=Value was either too large or too small for a UInt64. Overflow_Decimal=Value was either too large or too small for a Decimal. +Arg_ArgumentOutOfRangeException=Index was out of bounds: +Arg_ElementsInSourceIsGreaterThanDestination=Number of elements in source vector is greater than the destination array +Arg_MultiDimArrayNotSupported=Only one-dimensional arrays are supported +Arg_RegisterLengthOfRangeException=length must be less than +Arg_NullArgumentNullRef=The method was called with a null array argument. diff --git a/System.Numerics/System/Numerics/Complex.cs b/System.Numerics/System/Numerics/Complex.cs index c1c4e1acb..579a96446 100644 --- a/System.Numerics/System/Numerics/Complex.cs +++ b/System.Numerics/System/Numerics/Complex.cs @@ -290,7 +290,7 @@ public static Complex Sin(Complex value) { return new Complex(Math.Sin(a) * Math.Cosh(b), Math.Cos(a) * Math.Sinh(b)); } - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sinh", Justification = "[....]: Existing Name")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sinh", Justification = "Microsoft: Existing Name")] public static Complex Sinh(Complex value) /* Hyperbolic sin */ { double a = value.m_real; @@ -309,7 +309,7 @@ public static Complex Cos(Complex value) { return new Complex(Math.Cos(a) * Math.Cosh(b), - (Math.Sin(a) * Math.Sinh(b))); } - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cosh", Justification = "[....]: Existing Name")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cosh", Justification = "Microsoft: Existing Name")] public static Complex Cosh(Complex value) /* Hyperbolic cos */ { double a = value.m_real; @@ -325,7 +325,7 @@ public static Complex Tan(Complex value) { return (Sin(value) / Cos(value)); } - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tanh", Justification = "[....]: Existing Name")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tanh", Justification = "Microsoft: Existing Name")] public static Complex Tanh(Complex value) /* Hyperbolic tan */ { return (Sinh(value) / Cosh(value)); @@ -362,7 +362,7 @@ public static Complex Exp(Complex value) /* The complex number raised to e */ return (new Complex(result_re, result_im)); } - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sqrt", Justification = "[....]: Existing Name")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sqrt", Justification = "Microsoft: Existing Name")] public static Complex Sqrt(Complex value) /* Square root ot the complex number */ { return Complex.FromPolarCoordinates(Math.Sqrt(value.Magnitude), value.Phase / 2.0); diff --git a/System.Runtime.Caching/R.resx b/System.Runtime.Caching/R.resx new file mode 100644 index 000000000..85da51f1f --- /dev/null +++ b/System.Runtime.Caching/R.resx @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Unable to retrieve configuration section '{0}'. + + + Invalid configuration: {0}="{1}". The {0} value must be a time interval that can be parsed by System.TimeSpan.Parse. + + + Invalid configuration: {0}="{1}". The {0} value must be a non-negative 32-bit integer. + + + Invalid configuration: {0}="{1}". The {0} value must be a positive 32-bit integer. + + + Invalid configuration: {0}="{1}". The {0} value cannot be greater than '{2}'. + + + The collection '{0}' is empty. + + + The collection '{0}' contains a null element. + + + The collection '{0}' contains a null or empty string. + + + The method has already been invoked, and can only be invoked once. + + + The property has already been set, and can only be set once. + + + Invalid state. + + + Initialization has not completed yet. The InitializationComplete method must be invoked before Dispose is invoked. + + + Default is a reserved MemoryCache name. + + + AbsoluteExpiration must be DateTimeOffset.MaxValue or SlidingExpiration must be TimeSpan.Zero. + + + Only one callback can be specified. Either RemovedCallback or UpdateCallback must be null. + + + One of the following parameters must be specified: dependencies, absoluteExpiration, slidingExpiration. + + + CacheItemUpdateCallback must be null. + + + '{0}' must be greater than or equal to '{1}' and less than or equal to '{2}'. + + + An empty string is invalid. + + + The parameter regionName must be null. + + + Invalid configuration: {0}="{1}". The {0} value must be a boolean. + + \ No newline at end of file diff --git a/System.Runtime.Caching/Resources/R.Designer.cs b/System.Runtime.Caching/Resources/R.Designer.cs index fc9a8303c..a6a4cc0f7 100644 --- a/System.Runtime.Caching/Resources/R.Designer.cs +++ b/System.Runtime.Caching/Resources/R.Designer.cs @@ -222,6 +222,15 @@ internal static string Value_too_big { } } + /// + /// Looks up a localized string similar to Invalid configuration: {0}="{1}". The {0} value must be a boolean.. + /// + internal static string Value_must_be_boolean { + get { + return ResourceManager.GetString("Value_must_be_boolean", resourceCulture); + } + } + /// /// Looks up a localized string similar to An empty string is invalid.. /// diff --git a/System.Runtime.Caching/System/Caching/CacheMemoryMonitor.cs b/System.Runtime.Caching/System/Caching/CacheMemoryMonitor.cs index 05af14359..0de026fa2 100644 --- a/System.Runtime.Caching/System/Caching/CacheMemoryMonitor.cs +++ b/System.Runtime.Caching/System/Caching/CacheMemoryMonitor.cs @@ -44,7 +44,8 @@ internal CacheMemoryMonitor(MemoryCache memoryCache, int cacheMemoryLimitMegabyt _gen2Count = GC.CollectionCount(2); _cacheSizeSamples = new long[SAMPLE_COUNT]; _cacheSizeSampleTimes = new DateTime[SAMPLE_COUNT]; - InitMemoryCacheManager(); + if (memoryCache.UseMemoryCacheManager) + InitMemoryCacheManager(); // This magic thing connects us to ObjectCacheHost magically. :/ InitDisposableMembers(cacheMemoryLimitMegabytes); } diff --git a/System.Runtime.Caching/System/Caching/Configuration/ConfigUtil.cs b/System.Runtime.Caching/System/Caching/Configuration/ConfigUtil.cs index 48aff5f2d..587d4f3b6 100644 --- a/System.Runtime.Caching/System/Caching/Configuration/ConfigUtil.cs +++ b/System.Runtime.Caching/System/Caching/Configuration/ConfigUtil.cs @@ -12,6 +12,7 @@ internal static class ConfigUtil { internal const string CacheMemoryLimitMegabytes = "cacheMemoryLimitMegabytes"; internal const string PhysicalMemoryLimitPercentage = "physicalMemoryLimitPercentage"; internal const string PollingInterval = "pollingInterval"; + internal const string UseMemoryCacheManager = "useMemoryCacheManager"; internal const int DefaultPollingTimeMilliseconds = 120000; internal static int GetIntValue(NameValueCollection config, string valueName, int defaultValue, bool zeroAllowed, int maxValueAllowed) { @@ -63,5 +64,19 @@ internal static int GetIntValueFromTimeSpan(NameValueCollection config, string v return iValue; } + internal static bool GetBooleanValue(NameValueCollection config, string valueName, bool defaultValue) { + string sValue = config[valueName]; + + if (sValue == null) { + return defaultValue; + } + + bool bValue; + if (!Boolean.TryParse(sValue, out bValue)) { + throw new ArgumentException(RH.Format(R.Value_must_be_boolean, valueName, sValue), "config"); + } + + return bValue; + } } } diff --git a/System.Runtime.Caching/System/Caching/MemoryCache.cs b/System.Runtime.Caching/System/Caching/MemoryCache.cs index cfc0c0315..fc82c52b7 100644 --- a/System.Runtime.Caching/System/Caching/MemoryCache.cs +++ b/System.Runtime.Caching/System/Caching/MemoryCache.cs @@ -34,6 +34,7 @@ public class MemoryCache : ObjectCache, IEnumerable, IDisposable { private string _name; private PerfCounters _perfCounters; private bool _configLess; + private bool _useMemoryCacheManager = true; EventHandler _onAppDomainUnload; UnhandledExceptionEventHandler _onUnhandledException; @@ -258,6 +259,10 @@ public override string Name get { return _name; } } + internal bool UseMemoryCacheManager { + get { return _useMemoryCacheManager; } + } + // Percentage of physical memory that can be used before // the cache begins to forcibly remove items. public long PhysicalMemoryLimit { @@ -280,7 +285,7 @@ private MemoryCache() { Init(null); } - [SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Justification="This is assembly is a special case approved by the NetFx API review board")] + [SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Justification = "This is assembly is a special case approved by the NetFx API review board")] public MemoryCache(string name, NameValueCollection config = null) { if (name == null) { throw new ArgumentNullException("name"); @@ -294,12 +299,12 @@ public MemoryCache(string name, NameValueCollection config = null) { _name = name; Init(config); } - - // Configless is used when redirecting ASP.NET cache into the MemoryCache. This avoids infinite recursion + + // ignoreConfigSection is used when redirecting ASP.NET cache into the MemoryCache. This avoids infinite recursion // due to the fact that the (ASP.NET) config system uses the cache, and the cache uses the // config system. This method could be made public, perhaps with CAS to prevent partial trust callers. - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Grandfathered suppression from original caching code checkin")] - internal MemoryCache(string name, NameValueCollection config, bool configLess) { + [SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Justification = "This is assembly is a special case approved by the NetFx API review board")] + public MemoryCache(string name, NameValueCollection config, bool ignoreConfigSection) { if (name == null) { throw new ArgumentNullException("name"); } @@ -310,13 +315,16 @@ internal MemoryCache(string name, NameValueCollection config, bool configLess) { throw new ArgumentException(R.Default_is_reserved, "name"); } _name = name; - _configLess = configLess; + _configLess = ignoreConfigSection; Init(config); } private void Init(NameValueCollection config) { _storeCount = Environment.ProcessorCount; _storeRefs = new GCHandleRef[_storeCount]; + if (config != null) { + _useMemoryCacheManager = ConfigUtil.GetBooleanValue(config, ConfigUtil.UseMemoryCacheManager, true); + } InitDisposableMembers(config); } @@ -654,6 +662,11 @@ internal void Set(string key, [SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Justification="This is assembly is a special case approved by the NetFx API review board")] public override object Remove(string key, string regionName = null) { + return Remove(key, CacheEntryRemovedReason.Removed, regionName); + } + + [SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Justification = "This is assembly is a special case approved by the NetFx API review board")] + public object Remove(string key, CacheEntryRemovedReason reason, string regionName = null) { if (regionName != null) { throw new NotSupportedException(R.RegionName_not_supported); } @@ -663,7 +676,7 @@ public override object Remove(string key, string regionName = null) { if (IsDisposed) { return null; } - MemoryCacheEntry entry = RemoveEntry(key, null, CacheEntryRemovedReason.Removed); + MemoryCacheEntry entry = RemoveEntry(key, null, reason); return (entry != null) ? entry.Value : null; } @@ -681,6 +694,14 @@ public override long GetCount(string regionName = null) { return count; } + public long GetLastSize(string regionName = null) { + if (regionName != null) { + throw new NotSupportedException(R.RegionName_not_supported); + } + + return _stats.GetLastSize(); + } + [SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Justification="This is assembly is a special case approved by the NetFx API review board")] public override IDictionary GetValues(IEnumerable keys, string regionName = null) { if (regionName != null) { diff --git a/System.Runtime.Caching/System/Caching/MemoryCacheStatistics.cs b/System.Runtime.Caching/System/Caching/MemoryCacheStatistics.cs index 99196c05f..69f3e7b79 100644 --- a/System.Runtime.Caching/System/Caching/MemoryCacheStatistics.cs +++ b/System.Runtime.Caching/System/Caching/MemoryCacheStatistics.cs @@ -85,6 +85,10 @@ private void CacheManagerTimerCallback(object state) { CacheManagerThread(0); } + internal long GetLastSize() { + return this._cacheMemoryMonitor.PressureLast; + } + private int GetPercentToTrim() { int gen2Count = GC.CollectionCount(2); // has there been a Gen 2 Collection since the last trim? diff --git a/System.Runtime.DurableInstancing/System/Runtime/DurableInstancing/InstanceHandle.cs b/System.Runtime.DurableInstancing/System/Runtime/DurableInstancing/InstanceHandle.cs index 95764cc2b..fc6f606c0 100644 --- a/System.Runtime.DurableInstancing/System/Runtime/DurableInstancing/InstanceHandle.cs +++ b/System.Runtime.DurableInstancing/System/Runtime/DurableInstancing/InstanceHandle.cs @@ -89,7 +89,7 @@ private set { Fx.Assert(value != Guid.Empty, "Cannot set an empty Id."); Fx.Assert(this.id == Guid.Empty, "Cannot set Id more than once."); - Fx.Assert(!this.idIsSet, "idIsSet out of [....] with id."); + Fx.Assert(!this.idIsSet, "idIsSet out of sync with id."); this.id = value; diff --git a/System.Runtime.DurableInstancing/System/Runtime/DurableInstancing/InstancePersistenceContext.cs b/System.Runtime.DurableInstancing/System/Runtime/DurableInstancing/InstancePersistenceContext.cs index f5e657cf6..10f946682 100644 --- a/System.Runtime.DurableInstancing/System/Runtime/DurableInstancing/InstancePersistenceContext.cs +++ b/System.Runtime.DurableInstancing/System/Runtime/DurableInstancing/InstancePersistenceContext.cs @@ -1596,7 +1596,7 @@ void Cleanup(AsyncResult result, Exception exception) } finally { - Fx.AssertAndThrowFatal(this.context.Active, "Out-of-[....] between InstanceExecutionContext and ExecutionAsyncResult."); + Fx.AssertAndThrowFatal(this.context.Active, "Out-of-sync between InstanceExecutionContext and ExecutionAsyncResult."); this.context.LastAsyncResult = null; this.context.RootAsyncResult = null; diff --git a/System.Runtime.Serialization/System.Runtime.Serialization.txt b/System.Runtime.Serialization/System.Runtime.Serialization.txt index 2f8b8280a..974e29882 100644 --- a/System.Runtime.Serialization/System.Runtime.Serialization.txt +++ b/System.Runtime.Serialization/System.Runtime.Serialization.txt @@ -164,6 +164,7 @@ XmlInvalidConversion=The value '{0}' cannot be parsed as the type '{1}'. XmlInvalidConversionWithoutValue=The value cannot be parsed as the type '{0}'. XmlStartElementExpected=Start element expected. Found {0}. XmlWriterMustBeInElement=WriteState '{0}' not valid. Caller must write start element before serializing in contentOnly mode. +NonOptionalFieldMemberOnIsReferenceSerializableType={0}.{1}' is not marked with OptionalFieldAttribute, thus indicating that it must be serialized. However, '{0}' derives from a class marked with DataContractAttribute and an IsReference setting of '{2}'. It is not possible to have required data members on IsReference classes. Either decorate '{0}.{1}' with OptionalFieldAttribute, or disable the IsReference setting on the appropriate parent class. # System.Text @@ -188,25 +189,25 @@ InvalidLocalNameEmpty=The empty string is not a valid local name. ;QuotaMustBePositive=Quota must be a positive value. XmlArrayTooSmall=Array too small. XmlArrayTooSmallInput=Array too small. Length of available data must be at least {0}. -;XmlBadBOM=Unrecognized Byte Order Mark. +XmlBadBOM=Unrecognized Byte Order Mark. XmlBase64DataExpected=Base64 encoded data expected. Found {0}. -;XmlCDATAInvalidAtTopLevel=CData elements not valid at top level of an XML document. -;XmlCloseCData=']]>' not valid in text node content. +XmlCDATAInvalidAtTopLevel=CData elements not valid at top level of an XML document. +XmlCloseCData=']]>' not valid in text node content. XmlConversionOverflow=The value '{0}' cannot be represented with the type '{1}'. -;XmlDeclarationRequired=An XML declaration with an encoding is required for all non-UTF8 documents. +XmlDeclarationRequired=An XML declaration with an encoding is required for all non-UTF8 documents. XmlDeclMissingVersion=Version not found in XML declaration. -;XmlDeclMissing=An XML declaration is required for all non-UTF8 documents. -;XmlDeclNotFirst=No characters can appear before the XML declaration. +XmlDeclMissing=An XML declaration is required for all non-UTF8 documents. +XmlDeclNotFirst=No characters can appear before the XML declaration. XmlDictionaryStringIDRange=XmlDictionaryString IDs must be in the range from {0} to {1}. XmlDictionaryStringIDUndefinedSession=XmlDictionaryString ID {0} not defined in the XmlBinaryReaderSession. XmlDictionaryStringIDUndefinedStatic=XmlDictionaryString ID {0} not defined in the static dictionary. XmlDuplicateAttribute=Duplicate attribute found. Both '{0}' and '{1}' are from the namespace '{2}'. XmlEmptyNamespaceRequiresNullPrefix=The empty namespace requires a null or empty prefix. -;XmlEncodingMismatch=The encoding in the declaration '{0}' does not match the encoding of the document '{1}'. -;XmlEncodingNotSupported=XML encoding not supported. +XmlEncodingMismatch=The encoding in the declaration '{0}' does not match the encoding of the document '{1}'. +XmlEncodingNotSupported=XML encoding not supported. XmlEndElementExpected=End element '{0}' from namespace '{1}' expected. Found {2}. XmlEndElementNoOpenNodes=No corresponding start element is open. -;XmlExpectedEncoding=The expected encoding '{0}' does not match the actual encoding '{1}'. +XmlExpectedEncoding=The expected encoding '{0}' does not match the actual encoding '{1}'. XmlFoundCData=cdata '{0}' XmlFoundComment=comment '{0}' XmlFoundElement=element '{0}' from namespace '{1}' @@ -220,31 +221,31 @@ XmlFullStartElementNameExpected=Non-empty start element '{0}' expected. Found {1 XmlIDDefined=ID already defined. XmlKeyAlreadyExists=The specified key already exists in the dictionary. XmlIllegalOutsideRoot=Text cannot be written outside the root element. -;XmlInvalidBytes=Invalid byte encoding. +XmlInvalidBytes=Invalid byte encoding. XmlInvalidCharRef=Character reference not valid. XmlInvalidCommentChars=XML comments cannot contain '--' or end with '-'. XmlInvalidDeclaration=XML declaration can only be written at the beginning of the document. XmlInvalidDepth=Cannot call '{0}' while Depth is '{1}'. XmlInvalidEncoding=XML encoding must be 'UTF-8'. -;XmlInvalidFFFE=Characters with hexadecimal values 0xFFFE and 0xFFFF are not valid. +XmlInvalidFFFE=Characters with hexadecimal values 0xFFFE and 0xFFFF are not valid. XmlInvalidFormat=The input source is not correctly formatted. XmlInvalidID=ID must be >= 0. XmlInvalidOperation=The reader cannot be advanced. XmlInvalidPrefixState=A prefix cannot be defined while WriteState is '{0}'. XmlInvalidQualifiedName=Expected XML qualified name. Found '{0}'. -;XmlInvalidRootData=The data at the root level is invalid. +XmlInvalidRootData=The data at the root level is invalid. XmlInvalidStandalone='standalone' value in declaration must be 'yes' or 'no'. ;XmlInvalidStream=Stream returned by IStreamProvider cannot be null. XmlInvalidUniqueId=UniqueId cannot be zero length. XmlInvalidUTF8Bytes='{0}' contains invalid UTF8 bytes. XmlInvalidVersion=XML version must be '1.0'. XmlInvalidWriteState='{0}' cannot be called while WriteState is '{1}'. -;XmlInvalidXmlByte=The byte 0x{0} is not valid at this location. +XmlInvalidXmlByte=The byte 0x{0} is not valid at this location. XmlInvalidXmlSpace='{0}' is not a valid xml:space value. Valid values are 'default' and 'preserve'. XmlLineInfo=Line {0}, position {1}. XmlMalformedDecl=Malformed XML declaration. XmlMaxArrayLengthExceeded=The maximum array length quota ({0}) has been exceeded while reading XML data. This quota may be increased by changing the MaxArrayLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader. -#XmlMaxBytesPerReadExceeded=The 'maximum bytes per Read operation' quota ({0}) has been exceeded while reading XML data. Long element start tags (consisting of the element name, attribute names and attribute values) may trigger this quota. This quota may be increased by changing the MaxBytesPerRead property on the XmlDictionaryReaderQuotas object used when creating the XML reader. +XmlMaxBytesPerReadExceeded=The 'maximum bytes per Read operation' quota ({0}) has been exceeded while reading XML data. Long element start tags (consisting of the element name, attribute names and attribute values) may trigger this quota. This quota may be increased by changing the MaxBytesPerRead property on the XmlDictionaryReaderQuotas object used when creating the XML reader. #XmlMaxDepthExceeded=The maximum read depth ({0}) has been exceeded because XML data being read has more levels of nesting than is allowed by the quota. This quota may be increased by changing the MaxDepth property on the XmlDictionaryReaderQuotas object used when creating the XML reader. XmlMaxNameTableCharCountExceeded=The maximum nametable character count quota ({0}) has been exceeded while reading XML data. The nametable is a data structure used to store strings encountered during XML processing - long XML documents with non-repeating element names, attribute names and attribute values may trigger this quota. This quota may be increased by changing the MaxNameTableCharCount property on the XmlDictionaryReaderQuotas object used when creating the XML reader. #XmlMaxStringContentLengthExceeded=The maximum string content length quota ({0}) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader. @@ -260,13 +261,13 @@ XmlOnlySingleValue=Only a single typed value may be written inside an attribute XmlPrefixBoundToNamespace=The prefix '{0}' is bound to the namespace '{1}' and cannot be changed to '{2}'. XmlProcessingInstructionNotSupported=Processing instructions (other than the XML declaration) and DTDs are not supported. XmlReservedPrefix=Prefixes beginning with "xml" (regardless of casing) are reserved for use by XML. -;XmlSpaceBetweenAttributes=Whitespace must appear between attributes. +XmlSpaceBetweenAttributes=Whitespace must appear between attributes. XmlSpecificBindingNamespace=The namespace '{1}' can only be bound to the prefix '{0}'. XmlSpecificBindingPrefix=The prefix '{0}' can only be bound to the namespace '{1}'. XmlStartElementLocalNameNsExpected=Start element '{0}' from namespace '{1}' expected. Found {2}. XmlStartElementNameExpected=Start element '{0}' expected. Found {1}. -;XmlTagMismatch=Start element '{0}' does not match end element '{1}'. -;XmlTokenExpected=The token '{0}' was expected but found '{1}'. +XmlTagMismatch=Start element '{0}' does not match end element '{1}'. +XmlTokenExpected=The token '{0}' was expected but found '{1}'. XmlUndefinedPrefix=The prefix '{0}' is not defined. XmlUnexpectedEndElement=No matching start tag for end element. XmlUnexpectedEndOfFile=Unexpected end of file. Following elements are not closed: {0}. diff --git a/System.Runtime.Serialization/System/Runtime/Serialization/Configuration/SerializationSectionGroup.cs b/System.Runtime.Serialization/System/Runtime/Serialization/Configuration/SerializationSectionGroup.cs index 044ffea17..7b73dabbe 100644 --- a/System.Runtime.Serialization/System/Runtime/Serialization/Configuration/SerializationSectionGroup.cs +++ b/System.Runtime.Serialization/System/Runtime/Serialization/Configuration/SerializationSectionGroup.cs @@ -13,7 +13,7 @@ static public SerializationSectionGroup GetSectionGroup(Configuration config) { throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("config"); } -#pragma warning suppress 56506 // [....], config is checked above +#pragma warning suppress 56506 // Microsoft, config is checked above return (SerializationSectionGroup)config.SectionGroups[ConfigurationStrings.SectionGroupName]; } diff --git a/System.Runtime.Serialization/System/Runtime/Serialization/Json/JsonEncodingStreamWrapper.cs b/System.Runtime.Serialization/System/Runtime/Serialization/Json/JsonEncodingStreamWrapper.cs index 3f756c1dc..b8620e452 100644 --- a/System.Runtime.Serialization/System/Runtime/Serialization/Json/JsonEncodingStreamWrapper.cs +++ b/System.Runtime.Serialization/System/Runtime/Serialization/Json/JsonEncodingStreamWrapper.cs @@ -14,7 +14,7 @@ namespace System.Runtime.Serialization.Json // This wrapper does not support seek. // Supports: UTF-8, Unicode, BigEndianUnicode - // ASSUMPTION ([....]): This class will only be used for EITHER reading OR writing. It can be done, it would just mean more buffers. + // ASSUMPTION (Microsoft): This class will only be used for EITHER reading OR writing. It can be done, it would just mean more buffers. class JsonEncodingStreamWrapper : Stream { [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent" diff --git a/System.Runtime.Serialization/System/Runtime/Serialization/Json/XmlJsonWriter.cs b/System.Runtime.Serialization/System/Runtime/Serialization/Json/XmlJsonWriter.cs index 581e40aee..1f16414a4 100644 --- a/System.Runtime.Serialization/System/Runtime/Serialization/Json/XmlJsonWriter.cs +++ b/System.Runtime.Serialization/System/Runtime/Serialization/Json/XmlJsonWriter.cs @@ -25,6 +25,9 @@ class XmlJsonWriter : XmlDictionaryWriter, IXmlJsonWriterInitializer const char WHITESPACE = ' '; const char CARRIAGE_RETURN = '\r'; const char NEWLINE = '\n'; + const char BACKSPACE = '\b'; + const char FORM_FEED = '\f'; + const char HORIZONTAL_TABULATION = '\t'; const string xmlNamespace = "http://www.w3.org/XML/1998/namespace"; const string xmlnsNamespace = "http://www.w3.org/2000/xmlns/"; @@ -32,6 +35,9 @@ class XmlJsonWriter : XmlDictionaryWriter, IXmlJsonWriterInitializer + " data from being modified or leaked to other components in appdomain.")] [SecurityCritical] static BinHexEncoding binHexEncoding; + + // This array was part of a perf improvement for escaping characters < WHITESPACE. + static char[] CharacterAbbrevs; string attributeText; JsonDataType dataType; @@ -69,6 +75,57 @@ public XmlJsonWriter(bool indent, string indentChars) this.indentChars = indentChars; } InitializeWriter(); + + if (CharacterAbbrevs == null) + { + CharacterAbbrevs = GetCharacterAbbrevs(); + } + } + + private static char[] GetCharacterAbbrevs() + { + var abbrevs = new char[WHITESPACE]; + for(int i = 0; i < WHITESPACE; i++) + { + char abbrev; + if (!LocalAppContextSwitches.DoNotUseEcmaScriptV6EscapeControlCharacter && TryEscapeControlCharacter((char)i, out abbrev)) + { + abbrevs[i] = abbrev; + } + else + { + abbrevs[i] = (char) 0; + } + } + + return abbrevs; + } + + private static bool TryEscapeControlCharacter(char ch, out char abbrev) + { + switch (ch) + { + case BACKSPACE: + abbrev = 'b'; + break; + case HORIZONTAL_TABULATION: + abbrev = 't'; + break; + case NEWLINE: + abbrev = 'n'; + break; + case FORM_FEED: + abbrev = 'f'; + break; + case CARRIAGE_RETURN: + abbrev = 'r'; + break; + default: + abbrev = ' '; + return false; + } + + return true; } enum JsonDataType @@ -792,7 +849,7 @@ public override void WriteRaw(char[] buffer, int index, int count) WriteString(new string(buffer, index, count)); } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase")] // [....], ToLowerInvariant is just used in Json error message + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase")] // Microsoft, ToLowerInvariant is just used in Json error message public override void WriteStartAttribute(string prefix, string localName, string ns) { if (IsClosed) @@ -1374,7 +1431,7 @@ void ThrowIfServerTypeWritten(string dataTypeSpecified) } } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase")] // [....], ToLowerInvariant is just used in Json error message + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase")] // Microsoft, ToLowerInvariant is just used in Json error message void ThrowInvalidAttributeContent() { if (HasOpenAttribute) @@ -1448,7 +1505,7 @@ unsafe void WriteEscapedJsonString(string str) { char ch = chars[j]; if (ch <= FORWARD_SLASH) - { + { if (ch == FORWARD_SLASH || ch == JsonGlobals.QuoteChar) { nodeWriter.WriteChars(chars + i, j - i); @@ -1460,9 +1517,17 @@ unsafe void WriteEscapedJsonString(string str) { nodeWriter.WriteChars(chars + i, j - i); nodeWriter.WriteText(BACK_SLASH); - nodeWriter.WriteText('u'); - nodeWriter.WriteText(string.Format(CultureInfo.InvariantCulture, "{0:x4}", (int)ch)); - i = j + 1; + if (CharacterAbbrevs[ch] == 0) + { + nodeWriter.WriteText('u'); + nodeWriter.WriteText(string.Format(CultureInfo.InvariantCulture, "{0:x4}", (int)ch)); + i = j + 1; + } + else + { + nodeWriter.WriteText(CharacterAbbrevs[ch]); + i = j + 1; + } } } else if (ch == BACK_SLASH) diff --git a/System.Runtime.Serialization/System/Xml/EncodingStreamWrapper.cs b/System.Runtime.Serialization/System/Xml/EncodingStreamWrapper.cs index bea64bce4..b0a6487fc 100644 --- a/System.Runtime.Serialization/System/Xml/EncodingStreamWrapper.cs +++ b/System.Runtime.Serialization/System/Xml/EncodingStreamWrapper.cs @@ -11,9 +11,9 @@ namespace System.Xml // This wrapper does not support seek. // Constructors consume/emit byte order mark. // Supports: UTF-8, Unicode, BigEndianUnicode - // ASSUMPTION ([....]): This class will only be used for EITHER reading OR writing. It can be done, it would just mean more buffers. - // ASSUMPTION ([....]): The byte buffer is large enough to hold the declaration - // ASSUMPTION ([....]): The buffer manipulation methods (FillBuffer/Compare/etc.) will only be used to parse the declaration + // ASSUMPTION (Microsoft): This class will only be used for EITHER reading OR writing. It can be done, it would just mean more buffers. + // ASSUMPTION (Microsoft): The byte buffer is large enough to hold the declaration + // ASSUMPTION (Microsoft): The buffer manipulation methods (FillBuffer/Compare/etc.) will only be used to parse the declaration // during construction. class EncodingStreamWrapper : Stream { @@ -749,7 +749,7 @@ public override void SetLength(long value) // Add format exceptions // Do we need to modify the stream position/Seek to account for the buffer? - // ASSUMPTION ([....]): This class will only be used for EITHER reading OR writing. + // ASSUMPTION (Microsoft): This class will only be used for EITHER reading OR writing. #if NO class UTF16Stream : Stream { diff --git a/System.Runtime.Serialization/System/Xml/UniqueID.cs b/System.Runtime.Serialization/System/Xml/UniqueID.cs index 2db9f63d6..53fe8347c 100644 --- a/System.Runtime.Serialization/System/Xml/UniqueID.cs +++ b/System.Runtime.Serialization/System/Xml/UniqueID.cs @@ -352,7 +352,7 @@ unsafe public override string ToString() if (object.ReferenceEquals(id1, null) || object.ReferenceEquals(id2, null)) return false; -#pragma warning suppress 56506 // [....], checks for whether id1 and id2 are null done above. +#pragma warning suppress 56506 // Microsoft, checks for whether id1 and id2 are null done above. if (id1.IsGuid && id2.IsGuid) { return id1.idLow == id2.idLow && id1.idHigh == id2.idHigh; diff --git a/System.Runtime.Serialization/System/Xml/ValueHandle.cs b/System.Runtime.Serialization/System/Xml/ValueHandle.cs index 74313dec9..5d18e55fe 100644 --- a/System.Runtime.Serialization/System/Xml/ValueHandle.cs +++ b/System.Runtime.Serialization/System/Xml/ValueHandle.cs @@ -539,7 +539,7 @@ public string GetString() } } - // ASSUMPTION ([....]): all chars in str will be ASCII + // ASSUMPTION (Microsoft): all chars in str will be ASCII public bool Equals2(string str, bool checkLower) { if (this.type != ValueHandleType.UTF8) diff --git a/System.Runtime.Serialization/System/Xml/XmlBaseReader.cs b/System.Runtime.Serialization/System/Xml/XmlBaseReader.cs index 008ed195f..f92e4af74 100644 --- a/System.Runtime.Serialization/System/Xml/XmlBaseReader.cs +++ b/System.Runtime.Serialization/System/Xml/XmlBaseReader.cs @@ -1,8 +1,8 @@ //------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------ -// PERF, [....], [....]: Make LookupNamespace do something smarter when lots of names -// PERF, [....], [....]: Make Attribute lookup smarter when lots of attributes +// PERF, Microsoft, Microsoft: Make LookupNamespace do something smarter when lots of names +// PERF, Microsoft, Microsoft: Make Attribute lookup smarter when lots of attributes namespace System.Xml { using System; diff --git a/System.Runtime.Serialization/System/Xml/XmlConverter.cs b/System.Runtime.Serialization/System/Xml/XmlConverter.cs index 3497ba645..3f683a495 100644 --- a/System.Runtime.Serialization/System/Xml/XmlConverter.cs +++ b/System.Runtime.Serialization/System/Xml/XmlConverter.cs @@ -1,9 +1,9 @@ //------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------ -// PERF, [....], [....]: Make LookupNamespace do something smarter when lots of names -// PERF, [....], [....]: Make Attribute lookup smarter when lots of attributes -// PERF: [....], [....]: Compare safe/unsafe versions +// PERF, Microsoft, Microsoft: Make LookupNamespace do something smarter when lots of names +// PERF, Microsoft, Microsoft: Make Attribute lookup smarter when lots of attributes +// PERF: Microsoft, Microsoft: Compare safe/unsafe versions namespace System.Xml { diff --git a/System.Runtime.Serialization/System/Xml/XmlDictionaryWriter.cs b/System.Runtime.Serialization/System/Xml/XmlDictionaryWriter.cs index bfb1b2a98..3868664cd 100644 --- a/System.Runtime.Serialization/System/Xml/XmlDictionaryWriter.cs +++ b/System.Runtime.Serialization/System/Xml/XmlDictionaryWriter.cs @@ -145,7 +145,7 @@ public virtual void WriteXmlnsAttribute(string prefix, string namespaceUri) { if (LookupPrefix(namespaceUri) != null) return; -#pragma warning suppress 56506 // [....], namespaceUri is already checked +#pragma warning suppress 56506 // Microsoft, namespaceUri is already checked prefix = namespaceUri.Length == 0 ? string.Empty : string.Concat("d", namespaceUri.Length.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)); } WriteAttributeString("xmlns", prefix, null, namespaceUri); @@ -196,7 +196,7 @@ public virtual void WriteQualifiedName(XmlDictionaryString localName, XmlDiction throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName")); if (namespaceUri == null) namespaceUri = XmlDictionaryString.Empty; -#pragma warning suppress 56506 // [....], XmlDictionaryString.Empty is never null +#pragma warning suppress 56506 // Microsoft, XmlDictionaryString.Empty is never null WriteQualifiedName(localName.Value, namespaceUri.Value); } @@ -301,7 +301,7 @@ void CompleteAndReleaseStream(bool completedSynchronously, Exception completionE { if (completionException == null) { - // only release stream when no exception (mirrors [....] behaviour) + // only release stream when no exception (mirrors sync behaviour) this.streamProvider.ReleaseStream(this.stream); this.stream = null; } @@ -311,7 +311,7 @@ void CompleteAndReleaseStream(bool completedSynchronously, Exception completionE void ContinueWork(bool completedSynchronously, Exception completionException = null) { - // Individual Reads or writes may complete [....] or async. A callback however + // Individual Reads or writes may complete sync or async. A callback however // will always all ContinueWork() with CompletedSynchronously=false this flag // is used to complete this AsyncResult. try @@ -565,7 +565,7 @@ void CompleteAndReleaseStream(bool completedSynchronously, Exception completionE { if (completionException == null) { - // only release stream when no exception (mirrors [....] behaviour) + // only release stream when no exception (mirrors sync behaviour) this.streamProvider.ReleaseStream(this.stream); this.stream = null; } @@ -582,7 +582,7 @@ bool ContinueWork(IAsyncResult result) { if (HandleReadBlock(result)) { - // Read completed ([....] or async, doesn't matter) + // Read completed (sync or async, doesn't matter) if (this.bytesRead > 0) { // allow loop to continue at Write @@ -604,7 +604,7 @@ bool ContinueWork(IAsyncResult result) { if (this.writeBlockHandler(result, this)) { - // Write completed ([....] or async, doesn't matter) + // Write completed (sync or async, doesn't matter) AdjustBlockSize(); operation = Operation.Read; } diff --git a/System.Runtime.Serialization/System/Xml/XmlMtomReader.cs b/System.Runtime.Serialization/System/Xml/XmlMtomReader.cs index 69831c0d8..1c5fd2c4c 100644 --- a/System.Runtime.Serialization/System/Xml/XmlMtomReader.cs +++ b/System.Runtime.Serialization/System/Xml/XmlMtomReader.cs @@ -2102,7 +2102,7 @@ public override bool CanWrite public override long Length { -#pragma warning suppress 56503 // [....], required by the XmlReader +#pragma warning suppress 56503 // Microsoft, required by the XmlReader get { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupportedOnStream, this.GetType().FullName))); } } @@ -2110,7 +2110,7 @@ public override long Position { get { -#pragma warning suppress 56503 // [....], required by the XmlReader +#pragma warning suppress 56503 // Microsoft, required by the XmlReader throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupportedOnStream, this.GetType().FullName))); } set { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupportedOnStream, this.GetType().FullName))); } @@ -2831,7 +2831,7 @@ public override long Length { get { -#pragma warning suppress 56503 // [....], required by the Stream contract +#pragma warning suppress 56503 // Microsoft, required by the Stream contract throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupportedOnStream, stream.GetType().FullName))); } } @@ -2840,7 +2840,7 @@ public override long Position { get { -#pragma warning suppress 56503 // [....], required by the Stream contract +#pragma warning suppress 56503 // Microsoft, required by the Stream contract throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupportedOnStream, stream.GetType().FullName))); } set diff --git a/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/BufferedReceiveManager.cs b/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/BufferedReceiveManager.cs index e8670e2a0..b240804d4 100644 --- a/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/BufferedReceiveManager.cs +++ b/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/BufferedReceiveManager.cs @@ -83,7 +83,7 @@ public bool BufferReceive(OperationContext operationContext, ReceiveContext rece // Actual Buffering lock (this.thisLock) { - // Optimistic state check in case we just ----d with the receiveContext + // Optimistic state check in case we just raced with the receiveContext // faulting. If the receiveContext still faults after the state check, the above // cleanup routine will handle things correctly. In both cases, a double-release // of the throttle is protected. diff --git a/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/DurableInstanceManager.cs b/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/DurableInstanceManager.cs index 2ff32b65c..198c51157 100644 --- a/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/DurableInstanceManager.cs +++ b/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/DurableInstanceManager.cs @@ -1323,7 +1323,7 @@ static void Finally(AsyncResult result, Exception exception) // This async result waits for store events and handle them (currently only support HasRunnableWorkflowEvent). // It is intended to always complete async to simplify caller usage. - // 1) no code to handle [....] completion. + // 1) no code to handle sync completion. // 2) recursive call will be safe from StackOverflow. // For simplicity, we handle (load/run) each event one-by-one. // We ---- certain set of exception (see HandleException). Other will crash the process. diff --git a/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/PersistenceContext.cs b/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/PersistenceContext.cs index eb135add2..96a92a8fe 100644 --- a/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/PersistenceContext.cs +++ b/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/PersistenceContext.cs @@ -102,7 +102,7 @@ internal PersistenceContext(PersistenceProviderDirectory directory, InstanceStor ReadSuspendedInfo(view); } - // If we were loaded or we locked the instance, the keys will have been [....]'d. + // If we were loaded or we locked the instance, the keys will have been sync'd. if (IsInitialized || IsLocked) { RationalizeSavedKeys(false); diff --git a/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/PersistenceProviderDirectory.cs b/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/PersistenceProviderDirectory.cs index ed99706cb..126936ab2 100644 --- a/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/PersistenceProviderDirectory.cs +++ b/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/PersistenceProviderDirectory.cs @@ -1178,7 +1178,7 @@ bool Finish() this.pipeline.Publish(); } - // PersistenceContext.Open doesn't do anything, so it's ok to call [....]. + // PersistenceContext.Open doesn't do anything, so it's ok to call sync. this.context.Open(TimeSpan.Zero); IAsyncResult result; diff --git a/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/WorkflowServiceInstance.cs b/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/WorkflowServiceInstance.cs index e5ea1459f..539cdf580 100644 --- a/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/WorkflowServiceInstance.cs +++ b/System.ServiceModel.Activities/System/ServiceModel/Activities/Dispatcher/WorkflowServiceInstance.cs @@ -42,7 +42,7 @@ namespace System.ServiceModel.Activities.Dispatcher // NOTE: There is a small period of time where no one things they own the lock. Exit has "handed // off the lock by calling Set on the waiter, but the waiter has not yet executed the code // which sets ownsLock to true. - // [....] Handoff - During [....] handoff the ref bool ownsLock will be set accordingly by the + // Sync Handoff - During sync handoff the ref bool ownsLock will be set accordingly by the // Acquire* method. These methods should always be called in a try block with a finally // which calls ReleaseLock. // Async Handoff - During async handoff the callback can assume it has the lock if either @@ -655,12 +655,12 @@ bool CleanupIdleWaiter(AsyncWaitHandle idleEvent, Exception waitException, ref b { if (!this.idleWaiters.Remove(idleEvent)) { - // If it wasn't in the list that means we ----d between throwing from Wait + // If it wasn't in the list that means we raced between throwing from Wait // and setting the event. This thread now is responsible for the lock. if (waitException is TimeoutException) { // In the case of Timeout we let setting the event win and signal to - // ---- the exception + // swallow the exception ownsLock = true; return false; @@ -814,7 +814,7 @@ void ReleaseLock(ref bool ownsLock, bool hasBeenPersistedByIdlePolicy) if (!this.executorLock.Exit(isRunnable, ref ownsLock)) { // No one was waiting, but we had activeOperations (otherwise we would not have gotten - // to this branch of the if). This means that we ----d with a timeout and should resume + // to this branch of the if). This means that we raced with a timeout and should resume // the workflow's execution. If we don't resume execution we'll just hang ... no one // has the lock, the workflow is ready to execute, but it is not. Fx.Assert(this.activeOperations > 0, "We should always have active operations otherwise we should have taken a different code path."); @@ -3268,7 +3268,7 @@ static void OnNextIdle(object state, TimeoutException asyncException) { // If the waitHandle is not in either of these lists then it must have // been removed by the Set() path - that means we've got the lock, so let's - // just run with it (IE - ---- the exception). + // just run with it (IE - swallow the exception). if (thisPtr.instance.nextIdleWaiters.Remove(thisPtr.waitHandle) || thisPtr.instance.idleWaiters.Remove(thisPtr.waitHandle)) { thisPtr.Complete(false, asyncException); @@ -5311,7 +5311,7 @@ static void OnAsyncWaiterSignaled(object state, TimeoutException asyncException) { if (!asyncWaiter.Owner.waiters.Remove(asyncWaiter.Token)) { - // We ----d between timing out and getting signaled. + // We raced between timing out and getting signaled. // We'll take the signal which means we now own the lock completionException = null; @@ -5604,7 +5604,7 @@ public bool TryBeginComplete(AsyncCallback callback, object state, out IAsyncRes { // In the interest of allocating less objects we don't implement // the full async pattern here. Instead, we've flattened it to - // do the [....] part and then optionally delegate down to the inner + // do the sync part and then optionally delegate down to the inner // BeginCommit. if (this.contextOwnedTransaction != null) { diff --git a/System.ServiceModel.Activities/System/ServiceModel/Activities/InternalSendMessage.cs b/System.ServiceModel.Activities/System/ServiceModel/Activities/InternalSendMessage.cs index 835190494..ffbe82df4 100644 --- a/System.ServiceModel.Activities/System/ServiceModel/Activities/InternalSendMessage.cs +++ b/System.ServiceModel.Activities/System/ServiceModel/Activities/InternalSendMessage.cs @@ -1830,7 +1830,7 @@ bool BeginSendMessage() { if (asyncSend) { - //If there is a transaction that we could be flowing out then we create this blocking clone to [....] with the commit processing. + //If there is a transaction that we could be flowing out then we create this blocking clone to sync with the commit processing. if (this.currentTransactionContext != null) { this.dependentClone = this.currentTransactionContext.DependentClone(DependentCloneOption.BlockCommitUntilComplete); @@ -2664,9 +2664,9 @@ public FinalizeCorrelationAsyncResult(MessageCorrelationCallbackMessageProperty property.Instance.CorrelationSynchronizer.NotifyRequestSetByChannel(new Action(OnWorkflowCorrelationProcessingComplete)); // We have to do this dance with the lock because - // we aren't sure if we've been running [....] or not. + // we aren't sure if we've been running sync or not. // NOTE: It is possible for us to go async and - // still decide we're completing [....]. This is fine + // still decide we're completing sync. This is fine // as it does not violate the async pattern since // the work is done by the time Begin completes. completeSelf = false; @@ -2697,9 +2697,9 @@ void OnWorkflowCorrelationProcessingComplete(Message updatedMessage) this.message = updatedMessage; // We have to do this dance with the lock because - // we aren't sure if we've been running [....] or not. + // we aren't sure if we've been running sync or not. // NOTE: It is possible for us to go async and - // still decide we're completing [....]. This is fine + // still decide we're completing sync. This is fine // as it does not violate the async pattern since // the work is done by the time Begin completes. bool completeSelf = false; diff --git a/System.ServiceModel.Channels/System/ServiceModel/Channels/UdpChannelBase.cs b/System.ServiceModel.Channels/System/ServiceModel/Channels/UdpChannelBase.cs index bd420a64d..6e0f45677 100644 --- a/System.ServiceModel.Channels/System/ServiceModel/Channels/UdpChannelBase.cs +++ b/System.ServiceModel.Channels/System/ServiceModel/Channels/UdpChannelBase.cs @@ -481,7 +481,7 @@ private bool BeginCloseOutputChannel() // AsyncResult.AsyncCompletionWrapperCallback takes care of catching the exceptions for us. IAsyncResult result = this.channel.UdpOutputChannel.BeginClose(this.timeoutHelper.RemainingTime(), this.PrepareAsyncCompletion(completeCloseOutputChannelCallback), this); - // SyncContinue calls CompleteCloseOutputChannel for us in [....] case. + // SyncContinue calls CompleteCloseOutputChannel for us in sync case. return this.SyncContinue(result); } @@ -490,7 +490,7 @@ private bool BeginBaseClose() // AsyncResult.AsyncCompletionWrapperCallback takes care of catching the exceptions for us. IAsyncResult result = this.baseBeginClose(this.timeoutHelper.RemainingTime(), this.PrepareAsyncCompletion(completeBaseCloseCallback), this); - // SyncContinue calls CompleteBaseClose for us in [....] case. + // SyncContinue calls CompleteBaseClose for us in sync case. return this.SyncContinue(result); } } diff --git a/System.ServiceModel.Channels/System/ServiceModel/Channels/UdpOutputChannel.cs b/System.ServiceModel.Channels/System/ServiceModel/Channels/UdpOutputChannel.cs index 2a932ecbe..ebc66d5ea 100644 --- a/System.ServiceModel.Channels/System/ServiceModel/Channels/UdpOutputChannel.cs +++ b/System.ServiceModel.Channels/System/ServiceModel/Channels/UdpOutputChannel.cs @@ -664,7 +664,7 @@ public SendAsyncResult(UdpOutputChannel channel, Message message, TimeSpan timeo if (completedSynchronously && this.retransmissionEnabled) { - // initial send completed [....], now we need to start the retransmission process... + // initial send completed sync, now we need to start the retransmission process... completedSynchronously = this.BeginRetransmission(); } diff --git a/System.ServiceModel.Discovery/System/ServiceModel/Discovery/AnnouncementService.cs b/System.ServiceModel.Discovery/System/ServiceModel/Discovery/AnnouncementService.cs index 89dd02a9a..f464d031e 100644 --- a/System.ServiceModel.Discovery/System/ServiceModel/Discovery/AnnouncementService.cs +++ b/System.ServiceModel.Discovery/System/ServiceModel/Discovery/AnnouncementService.cs @@ -46,7 +46,7 @@ public AnnouncementService(int duplicateMessageHistoryLength) void IAnnouncementContractApril2005.HelloOperation(HelloMessageApril2005 message) { - Fx.Assert("The [....] method IAnnouncementContractApril2005.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContractApril2005.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContractApril2005.BeginHelloOperation(HelloMessageApril2005 message, AsyncCallback callback, object state) @@ -61,7 +61,7 @@ void IAnnouncementContractApril2005.EndHelloOperation(IAsyncResult result) void IAnnouncementContractApril2005.ByeOperation(ByeMessageApril2005 message) { - Fx.Assert("The [....] method IAnnouncementContractApril2005.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContractApril2005.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContractApril2005.BeginByeOperation(ByeMessageApril2005 message, AsyncCallback callback, object state) @@ -76,7 +76,7 @@ void IAnnouncementContractApril2005.EndByeOperation(IAsyncResult result) void IAnnouncementContract11.HelloOperation(HelloMessage11 message) { - Fx.Assert("The [....] method IAnnouncementContract11.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContract11.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContract11.BeginHelloOperation(HelloMessage11 message, AsyncCallback callback, object state) @@ -91,7 +91,7 @@ void IAnnouncementContract11.EndHelloOperation(IAsyncResult result) void IAnnouncementContract11.ByeOperation(ByeMessage11 message) { - Fx.Assert("The [....] method IAnnouncementContract11.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContract11.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContract11.BeginByeOperation(ByeMessage11 message, AsyncCallback callback, object state) @@ -106,7 +106,7 @@ void IAnnouncementContract11.EndByeOperation(IAsyncResult result) void IAnnouncementContractCD1.HelloOperation(HelloMessageCD1 message) { - Fx.Assert("The [....] method IAnnouncementContractCD1.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContractCD1.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContractCD1.BeginHelloOperation(HelloMessageCD1 message, AsyncCallback callback, object state) @@ -121,7 +121,7 @@ void IAnnouncementContractCD1.EndHelloOperation(IAsyncResult result) void IAnnouncementContractCD1.ByeOperation(ByeMessageCD1 message) { - Fx.Assert("The [....] method IAnnouncementContractCD1.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContractCD1.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContractCD1.BeginByeOperation(ByeMessageCD1 message, AsyncCallback callback, object state) diff --git a/System.ServiceModel.Discovery/System/ServiceModel/Discovery/DiscoveryProxy.cs b/System.ServiceModel.Discovery/System/ServiceModel/Discovery/DiscoveryProxy.cs index 8b32eb3d7..7f2946925 100644 --- a/System.ServiceModel.Discovery/System/ServiceModel/Discovery/DiscoveryProxy.cs +++ b/System.ServiceModel.Discovery/System/ServiceModel/Discovery/DiscoveryProxy.cs @@ -65,7 +65,7 @@ protected DiscoveryProxy( void IAnnouncementContractApril2005.HelloOperation(HelloMessageApril2005 message) { - Fx.Assert("The [....] method IAnnouncementContractApril2005.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContractApril2005.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContractApril2005.BeginHelloOperation(HelloMessageApril2005 message, AsyncCallback callback, object state) @@ -80,7 +80,7 @@ void IAnnouncementContractApril2005.EndHelloOperation(IAsyncResult result) void IAnnouncementContractApril2005.ByeOperation(ByeMessageApril2005 message) { - Fx.Assert("The [....] method IAnnouncementContractApril2005.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContractApril2005.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContractApril2005.BeginByeOperation(ByeMessageApril2005 message, AsyncCallback callback, object state) @@ -95,7 +95,7 @@ void IAnnouncementContractApril2005.EndByeOperation(IAsyncResult result) void IAnnouncementContract11.HelloOperation(HelloMessage11 message) { - Fx.Assert("The [....] method IAnnouncementContract11.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContract11.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContract11.BeginHelloOperation(HelloMessage11 message, AsyncCallback callback, object state) @@ -110,7 +110,7 @@ void IAnnouncementContract11.EndHelloOperation(IAsyncResult result) void IAnnouncementContract11.ByeOperation(ByeMessage11 message) { - Fx.Assert("The [....] method IAnnouncementContract11.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContract11.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContract11.BeginByeOperation(ByeMessage11 message, AsyncCallback callback, object state) @@ -125,7 +125,7 @@ void IAnnouncementContract11.EndByeOperation(IAsyncResult result) void IAnnouncementContractCD1.HelloOperation(HelloMessageCD1 message) { - Fx.Assert("The [....] method IAnnouncementContractCD1.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContractCD1.HelloOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContractCD1.BeginHelloOperation(HelloMessageCD1 message, AsyncCallback callback, object state) @@ -140,7 +140,7 @@ void IAnnouncementContractCD1.EndHelloOperation(IAsyncResult result) void IAnnouncementContractCD1.ByeOperation(ByeMessageCD1 message) { - Fx.Assert("The [....] method IAnnouncementContractCD1.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IAnnouncementContractCD1.ByeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IAnnouncementContractCD1.BeginByeOperation(ByeMessageCD1 message, AsyncCallback callback, object state) @@ -155,7 +155,7 @@ void IAnnouncementContractCD1.EndByeOperation(IAsyncResult result) void IDiscoveryContractApril2005.ProbeOperation(ProbeMessageApril2005 request) { - Fx.Assert("The [....] method IDiscoveryContractApril2005.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractApril2005.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractApril2005.BeginProbeOperation(ProbeMessageApril2005 request, AsyncCallback callback, object state) @@ -170,7 +170,7 @@ void IDiscoveryContractApril2005.EndProbeOperation(IAsyncResult result) void IDiscoveryContractApril2005.ResolveOperation(ResolveMessageApril2005 request) { - Fx.Assert("The [....] method IDiscoveryContractApril2005.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractApril2005.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractApril2005.BeginResolveOperation(ResolveMessageApril2005 request, AsyncCallback callback, object state) @@ -185,7 +185,7 @@ void IDiscoveryContractApril2005.EndResolveOperation(IAsyncResult result) void IDiscoveryContractAdhoc11.ProbeOperation(ProbeMessage11 request) { - Fx.Assert("The [....] method IDiscoveryContractAdhoc11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractAdhoc11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractAdhoc11.BeginProbeOperation(ProbeMessage11 request, AsyncCallback callback, object state) @@ -200,7 +200,7 @@ void IDiscoveryContractAdhoc11.EndProbeOperation(IAsyncResult result) void IDiscoveryContractAdhoc11.ResolveOperation(ResolveMessage11 request) { - Fx.Assert("The [....] method IDiscoveryContractAdhoc11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractAdhoc11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractAdhoc11.BeginResolveOperation(ResolveMessage11 request, AsyncCallback callback, object state) @@ -215,7 +215,7 @@ void IDiscoveryContractAdhoc11.EndResolveOperation(IAsyncResult result) ProbeMatchesMessage11 IDiscoveryContractManaged11.ProbeOperation(ProbeMessage11 request) { - Fx.Assert("The [....] method IDiscoveryContractManaged11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractManaged11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); return null; } @@ -231,7 +231,7 @@ ProbeMatchesMessage11 IDiscoveryContractManaged11.EndProbeOperation(IAsyncResult ResolveMatchesMessage11 IDiscoveryContractManaged11.ResolveOperation(ResolveMessage11 request) { - Fx.Assert("The [....] method IDiscoveryContractManaged11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractManaged11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); return null; } @@ -247,7 +247,7 @@ ResolveMatchesMessage11 IDiscoveryContractManaged11.EndResolveOperation(IAsyncRe void IDiscoveryContractAdhocCD1.ProbeOperation(ProbeMessageCD1 request) { - Fx.Assert("The [....] method IDiscoveryContractAdhocCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractAdhocCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractAdhocCD1.BeginProbeOperation(ProbeMessageCD1 request, AsyncCallback callback, object state) @@ -262,7 +262,7 @@ void IDiscoveryContractAdhocCD1.EndProbeOperation(IAsyncResult result) void IDiscoveryContractAdhocCD1.ResolveOperation(ResolveMessageCD1 request) { - Fx.Assert("The [....] method IDiscoveryContractAdhocCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractAdhocCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractAdhocCD1.BeginResolveOperation(ResolveMessageCD1 request, AsyncCallback callback, object state) @@ -277,7 +277,7 @@ void IDiscoveryContractAdhocCD1.EndResolveOperation(IAsyncResult result) ProbeMatchesMessageCD1 IDiscoveryContractManagedCD1.ProbeOperation(ProbeMessageCD1 request) { - Fx.Assert("The [....] method IDiscoveryContractManagedCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractManagedCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); return null; } @@ -293,7 +293,7 @@ ProbeMatchesMessageCD1 IDiscoveryContractManagedCD1.EndProbeOperation(IAsyncResu ResolveMatchesMessageCD1 IDiscoveryContractManagedCD1.ResolveOperation(ResolveMessageCD1 request) { - Fx.Assert("The [....] method IDiscoveryContractManagedCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractManagedCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); return null; } diff --git a/System.ServiceModel.Discovery/System/ServiceModel/Discovery/DiscoveryService.cs b/System.ServiceModel.Discovery/System/ServiceModel/Discovery/DiscoveryService.cs index b7119cb08..98adc930d 100644 --- a/System.ServiceModel.Discovery/System/ServiceModel/Discovery/DiscoveryService.cs +++ b/System.ServiceModel.Discovery/System/ServiceModel/Discovery/DiscoveryService.cs @@ -69,7 +69,7 @@ internal DiscoveryMessageSequenceGenerator MessageSequenceGenerator void IDiscoveryContractApril2005.ProbeOperation(ProbeMessageApril2005 request) { - Fx.Assert("The [....] method IDiscoveryContractApril2005.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractApril2005.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractApril2005.BeginProbeOperation(ProbeMessageApril2005 request, AsyncCallback callback, object state) @@ -84,7 +84,7 @@ void IDiscoveryContractApril2005.EndProbeOperation(IAsyncResult result) void IDiscoveryContractApril2005.ResolveOperation(ResolveMessageApril2005 request) { - Fx.Assert("The [....] method IDiscoveryContractApril2005.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractApril2005.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractApril2005.BeginResolveOperation(ResolveMessageApril2005 request, AsyncCallback callback, object state) @@ -99,7 +99,7 @@ void IDiscoveryContractApril2005.EndResolveOperation(IAsyncResult result) void IDiscoveryContractAdhoc11.ProbeOperation(ProbeMessage11 request) { - Fx.Assert("The [....] method IDiscoveryContractAdhoc11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractAdhoc11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractAdhoc11.BeginProbeOperation(ProbeMessage11 request, AsyncCallback callback, object state) @@ -114,7 +114,7 @@ void IDiscoveryContractAdhoc11.EndProbeOperation(IAsyncResult result) void IDiscoveryContractAdhoc11.ResolveOperation(ResolveMessage11 request) { - Fx.Assert("The [....] method IDiscoveryContractAdhoc11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractAdhoc11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractAdhoc11.BeginResolveOperation(ResolveMessage11 request, AsyncCallback callback, object state) @@ -129,7 +129,7 @@ void IDiscoveryContractAdhoc11.EndResolveOperation(IAsyncResult result) ProbeMatchesMessage11 IDiscoveryContractManaged11.ProbeOperation(ProbeMessage11 request) { - Fx.Assert("The [....] method IDiscoveryContractManaged11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractManaged11.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); return null; } @@ -145,7 +145,7 @@ ProbeMatchesMessage11 IDiscoveryContractManaged11.EndProbeOperation(IAsyncResult ResolveMatchesMessage11 IDiscoveryContractManaged11.ResolveOperation(ResolveMessage11 request) { - Fx.Assert("The [....] method IDiscoveryContractManaged11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractManaged11.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); return null; } @@ -162,7 +162,7 @@ ResolveMatchesMessage11 IDiscoveryContractManaged11.EndResolveOperation(IAsyncRe void IDiscoveryContractAdhocCD1.ProbeOperation(ProbeMessageCD1 request) { - Fx.Assert("The [....] method IDiscoveryContractAdhocCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractAdhocCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractAdhocCD1.BeginProbeOperation(ProbeMessageCD1 request, AsyncCallback callback, object state) @@ -177,7 +177,7 @@ void IDiscoveryContractAdhocCD1.EndProbeOperation(IAsyncResult result) void IDiscoveryContractAdhocCD1.ResolveOperation(ResolveMessageCD1 request) { - Fx.Assert("The [....] method IDiscoveryContractAdhocCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractAdhocCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); } IAsyncResult IDiscoveryContractAdhocCD1.BeginResolveOperation(ResolveMessageCD1 request, AsyncCallback callback, object state) @@ -192,7 +192,7 @@ void IDiscoveryContractAdhocCD1.EndResolveOperation(IAsyncResult result) ProbeMatchesMessageCD1 IDiscoveryContractManagedCD1.ProbeOperation(ProbeMessageCD1 request) { - Fx.Assert("The [....] method IDiscoveryContractManagedCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractManagedCD1.ProbeOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); return null; } @@ -208,7 +208,7 @@ ProbeMatchesMessageCD1 IDiscoveryContractManagedCD1.EndProbeOperation(IAsyncResu ResolveMatchesMessageCD1 IDiscoveryContractManagedCD1.ResolveOperation(ResolveMessageCD1 request) { - Fx.Assert("The [....] method IDiscoveryContractManagedCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); + Fx.Assert("The sync method IDiscoveryContractManagedCD1.ResolveOperation must not get invoked. It is marked with PreferAsyncInvocation flag."); return null; } diff --git a/System.ServiceModel.Internals/System/Runtime/AsyncResult.cs b/System.ServiceModel.Internals/System/Runtime/AsyncResult.cs index 652bb8721..996b8bece 100644 --- a/System.ServiceModel.Internals/System/Runtime/AsyncResult.cs +++ b/System.ServiceModel.Internals/System/Runtime/AsyncResult.cs @@ -402,7 +402,7 @@ protected static TAsyncResult End(IAsyncResult result) return asyncResult; } - // can be utilized by subclasses to write core completion code for both the [....] and async paths + // can be utilized by subclasses to write core completion code for both the sync and async paths // in one location, signalling chainable synchronous completion with the boolean result, // and leveraging PrepareAsyncCompletion for conversion to an AsyncCallback. // NOTE: requires that "this" is passed in as the state object to the asynchronous sub-call being used with a completion routine. diff --git a/System.ServiceModel.Internals/System/Runtime/Diagnostics/DiagnosticTraceBase.cs b/System.ServiceModel.Internals/System/Runtime/Diagnostics/DiagnosticTraceBase.cs index 5089c8727..b05c6e8fb 100644 --- a/System.ServiceModel.Internals/System/Runtime/Diagnostics/DiagnosticTraceBase.cs +++ b/System.ServiceModel.Internals/System/Runtime/Diagnostics/DiagnosticTraceBase.cs @@ -482,7 +482,7 @@ void ShutdownTracing() { OnShutdownTracing(); } -#pragma warning suppress 56500 //[....]; Taken care of by FxCop +#pragma warning suppress 56500 //Microsoft; Taken care of by FxCop catch (Exception exception) { if (Fx.IsFatal(exception)) diff --git a/System.ServiceModel.Internals/System/Runtime/Diagnostics/EtwDiagnosticTrace.cs b/System.ServiceModel.Internals/System/Runtime/Diagnostics/EtwDiagnosticTrace.cs index c84160682..bc881d88f 100644 --- a/System.ServiceModel.Internals/System/Runtime/Diagnostics/EtwDiagnosticTrace.cs +++ b/System.ServiceModel.Internals/System/Runtime/Diagnostics/EtwDiagnosticTrace.cs @@ -15,6 +15,7 @@ namespace System.Runtime.Diagnostics using System.Xml.XPath; using System.Diagnostics.CodeAnalysis; using System.Security.Permissions; + using System.ServiceModel.Internals; using System.Collections.Generic; using System.Collections.Concurrent; @@ -29,6 +30,7 @@ sealed class EtwDiagnosticTrace : DiagnosticTraceBase const string DiagnosticTraceSource = "System.ServiceModel.Diagnostics"; const int XmlBracketsLength = 5; // "<>".Length; + const int XmlBracketsLengthForNullValue = 4; // "< />".Length; (Empty XML Element) static readonly public Guid ImmutableDefaultEtwProviderId = new Guid("{c651f5f6-1c0d-492e-8ae1-b4efd7c9d503}"); [Fx.Tag.SecurityNote(Critical = "provider Id to create EtwProvider, which is SecurityCritical")] @@ -891,7 +893,19 @@ static bool WriteStartElement(XmlTextWriter xml, string localName, ref int remai static bool WriteXmlElementString(XmlTextWriter xml, string localName, string value, ref int remainingLength) { - int xmlElementLength = (localName.Length * 2) + EtwDiagnosticTrace.XmlBracketsLength + value.Length; + int xmlElementLength; + + // Quirk to fix DevDiv 155469: All previous versions of that platform (up-to 4.6.2) will get the old behavior (throw null ref when Exception Message property is null) + if (string.IsNullOrEmpty(value) && !LocalAppContextSwitches.IncludeNullExceptionMessageInETWTrace) + { + xmlElementLength = localName.Length + EtwDiagnosticTrace.XmlBracketsLengthForNullValue; + } + + else + { + xmlElementLength = (localName.Length * 2) + EtwDiagnosticTrace.XmlBracketsLength + value.Length; + } + if (xmlElementLength <= remainingLength) { xml.WriteElementString(localName, value); diff --git a/System.ServiceModel.Internals/System/Runtime/MruCache.cs b/System.ServiceModel.Internals/System/Runtime/MruCache.cs index 91555c98f..dada2897f 100644 --- a/System.ServiceModel.Internals/System/Runtime/MruCache.cs +++ b/System.ServiceModel.Internals/System/Runtime/MruCache.cs @@ -60,7 +60,7 @@ public void Add(TKey key, TValue value) Fx.Assert(null != key, ""); // if anything goes wrong (duplicate entry, etc) we should - // clear our caches so that we don't get out of [....] + // clear our caches so that we don't get out of sync bool success = false; try { diff --git a/System.ServiceModel.Internals/System/Runtime/ThreadNeutralSemaphore.cs b/System.ServiceModel.Internals/System/Runtime/ThreadNeutralSemaphore.cs index 814d7819b..054e0504f 100644 --- a/System.ServiceModel.Internals/System/Runtime/ThreadNeutralSemaphore.cs +++ b/System.ServiceModel.Internals/System/Runtime/ThreadNeutralSemaphore.cs @@ -105,7 +105,7 @@ static void OnEnteredAsync(object state, TimeoutException exception) { if (!thisPtr.RemoveWaiter(data.Waiter)) { - // The timeout ----d with Exit and exit won. + // The timeout raced with Exit and exit won. // We've successfully entered. exceptionToPropagate = null; } @@ -160,7 +160,7 @@ public bool TryEnter(TimeSpan timeout) if (timedOut && !RemoveWaiter(waiter)) { - // The timeout ----d with Exit and exit won. + // The timeout raced with Exit and exit won. // We've successfully entered. timedOut = false; diff --git a/System.ServiceModel.Internals/System/Runtime/TraceLevelHelper.cs b/System.ServiceModel.Internals/System/Runtime/TraceLevelHelper.cs index 2098afd1b..9eaf540e6 100644 --- a/System.ServiceModel.Internals/System/Runtime/TraceLevelHelper.cs +++ b/System.ServiceModel.Internals/System/Runtime/TraceLevelHelper.cs @@ -10,7 +10,7 @@ namespace System.Runtime using System.Diagnostics; /// - /// [....] (11/15/10, CSDMain 194940) - Previously, this code first checked that the opcode was set to informational. If not, it would check + /// Microsoft (11/15/10, CSDMain 194940) - Previously, this code first checked that the opcode was set to informational. If not, it would check /// the opcode name for start, stop, suspend, or resume and use that or return Information otherwise. This does not work well with the latest /// ETW changes where almost every event has a task and opcode. With the old logic, if an opcode is set on the event with a level such as /// warning or error, the level would be incorrectly reported in diagnostic tracing as informational. Also, start/stop/suspend/resume events diff --git a/System.ServiceModel.Routing/System/ServiceModel/Routing/RoutingService.cs b/System.ServiceModel.Routing/System/ServiceModel/Routing/RoutingService.cs index 32e9d3dcf..d136269d2 100644 --- a/System.ServiceModel.Routing/System/ServiceModel/Routing/RoutingService.cs +++ b/System.ServiceModel.Routing/System/ServiceModel/Routing/RoutingService.cs @@ -200,7 +200,7 @@ void IDisposable.Dispose() { if (this.perMessageChannels != null) { - //This is for impersonation, thus it's supposed to complete [....] + //This is for impersonation, thus it's supposed to complete sync IAsyncResult result = this.perMessageChannels.BeginClose(this.ChannelExtension.OperationTimeout, null, null); this.perMessageChannels.EndClose(result); this.perMessageChannels = null; diff --git a/System.ServiceModel.Web/System/ServiceModel/Description/WebHttpBehavior.cs b/System.ServiceModel.Web/System/ServiceModel/Description/WebHttpBehavior.cs index 7e9b5bf65..83b5943fb 100644 --- a/System.ServiceModel.Web/System/ServiceModel/Description/WebHttpBehavior.cs +++ b/System.ServiceModel.Web/System/ServiceModel/Description/WebHttpBehavior.cs @@ -116,12 +116,12 @@ public virtual void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.CrossDomainJavascriptNotsupported)); } -#pragma warning disable 56506 // [....], endpoint.Contract is never null +#pragma warning disable 56506 // Microsoft, endpoint.Contract is never null this.reflector = new XmlSerializerOperationBehavior.Reflector(endpoint.Contract.Namespace, null); foreach (OperationDescription od in endpoint.Contract.Operations) #pragma warning restore 56506 { -#pragma warning disable 56506 // [....], clientRuntime.Operations is never null +#pragma warning disable 56506 // Microsoft, clientRuntime.Operations is never null if (clientRuntime.Operations.Contains(od.Name)) #pragma warning restore 56506 { @@ -169,7 +169,7 @@ public virtual void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDisp { this.HelpUri = new UriTemplate(HelpPage.OperationListHelpPageUriTemplate).BindByPosition(endpoint.ListenUri); } -#pragma warning disable 56506 // [....], endpoint.Contract is never null +#pragma warning disable 56506 // Microsoft, endpoint.Contract is never null this.reflector = new XmlSerializerOperationBehavior.Reflector(endpoint.Contract.Namespace, null); #pragma warning restore 56506 @@ -177,12 +177,12 @@ public virtual void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDisp endpointDispatcher.AddressFilter = new PrefixEndpointAddressMessageFilter(endpoint.Address); endpointDispatcher.ContractFilter = new MatchAllMessageFilter(); // operation selector -#pragma warning disable 56506 // [....], endpointDispatcher.DispatchRuntime is never null +#pragma warning disable 56506 // Microsoft, endpointDispatcher.DispatchRuntime is never null endpointDispatcher.DispatchRuntime.OperationSelector = this.GetOperationSelector(endpoint); #pragma warning restore 56506 // unhandled operation string actionStarOperationName = null; -#pragma warning disable 56506 // [....], endpoint.Contract is never null +#pragma warning disable 56506 // Microsoft, endpoint.Contract is never null foreach (OperationDescription od in endpoint.Contract.Operations) #pragma warning restore 56506 { @@ -197,7 +197,7 @@ public virtual void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDisp { // WCF v1 installs any Action="*" op into UnhandledDispatchOperation, but WebHttpBehavior // doesn't want this, so we 'move' that operation back into normal set of operations -#pragma warning disable 56506 // [....], endpointDispatcher.DispatchRuntime.{Operations,UnhandledDispatchOperation} is never null +#pragma warning disable 56506 // Microsoft, endpointDispatcher.DispatchRuntime.{Operations,UnhandledDispatchOperation} is never null endpointDispatcher.DispatchRuntime.Operations.Add( endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation); #pragma warning restore 56506 @@ -228,7 +228,7 @@ public virtual void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDisp jsonContentType = JsonMessageEncoderFactory.GetContentType(null); } -#pragma warning disable 56506 // [....], endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation is never null +#pragma warning disable 56506 // Microsoft, endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation is never null // always install UnhandledDispatchOperation (WebHttpDispatchOperationSelector may choose not to use it) endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation = new DispatchOperation(endpointDispatcher.DispatchRuntime, "*", WildcardAction, WildcardAction); endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.DeserializeRequest = false; @@ -239,13 +239,13 @@ public virtual void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDisp foreach (OperationDescription od in endpoint.Contract.Operations) { DispatchOperation dop = null; -#pragma warning disable 56506 // [....], endpointDispatcher.DispatchRuntime, DispatchRuntime.Operations are never null +#pragma warning disable 56506 // Microsoft, endpointDispatcher.DispatchRuntime, DispatchRuntime.Operations are never null if (endpointDispatcher.DispatchRuntime.Operations.Contains(od.Name)) #pragma warning restore 56506 { dop = endpointDispatcher.DispatchRuntime.Operations[od.Name]; } -#pragma warning disable 56506 // [....], endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation is never null +#pragma warning disable 56506 // Microsoft, endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation is never null else if (endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.Name == od.Name) { dop = endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation; @@ -600,7 +600,7 @@ protected virtual IDispatchMessageFormatter GetReplyDispatchFormatter(OperationD WebMessageFormat responseFormat = GetResponseFormat(operationDescription); // Determine if we should add a json formatter; If the ResponseFormat is json, we always add the json formatter even if the - // operation is XmlSerializerFormat because the formatter constructor throws the exception: "json not valid with XmlSerializerFormat" [[....]] + // operation is XmlSerializerFormat because the formatter constructor throws the exception: "json not valid with XmlSerializerFormat" [Microsoft] bool useJson = (responseFormat == WebMessageFormat.Json || SupportsJsonFormat(operationDescription)); IDispatchMessageFormatter innerFormatter; diff --git a/System.ServiceModel.Web/System/ServiceModel/Description/WebScriptEnablingBehavior.cs b/System.ServiceModel.Web/System/ServiceModel/Description/WebScriptEnablingBehavior.cs index bfa998237..8913c7090 100644 --- a/System.ServiceModel.Web/System/ServiceModel/Description/WebScriptEnablingBehavior.cs +++ b/System.ServiceModel.Web/System/ServiceModel/Description/WebScriptEnablingBehavior.cs @@ -126,7 +126,7 @@ public override bool FaultExceptionEnabled public override void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { base.ApplyClientBehavior(endpoint, clientRuntime); -#pragma warning disable 56506 // [....], clientRuntime.MessageInspectors is never null +#pragma warning disable 56506 // Microsoft, clientRuntime.MessageInspectors is never null clientRuntime.MessageInspectors.Add(new JsonClientMessageInspector()); #pragma warning restore 56506 } @@ -142,7 +142,7 @@ public override void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDis } catch (XmlException exception) { - // [....], need to reference this resource string although fix for 13332 was removed + // Microsoft, need to reference this resource string although fix for 13332 was removed throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.InvalidXmlCharactersInNameUsedWithPOSTMethod, string.Empty, string.Empty, string.Empty), exception)); } } @@ -151,7 +151,7 @@ public override void Validate(ServiceEndpoint endpoint) { base.Validate(endpoint); -#pragma warning disable 56506 // [....], endpoint.Contract is never null +#pragma warning disable 56506 // Microsoft, endpoint.Contract is never null foreach (OperationDescription operation in endpoint.Contract.Operations) #pragma warning restore 56506 { @@ -232,7 +232,7 @@ protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, Endpoin throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( "endpointDispatcher", SR2.GetString(SR2.ChannelDispatcherMustBePresent)); } -#pragma warning disable 56506 // [....], endpointDispatcher.ChannelDispatcher.ErrorHandlers never null +#pragma warning disable 56506 // Microsoft, endpointDispatcher.ChannelDispatcher.ErrorHandlers never null endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(new JsonErrorHandler(endpoint, endpointDispatcher.ChannelDispatcher.IncludeExceptionDetailInFaults)); #pragma warning restore 56506 } diff --git a/System.ServiceModel.Web/System/ServiceModel/Dispatcher/HttpUnhandledOperationInvoker.cs b/System.ServiceModel.Web/System/ServiceModel/Dispatcher/HttpUnhandledOperationInvoker.cs index 22389d6d9..523e330f0 100644 --- a/System.ServiceModel.Web/System/ServiceModel/Dispatcher/HttpUnhandledOperationInvoker.cs +++ b/System.ServiceModel.Web/System/ServiceModel/Dispatcher/HttpUnhandledOperationInvoker.cs @@ -36,7 +36,7 @@ public object Invoke(object instance, object[] inputs, out object[] outputs) { Message message = inputs[0] as Message; outputs = null; -#pragma warning disable 56506 // [....], message.Properties is never null +#pragma warning disable 56506 // Microsoft, message.Properties is never null if (message == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( diff --git a/System.ServiceModel.Web/System/ServiceModel/Dispatcher/WebHttpDispatchOperationSelector.cs b/System.ServiceModel.Web/System/ServiceModel/Dispatcher/WebHttpDispatchOperationSelector.cs index ee73a7fd9..dba20ddce 100644 --- a/System.ServiceModel.Web/System/ServiceModel/Dispatcher/WebHttpDispatchOperationSelector.cs +++ b/System.ServiceModel.Web/System/ServiceModel/Dispatcher/WebHttpDispatchOperationSelector.cs @@ -47,7 +47,7 @@ public WebHttpDispatchOperationSelector(ServiceEndpoint endpoint) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR2.GetString(SR2.EndpointAddressCannotBeNull))); } -#pragma warning disable 56506 // [....], endpoint.Address.Uri is never null +#pragma warning disable 56506 // Microsoft, endpoint.Address.Uri is never null Uri baseUri = endpoint.Address.Uri; this.methodSpecificTables = new Dictionary(); this.templates = new Dictionary(); @@ -61,7 +61,7 @@ public WebHttpDispatchOperationSelector(ServiceEndpoint endpoint) Dictionary alreadyHaves = new Dictionary(); -#pragma warning disable 56506 // [....], endpoint.Contract is never null +#pragma warning disable 56506 // Microsoft, endpoint.Contract is never null foreach (OperationDescription od in endpoint.Contract.Operations) #pragma warning restore 56506 { @@ -156,7 +156,7 @@ public string SelectOperation(ref Message message) } bool uriMatched; string result = this.SelectOperation(ref message, out uriMatched); -#pragma warning disable 56506 // [....], Message.Properties is never null +#pragma warning disable 56506 // Microsoft, Message.Properties is never null message.Properties.Add(HttpOperationSelectorUriMatchedPropertyName, uriMatched); #pragma warning restore 56506 if (result != null) @@ -164,7 +164,7 @@ public string SelectOperation(ref Message message) message.Properties.Add(HttpOperationNamePropertyName, result); if (DiagnosticUtility.ShouldTraceInformation) { -#pragma warning disable 56506 // [....], Message.Headers is never null +#pragma warning disable 56506 // Microsoft, Message.Headers is never null TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.WebRequestMatchesOperation, SR2.GetString(SR2.TraceCodeWebRequestMatchesOperation, message.Headers.To, result)); #pragma warning restore 56506 } @@ -186,7 +186,7 @@ protected virtual string SelectOperation(ref Message message, out bool uriMatche return this.catchAllOperationName; } -#pragma warning disable 56506 // [....], message.Properties is never null +#pragma warning disable 56506 // Microsoft, message.Properties is never null if (!message.Properties.ContainsKey(HttpRequestMessageProperty.Name)) { return this.catchAllOperationName; diff --git a/System.ServiceModel.Web/System/ServiceModel/Web/HttpDateParse.cs b/System.ServiceModel.Web/System/ServiceModel/Web/HttpDateParse.cs index 4a3d17d51..cadf9da9e 100644 --- a/System.ServiceModel.Web/System/ServiceModel/Web/HttpDateParse.cs +++ b/System.ServiceModel.Web/System/ServiceModel/Web/HttpDateParse.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------ +//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------ namespace System.ServiceModel.Web @@ -11,7 +11,7 @@ namespace System.ServiceModel.Web // All of the code from this class was taken from build 20717.00 // of System.Net.HttpDateParse. If there is a bug with this code // it should be fixed in the original System.Net.HttpDateParse - // and then ported here. [[....]] + // and then ported here. [Microsoft] internal static class HttpDateParse { @@ -48,7 +48,7 @@ internal static class HttpDateParse private const int DATE_TOKEN_JANUARY = 1; private const int DATE_TOKEN_FEBRUARY = 2; - private const int DATE_TOKEN_MARCH = 3; + private const int DATE_TOKEN_Microsoft = 3; private const int DATE_TOKEN_APRIL = 4; private const int DATE_TOKEN_MAY = 5; private const int DATE_TOKEN_JUNE = 6; @@ -145,7 +145,7 @@ static int MapDayMonthToDword(char[] lpszDay, int index) switch (MakeUpper(lpszDay[index + 2])) { case 'R': - return DATE_TOKEN_MARCH; + return DATE_TOKEN_Microsoft; case 'Y': return DATE_TOKEN_MAY; } diff --git a/System.ServiceModel.Web/System/ServiceModel/Web/WebOperationContext.cs b/System.ServiceModel.Web/System/ServiceModel/Web/WebOperationContext.cs index e6d3a74f4..aaff3cea2 100644 --- a/System.ServiceModel.Web/System/ServiceModel/Web/WebOperationContext.cs +++ b/System.ServiceModel.Web/System/ServiceModel/Web/WebOperationContext.cs @@ -37,7 +37,7 @@ public WebOperationContext(OperationContext operationContext) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operationContext"); } this.operationContext = operationContext; -#pragma warning disable 56506 // [....], operationContext.Extensions is never null +#pragma warning disable 56506 // Microsoft, operationContext.Extensions is never null if (operationContext.Extensions.Find() == null) { operationContext.Extensions.Add(this); diff --git a/System.ServiceModel.Web/System/ServiceModel/WebHttpBinding.cs b/System.ServiceModel.Web/System/ServiceModel/WebHttpBinding.cs index 7fd8d6fd5..2b72d5577 100644 --- a/System.ServiceModel.Web/System/ServiceModel/WebHttpBinding.cs +++ b/System.ServiceModel.Web/System/ServiceModel/WebHttpBinding.cs @@ -195,7 +195,7 @@ public bool CrossDomainScriptAccessEnabled } } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] // [....], This is the pattern we use on the standard bindings in Indigo V1 + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] // Microsoft, This is the pattern we use on the standard bindings in Indigo V1 bool IBindingRuntimePreferences.ReceiveSynchronously { get { return false; } diff --git a/System.ServiceModel/System/ServiceModel/Activation/Configuration/ServiceModelActivationSectionGroup.cs b/System.ServiceModel/System/ServiceModel/Activation/Configuration/ServiceModelActivationSectionGroup.cs index 5688f5591..19c842d4e 100644 --- a/System.ServiceModel/System/ServiceModel/Activation/Configuration/ServiceModelActivationSectionGroup.cs +++ b/System.ServiceModel/System/ServiceModel/Activation/Configuration/ServiceModelActivationSectionGroup.cs @@ -19,7 +19,7 @@ static public ServiceModelActivationSectionGroup GetSectionGroup(Configuration c { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("config"); } -#pragma warning suppress 56506 // [....], Configuration.SectionGroups cannot be null +#pragma warning suppress 56506 // Microsoft, Configuration.SectionGroups cannot be null return (ServiceModelActivationSectionGroup)config.SectionGroups[ConfigurationStrings.SectionGroupName]; } diff --git a/System.ServiceModel/System/ServiceModel/Activation/ListenerUnsafeNativeMethods.cs b/System.ServiceModel/System/ServiceModel/Activation/ListenerUnsafeNativeMethods.cs index 6e8d01914..b8fb610e4 100644 --- a/System.ServiceModel/System/ServiceModel/Activation/ListenerUnsafeNativeMethods.cs +++ b/System.ServiceModel/System/ServiceModel/Activation/ListenerUnsafeNativeMethods.cs @@ -279,7 +279,7 @@ internal SafeServiceHandle() override protected bool ReleaseHandle() { -#pragma warning suppress 56523 // [....], should only fail if there is a bug (invalid handle); MDA will be raised +#pragma warning suppress 56523 // Microsoft, should only fail if there is a bug (invalid handle); MDA will be raised return ListenerUnsafeNativeMethods.CloseServiceHandle(handle); } } diff --git a/System.ServiceModel/System/ServiceModel/Activation/Utility.cs b/System.ServiceModel/System/ServiceModel/Activation/Utility.cs index 32b1ecdc9..9a011db96 100644 --- a/System.ServiceModel/System/ServiceModel/Activation/Utility.cs +++ b/System.ServiceModel/System/ServiceModel/Activation/Utility.cs @@ -33,7 +33,7 @@ internal static Uri FormatListenerEndpoint(string serviceName, string listenerEn static SafeCloseHandle OpenCurrentProcessForWrite() { int processId = Process.GetCurrentProcess().Id; -#pragma warning suppress 56523 // [....], Win32Exception ctor calls Marshal.GetLastWin32Error() +#pragma warning suppress 56523 // Microsoft, Win32Exception ctor calls Marshal.GetLastWin32Error() SafeCloseHandle process = ListenerUnsafeNativeMethods.OpenProcess(ListenerUnsafeNativeMethods.PROCESS_QUERY_INFORMATION | ListenerUnsafeNativeMethods.WRITE_DAC | ListenerUnsafeNativeMethods.READ_CONTROL, false, processId); if (process.IsInvalid) { @@ -46,7 +46,7 @@ static SafeCloseHandle OpenCurrentProcessForWrite() static SafeCloseHandle OpenProcessForQuery(int pid) { -#pragma warning suppress 56523 // [....], Win32Exception ctor calls Marshal.GetLastWin32Error() +#pragma warning suppress 56523 // Microsoft, Win32Exception ctor calls Marshal.GetLastWin32Error() SafeCloseHandle process = ListenerUnsafeNativeMethods.OpenProcess(ListenerUnsafeNativeMethods.PROCESS_QUERY_INFORMATION, false, pid); if (process.IsInvalid) { @@ -99,7 +99,7 @@ static void GetTokenInformation(SafeCloseHandle token, ListenerUnsafeNativeMetho static SafeServiceHandle OpenSCManager() { -#pragma warning suppress 56523 // [....], Win32Exception ctor calls Marshal.GetLastWin32Error() +#pragma warning suppress 56523 // Microsoft, Win32Exception ctor calls Marshal.GetLastWin32Error() SafeServiceHandle scManager = ListenerUnsafeNativeMethods.OpenSCManager(null, null, ListenerUnsafeNativeMethods.SC_MANAGER_CONNECT); if (scManager.IsInvalid) { @@ -112,7 +112,7 @@ static SafeServiceHandle OpenSCManager() static SafeServiceHandle OpenService(SafeServiceHandle scManager, string serviceName, int purpose) { -#pragma warning suppress 56523 // [....], Win32Exception ctor calls Marshal.GetLastWin32Error() +#pragma warning suppress 56523 // Microsoft, Win32Exception ctor calls Marshal.GetLastWin32Error() SafeServiceHandle service = ListenerUnsafeNativeMethods.OpenService(scManager, serviceName, purpose); if (service.IsInvalid) { @@ -249,7 +249,7 @@ static void EditKernelObjectSecurity(SafeCloseHandle kernelObject, List @@ -78,7 +78,7 @@ public override long Length { get { -#pragma warning suppress 56503 // [....], required by the Stream.Length contract +#pragma warning suppress 56503 // Microsoft, required by the Stream.Length contract throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.ReadNotSupported))); } } @@ -87,7 +87,7 @@ public override long Position { get { -#pragma warning suppress 56503 // [....], required by the Stream.Position contract +#pragma warning suppress 56503 // Microsoft, required by the Stream.Position contract throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupported))); } set @@ -335,7 +335,7 @@ public override void WriteByte(byte value) void DequeueAndFlush(ByteBuffer currentBuffer, AsyncEventArgsCallback callback) { // Dequeue does a checkout of the buffer from its slot. - // the callback for the [....] path only enqueues the buffer. + // the callback for the sync path only enqueues the buffer. // The WriteAsync callback needs to enqueue and also complete. this.currentByteBuffer = null; ByteBuffer dequeued = this.buffers.Dequeue(); @@ -756,7 +756,7 @@ static void WriteCallback(IAsyncResult result) buffer.stream.EndWrite(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/CompositeDuplexBindingElement.cs b/System.ServiceModel/System/ServiceModel/Channels/CompositeDuplexBindingElement.cs index f038eb553..1dcac8496 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/CompositeDuplexBindingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/CompositeDuplexBindingElement.cs @@ -86,7 +86,7 @@ public override IChannelListener BuildChannelListener(Bindin else { // -#pragma warning suppress 56506 // [....], context.Binding will never be null. +#pragma warning suppress 56506 // Microsoft, context.Binding will never be null. context.ListenUriRelativeAddress = String.Empty; context.ListenUriMode = ListenUriMode.Unique; } diff --git a/System.ServiceModel/System/ServiceModel/Channels/Connection.cs b/System.ServiceModel/System/ServiceModel/Channels/Connection.cs index 9934d41ff..c795e66a1 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/Connection.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/Connection.cs @@ -338,7 +338,7 @@ public override long Length { get { -#pragma warning suppress 56503 // [....], required by the Stream.Length contract +#pragma warning suppress 56503 // Microsoft, required by the Stream.Length contract throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupported))); } } @@ -347,7 +347,7 @@ public override long Position { get { -#pragma warning suppress 56503 // [....], required by the Stream.Position contract +#pragma warning suppress 56503 // Microsoft, required by the Stream.Position contract throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SeekNotSupported))); } set @@ -470,7 +470,7 @@ static void OnAsyncIOComplete(object state) { thisPtr.HandleIO(thisPtr.connection); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/ConnectionDemuxer.cs b/System.ServiceModel/System/ServiceModel/Channels/ConnectionDemuxer.cs index 0a74ee019..9f50f397f 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/ConnectionDemuxer.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/ConnectionDemuxer.cs @@ -554,7 +554,7 @@ bool HandlePreambleComplete(IAsyncResult result) IConnection upgradedConnection = this.serverSingletonPreambleReader.EndCompletePreamble(result); ServerSingletonConnectionReader singletonReader = new ServerSingletonConnectionReader(serverSingletonPreambleReader, upgradedConnection, this.demuxer); - //singletonReader doesn't have async version of ReceiveRequest, so just call the [....] method for now. + //singletonReader doesn't have async version of ReceiveRequest, so just call the sync method for now. RequestContext requestContext = singletonReader.ReceiveRequest(this.timeoutHelper.RemainingTime()); singletonChannelListener.ReceiveRequest(requestContext, serverSingletonPreambleReader.ConnectionDequeuedCallback, true); diff --git a/System.ServiceModel/System/ServiceModel/Channels/ConnectionModeReader.cs b/System.ServiceModel/System/ServiceModel/Channels/ConnectionModeReader.cs index de091c4ea..57a54e084 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/ConnectionModeReader.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/ConnectionModeReader.cs @@ -134,7 +134,7 @@ static void ReadCallback(object state) completeSelf = reader.ContinueReading(); } } -#pragma warning suppress 56500 // [....], transferring exception to caller +#pragma warning suppress 56500 // Microsoft, transferring exception to caller catch (Exception e) { if (Fx.IsFatal(e)) @@ -201,7 +201,7 @@ public void StartReading(TimeSpan receiveTimeout, Action connectionDequeuedCallb { completeSelf = ContinueReading(); } -#pragma warning suppress 56500 // [....], transferring exception to caller +#pragma warning suppress 56500 // Microsoft, transferring exception to caller catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/ConnectionPool.cs b/System.ServiceModel/System/ServiceModel/Channels/ConnectionPool.cs index a76041897..fcab3692d 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/ConnectionPool.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/ConnectionPool.cs @@ -1213,7 +1213,7 @@ static void OnConnect(IAsyncResult result) { completeSelf = thisPtr.HandleConnect(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1292,7 +1292,7 @@ static void OnProcessConnection(IAsyncResult result) thisPtr.SnapshotConnection(); } } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/ContentOnlyMessage.cs b/System.ServiceModel/System/ServiceModel/Channels/ContentOnlyMessage.cs index a2413853a..0173e2b62 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/ContentOnlyMessage.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/ContentOnlyMessage.cs @@ -28,7 +28,7 @@ public override MessageHeaders Headers { if (IsDisposed) { -#pragma warning suppress 56503 // [....], required by base class contract +#pragma warning suppress 56503 // Microsoft, required by base class contract throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); } @@ -42,7 +42,7 @@ public override MessageProperties Properties { if (IsDisposed) { -#pragma warning suppress 56503 // [....], required by base class contract +#pragma warning suppress 56503 // Microsoft, required by base class contract throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); } diff --git a/System.ServiceModel/System/ServiceModel/Channels/FramingChannels.cs b/System.ServiceModel/System/ServiceModel/Channels/FramingChannels.cs index f232b0f7d..41c0e1f37 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/FramingChannels.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/FramingChannels.cs @@ -641,7 +641,7 @@ static void OnWritePreamble(object asyncState) { completeSelf = thisPtr.HandleWritePreamble(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -669,7 +669,7 @@ static void OnReadPreambleAck(object state) { completeSelf = thisPtr.HandlePreambleAck(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -702,7 +702,7 @@ static void OnUpgradeInitiatorOpen(IAsyncResult result) { completeSelf = thisPtr.HandleInitiatorOpen(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -735,7 +735,7 @@ static void OnUpgrade(IAsyncResult result) { completeSelf = thisPtr.HandleUpgrade(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -768,7 +768,7 @@ static void OnUpgradeInitiatorClose(IAsyncResult result) { completeSelf = thisPtr.HandleInitiatorClose(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -796,7 +796,7 @@ static void OnWritePreambleEnd(object asyncState) thisPtr.connection.EndWrite(); completeSelf = thisPtr.ReadAck(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -826,7 +826,7 @@ void OnFailedPreamble(IAsyncResult result) { ConnectionUpgradeHelper.EndDecodeFramingFault(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -913,7 +913,7 @@ static void OnEstablishConnection(IAsyncResult result) { completeSelf = thisPtr.HandleEstablishConnection(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1172,7 +1172,7 @@ static void OnReadFaultData(object state) { thisPtr.CompleteReadFaultData(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1335,7 +1335,7 @@ static void OnReadUpgradeResponse(object state) completeSelf = thisPtr.Begin(); } } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1366,7 +1366,7 @@ static void OnFailedUpgrade(IAsyncResult result) { ConnectionUpgradeHelper.EndDecodeFramingFault(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1392,7 +1392,7 @@ static void OnWriteUpgradeBytes(object asyncState) completeSelf = thisPtr.Begin(); } } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1423,7 +1423,7 @@ static void OnInitiateUpgrade(IAsyncResult result) thisPtr.CompleteUpgrade(result); completeSelf = thisPtr.Begin(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/FramingDecoders.cs b/System.ServiceModel/System/ServiceModel/Channels/FramingDecoders.cs index 8c5b4e614..dbd6ca609 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/FramingDecoders.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/FramingDecoders.cs @@ -32,7 +32,7 @@ public int Value get { if (!isValueDecoded) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return value; } @@ -108,7 +108,7 @@ public string Value get { if (currentState != State.Done) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return value; } @@ -236,7 +236,7 @@ public Uri ValueAsUri get { if (!IsValueDecoded) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return via; } @@ -544,7 +544,7 @@ public FramingMode Mode get { if (currentState != State.Done) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return mode; } @@ -555,7 +555,7 @@ public int MajorVersion get { if (currentState != State.Done) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return majorVersion; } @@ -566,7 +566,7 @@ public int MinorVersion get { if (currentState != State.Done) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return minorVersion; } @@ -624,7 +624,7 @@ public string ContentType get { if (currentState < State.PreUpgradeStart) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return contentType; } @@ -635,7 +635,7 @@ public Uri Via get { if (currentState < State.ReadingContentTypeRecord) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return viaDecoder.ValueAsUri; } @@ -652,7 +652,7 @@ public string Upgrade get { if (currentState != State.UpgradeRequest) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return upgrade; } @@ -663,7 +663,7 @@ public int EnvelopeSize get { if (currentState < State.EnvelopeStart) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return envelopeSize; } @@ -880,7 +880,7 @@ public int ChunkSize { if (currentState < State.ChunkStart) { -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); } @@ -1009,7 +1009,7 @@ public Uri Via get { if (currentState < State.ReadingContentTypeRecord) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return viaDecoder.ValueAsUri; } @@ -1020,7 +1020,7 @@ public string ContentType get { if (currentState < State.PreUpgradeStart) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return contentType; } @@ -1031,7 +1031,7 @@ public string Upgrade get { if (currentState != State.UpgradeRequest) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return upgrade; } @@ -1280,7 +1280,7 @@ public Uri Via get { if (currentState < State.ReadingContentTypeRecord) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return viaDecoder.ValueAsUri; } @@ -1291,7 +1291,7 @@ public string ContentType get { if (currentState < State.Start) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return contentType; } @@ -1386,7 +1386,7 @@ public int EnvelopeSize get { if (CurrentState < ClientFramingDecoderState.EnvelopeStart) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return envelopeSize; } @@ -1397,7 +1397,7 @@ public override string Fault get { if (CurrentState < ClientFramingDecoderState.Fault) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return faultDecoder.Value; } @@ -1543,7 +1543,7 @@ public override string Fault get { if (CurrentState < ClientFramingDecoderState.Fault) -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FramingValueNotAvailable))); return faultDecoder.Value; } diff --git a/System.ServiceModel/System/ServiceModel/Channels/HttpChannelFactory.cs b/System.ServiceModel/System/ServiceModel/Channels/HttpChannelFactory.cs index 482d0bfde..323b25415 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/HttpChannelFactory.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/HttpChannelFactory.cs @@ -1496,7 +1496,7 @@ static void OnGetWebRequestCompletedCallback(IAsyncResult result) { completeSelf = thisPtr.OnGetWebRequestCompleted(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1810,7 +1810,7 @@ static void OnParseIncomingMessage(IAsyncResult result) { thisPtr.CompleteParseIncomingMessage(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1837,7 +1837,7 @@ static void OnSend(IAsyncResult result) { completeSelf = thisPtr.CompleteSend(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1882,7 +1882,7 @@ static void OnGetResponse(IAsyncResult result) completeSelf = true; completionException = new CommunicationException(webException.Message, webException); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -2068,7 +2068,7 @@ static void OnGetSspiCredential(IAsyncResult result) thisPtr.CompleteGetSspiCredential(result); thisPtr.CloseTokenProvidersIfRequired(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -2096,7 +2096,7 @@ static void OnGetUserNameCredential(IAsyncResult result) thisPtr.CompleteGetUserNameCredential(result); thisPtr.CloseTokenProvidersIfRequired(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/HttpChannelHelpers.cs b/System.ServiceModel/System/ServiceModel/Channels/HttpChannelHelpers.cs index 5df21319d..f75afcecf 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/HttpChannelHelpers.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/HttpChannelHelpers.cs @@ -780,7 +780,7 @@ static void OnRead(IAsyncResult result) { completeSelf = thisPtr.ContinueReading(thisPtr.inputStream.EndRead(result)); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -2193,7 +2193,7 @@ bool WriteMessage(bool isStillSynchronous) bool WriteStreamedMessage() { - // return a bool to determine if we are [....]. + // return a bool to determine if we are sync. if (onWriteStreamedMessage == null) { @@ -2289,7 +2289,7 @@ static void OnGetOutputStream(IAsyncResult result) completeSelf = true; } } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -2315,7 +2315,7 @@ static void OnWriteStreamedMessageLater(object state) { completeSelf = thisPtr.WriteStreamedMessage(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -2349,7 +2349,7 @@ static void OnWriteBody(IAsyncResult result) thisPtr.CompleteWriteBody(result); thisPtr.httpOutput.TraceSend(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -2781,7 +2781,7 @@ static void OnGetRequestStream(IAsyncResult result) { thisPtr.CompleteGetRequestStream(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/HttpPipeline.cs b/System.ServiceModel/System/ServiceModel/Channels/HttpPipeline.cs index ee321225b..2b6563596 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/HttpPipeline.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/HttpPipeline.cs @@ -444,7 +444,7 @@ public override void SendReply(Message message, TimeSpan timeout) bool lockTaken = false; try { - // We need this lock only in [....] reply case. In this case, we hopped the thread in the request side, so it's possible to send the response here + // We need this lock only in sync reply case. In this case, we hopped the thread in the request side, so it's possible to send the response here // before the TransportIntegrationHandler is ready on another thread (thus a race condition). So we use the lock here. In the incoming path, we won't // release the lock until the TransportIntegrationHandler is ready. Once we get the lock on the outgoing path, we can then call Wait() on this handler safely. Monitor.TryEnter(this.ThisLock, TimeoutHelper.ToMilliseconds(helper.RemainingTime()), ref lockTaken); @@ -615,7 +615,7 @@ protected virtual void SendHttpPipelineResponse() this.cancellationTokenSource.Dispose(); this.wasProcessInboundRequestSuccessful = true; //// shortcut scenario - //// Currently we are always doing [....] send even async send is enabled. + //// Currently we are always doing sync send even async send is enabled. this.SendAndClose(t.Result); } else if (this.isAsyncReply) diff --git a/System.ServiceModel/System/ServiceModel/Channels/HttpTransportBindingElement.cs b/System.ServiceModel/System/ServiceModel/Channels/HttpTransportBindingElement.cs index 479ca4862..c173b4317 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/HttpTransportBindingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/HttpTransportBindingElement.cs @@ -528,7 +528,7 @@ public override T GetProperty(BindingContext context) } else { -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters cannot be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null if (context.BindingParameters.Find() == null) { context.BindingParameters.Add(new TextMessageEncodingBindingElement()); @@ -578,7 +578,7 @@ public override IChannelFactory BuildChannelFactory(BindingC if (!this.CanBuildChannelFactory(context)) { -#pragma warning suppress 56506 // [....], context.Binding will never be null. +#pragma warning suppress 56506 // Microsoft, context.Binding will never be null. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TChannel", SR.GetString(SR.CouldnTCreateChannelForChannelType2, context.Binding.Name, typeof(TChannel))); } @@ -649,7 +649,7 @@ public override IChannelListener BuildChannelListener(Bindin if (!this.CanBuildChannelListener(context)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( -#pragma warning suppress 56506 // [....], context.Binding will never be null. +#pragma warning suppress 56506 // Microsoft, context.Binding will never be null. "TChannel", SR.GetString(SR.CouldnTCreateChannelForChannelType2, context.Binding.Name, typeof(TChannel))); } @@ -672,7 +672,7 @@ protected void UpdateAuthenticationSchemes(BindingContext context) if (effectiveAutheSchemes == AuthenticationSchemes.None) { -#pragma warning suppress 56506 // [....], context.Binding will never be null. +#pragma warning suppress 56506 // Microsoft, context.Binding will never be null. string bindingName = context.Binding.Name; if (this.AuthenticationScheme == AuthenticationSchemes.None) diff --git a/System.ServiceModel/System/ServiceModel/Channels/HttpsChannelFactory.cs b/System.ServiceModel/System/ServiceModel/Channels/HttpsChannelFactory.cs index 6b2511b4c..6f0924176 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/HttpsChannelFactory.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/HttpsChannelFactory.cs @@ -488,7 +488,7 @@ static void OnGetBaseWebRequestCallback(IAsyncResult result) thisPtr.request = thisPtr.httpsChannel.EndBaseGetWebRequest(result); thisPtr.factory.AddServerCertMappingOrSetRemoteCertificateValidationCallback(thisPtr.request, thisPtr.to); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -514,7 +514,7 @@ static void OnGetTokenCallback(IAsyncResult result) thisPtr.OnGetToken(result); completeSelf = thisPtr.GetWebRequest(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/IdlingCommunicationPool.cs b/System.ServiceModel/System/ServiceModel/Channels/IdlingCommunicationPool.cs index b2563cc48..e576d74b1 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/IdlingCommunicationPool.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/IdlingCommunicationPool.cs @@ -37,7 +37,7 @@ protected TimeSpan LeaseTimeout protected override void CloseItemAsync(TItem item, TimeSpan timeout) { - // Default behavior is [....]. Derived classes can override. + // Default behavior is sync. Derived classes can override. this.CloseItem(item, timeout); } diff --git a/System.ServiceModel/System/ServiceModel/Channels/InitialServerConnectionReader.cs b/System.ServiceModel/System/ServiceModel/Channels/InitialServerConnectionReader.cs index 4bc768331..d9d1af921 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/InitialServerConnectionReader.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/InitialServerConnectionReader.cs @@ -404,7 +404,7 @@ static void OnAcceptUpgrade(IAsyncResult result) { thisPtr.CompleteAcceptUpgrade(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/InputChannel.cs b/System.ServiceModel/System/ServiceModel/Channels/InputChannel.cs index 26f1e3aa3..b4e5202fa 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/InputChannel.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/InputChannel.cs @@ -223,7 +223,7 @@ static void OnReceive(IAsyncResult result) { thisPtr.HandleReceiveComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/InternalDuplexBindingElement.cs b/System.ServiceModel/System/ServiceModel/Channels/InternalDuplexBindingElement.cs index dc126777c..5abee3c70 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/InternalDuplexBindingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/InternalDuplexBindingElement.cs @@ -69,7 +69,7 @@ public override IChannelFactory BuildChannelFactory(BindingC } else { -#pragma warning suppress 56506 // [....], context.RemainingBindingElements will never be null +#pragma warning suppress 56506 // Microsoft, context.RemainingBindingElements will never be null context.RemainingBindingElements.Clear(); } LocalAddressProvider localAddressProvider = context.BindingParameters.Remove(); diff --git a/System.ServiceModel/System/ServiceModel/Channels/InternalDuplexChannelListener.cs b/System.ServiceModel/System/ServiceModel/Channels/InternalDuplexChannelListener.cs index 279523221..9f3022762 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/InternalDuplexChannelListener.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/InternalDuplexChannelListener.cs @@ -345,7 +345,7 @@ static void SendCompleteCallback(IAsyncResult result) { thisPtr.CompleteSend(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/Message.cs b/System.ServiceModel/System/ServiceModel/Channels/Message.cs index 5ea731f08..6575d29ff 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/Message.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/Message.cs @@ -34,7 +34,7 @@ public virtual bool IsFault get { if (IsDisposed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); return false; @@ -46,7 +46,7 @@ public virtual bool IsEmpty get { if (IsDisposed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); return false; @@ -57,6 +57,29 @@ public virtual bool IsEmpty public abstract MessageVersion Version { get; } // must never return null + internal virtual void SetProperty(string name, object value) + { + MessageProperties prop = Properties; + + if (prop != null) + { + prop[name] = value; + } + } + + internal virtual bool GetProperty(string name, out object result) + { + MessageProperties prop = Properties; + + if (prop != null) + { + return prop.TryGetValue(name, out result); + } + + result = null; + return false; + } + internal virtual RecycledMessageState RecycledMessageState { get { return null; } @@ -978,7 +1001,7 @@ public override bool IsFault get { if (IsDisposed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); return bodyWriter.IsFault; } @@ -989,7 +1012,7 @@ public override bool IsEmpty get { if (IsDisposed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); return bodyWriter.IsEmpty; } @@ -1000,7 +1023,7 @@ public override MessageHeaders Headers get { if (IsDisposed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); return headers; } @@ -1011,7 +1034,7 @@ public override MessageProperties Properties get { if (IsDisposed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); if (properties == null) properties = new MessageProperties(); @@ -1019,12 +1042,36 @@ public override MessageProperties Properties } } + internal override void SetProperty(string name, object value) + { + MessageProperties prop = this.properties; + + if (prop != null) + { + prop[name] = value; + } + } + + internal override bool GetProperty(string name, out object result) + { + MessageProperties prop = this.properties; + + if (prop != null) + { + return prop.TryGetValue(name, out result); + } + + result = null; + return false; + } + + public override MessageVersion Version { get { if (IsDisposed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); return headers.MessageVersion; } @@ -1306,7 +1353,7 @@ public override MessageHeaders Headers get { if (IsDisposed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); return headers; } @@ -1522,7 +1569,7 @@ public override MessageHeaders Headers get { if (IsDisposed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); return headers; } @@ -1541,7 +1588,7 @@ public override MessageProperties Properties get { if (IsDisposed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); return properties; } diff --git a/System.ServiceModel/System/ServiceModel/Channels/MessageBuffer.cs b/System.ServiceModel/System/ServiceModel/Channels/MessageBuffer.cs index 4a1588076..383bf17b7 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/MessageBuffer.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/MessageBuffer.cs @@ -197,7 +197,7 @@ public override int BufferSize lock (ThisLock) { if (closed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException()); return messageData.Buffer.Count; } @@ -224,7 +224,7 @@ public override string MessageContentType lock (ThisLock) { if (closed) -#pragma warning suppress 56503 // [....], Invalid State after dispose +#pragma warning suppress 56503 // Microsoft, Invalid State after dispose throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBufferDisposedException()); return messageData.MessageEncoder.ContentType; } diff --git a/System.ServiceModel/System/ServiceModel/Channels/MessageEncodingBindingElement.cs b/System.ServiceModel/System/ServiceModel/Channels/MessageEncodingBindingElement.cs index 1dcae5bf0..72af69543 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/MessageEncodingBindingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/MessageEncodingBindingElement.cs @@ -38,7 +38,7 @@ internal IChannelFactory InternalBuildChannelFactory(Binding throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("context")); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters never be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters never be null context.BindingParameters.Add(this); return context.BuildInnerChannelFactory(); } @@ -50,7 +50,7 @@ internal bool InternalCanBuildChannelFactory(BindingContext context) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("context")); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters never be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters never be null context.BindingParameters.Add(this); return context.CanBuildInnerChannelFactory(); } @@ -63,7 +63,7 @@ internal IChannelListener InternalBuildChannelListener(Bindi throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("context")); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters never be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters never be null context.BindingParameters.Add(this); return context.BuildInnerChannelListener(); } @@ -76,7 +76,7 @@ internal bool InternalCanBuildChannelListener(BindingContext context) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("context")); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters never be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters never be null context.BindingParameters.Add(this); return context.CanBuildInnerChannelListener(); } diff --git a/System.ServiceModel/System/ServiceModel/Channels/MessageEncodingBindingElementImporter.cs b/System.ServiceModel/System/ServiceModel/Channels/MessageEncodingBindingElementImporter.cs index 6b4de1fab..3662da87d 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/MessageEncodingBindingElementImporter.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/MessageEncodingBindingElementImporter.cs @@ -25,7 +25,7 @@ void IWsdlImportExtension.ImportEndpoint(WsdlImporter importer, WsdlEndpointConv throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } -#pragma warning suppress 56506 // [....], these properties cannot be null in this context +#pragma warning suppress 56506 // Microsoft, these properties cannot be null in this context if (context.Endpoint.Binding == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context.Endpoint.Binding"); diff --git a/System.ServiceModel/System/ServiceModel/Channels/MessageFault.cs b/System.ServiceModel/System/ServiceModel/Channels/MessageFault.cs index 5803f1710..09e60dfff 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/MessageFault.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/MessageFault.cs @@ -69,7 +69,7 @@ public static MessageFault CreateFault(Message message, int maxBufferSize) { try { -#pragma warning suppress 56506 // [....], Message.Version can never be null +#pragma warning suppress 56506 // Microsoft, Message.Version can never be null EnvelopeVersion envelopeVersion = message.Version.Envelope; MessageFault fault; if (envelopeVersion == EnvelopeVersion.Soap12) diff --git a/System.ServiceModel/System/ServiceModel/Channels/MessageHeaders.cs b/System.ServiceModel/System/ServiceModel/Channels/MessageHeaders.cs index de966e449..5accd13b6 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/MessageHeaders.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/MessageHeaders.cs @@ -490,7 +490,7 @@ public void CopyHeaderFrom(MessageHeaders collection, int headerIndex) if (collection.version != version) { -#pragma warning suppress 56506 // [....], collection.version is never null +#pragma warning suppress 56506 // Microsoft, collection.version is never null throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MessageHeaderVersionMismatch, collection.version.ToString(), version.ToString()), "collection")); } diff --git a/System.ServiceModel/System/ServiceModel/Channels/OneWayChannelFactory.cs b/System.ServiceModel/System/ServiceModel/Channels/OneWayChannelFactory.cs index f45463a33..c37698a5e 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/OneWayChannelFactory.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/OneWayChannelFactory.cs @@ -763,7 +763,7 @@ static void OnOpen(IAsyncResult result) thisPtr.CompleteOpen(result); completeSelf = thisPtr.SendMessage(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -796,7 +796,7 @@ static void OnInnerSend(IAsyncResult result) { thisPtr.innerChannel.EndSend(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/OneWayChannelListener.cs b/System.ServiceModel/System/ServiceModel/Channels/OneWayChannelListener.cs index ef8abafcf..afba9b018 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/OneWayChannelListener.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/OneWayChannelListener.cs @@ -429,7 +429,7 @@ static void OnReceiveRequest(IAsyncResult result) { completeSelf = thisPtr.HandleReceiveRequestComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -461,7 +461,7 @@ static void OnReply(IAsyncResult result) { completeSelf = thisPtr.HandleReplyComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -770,7 +770,7 @@ void AcceptLoop(IAsyncResult pendingResult) return; } } -#pragma warning suppress 56500 // [....], transferring exception to input queue to be pulled off by user +#pragma warning suppress 56500 // Microsoft, transferring exception to input queue to be pulled off by user catch (Exception e) { if (Fx.IsFatal(e)) @@ -809,7 +809,7 @@ bool ProcessEndAccept(IAsyncResult result, out IDuplexSessionChannel channel) { DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); } -#pragma warning suppress 56500 // [....], transferring exception to input queue to be pulled off by user +#pragma warning suppress 56500 // Microsoft, transferring exception to input queue to be pulled off by user catch (Exception e) { if (Fx.IsFatal(e)) @@ -940,7 +940,7 @@ void HandleAcceptComplete(IDuplexSessionChannel channel) } DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); } -#pragma warning suppress 56500 // [....], transferring exception to input queue to be pulled off by user +#pragma warning suppress 56500 // Microsoft, transferring exception to input queue to be pulled off by user catch (Exception e) { if (Fx.IsFatal(e)) @@ -1007,7 +1007,7 @@ void CompleteOpen(IDuplexSessionChannel channel, IAsyncResult result) } DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); } -#pragma warning suppress 56500 // [....], transferring exception to input queue to be pulled off by user +#pragma warning suppress 56500 // Microsoft, transferring exception to input queue to be pulled off by user catch (Exception e) { if (Fx.IsFatal(e)) @@ -1274,7 +1274,7 @@ public void StartReceiving() { DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); } -#pragma warning suppress 56500 // [....], transferring exception to input queue to be pulled off by user +#pragma warning suppress 56500 // Microsoft, transferring exception to input queue to be pulled off by user catch (Exception e) { if (Fx.IsFatal(e)) @@ -1379,7 +1379,7 @@ bool OnCompleteReceive(IAsyncResult result, out bool dispatchLater) DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); startLoop = (this.channel.State == CommunicationState.Opened); } -#pragma warning suppress 56500 // [....], transferring exception to input queue to be pulled off by user +#pragma warning suppress 56500 // Microsoft, transferring exception to input queue to be pulled off by user catch (Exception e) { if (Fx.IsFatal(e)) @@ -1415,7 +1415,7 @@ void OnMessageDequeued() { DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); } -#pragma warning suppress 56500 // [....], transferring exception to input queue to be pulled off by user +#pragma warning suppress 56500 // Microsoft, transferring exception to input queue to be pulled off by user catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/OverlappedContext.cs b/System.ServiceModel/System/ServiceModel/Channels/OverlappedContext.cs index 7af860972..f03b40799 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/OverlappedContext.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/OverlappedContext.cs @@ -109,7 +109,7 @@ public void Free() } if (this.syncOperationPending) { - throw Fx.AssertAndThrow("OverlappedContext.Free called while [....] operation is pending."); + throw Fx.AssertAndThrow("OverlappedContext.Free called while sync operation is pending."); } if (this.nativeOverlapped == null) { @@ -172,7 +172,7 @@ public void StartAsyncOperation(byte[] buffer, OverlappedIOCompleteCallback call } if (this.syncOperationPending) { - throw Fx.AssertAndThrow("StartAsyncOperation called while a [....] operation was already pending."); + throw Fx.AssertAndThrow("StartAsyncOperation called while a sync operation was already pending."); } if (this.nativeOverlapped == null) { @@ -249,7 +249,7 @@ public void StartSyncOperation(byte[] buffer, ref object holder) this.overlapped.EventHandleIntPtr = EventHandle; - // [....] operations do NOT root this object. If it gets finalized, we need to know not to free the buffer. + // Sync operations do NOT root this object. If it gets finalized, we need to know not to free the buffer. // We do root the event. this.rootedHolder.EventHolder = this.completionEvent; this.syncOperationPending = true; @@ -292,7 +292,7 @@ public bool WaitForSyncOperation(TimeSpan timeout, ref object holder) } Fx.Assert(this.bufferPtr == null || this.bufferPtr == (byte*)Marshal.UnsafeAddrOfPinnedArrayElement((byte[])holder, 0), - "The buffer moved during a [....] call!"); + "The buffer moved during a sync call!"); CancelSyncOperation(ref holder); return true; @@ -333,7 +333,7 @@ public byte* BufferPtr byte* ptr = this.bufferPtr; if (ptr == null) { -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw Fx.AssertAndThrow("Pointer requested while no operation pending or no buffer provided."); } return ptr; @@ -348,7 +348,7 @@ public NativeOverlapped* NativeOverlapped NativeOverlapped* ptr = this.nativeOverlapped; if (ptr == null) { -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw Fx.AssertAndThrow("NativeOverlapped pointer requested after it was freed."); } return ptr; @@ -446,14 +446,14 @@ static void CleanupCallback(object state, bool timedOut) Fx.Assert(pThis.bufferPtr == null || pThis.bufferPtr == (byte*)Marshal.UnsafeAddrOfPinnedArrayElement((byte[])pThis.bufferHolder[0], 0), "Buffer moved during synchronous deferred cleanup!"); - Fx.Assert(pThis.syncOperationPending, "OverlappedContext.CleanupCallback called with no [....] operation pending."); + Fx.Assert(pThis.syncOperationPending, "OverlappedContext.CleanupCallback called with no sync operation pending."); pThis.pinnedTarget = null; pThis.rootedHolder.EventHolder.Close(); Overlapped.Free(pThis.nativeOverlapped); } // This class is always held onto (rooted) by the packed Overlapped. The OverlappedContext instance moves itself in and out of - // this object to root itself. It's also used to root the ManualResetEvent during [....] operations. + // this object to root itself. It's also used to root the ManualResetEvent during sync operations. // It needs to be an IAsyncResult since that's what Overlapped takes. class RootedHolder : IAsyncResult { @@ -493,7 +493,7 @@ object IAsyncResult.AsyncState { get { -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw Fx.AssertAndThrow("RootedHolder.AsyncState called."); } } @@ -502,7 +502,7 @@ WaitHandle IAsyncResult.AsyncWaitHandle { get { -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw Fx.AssertAndThrow("RootedHolder.AsyncWaitHandle called."); } } @@ -511,7 +511,7 @@ bool IAsyncResult.CompletedSynchronously { get { -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw Fx.AssertAndThrow("RootedHolder.CompletedSynchronously called."); } } @@ -520,7 +520,7 @@ bool IAsyncResult.IsCompleted { get { -#pragma warning suppress 56503 // [....], not a publicly accessible API +#pragma warning suppress 56503 // Microsoft, not a publicly accessible API throw Fx.AssertAndThrow("RootedHolder.IsCompleted called."); } } diff --git a/System.ServiceModel/System/ServiceModel/Channels/PeerCustomResolverBindingElement.cs b/System.ServiceModel/System/ServiceModel/Channels/PeerCustomResolverBindingElement.cs index a9e8a8ea0..00ba45b87 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/PeerCustomResolverBindingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/PeerCustomResolverBindingElement.cs @@ -52,7 +52,7 @@ public PeerCustomResolverBindingElement(BindingContext context, PeerCustomResolv if (context == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("context")); -#pragma warning suppress 56506 // [....], context.BindingParameters is never null +#pragma warning suppress 56506 // Microsoft, context.BindingParameters is never null credentials = context.BindingParameters.Find(); } public override T GetProperty(System.ServiceModel.Channels.BindingContext context) @@ -110,7 +110,7 @@ public override IChannelFactory BuildChannelFactory(BindingC if (context == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("context")); -#pragma warning suppress 56506 // [....], context.BindingParameters is never null +#pragma warning suppress 56506 // Microsoft, context.BindingParameters is never null context.BindingParameters.Add(this); credentials = context.BindingParameters.Find(); return context.BuildInnerChannelFactory(); @@ -120,7 +120,7 @@ public override bool CanBuildChannelFactory(BindingContext context) { if (context == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("context")); -#pragma warning suppress 56506 // [....], context.BindingParameters is never null +#pragma warning suppress 56506 // Microsoft, context.BindingParameters is never null this.credentials = context.BindingParameters.Find(); context.BindingParameters.Add(this); return context.CanBuildInnerChannelFactory(); @@ -131,7 +131,7 @@ public override IChannelListener BuildChannelListener(Bindin if (context == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("context")); -#pragma warning suppress 56506 // [....], context.BindingParameters is never null +#pragma warning suppress 56506 // Microsoft, context.BindingParameters is never null context.BindingParameters.Add(this); this.credentials = context.BindingParameters.Find(); return context.BuildInnerChannelListener(); @@ -141,7 +141,7 @@ public override bool CanBuildChannelListener(BindingContext context) { if (context == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("context")); -#pragma warning suppress 56506 // [....], context.BindingParameters is never null +#pragma warning suppress 56506 // Microsoft, context.BindingParameters is never null this.credentials = context.BindingParameters.Find(); context.BindingParameters.Add(this); return context.CanBuildInnerChannelListener(); diff --git a/System.ServiceModel/System/ServiceModel/Channels/PeerFlooder.cs b/System.ServiceModel/System/ServiceModel/Channels/PeerFlooder.cs index b3866971e..9559bfb66 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/PeerFlooder.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/PeerFlooder.cs @@ -938,7 +938,7 @@ public void MarkEnd(bool success) //this is the callback routine for async completion on channel BeginSend() operations. - //if we are done, simply return. This can happen if user called [....] EndX. + //if we are done, simply return. This can happen if user called sync EndX. //if the flooder is still processing BeginSend(), then we probably cant complete. In this case, add the result to pending and return //main thread will flush the pending completions in MarkEnd(). //otherwise, call EndX on the result and remove it from results. diff --git a/System.ServiceModel/System/ServiceModel/Channels/PeerNeighborManager.cs b/System.ServiceModel/System/ServiceModel/Channels/PeerNeighborManager.cs index 0ae8268e7..1698d2788 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/PeerNeighborManager.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/PeerNeighborManager.cs @@ -1635,7 +1635,7 @@ public NeighborOpenAsyncResult(PeerNeighbor neighbor, PeerNodeAddress remoteAddr throw; } - // Indicate [....] completion to the caller + // Indicate sync completion to the caller if (result.CompletedSynchronously) base.Complete(true); } diff --git a/System.ServiceModel/System/ServiceModel/Channels/PipeConnection.cs b/System.ServiceModel/System/ServiceModel/Channels/PipeConnection.cs index ee3fbc127..9b1f4f0e0 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/PipeConnection.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/PipeConnection.cs @@ -799,7 +799,7 @@ void FinishPendingWrite(TimeSpan timeout) ulong GetServerPid() { ulong id; -#pragma warning suppress 56523 // [....], Win32Exception ctor calls Marshal.GetLastWin32Error() +#pragma warning suppress 56523 // Microsoft, Win32Exception ctor calls Marshal.GetLastWin32Error() if (!UnsafeNativeMethods.GetNamedPipeServerProcessId(pipe, out id)) { Win32Exception e = new Win32Exception(); @@ -811,7 +811,7 @@ ulong GetServerPid() ulong GetClientPid() { ulong id; -#pragma warning suppress 56523 // [....], Win32Exception ctor calls Marshal.GetLastWin32Error() +#pragma warning suppress 56523 // Microsoft, Win32Exception ctor calls Marshal.GetLastWin32Error() if (!UnsafeNativeMethods.GetNamedPipeServerProcessId(pipe, out id)) { Win32Exception e = new Win32Exception(); @@ -886,7 +886,7 @@ unsafe void OnAsyncReadComplete(bool haveResult, int error, int numBytes) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertPipeException(e, TransferOperation.Read)); } } -#pragma warning suppress 56500 // [....], transferring exception to caller +#pragma warning suppress 56500 // Microsoft, transferring exception to caller catch (Exception e) { if (Fx.IsFatal(e)) @@ -956,7 +956,7 @@ unsafe void OnAsyncWriteComplete(bool haveResult, int error, int numBytes) throw DiagnosticUtility.ExceptionUtility.ThrowHelper(ConvertPipeException(e, TransferOperation.Write), ExceptionEventType); } } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -2315,7 +2315,7 @@ unsafe void StartAccept(bool synchronous) } } } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/ReliableChannelBinder.cs b/System.ServiceModel/System/ServiceModel/Channels/ReliableChannelBinder.cs index 74d844b01..4bb39e2fc 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/ReliableChannelBinder.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/ReliableChannelBinder.cs @@ -1743,6 +1743,12 @@ public void OnReadEof() bool RemoveWaiter(IWaiter waiter) { Queue waiters = waiter.CanGetChannel ? this.getChannelQueue : this.waitQueue; + + if (waiters == null) + { + return false; + } + bool removed = false; lock (this.ThisLock) diff --git a/System.ServiceModel/System/ServiceModel/Channels/ReplyChannel.cs b/System.ServiceModel/System/ServiceModel/Channels/ReplyChannel.cs index 3f258f164..58c50c38a 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/ReplyChannel.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/ReplyChannel.cs @@ -129,7 +129,7 @@ static void OnReceiveRequest(IAsyncResult result) { thisPtr.HandleReceiveRequestComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/RequestChannel.cs b/System.ServiceModel/System/ServiceModel/Channels/RequestChannel.cs index 687c24254..f6e2de5fe 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/RequestChannel.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/RequestChannel.cs @@ -415,7 +415,7 @@ static void OnCompleteWaitCallBack(object state, bool timedOut) } thisPtr.CleanupEvents(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/RequestContextBase.cs b/System.ServiceModel/System/ServiceModel/Channels/RequestContextBase.cs index f062f22e9..269367ec4 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/RequestContextBase.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/RequestContextBase.cs @@ -45,7 +45,7 @@ public override Message RequestMessage { if (this.requestMessageException != null) { -#pragma warning suppress 56503 // [....], see outcome of DCR 50092 +#pragma warning suppress 56503 // Microsoft, see outcome of DCR 50092 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(this.requestMessageException); } diff --git a/System.ServiceModel/System/ServiceModel/Channels/SecurityBindingElementImporter.cs b/System.ServiceModel/System/ServiceModel/Channels/SecurityBindingElementImporter.cs index 4a1402464..e71c0e849 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/SecurityBindingElementImporter.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/SecurityBindingElementImporter.cs @@ -349,7 +349,7 @@ void ImportMessageScopeProtectionPolicy(MetadataImporter importer, PolicyConvers // normalize protection level settings at the operation scope if possible to help avoid typed message generation if (hasProtectionLevel && isProtectionLevelUniform) { - // ([....]) remove the foreach message here + // (Microsoft) remove the foreach message here // foreach (MessageDescription message in operation.Messages) this.ResetProtectionLevelForMessages(operation); diff --git a/System.ServiceModel/System/ServiceModel/Channels/ServiceChannelProxy.cs b/System.ServiceModel/System/ServiceModel/Channels/ServiceChannelProxy.cs index d2551e9e3..8469527be 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/ServiceChannelProxy.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/ServiceChannelProxy.cs @@ -765,7 +765,7 @@ public Object Current { get { -#pragma warning suppress 56503 // [....], IEnumerator guidelines, Current throws exception before calling MoveNext +#pragma warning suppress 56503 // Microsoft, IEnumerator guidelines, Current throws exception before calling MoveNext throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDictionaryIsEmpty))); } } @@ -778,7 +778,7 @@ public Object Key { get { -#pragma warning suppress 56503 // [....], IEnumerator guidelines, Current throws exception before calling MoveNext +#pragma warning suppress 56503 // Microsoft, IEnumerator guidelines, Current throws exception before calling MoveNext throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDictionaryIsEmpty))); } } @@ -787,7 +787,7 @@ public Object Value { get { -#pragma warning suppress 56503 // [....], IEnumerator guidelines, Current throws exception before calling MoveNext +#pragma warning suppress 56503 // Microsoft, IEnumerator guidelines, Current throws exception before calling MoveNext throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDictionaryIsEmpty))); } } @@ -796,7 +796,7 @@ public DictionaryEntry Entry { get { -#pragma warning suppress 56503 // [....], IEnumerator guidelines, Current throws exception before calling MoveNext +#pragma warning suppress 56503 // Microsoft, IEnumerator guidelines, Current throws exception before calling MoveNext throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDictionaryIsEmpty))); } } diff --git a/System.ServiceModel/System/ServiceModel/Channels/SessionConnectionReader.cs b/System.ServiceModel/System/ServiceModel/Channels/SessionConnectionReader.cs index 71a06c030..62fff724f 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/SessionConnectionReader.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/SessionConnectionReader.cs @@ -1465,7 +1465,7 @@ void OnAsyncReadComplete(object state) } } } -#pragma warning suppress 56500 // [....], transferring exception to caller +#pragma warning suppress 56500 // Microsoft, transferring exception to caller catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/SharedConnectionListener.cs b/System.ServiceModel/System/ServiceModel/Channels/SharedConnectionListener.cs index 6a655ad26..81daac429 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/SharedConnectionListener.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/SharedConnectionListener.cs @@ -778,22 +778,20 @@ bool EndValidateUriRoute(IAsyncResult result) CompletedAsyncResult.End(completedResult); } - using (LockHelper.TakeReaderLock(this.readerWriterLock)) + bool isClosed = !closed; + try { - try + return ValidateUriRouteAsyncResult.End(result); + } + catch (Exception exception) + { + if (Fx.IsFatal(exception) || !isClosed) { - return ValidateUriRouteAsyncResult.End(result); + throw; } - catch (Exception exception) - { - if (Fx.IsFatal(exception) || !closed) - { - throw; - } - DiagnosticUtility.TraceHandledException(exception, TraceEventType.Error); - return false; - } + DiagnosticUtility.TraceHandledException(exception, TraceEventType.Error); + return false; } } diff --git a/System.ServiceModel/System/ServiceModel/Channels/SingletonConnectionReader.cs b/System.ServiceModel/System/ServiceModel/Channels/SingletonConnectionReader.cs index 5660eb1b9..4cb52f579 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/SingletonConnectionReader.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/SingletonConnectionReader.cs @@ -595,7 +595,7 @@ bool BeginUpgrade(out IAsyncResult upgradeAsyncResult) if (!upgradeAsyncResult.CompletedSynchronously) { - upgradeAsyncResult = null; //caller shouldn't use this out param unless completed [....]. + upgradeAsyncResult = null; //caller shouldn't use this out param unless completed sync. return false; } @@ -1295,7 +1295,7 @@ static void OnReceiveScheduled(object state) { thisPtr.message = thisPtr.parent.Receive(thisPtr.timeout); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception exception) { if (Fx.IsFatal(exception)) @@ -1892,7 +1892,7 @@ static void OnWriteStartBytesCallbackHelper(object asyncState) completeSelf = thisPtr.HandleWriteStartBytes(); throwing = false; } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1928,7 +1928,7 @@ static void OnWriteBufferedMessage(object asyncState) completeSelf = thisPtr.HandleWriteBufferedMessage(); throwing = false; } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1963,7 +1963,7 @@ static void OnWriteEndBytes(object asyncState) completeSelf = thisPtr.HandleWriteEndBytes(); success = true; } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/SocketConnection.cs b/System.ServiceModel/System/ServiceModel/Channels/SocketConnection.cs index 2a57b0bdb..989fda614 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/SocketConnection.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/SocketConnection.cs @@ -27,9 +27,16 @@ class SocketConnection : IConnection // common state Socket socket; - TimeSpan sendTimeout; + TimeSpan asyncSendTimeout; TimeSpan readFinTimeout; - TimeSpan receiveTimeout; + TimeSpan asyncReceiveTimeout; + + // Socket.SendTimeout/Socket.ReceiveTimeout only work with the synchronous API calls and therefore they + // do not get updated when asynchronous Send/Read operations are performed. In order to make sure we + // Set the proper timeouts on the Socket itself we need to keep these two additional fields. + TimeSpan socketSyncSendTimeout; + TimeSpan socketSyncReceiveTimeout; + CloseState closeState; bool isShutdown; bool noDelay = false; @@ -83,7 +90,8 @@ public SocketConnection(Socket socket, ConnectionBufferPool connectionBufferPool this.readBuffer = this.connectionBufferPool.Take(); this.asyncReadBufferSize = this.readBuffer.Length; this.socket.SendBufferSize = this.socket.ReceiveBufferSize = this.asyncReadBufferSize; - this.sendTimeout = this.receiveTimeout = TimeSpan.MaxValue; + this.asyncSendTimeout = this.asyncReceiveTimeout = TimeSpan.MaxValue; + this.socketSyncSendTimeout = this.socketSyncReceiveTimeout = TimeSpan.MaxValue; this.remoteEndpoint = null; @@ -147,7 +155,7 @@ public IPEndPoint RemoteIPEndPoint // will never be a timeout error, so TimeSpan.Zero is ok #pragma warning suppress 56503 // Called from Receive path, SocketConnection cannot allow a SocketException to escape. throw DiagnosticUtility.ExceptionUtility.ThrowHelper( - ConvertReceiveException(socketException, TimeSpan.Zero), ExceptionEventType); + ConvertReceiveException(socketException, TimeSpan.Zero, TimeSpan.Zero), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { @@ -241,14 +249,14 @@ string RemoteEndpointAddress static void OnReceiveTimeout(object state) { SocketConnection thisPtr = (SocketConnection)state; - thisPtr.Abort(SR.GetString(SR.SocketAbortedReceiveTimedOut, thisPtr.receiveTimeout), TransferOperation.Read); + thisPtr.Abort(SR.GetString(SR.SocketAbortedReceiveTimedOut, thisPtr.asyncReceiveTimeout), TransferOperation.Read); } static void OnSendTimeout(object state) { SocketConnection thisPtr = (SocketConnection)state; thisPtr.Abort(TraceEventType.Warning, - SR.GetString(SR.SocketAbortedSendTimedOut, thisPtr.sendTimeout), TransferOperation.Write); + SR.GetString(SR.SocketAbortedSendTimedOut, thisPtr.asyncSendTimeout), TransferOperation.Write); } static void OnReceiveCompleted(IAsyncResult result) @@ -559,7 +567,7 @@ public void Shutdown(TimeSpan timeout) catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( - ConvertSendException(socketException, TimeSpan.MaxValue), ExceptionEventType); + ConvertSendException(socketException, TimeSpan.MaxValue, this.socketSyncSendTimeout), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { @@ -670,15 +678,15 @@ public bool EndValidate(IAsyncResult result) return CompletedAsyncResult.End(result); } - Exception ConvertSendException(SocketException socketException, TimeSpan remainingTime) + Exception ConvertSendException(SocketException socketException, TimeSpan remainingTime, TimeSpan timeout) { - return ConvertTransferException(socketException, this.sendTimeout, socketException, + return ConvertTransferException(socketException, timeout, socketException, TransferOperation.Write, this.aborted, this.timeoutErrorString, this.timeoutErrorTransferOperation, this, remainingTime); } - Exception ConvertReceiveException(SocketException socketException, TimeSpan remainingTime) + Exception ConvertReceiveException(SocketException socketException, TimeSpan remainingTime, TimeSpan timeout) { - return ConvertTransferException(socketException, this.receiveTimeout, socketException, + return ConvertTransferException(socketException, timeout, socketException, TransferOperation.Read, this.aborted, this.timeoutErrorString, this.timeoutErrorTransferOperation, this, remainingTime); } @@ -879,7 +887,7 @@ public AsyncCompletionResult BeginWrite(byte[] buffer, int offset, int size, boo catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( - ConvertSendException(socketException, TimeSpan.MaxValue), ExceptionEventType); + ConvertSendException(socketException, TimeSpan.MaxValue, this.asyncSendTimeout), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { @@ -939,9 +947,9 @@ void OnSendAsync(object sender, SocketAsyncEventArgs eventArgs) } catch (SocketException socketException) { - this.asyncWriteException = ConvertSendException(socketException, TimeSpan.MaxValue); + this.asyncWriteException = ConvertSendException(socketException, TimeSpan.MaxValue, this.asyncSendTimeout); } -#pragma warning suppress 56500 // [....], transferring exception to caller +#pragma warning suppress 56500 // Microsoft, transferring exception to caller catch (Exception exception) { if (Fx.IsFatal(exception)) @@ -1038,7 +1046,7 @@ public void Write(byte[] buffer, int offset, int size, bool immediate, TimeSpan catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( - ConvertSendException(socketException, timeoutHelper.RemainingTime()), ExceptionEventType); + ConvertSendException(socketException, timeoutHelper.RemainingTime(), this.socketSyncSendTimeout), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { @@ -1102,7 +1110,7 @@ int ReadCore(byte[] buffer, int offset, int size, TimeSpan timeout, bool closing catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper( - ConvertReceiveException(socketException, timeoutHelper.RemainingTime()), ExceptionEventType); + ConvertReceiveException(socketException, timeoutHelper.RemainingTime(), this.socketSyncReceiveTimeout), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { @@ -1199,7 +1207,7 @@ AsyncCompletionResult BeginReadCore(int offset, int size, TimeSpan timeout, } catch (SocketException socketException) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelper(ConvertReceiveException(socketException, TimeSpan.MaxValue), ExceptionEventType); + throw DiagnosticUtility.ExceptionUtility.ThrowHelper(ConvertReceiveException(socketException, TimeSpan.MaxValue, this.asyncReceiveTimeout), ExceptionEventType); } catch (ObjectDisposedException objectDisposedException) { @@ -1268,13 +1276,13 @@ void OnReceive(IAsyncResult result) } catch (SocketException socketException) { - this.asyncReadException = ConvertReceiveException(socketException, TimeSpan.MaxValue); + this.asyncReadException = ConvertReceiveException(socketException, TimeSpan.MaxValue, this.asyncReceiveTimeout); } catch (ObjectDisposedException objectDisposedException) { this.asyncReadException = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Read); } -#pragma warning suppress 56500 // [....], transferring exception to caller +#pragma warning suppress 56500 // Microsoft, transferring exception to caller catch (Exception exception) { if (Fx.IsFatal(exception)) @@ -1304,9 +1312,9 @@ void OnReceiveAsync(object sender, SocketAsyncEventArgs eventArgs) } catch (SocketException socketException) { - asyncReadException = ConvertReceiveException(socketException, TimeSpan.MaxValue); + asyncReadException = ConvertReceiveException(socketException, TimeSpan.MaxValue, this.asyncReceiveTimeout); } -#pragma warning suppress 56500 // [....], transferring exception to caller +#pragma warning suppress 56500 // Microsoft, transferring exception to caller catch (Exception exception) { if (Fx.IsFatal(exception)) @@ -1429,7 +1437,7 @@ void SetReadTimeout(TimeSpan timeout, bool synchronous, bool closing) new TimeoutException(SR.GetString(SR.TcpConnectionTimedOut, timeout)), ExceptionEventType); } - if (UpdateTimeout(this.receiveTimeout, timeout)) + if (ShouldUpdateTimeout(this.socketSyncReceiveTimeout, timeout)) { lock (ThisLock) { @@ -1439,12 +1447,12 @@ void SetReadTimeout(TimeSpan timeout, bool synchronous, bool closing) } this.socket.ReceiveTimeout = TimeoutHelper.ToMilliseconds(timeout); } - this.receiveTimeout = timeout; + this.socketSyncReceiveTimeout = timeout; } } else { - this.receiveTimeout = timeout; + this.asyncReceiveTimeout = timeout; if (timeout == TimeSpan.MaxValue) { CancelReceiveTimer(); @@ -1469,19 +1477,19 @@ void SetWriteTimeout(TimeSpan timeout, bool synchronous) new TimeoutException(SR.GetString(SR.TcpConnectionTimedOut, timeout)), ExceptionEventType); } - if (UpdateTimeout(this.sendTimeout, timeout)) + if (ShouldUpdateTimeout(this.socketSyncSendTimeout, timeout)) { lock (ThisLock) { ThrowIfNotOpen(); this.socket.SendTimeout = TimeoutHelper.ToMilliseconds(timeout); } - this.sendTimeout = timeout; + this.socketSyncSendTimeout = timeout; } } else { - this.sendTimeout = timeout; + this.asyncSendTimeout = timeout; if (timeout == TimeSpan.MaxValue) { CancelSendTimer(); @@ -1493,7 +1501,7 @@ void SetWriteTimeout(TimeSpan timeout, bool synchronous) } } - bool UpdateTimeout(TimeSpan oldTimeout, TimeSpan newTimeout) + bool ShouldUpdateTimeout(TimeSpan oldTimeout, TimeSpan newTimeout) { if (oldTimeout == newTimeout) { @@ -1927,7 +1935,7 @@ static void OnConnect(IAsyncResult result) { completeSelf = thisPtr.StartConnect(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -2234,7 +2242,7 @@ static void StartAccept(object state) { completeSelf = thisPtr.StartAccept(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/SslStreamSecurityBindingElement.cs b/System.ServiceModel/System/ServiceModel/Channels/SslStreamSecurityBindingElement.cs index baf6e2dfd..957aefd91 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/SslStreamSecurityBindingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/SslStreamSecurityBindingElement.cs @@ -89,7 +89,7 @@ public override IChannelFactory BuildChannelFactory(BindingC throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters cannot be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null context.BindingParameters.Add(this); return context.BuildInnerChannelFactory(); } @@ -101,7 +101,7 @@ public override bool CanBuildChannelFactory(BindingContext context) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters cannot be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null context.BindingParameters.Add(this); return context.CanBuildInnerChannelFactory(); } @@ -113,7 +113,7 @@ public override IChannelListener BuildChannelListener(Bindin throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters cannot be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null context.BindingParameters.Add(this); return context.BuildInnerChannelListener(); } @@ -125,7 +125,7 @@ public override bool CanBuildChannelListener(BindingContext context) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters cannot be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null context.BindingParameters.Add(this); return context.CanBuildInnerChannelListener(); } diff --git a/System.ServiceModel/System/ServiceModel/Channels/SslStreamSecurityUpgradeProvider.cs b/System.ServiceModel/System/ServiceModel/Channels/SslStreamSecurityUpgradeProvider.cs index a675b3993..a9761c4dc 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/SslStreamSecurityUpgradeProvider.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/SslStreamSecurityUpgradeProvider.cs @@ -439,7 +439,7 @@ void OnOpenTokenAuthenticator(IAsyncResult result) { completeSelf = this.HandleOpenAuthenticatorComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -470,7 +470,7 @@ void OnOpenTokenProvider(IAsyncResult result) { completeSelf = this.HandleOpenTokenProviderComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -501,7 +501,7 @@ void OnGetToken(IAsyncResult result) { completeSelf = this.HandleGetTokenComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -532,7 +532,7 @@ void OnCloseTokenProvider(IAsyncResult result) { completeSelf = this.HandleCloseTokenProviderComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1142,7 +1142,7 @@ void OnBaseOpen(IAsyncResult result) { completeSelf = this.HandleBaseOpenComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1173,7 +1173,7 @@ void OnOpenTokenProvider(IAsyncResult result) { completeSelf = this.HandleOpenTokenProviderComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1204,7 +1204,7 @@ void OnGetClientToken(IAsyncResult result) { completeSelf = this.HandleGetTokenComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1294,7 +1294,7 @@ void OnBaseClose(IAsyncResult result) { completeSelf = this.HandleBaseCloseComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1324,7 +1324,7 @@ void OnCloseTokenProvider(IAsyncResult result) { SecurityUtils.EndCloseTokenProviderIfRequired(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/StandardBindingImporter.cs b/System.ServiceModel/System/ServiceModel/Channels/StandardBindingImporter.cs index 55a2020f7..364205eab 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/StandardBindingImporter.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/StandardBindingImporter.cs @@ -21,7 +21,7 @@ void IWsdlImportExtension.ImportEndpoint(WsdlImporter importer, WsdlEndpointConv if (endpointContext == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointContext"); -#pragma warning suppress 56506 // [....], endpointContext.Endpoint is never null +#pragma warning suppress 56506 // Microsoft, endpointContext.Endpoint is never null if (endpointContext.Endpoint.Binding == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointContext.Binding"); diff --git a/System.ServiceModel/System/ServiceModel/Channels/StreamSecurityUpgradeAcceptorAsyncResult.cs b/System.ServiceModel/System/ServiceModel/Channels/StreamSecurityUpgradeAcceptorAsyncResult.cs index fb32637e2..f045513e2 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/StreamSecurityUpgradeAcceptorAsyncResult.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/StreamSecurityUpgradeAcceptorAsyncResult.cs @@ -90,7 +90,7 @@ static void OnAuthenticateAsServer(IAsyncResult result) { acceptUpgradeAsyncResult.CompleteAuthenticateAsServer(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/StreamSecurityUpgradeInitiatorAsyncResult.cs b/System.ServiceModel/System/ServiceModel/Channels/StreamSecurityUpgradeInitiatorAsyncResult.cs index 5d18a8df1..37d443c87 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/StreamSecurityUpgradeInitiatorAsyncResult.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/StreamSecurityUpgradeInitiatorAsyncResult.cs @@ -93,7 +93,7 @@ static void OnAuthenticateAsClient(IAsyncResult result) { thisPtr.CompleteAuthenticateAsClient(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/StreamedFramingRequestChannel.cs b/System.ServiceModel/System/ServiceModel/Channels/StreamedFramingRequestChannel.cs index fc5e285e2..ccfc53f43 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/StreamedFramingRequestChannel.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/StreamedFramingRequestChannel.cs @@ -348,7 +348,7 @@ static void OnWritePreamble(object asyncState) { completeSelf = thisPtr.HandleWritePreamble(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -377,7 +377,7 @@ static void OnWritePreambleEnd(object asyncState) thisPtr.connection.EndWrite(); completeSelf = thisPtr.ReadPreambleAck(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -405,7 +405,7 @@ static void OnReadPreambleAck(object state) { completeSelf = thisPtr.HandlePreambleAck(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -438,7 +438,7 @@ static void OnUpgrade(IAsyncResult result) { completeSelf = thisPtr.HandleUpgrade(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -470,7 +470,7 @@ static void OnFailedUpgrade(IAsyncResult result) { ConnectionUpgradeHelper.EndDecodeFramingFault(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -763,7 +763,7 @@ static void OnEstablishConnection(IAsyncResult result) completeSelf = thisPtr.HandleEstablishConnection(result); throwing = false; } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -805,7 +805,7 @@ static void OnWriteMessage(IAsyncResult result) completeSelf = thisPtr.HandleWriteMessage(result); throwing = false; } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -842,7 +842,7 @@ static void OnReceiveReply(IAsyncResult result) completeSelf = thisPtr.CompleteReceiveReply(result); throwing = false; } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/SynchronizedMessageSource.cs b/System.ServiceModel/System/ServiceModel/Channels/SynchronizedMessageSource.cs index 993807584..91df25a65 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/SynchronizedMessageSource.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/SynchronizedMessageSource.cs @@ -176,7 +176,7 @@ static void OnEnterComplete(object state, Exception asyncException) thisPtr.exitLock = true; completeSelf = thisPtr.PerformOperation(thisPtr.timeoutHelper.RemainingTime()); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -225,7 +225,7 @@ static void OnReceiveComplete(object state) { thisPtr.SetReturnValue(thisPtr.Source.EndReceive()); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -270,7 +270,7 @@ static void OnWaitForMessageComplete(object state) { thisPtr.SetReturnValue(thisPtr.Source.EndWaitForMessage()); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/TransportBindingElement.cs b/System.ServiceModel/System/ServiceModel/Channels/TransportBindingElement.cs index c1727702b..799f5ba41 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/TransportBindingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/TransportBindingElement.cs @@ -117,7 +117,7 @@ public override T GetProperty(BindingContext context) // to cover all our bases, let's iterate through the BindingParameters to make sure // we haven't missed a query (since we're the Transport and we're at the bottom) -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters cannot be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null Collection bindingElements = context.BindingParameters.FindAll(); T result = default(T); @@ -154,7 +154,7 @@ ChannelProtectionRequirements GetProtectionRequirements(AddressingVersion addres internal ChannelProtectionRequirements GetProtectionRequirements(BindingContext context) { AddressingVersion addressingVersion = AddressingVersion.WSAddressing10; -#pragma warning suppress 56506 // [....], CustomBinding.Elements can never be null +#pragma warning suppress 56506 // Microsoft, CustomBinding.Elements can never be null MessageEncodingBindingElement messageEncoderBindingElement = context.Binding.Elements.Find(); if (messageEncoderBindingElement != null) { @@ -183,7 +183,7 @@ internal static void ExportWsdlEndpoint(WsdlExporter exporter, WsdlEndpointConve } // Set SoapBinding Transport URI -#pragma warning suppress 56506 // [....], these properties cannot be null in this context +#pragma warning suppress 56506 // Microsoft, these properties cannot be null in this context BindingElementCollection bindingElements = endpointContext.Endpoint.Binding.CreateBindingElements(); if (wsdlTransportUri != null) { diff --git a/System.ServiceModel/System/ServiceModel/Channels/TransportBindingElementImporter.cs b/System.ServiceModel/System/ServiceModel/Channels/TransportBindingElementImporter.cs index 3cd450b6d..9e6b90657 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/TransportBindingElementImporter.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/TransportBindingElementImporter.cs @@ -36,20 +36,20 @@ void IWsdlImportExtension.ImportEndpoint(WsdlImporter importer, WsdlEndpointConv throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } -#pragma warning suppress 56506 // [....], these properties cannot be null in this context +#pragma warning suppress 56506 // Microsoft, these properties cannot be null in this context if (context.Endpoint.Binding == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context.Endpoint.Binding"); } -#pragma warning suppress 56506 // [....], CustomBinding.Elements never be null +#pragma warning suppress 56506 // Microsoft, CustomBinding.Elements never be null TransportBindingElement transportBindingElement = GetBindingElements(context).Find(); bool transportHandledExternaly = (transportBindingElement != null) && !StateHelper.IsRegisteredTransportBindingElement(importer, context); if (transportHandledExternaly) return; -#pragma warning suppress 56506 // [....], these properties cannot be null in this context +#pragma warning suppress 56506 // Microsoft, these properties cannot be null in this context WsdlNS.SoapBinding soapBinding = (WsdlNS.SoapBinding)context.WsdlBinding.Extensions.Find(typeof(WsdlNS.SoapBinding)); if (soapBinding != null && transportBindingElement == null) { diff --git a/System.ServiceModel/System/ServiceModel/Channels/TransportDuplexSessionChannel.cs b/System.ServiceModel/System/ServiceModel/Channels/TransportDuplexSessionChannel.cs index ec0777219..d0a75974c 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/TransportDuplexSessionChannel.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/TransportDuplexSessionChannel.cs @@ -739,7 +739,7 @@ static void OnCloseOutputSession(IAsyncResult result) { completeSelf = thisPtr.HandleCloseOutputSession(result, false); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -771,7 +771,7 @@ static void OnCloseInputSession(IAsyncResult result) { completeSelf = thisPtr.HandleCloseInputSession(result, false); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -937,7 +937,7 @@ static void OnEnterComplete(object state, Exception asyncException) { completeSelf = thisPtr.WriteEndBytes(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -965,7 +965,7 @@ static void OnWriteComplete(object asyncState) { thisPtr.HandleWriteEndBytesComplete(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1105,7 +1105,7 @@ static void OnEnterComplete(object state, Exception asyncException) { completeSelf = thisPtr.WriteCore(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1133,7 +1133,7 @@ static void OnWriteComplete(object asyncState) { thisPtr.channel.FinishWritingMessage(); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1290,7 +1290,7 @@ static void OnReceive(IAsyncResult result) DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/TransportManager.cs b/System.ServiceModel/System/ServiceModel/Channels/TransportManager.cs index aedfcbdd3..5bf91cc01 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/TransportManager.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/TransportManager.cs @@ -345,7 +345,7 @@ void OnScheduled() { this.OnScheduled(this.parent); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/TransportSecurityHelpers.cs b/System.ServiceModel/System/ServiceModel/Channels/TransportSecurityHelpers.cs index 3abbf4e36..84154efa7 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/TransportSecurityHelpers.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/TransportSecurityHelpers.cs @@ -606,7 +606,7 @@ static void OnGetToken(IAsyncResult result) { thisPtr.CompleteGetToken(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -700,7 +700,7 @@ static void OnGetToken(IAsyncResult result) { thisPtr.CompleteGetToken(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Channels/UnsafeNativeMethods.cs b/System.ServiceModel/System/ServiceModel/Channels/UnsafeNativeMethods.cs index 275270b40..1ace36ecf 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/UnsafeNativeMethods.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/UnsafeNativeMethods.cs @@ -1203,7 +1203,7 @@ internal PipeHandle(IntPtr handle) internal int GetClientPid() { int pid; -#pragma warning suppress 56523 // [....], Win32Exception ctor calls Marshal.GetLastWin32Error() +#pragma warning suppress 56523 // Microsoft, Win32Exception ctor calls Marshal.GetLastWin32Error() bool success = UnsafeNativeMethods.GetNamedPipeClientProcessId(this, out pid); if (!success) { diff --git a/System.ServiceModel/System/ServiceModel/Channels/UriPrefixTable.cs b/System.ServiceModel/System/ServiceModel/Channels/UriPrefixTable.cs index 71549cd70..4795a0917 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/UriPrefixTable.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/UriPrefixTable.cs @@ -56,7 +56,7 @@ object ThisLock { // The UriPrefixTable instance itself is used as a // synchronization primitive in the TransportManagers and the - // TransportManagerContainers so we return 'this' to keep them in [....]. + // TransportManagerContainers so we return 'this' to keep them in sync. return this; } } diff --git a/System.ServiceModel/System/ServiceModel/Channels/WindowsStreamSecurityBindingElement.cs b/System.ServiceModel/System/ServiceModel/Channels/WindowsStreamSecurityBindingElement.cs index 8f027c01c..e1f36707c 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/WindowsStreamSecurityBindingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/WindowsStreamSecurityBindingElement.cs @@ -57,7 +57,7 @@ public override IChannelFactory BuildChannelFactory(BindingC throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters cannot be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null context.BindingParameters.Add(this); return context.BuildInnerChannelFactory(); } @@ -69,7 +69,7 @@ public override bool CanBuildChannelFactory(BindingContext context) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters cannot be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null context.BindingParameters.Add(this); return context.CanBuildInnerChannelFactory(); } @@ -81,7 +81,7 @@ public override IChannelListener BuildChannelListener(Bindin throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters cannot be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null context.BindingParameters.Add(this); return context.BuildInnerChannelListener(); } @@ -93,7 +93,7 @@ public override bool CanBuildChannelListener(BindingContext context) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } -#pragma warning suppress 56506 // [....], BindingContext.BindingParameters cannot be null +#pragma warning suppress 56506 // Microsoft, BindingContext.BindingParameters cannot be null context.BindingParameters.Add(this); return context.CanBuildInnerChannelListener(); } diff --git a/System.ServiceModel/System/ServiceModel/Channels/WindowsStreamSecurityUpgradeProvider.cs b/System.ServiceModel/System/ServiceModel/Channels/WindowsStreamSecurityUpgradeProvider.cs index feaf5f1b1..441c80b91 100644 --- a/System.ServiceModel/System/ServiceModel/Channels/WindowsStreamSecurityUpgradeProvider.cs +++ b/System.ServiceModel/System/ServiceModel/Channels/WindowsStreamSecurityUpgradeProvider.cs @@ -614,7 +614,7 @@ void OnBaseOpen(IAsyncResult result) { completeSelf = this.HandleBaseOpenComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -645,7 +645,7 @@ void OnOpenTokenProvider(IAsyncResult result) { completeSelf = this.HandleOpenTokenProviderComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -676,7 +676,7 @@ void OnGetSspiCredential(IAsyncResult result) { completeSelf = this.HandleGetSspiCredentialComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -758,7 +758,7 @@ void OnBaseClose(IAsyncResult result) { completeSelf = this.HandleBaseCloseComplete(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -788,7 +788,7 @@ void OnCloseTokenProvider(IAsyncResult result) { SecurityUtils.EndCloseTokenProviderIfRequired(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/ClientBase.cs b/System.ServiceModel/System/ServiceModel/ClientBase.cs index c969544ef..9da24fb18 100644 --- a/System.ServiceModel/System/ServiceModel/ClientBase.cs +++ b/System.ServiceModel/System/ServiceModel/ClientBase.cs @@ -376,7 +376,7 @@ ex is ObjectDisposedException || } else { -#pragma warning suppress 56503 // [....], We throw only for unknown exceptions. +#pragma warning suppress 56503 // Microsoft, We throw only for unknown exceptions. throw; } } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/BinaryMessageEncodingElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/BinaryMessageEncodingElement.cs index 05db2a829..94912a949 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/BinaryMessageEncodingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/BinaryMessageEncodingElement.cs @@ -63,7 +63,7 @@ public override void ApplyConfiguration(BindingElement bindingElement) binding.MaxSessionSize = this.MaxSessionSize; binding.MaxReadPoolSize = this.MaxReadPoolSize; binding.MaxWritePoolSize = this.MaxWritePoolSize; -#pragma warning suppress 56506 //[....]; base.ApplyConfiguration() checks for 'binding' being null +#pragma warning suppress 56506 //Microsoft; base.ApplyConfiguration() checks for 'binding' being null this.ReaderQuotas.ApplyConfiguration(binding.ReaderQuotas); binding.CompressionFormat = this.CompressionFormat; } @@ -73,7 +73,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); BinaryMessageEncodingElement source = (BinaryMessageEncodingElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.MaxSessionSize = source.MaxSessionSize; this.MaxReadPoolSize = source.MaxReadPoolSize; this.MaxWritePoolSize = source.MaxWritePoolSize; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/CallbackDebugElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/CallbackDebugElement.cs index e9ffa4980..68aaa7192 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/CallbackDebugElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/CallbackDebugElement.cs @@ -25,7 +25,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); CallbackDebugElement source = (CallbackDebugElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() check for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() check for 'from' being null this.IncludeExceptionDetailInFaults = source.IncludeExceptionDetailInFaults; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/CallbackTimeoutsElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/CallbackTimeoutsElement.cs index c12e897d2..e998b23a0 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/CallbackTimeoutsElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/CallbackTimeoutsElement.cs @@ -29,7 +29,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); CallbackTimeoutsElement source = (CallbackTimeoutsElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.TransactionTimeout = source.TransactionTimeout; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ClientCredentialsElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ClientCredentialsElement.cs index ca6fdc463..71c11065a 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ClientCredentialsElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ClientCredentialsElement.cs @@ -96,7 +96,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); ClientCredentialsElement source = (ClientCredentialsElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.ClientCertificate.Copy(source.ClientCertificate); this.ServiceCertificate.Copy(source.ServiceCertificate); this.Windows.Copy(source.Windows); diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ClientViaElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ClientViaElement.cs index 7c79bab3f..33e4d36bd 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ClientViaElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ClientViaElement.cs @@ -25,7 +25,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); ClientViaElement source = (ClientViaElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() check for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() check for 'from' being null this.ViaUri = source.ViaUri; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/CommonEndpointBehaviorElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/CommonEndpointBehaviorElement.cs index 6913327c2..d5220b39c 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/CommonEndpointBehaviorElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/CommonEndpointBehaviorElement.cs @@ -23,7 +23,7 @@ public override void Add(BehaviorExtensionElement element) { if (!typeof(System.ServiceModel.Description.IEndpointBehavior).IsAssignableFrom(element.BehaviorType)) { -#pragma warning disable 56506 //[....]; element.ElementInformation is guaranteed to be non-null(System.Configuration) +#pragma warning disable 56506 //Microsoft; element.ElementInformation is guaranteed to be non-null(System.Configuration) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigInvalidCommonEndpointBehaviorType, element.ConfigurationElementName, typeof(System.ServiceModel.Description.IEndpointBehavior).FullName), @@ -44,7 +44,7 @@ public override bool CanAdd(BehaviorExtensionElement element) { if (!typeof(System.ServiceModel.Description.IEndpointBehavior).IsAssignableFrom(element.BehaviorType)) { -#pragma warning disable 56506 //[....]; element.ElementInformation is guaranteed to be non-null(System.Configuration) +#pragma warning disable 56506 //Microsoft; element.ElementInformation is guaranteed to be non-null(System.Configuration) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigInvalidCommonEndpointBehaviorType, element.ConfigurationElementName, typeof(System.ServiceModel.Description.IEndpointBehavior).FullName), diff --git a/System.ServiceModel/System/ServiceModel/Configuration/CommonServiceBehaviorElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/CommonServiceBehaviorElement.cs index 963969c6d..ab4e50ac0 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/CommonServiceBehaviorElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/CommonServiceBehaviorElement.cs @@ -23,7 +23,7 @@ public override void Add(BehaviorExtensionElement element) { if (!typeof(System.ServiceModel.Description.IServiceBehavior).IsAssignableFrom(element.BehaviorType)) { -#pragma warning disable 56506 //[....]; element.ElementInformation is guaranteed to be non-null(System.Configuration) +#pragma warning disable 56506 //Microsoft; element.ElementInformation is guaranteed to be non-null(System.Configuration) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigInvalidCommonServiceBehaviorType, element.ConfigurationElementName, typeof(System.ServiceModel.Description.IServiceBehavior).FullName), @@ -44,7 +44,7 @@ public override bool CanAdd(BehaviorExtensionElement element) { if (!typeof(System.ServiceModel.Description.IServiceBehavior).IsAssignableFrom(element.BehaviorType)) { -#pragma warning disable 56506 //[....]; element.ElementInformation is guaranteed to be non-null(System.Configuration) +#pragma warning disable 56506 //Microsoft; element.ElementInformation is guaranteed to be non-null(System.Configuration) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigInvalidCommonServiceBehaviorType, element.ConfigurationElementName, typeof(System.ServiceModel.Description.IServiceBehavior).FullName), diff --git a/System.ServiceModel/System/ServiceModel/Configuration/CompositeDuplexElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/CompositeDuplexElement.cs index 8367bce36..960392bb7 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/CompositeDuplexElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/CompositeDuplexElement.cs @@ -35,7 +35,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); CompositeDuplexElement source = (CompositeDuplexElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.ClientBaseAddress = source.ClientBaseAddress; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ConnectionOrientedTransportElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ConnectionOrientedTransportElement.cs index 40411ccbc..d9f93eff4 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ConnectionOrientedTransportElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ConnectionOrientedTransportElement.cs @@ -111,7 +111,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); ConnectionOrientedTransportElement source = (ConnectionOrientedTransportElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.ConnectionBufferSize = source.ConnectionBufferSize; this.HostNameComparisonMode = source.HostNameComparisonMode; this.ChannelInitializationTimeout = source.ChannelInitializationTimeout; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/DataContractSerializerElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/DataContractSerializerElement.cs index ac7dea534..2997f3209 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/DataContractSerializerElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/DataContractSerializerElement.cs @@ -38,7 +38,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); DataContractSerializerElement source = (DataContractSerializerElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.IgnoreExtensionDataObject = source.IgnoreExtensionDataObject; this.MaxItemsInObjectGraph = source.MaxItemsInObjectGraph; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/EndpointBehaviorElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/EndpointBehaviorElement.cs index 02733601e..4c079f993 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/EndpointBehaviorElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/EndpointBehaviorElement.cs @@ -37,7 +37,7 @@ public override void Add(BehaviorExtensionElement element) } if (!typeof(System.ServiceModel.Description.IEndpointBehavior).IsAssignableFrom(element.BehaviorType)) { -#pragma warning disable 56506 //[....]; element.ElementInformation is guaranteed to be non-null(System.Configuration) +#pragma warning disable 56506 //Microsoft; element.ElementInformation is guaranteed to be non-null(System.Configuration) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigInvalidEndpointBehaviorType, element.ConfigurationElementName, this.Name), @@ -62,7 +62,7 @@ public override bool CanAdd(BehaviorExtensionElement element) } if (!typeof(System.ServiceModel.Description.IEndpointBehavior).IsAssignableFrom(element.BehaviorType)) { -#pragma warning disable 56506 //[....]; element.ElementInformation is guaranteed to be non-null(System.Configuration) +#pragma warning disable 56506 //Microsoft; element.ElementInformation is guaranteed to be non-null(System.Configuration) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigInvalidEndpointBehaviorType, element.ConfigurationElementName, this.Name), diff --git a/System.ServiceModel/System/ServiceModel/Configuration/HttpTransportElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/HttpTransportElement.cs index e8e8d211e..b3df15d6f 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/HttpTransportElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/HttpTransportElement.cs @@ -211,7 +211,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); HttpTransportElement source = (HttpTransportElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.AllowCookies = source.AllowCookies; this.RequestInitializationTimeout = source.RequestInitializationTimeout; this.AuthenticationScheme = source.AuthenticationScheme; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/HttpsTransportElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/HttpsTransportElement.cs index 38d9700d5..5e54dbf2f 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/HttpsTransportElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/HttpsTransportElement.cs @@ -30,7 +30,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); HttpsTransportElement source = (HttpsTransportElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.RequireClientCertificate = source.RequireClientCertificate; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/IdentityElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/IdentityElement.cs index 50ed2a799..e7ec1f864 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/IdentityElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/IdentityElement.cs @@ -111,7 +111,7 @@ public void InitializeFrom(EndpointIdentity identity) else if (identity is X509CertificateEndpointIdentity) { X509Certificate2Collection certs = ((X509CertificateEndpointIdentity)identity).Certificates; -#pragma warning suppress 56506 //[....]; this.Certificate can never be null (underlying configuration system guarantees) +#pragma warning suppress 56506 //Microsoft; this.Certificate can never be null (underlying configuration system guarantees) this.Certificate.EncodedValue = Convert.ToBase64String(certs.Export(certs.Count == 1 ? X509ContentType.SerializedCert : X509ContentType.SerializedStore)); } } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/IssuedTokenClientElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/IssuedTokenClientElement.cs index c12c1022c..7c925c490 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/IssuedTokenClientElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/IssuedTokenClientElement.cs @@ -94,17 +94,17 @@ public void Copy(IssuedTokenClientElement from) this.MaxIssuedTokenCachingTime = from.MaxIssuedTokenCachingTime; this.IssuedTokenRenewalThresholdPercentage = from.IssuedTokenRenewalThresholdPercentage; -#pragma warning suppress 56506 //[....]; from.ElementInformation.Properties[ConfigurationStrings.LocalIssuerIssuedTokenParameters] can never be null (underlying configuration system guarantees) +#pragma warning suppress 56506 //Microsoft; from.ElementInformation.Properties[ConfigurationStrings.LocalIssuerIssuedTokenParameters] can never be null (underlying configuration system guarantees) if (PropertyValueOrigin.Default != from.ElementInformation.Properties[ConfigurationStrings.LocalIssuer].ValueOrigin) { this.LocalIssuer.Copy(from.LocalIssuer); } -#pragma warning suppress 56506 //[....]; from.ElementInformation.Properties[ConfigurationStrings.LocalIssuerChannelBehaviors] can never be null (underlying configuration system guarantees) +#pragma warning suppress 56506 //Microsoft; from.ElementInformation.Properties[ConfigurationStrings.LocalIssuerChannelBehaviors] can never be null (underlying configuration system guarantees) if (PropertyValueOrigin.Default != from.ElementInformation.Properties[ConfigurationStrings.LocalIssuerChannelBehaviors].ValueOrigin) { this.LocalIssuerChannelBehaviors = from.LocalIssuerChannelBehaviors; } -#pragma warning suppress 56506 //[....]; from.ElementInformation.Properties[ConfigurationStrings.IssuerChannelBehaviors] can never be null (underlying configuration system guarantees) +#pragma warning suppress 56506 //Microsoft; from.ElementInformation.Properties[ConfigurationStrings.IssuerChannelBehaviors] can never be null (underlying configuration system guarantees) if (PropertyValueOrigin.Default != from.ElementInformation.Properties[ConfigurationStrings.IssuerChannelBehaviors].ValueOrigin) { foreach (IssuedTokenClientBehaviorsElement element in from.IssuerChannelBehaviors) diff --git a/System.ServiceModel/System/ServiceModel/Configuration/IssuedTokenServiceElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/IssuedTokenServiceElement.cs index 426a9ae19..5d7544aeb 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/IssuedTokenServiceElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/IssuedTokenServiceElement.cs @@ -114,7 +114,7 @@ public void Copy(IssuedTokenServiceElement from) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("from"); } this.SamlSerializerType = from.SamlSerializerType; -#pragma warning suppress 56506 // [....]; ElementInformation is never null. +#pragma warning suppress 56506 // Microsoft; ElementInformation is never null. PropertyInformationCollection propertyInfo = from.ElementInformation.Properties; if (propertyInfo[ConfigurationStrings.KnownCertificates].ValueOrigin != PropertyValueOrigin.Default) { diff --git a/System.ServiceModel/System/ServiceModel/Configuration/MtomMessageEncodingElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/MtomMessageEncodingElement.cs index 8f40a1356..6ad15c1e4 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/MtomMessageEncodingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/MtomMessageEncodingElement.cs @@ -24,7 +24,7 @@ public override void ApplyConfiguration(BindingElement bindingElement) binding.WriteEncoding = this.WriteEncoding; binding.MaxReadPoolSize = this.MaxReadPoolSize; binding.MaxWritePoolSize = this.MaxWritePoolSize; -#pragma warning suppress 56506 //[....]; base.ApplyConfiguration() checks for 'binding' being null +#pragma warning suppress 56506 //Microsoft; base.ApplyConfiguration() checks for 'binding' being null this.ReaderQuotas.ApplyConfiguration(binding.ReaderQuotas); binding.MaxBufferSize = this.MaxBufferSize; } @@ -39,7 +39,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); MtomMessageEncodingElement source = (MtomMessageEncodingElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.MessageVersion = source.MessageVersion; this.WriteEncoding = source.WriteEncoding; this.MaxReadPoolSize = source.MaxReadPoolSize; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/NamedPipeTransportElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/NamedPipeTransportElement.cs index 941b4601c..d5cfd7558 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/NamedPipeTransportElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/NamedPipeTransportElement.cs @@ -22,7 +22,7 @@ public override void ApplyConfiguration(BindingElement bindingElement) { base.ApplyConfiguration(bindingElement); NamedPipeTransportBindingElement binding = (NamedPipeTransportBindingElement)bindingElement; -#pragma warning suppress 56506 //[....]; base.ApplyConfiguration above checks for bindingElement being null +#pragma warning suppress 56506 //Microsoft; base.ApplyConfiguration above checks for bindingElement being null this.ConnectionPoolSettings.ApplyConfiguration(binding.ConnectionPoolSettings); this.PipeSettings.ApplyConfiguration(binding.PipeSettings); } @@ -30,7 +30,7 @@ public override void ApplyConfiguration(BindingElement bindingElement) protected internal override void InitializeFrom(BindingElement bindingElement) { base.InitializeFrom(bindingElement); -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument NamedPipeTransportBindingElement binding = (NamedPipeTransportBindingElement)bindingElement; this.ConnectionPoolSettings.InitializeFrom(binding.ConnectionPoolSettings); this.PipeSettings.InitializeFrom(binding.PipeSettings); @@ -40,7 +40,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) { base.CopyFrom(from); NamedPipeTransportElement source = (NamedPipeTransportElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.ConnectionPoolSettings.CopyFrom(source.ConnectionPoolSettings); this.PipeSettings.CopyFrom(source.PipeSettings); } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/OneWayElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/OneWayElement.cs index 0c90b056a..c3d3c3692 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/OneWayElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/OneWayElement.cs @@ -47,7 +47,7 @@ public override void ApplyConfiguration(BindingElement bindingElement) PropertyInformationCollection propertyInfo = this.ElementInformation.Properties; if (propertyInfo[ConfigurationStrings.ChannelPoolSettings].ValueOrigin != PropertyValueOrigin.Default) { -#pragma warning suppress 56506 // [....], base.ApplyConfiguration() validates the argument +#pragma warning suppress 56506 // Microsoft, base.ApplyConfiguration() validates the argument this.ChannelPoolSettings.ApplyConfiguration(oneWayBindingElement.ChannelPoolSettings); } oneWayBindingElement.MaxAcceptedChannels = this.MaxAcceptedChannels; @@ -59,7 +59,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); OneWayElement source = (OneWayElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument PropertyInformationCollection propertyInfo = source.ElementInformation.Properties; if (propertyInfo[ConfigurationStrings.ChannelPoolSettings].ValueOrigin != PropertyValueOrigin.Default) { diff --git a/System.ServiceModel/System/ServiceModel/Configuration/PeerTransportElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/PeerTransportElement.cs index 5b8d687f3..ddc638c79 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/PeerTransportElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/PeerTransportElement.cs @@ -68,7 +68,7 @@ public override void ApplyConfiguration(BindingElement bindingElement) binding.Port = this.Port; binding.MaxBufferPoolSize = this.MaxBufferPoolSize; binding.MaxReceivedMessageSize = this.MaxReceivedMessageSize; -#pragma warning suppress 56506 //[....]; base.ApplyConfiguration() checks for 'binding' being null +#pragma warning suppress 56506 //Microsoft; base.ApplyConfiguration() checks for 'binding' being null this.Security.ApplyConfiguration(binding.Security); } @@ -77,7 +77,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); PeerTransportElement source = (PeerTransportElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.ListenIPAddress = source.ListenIPAddress; this.Port = source.Port; this.MaxBufferPoolSize = source.MaxBufferPoolSize; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/PrivacyNoticeElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/PrivacyNoticeElement.cs index c8e310db5..bdfdf19f5 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/PrivacyNoticeElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/PrivacyNoticeElement.cs @@ -50,7 +50,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); PrivacyNoticeElement source = (PrivacyNoticeElement) from; - #pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument + #pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.Url = source.Url; this.Version = source.Version; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ReliableMessagingVersionConverter.cs b/System.ServiceModel/System/ServiceModel/Configuration/ReliableMessagingVersionConverter.cs index 5ea78edda..dff1f8fd2 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ReliableMessagingVersionConverter.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ReliableMessagingVersionConverter.cs @@ -32,7 +32,7 @@ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinati public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { string version = value as string; -#pragma warning suppress 56507 // [....], Really checking for null (meaning value was not a string) versus String.Empty +#pragma warning suppress 56507 // Microsoft, Really checking for null (meaning value was not a string) versus String.Empty if (version != null) { switch (version) diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ReliableSessionElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ReliableSessionElement.cs index 5fa338c0c..78c194c19 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ReliableSessionElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ReliableSessionElement.cs @@ -104,7 +104,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); ReliableSessionElement source = (ReliableSessionElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.AcknowledgementInterval = source.AcknowledgementInterval; this.FlowControlEnabled = source.FlowControlEnabled; this.InactivityTimeout = source.InactivityTimeout; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/RemoveBehaviorElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/RemoveBehaviorElement.cs index f7d061da2..04f104761 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/RemoveBehaviorElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/RemoveBehaviorElement.cs @@ -23,7 +23,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); RemoveBehaviorElement source = (RemoveBehaviorElement) from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.Name = source.Name; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/SecurityElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/SecurityElement.cs index 70c98b016..6866807d7 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/SecurityElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/SecurityElement.cs @@ -37,7 +37,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) SecurityElement source = (SecurityElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.SecureConversationBootstrap].ValueOrigin) this.SecureConversationBootstrap.CopyFrom(source.SecureConversationBootstrap); } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/SecurityElementBase.cs b/System.ServiceModel/System/ServiceModel/Configuration/SecurityElementBase.cs index 98c71d0c3..f27d8b8a4 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/SecurityElementBase.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/SecurityElementBase.cs @@ -173,7 +173,7 @@ public override void ApplyConfiguration(BindingElement bindingElement) SecurityBindingElement sbe = (SecurityBindingElement)bindingElement; -#pragma warning disable 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning disable 56506 //Microsoft; base.CopyFrom() checks for 'from' being null if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.DefaultAlgorithmSuite].ValueOrigin) sbe.DefaultAlgorithmSuite = this.DefaultAlgorithmSuite; if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.IncludeTimestamp].ValueOrigin) diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ServiceAuthorizationElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ServiceAuthorizationElement.cs index 3871c52a5..bea61241b 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ServiceAuthorizationElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ServiceAuthorizationElement.cs @@ -84,7 +84,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); ServiceAuthorizationElement source = (ServiceAuthorizationElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.PrincipalPermissionMode = source.PrincipalPermissionMode; this.RoleProviderName = source.RoleProviderName; this.ImpersonateCallerForAllOperations = source.ImpersonateCallerForAllOperations; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ServiceBehaviorElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ServiceBehaviorElement.cs index 28a42f4bf..feac09174 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ServiceBehaviorElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ServiceBehaviorElement.cs @@ -37,7 +37,7 @@ public override void Add(BehaviorExtensionElement element) } if (!typeof(System.ServiceModel.Description.IServiceBehavior).IsAssignableFrom(element.BehaviorType)) { -#pragma warning disable 56506 //[....]; element.ElementInformation is guaranteed to be non-null(System.Configuration) +#pragma warning disable 56506 //Microsoft; element.ElementInformation is guaranteed to be non-null(System.Configuration) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigInvalidServiceBehaviorType, element.ConfigurationElementName, this.Name), @@ -62,7 +62,7 @@ public override bool CanAdd(BehaviorExtensionElement element) } if (!typeof(System.ServiceModel.Description.IServiceBehavior).IsAssignableFrom(element.BehaviorType)) { -#pragma warning disable 56506 //[....]; element.ElementInformation is guaranteed to be non-null(System.Configuration) +#pragma warning disable 56506 //Microsoft; element.ElementInformation is guaranteed to be non-null(System.Configuration) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigInvalidServiceBehaviorType, element.ConfigurationElementName, this.Name), diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ServiceCredentialsElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ServiceCredentialsElement.cs index 050bca034..ae57ebb3f 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ServiceCredentialsElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ServiceCredentialsElement.cs @@ -98,7 +98,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); ServiceCredentialsElement source = (ServiceCredentialsElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.ClientCertificate.Copy(source.ClientCertificate); this.ServiceCertificate.Copy(source.ServiceCertificate); this.UserNameAuthentication.Copy(source.UserNameAuthentication); diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ServiceDebugElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ServiceDebugElement.cs index 86a1000cb..c3e7c986f 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ServiceDebugElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ServiceDebugElement.cs @@ -86,7 +86,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); ServiceDebugElement source = (ServiceDebugElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() check for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() check for 'from' being null this.HttpHelpPageEnabled = source.HttpHelpPageEnabled; this.HttpHelpPageUrl = source.HttpHelpPageUrl; this.HttpsHelpPageEnabled = source.HttpsHelpPageEnabled; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ServiceMetadataPublishingElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ServiceMetadataPublishingElement.cs index 236a9d882..f23ce7621 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ServiceMetadataPublishingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ServiceMetadataPublishingElement.cs @@ -95,7 +95,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); ServiceMetadataPublishingElement source = (ServiceMetadataPublishingElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() check for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() check for 'from' being null this.HttpGetEnabled = source.HttpGetEnabled; this.HttpGetUrl = source.HttpGetUrl; this.HttpsGetEnabled = source.HttpsGetEnabled; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelConfigurationElementCollection.cs b/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelConfigurationElementCollection.cs index 277cdad03..576cff6c0 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelConfigurationElementCollection.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelConfigurationElementCollection.cs @@ -239,7 +239,7 @@ public virtual ConfigurationElementType this[object key] } else { -#pragma warning disable 56506 //[....]; Variable 'key' checked for null previously +#pragma warning disable 56506 //Microsoft; Variable 'key' checked for null previously throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.ConfigKeysDoNotMatch, this.GetElementKey(value).ToString(), key.ToString())); diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelExtensionCollectionElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelExtensionCollectionElement.cs index eba49b2e2..9a6073794 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelExtensionCollectionElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelExtensionCollectionElement.cs @@ -48,7 +48,7 @@ public TServiceModelExtensionElement this[Type extensionType] if (!this.CollectionElementBaseType.IsAssignableFrom(extensionType)) { -#pragma warning disable 56506 //[....]; Variable 'extensionType' checked for null previously +#pragma warning disable 56506 //Microsoft; Variable 'extensionType' checked for null previously throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("extensionType", SR.GetString(SR.ConfigInvalidExtensionType, extensionType.ToString(), diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelSectionGroup.cs b/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelSectionGroup.cs index c05708f7b..112d210c2 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelSectionGroup.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ServiceModelSectionGroup.cs @@ -74,7 +74,7 @@ public static ServiceModelSectionGroup GetSectionGroup(Configuration config) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("config"); } -#pragma warning suppress 56506 //[....]; config.SectionGroups can never be null (underlying configuration system guarantees) +#pragma warning suppress 56506 //Microsoft; config.SectionGroups can never be null (underlying configuration system guarantees) return (ServiceModelSectionGroup)config.SectionGroups[ConfigurationStrings.SectionGroupName]; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ServiceSecurityAuditElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ServiceSecurityAuditElement.cs index a26244ce5..5cbdf80e1 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ServiceSecurityAuditElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ServiceSecurityAuditElement.cs @@ -52,7 +52,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) { base.CopyFrom(from); ServiceSecurityAuditElement source = (ServiceSecurityAuditElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.AuditLogLocation = source.AuditLogLocation; this.SuppressAuditFailure = source.SuppressAuditFailure; this.ServiceAuthorizationAuditLevel = source.ServiceAuthorizationAuditLevel; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ServiceThrottlingElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ServiceThrottlingElement.cs index 11f81f426..b6df0f71a 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ServiceThrottlingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ServiceThrottlingElement.cs @@ -44,7 +44,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); ServiceThrottlingElement source = (ServiceThrottlingElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.MaxConcurrentCalls = source.MaxConcurrentCalls; this.MaxConcurrentSessions = source.MaxConcurrentSessions; this.MaxConcurrentInstances = source.MaxConcurrentInstances; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/ServiceTimeoutsElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/ServiceTimeoutsElement.cs index 9bd23149f..573b1d9a9 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/ServiceTimeoutsElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/ServiceTimeoutsElement.cs @@ -29,7 +29,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); ServiceTimeoutsElement source = (ServiceTimeoutsElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.TransactionTimeout = source.TransactionTimeout; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/SslStreamSecurityElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/SslStreamSecurityElement.cs index 025ebc794..247bd119d 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/SslStreamSecurityElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/SslStreamSecurityElement.cs @@ -60,7 +60,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); SslStreamSecurityElement source = (SslStreamSecurityElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.RequireClientCertificate = source.RequireClientCertificate; this.SslProtocols = source.SslProtocols; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/StandardBindingCollectionElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/StandardBindingCollectionElement.cs index 64932814a..ed2e5bb7e 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/StandardBindingCollectionElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/StandardBindingCollectionElement.cs @@ -44,7 +44,7 @@ public override bool ContainsKey(string name) { // This line needed because of the IBindingSection implementation StandardBindingCollectionElement me = (StandardBindingCollectionElement)this; -#pragma warning suppress 56506 //[....]; me.Bindings can never be null (underlying configuration system guarantees) +#pragma warning suppress 56506 //Microsoft; me.Bindings can never be null (underlying configuration system guarantees) return me.Bindings.ContainsKey(name); } protected internal override Binding GetDefault() diff --git a/System.ServiceModel/System/ServiceModel/Configuration/StandardEndpointCollectionElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/StandardEndpointCollectionElement.cs index 51b14b08d..848b2d899 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/StandardEndpointCollectionElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/StandardEndpointCollectionElement.cs @@ -44,7 +44,7 @@ public override ReadOnlyCollection ConfiguredEndpoints public override bool ContainsKey(string name) { StandardEndpointCollectionElement me = (StandardEndpointCollectionElement)this; -#pragma warning suppress 56506 //[....]; me.Endpoints can never be null (underlying configuration system guarantees) +#pragma warning suppress 56506 //Microsoft; me.Endpoints can never be null (underlying configuration system guarantees) return me.Endpoints.ContainsKey(name); } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/TcpTransportElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/TcpTransportElement.cs index e792c9cab..bed3878e5 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/TcpTransportElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/TcpTransportElement.cs @@ -19,7 +19,7 @@ public TcpTransportElement() public override void ApplyConfiguration(BindingElement bindingElement) { base.ApplyConfiguration(bindingElement); -#pragma warning suppress 56506 // [....], base.ApplyConfiguration() validates the argument +#pragma warning suppress 56506 // Microsoft, base.ApplyConfiguration() validates the argument TcpTransportBindingElement binding = (TcpTransportBindingElement)bindingElement; PropertyInformationCollection propertyInfo = this.ElementInformation.Properties; if (this.ListenBacklog != TcpTransportDefaults.ListenBacklogConst) @@ -28,7 +28,7 @@ public override void ApplyConfiguration(BindingElement bindingElement) } binding.PortSharingEnabled = this.PortSharingEnabled; binding.TeredoEnabled = this.TeredoEnabled; -#pragma warning suppress 56506 // [....], base.ApplyConfiguration() validates the argument +#pragma warning suppress 56506 // Microsoft, base.ApplyConfiguration() validates the argument this.ConnectionPoolSettings.ApplyConfiguration(binding.ConnectionPoolSettings); binding.ExtendedProtectionPolicy = ChannelBindingUtility.BuildPolicy(this.ExtendedProtectionPolicy); } @@ -43,7 +43,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); TcpTransportElement source = (TcpTransportElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.ListenBacklog = source.ListenBacklog; this.PortSharingEnabled = source.PortSharingEnabled; this.TeredoEnabled = source.TeredoEnabled; @@ -59,7 +59,7 @@ protected override TransportBindingElement CreateDefaultBindingElement() protected internal override void InitializeFrom(BindingElement bindingElement) { base.InitializeFrom(bindingElement); -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument TcpTransportBindingElement binding = (TcpTransportBindingElement)bindingElement; if (binding.IsListenBacklogSet) { diff --git a/System.ServiceModel/System/ServiceModel/Configuration/TextMessageEncodingElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/TextMessageEncodingElement.cs index bf6497235..ec04b51b2 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/TextMessageEncodingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/TextMessageEncodingElement.cs @@ -24,7 +24,7 @@ public override void ApplyConfiguration(BindingElement bindingElement) binding.WriteEncoding = this.WriteEncoding; binding.MaxReadPoolSize = this.MaxReadPoolSize; binding.MaxWritePoolSize = this.MaxWritePoolSize; -#pragma warning suppress 56506 //[....]; base.ApplyConfiguration() checks for 'binding' being null +#pragma warning suppress 56506 //Microsoft; base.ApplyConfiguration() checks for 'binding' being null this.ReaderQuotas.ApplyConfiguration(binding.ReaderQuotas); } @@ -38,7 +38,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); TextMessageEncodingElement source = (TextMessageEncodingElement)from; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.MessageVersion = source.MessageVersion; this.WriteEncoding = source.WriteEncoding; this.MaxReadPoolSize = source.MaxReadPoolSize; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/TransactedBatchingElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/TransactedBatchingElement.cs index b74805626..176571cd0 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/TransactedBatchingElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/TransactedBatchingElement.cs @@ -22,7 +22,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); TransactedBatchingElement source = from as TransactedBatchingElement; -#pragma warning suppress 56506 //[....]; base.CopyFrom() checks for 'from' being null +#pragma warning suppress 56506 //Microsoft; base.CopyFrom() checks for 'from' being null this.MaxBatchSize = source.MaxBatchSize; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/TransactionFlowElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/TransactionFlowElement.cs index 652f729b0..de6601252 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/TransactionFlowElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/TransactionFlowElement.cs @@ -53,7 +53,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) { base.CopyFrom(from); TransactionFlowElement source = (TransactionFlowElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.TransactionProtocol = source.TransactionProtocol; } diff --git a/System.ServiceModel/System/ServiceModel/Configuration/TransactionProtocolConverter.cs b/System.ServiceModel/System/ServiceModel/Configuration/TransactionProtocolConverter.cs index 9bba5ca4c..12c1308b5 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/TransactionProtocolConverter.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/TransactionProtocolConverter.cs @@ -32,7 +32,7 @@ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinati public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { string protocol = value as string; -#pragma warning suppress 56507 // [....], Really checking for null (meaning value was not a string) versus String.Empty +#pragma warning suppress 56507 // Microsoft, Really checking for null (meaning value was not a string) versus String.Empty if (protocol != null) { switch (protocol) diff --git a/System.ServiceModel/System/ServiceModel/Configuration/TransportElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/TransportElement.cs index c45992719..18d9aea87 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/TransportElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/TransportElement.cs @@ -27,7 +27,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); TransportElement source = (TransportElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.ManualAddressing = source.ManualAddressing; this.MaxBufferPoolSize = source.MaxBufferPoolSize; this.MaxReceivedMessageSize = source.MaxReceivedMessageSize; diff --git a/System.ServiceModel/System/ServiceModel/Configuration/WindowsStreamSecurityElement.cs b/System.ServiceModel/System/ServiceModel/Configuration/WindowsStreamSecurityElement.cs index f82b3f7c2..e31633cd8 100644 --- a/System.ServiceModel/System/ServiceModel/Configuration/WindowsStreamSecurityElement.cs +++ b/System.ServiceModel/System/ServiceModel/Configuration/WindowsStreamSecurityElement.cs @@ -52,7 +52,7 @@ public override void CopyFrom(ServiceModelExtensionElement from) base.CopyFrom(from); WindowsStreamSecurityElement source = (WindowsStreamSecurityElement)from; -#pragma warning suppress 56506 // [....], base.CopyFrom() validates the argument +#pragma warning suppress 56506 // Microsoft, base.CopyFrom() validates the argument this.ProtectionLevel = source.ProtectionLevel; } diff --git a/System.ServiceModel/System/ServiceModel/Description/ClientClassGenerator.cs b/System.ServiceModel/System/ServiceModel/Description/ClientClassGenerator.cs index c7362683b..5712afbf7 100644 --- a/System.ServiceModel/System/ServiceModel/Description/ClientClassGenerator.cs +++ b/System.ServiceModel/System/ServiceModel/Description/ClientClassGenerator.cs @@ -61,7 +61,7 @@ internal ClientClassGenerator(bool tryAddHelperMethod, bool generateEventAsyncMe static string getDefaultValueForInitializationMethodName = "GetDefaultValueForInitialization"; // IMPORTANT: this table tracks the set of .ctors in ClientBase and DuplexClientBase. - // This table must be kept in [....] + // This table must be kept in sync // for DuplexClientBase, the initial InstanceContext param is assumed; ctor overloads must match between ClientBase and DuplexClientBase static Type[][] ClientCtorParamTypes = new Type[][] { @@ -107,7 +107,7 @@ internal ClientClassGenerator(bool tryAddHelperMethod, bool generateEventAsyncMe #if DEBUG static BindingFlags ctorBindingFlags = BindingFlags.Instance | BindingFlags.NonPublic; - static string DebugCheckTable_errorString = "Client code generation table out of [....] with ClientBase and DuplexClientBase ctors. Please investigate."; + static string DebugCheckTable_errorString = "Client code generation table out of sync with ClientBase and DuplexClientBase ctors. Please investigate."; // check the table against what we would get from reflection static void DebugCheckTable() diff --git a/System.ServiceModel/System/ServiceModel/Description/ConfigWriter.cs b/System.ServiceModel/System/ServiceModel/Description/ConfigWriter.cs index 2020a0444..c111c900c 100644 --- a/System.ServiceModel/System/ServiceModel/Description/ConfigWriter.cs +++ b/System.ServiceModel/System/ServiceModel/Description/ConfigWriter.cs @@ -40,7 +40,7 @@ internal ChannelEndpointElement WriteChannelDescription(ServiceEndpoint endpoint channelElement = new ChannelEndpointElement(endpoint.Address, typeName); - // [....]: review: Use decoded form to preserve the user-given friendly name, however, beacuse our Encoding algorithm + // Microsoft: review: Use decoded form to preserve the user-given friendly name, however, beacuse our Encoding algorithm // does not touch ASCII names, a name that looks like encoded name will not roundtrip(Example: "_x002C_" will turned into ",") channelElement.Name = NamingHelper.GetUniqueName(NamingHelper.CodeName(endpoint.Name), this.CheckIfChannelNameInUse, null); @@ -64,7 +64,7 @@ BindingDictionaryValue CreateBindingConfig(Binding binding) BindingDictionaryValue bindingDV; if (!bindingTable.TryGetValue(binding, out bindingDV)) { - // [....]: review: Use decoded form to preserve the user-given friendly name, however, beacuse our Encoding algorithm + // Microsoft: review: Use decoded form to preserve the user-given friendly name, however, beacuse our Encoding algorithm // does not touch ASCII names, a name that looks like encoded name will not roundtrip(Example: "_x002C_" will turned into ",") string bindingName = NamingHelper.GetUniqueName(NamingHelper.CodeName(binding.Name), this.CheckIfBindingNameInUse, null); string bindingSectionName; diff --git a/System.ServiceModel/System/ServiceModel/Description/ImportedPolicyConversionContext.cs b/System.ServiceModel/System/ServiceModel/Description/ImportedPolicyConversionContext.cs index 5d9a36665..711970a2a 100644 --- a/System.ServiceModel/System/ServiceModel/Description/ImportedPolicyConversionContext.cs +++ b/System.ServiceModel/System/ServiceModel/Description/ImportedPolicyConversionContext.cs @@ -13,7 +13,7 @@ namespace System.ServiceModel.Description public abstract partial class MetadataImporter { - //Consider, [....]: make this public + //Consider, Microsoft: make this public internal static IEnumerable GetPolicyConversionContextEnumerator(ServiceEndpoint endpoint, PolicyAlternatives policyAlternatives) { return ImportedPolicyConversionContext.GetPolicyConversionContextEnumerator(endpoint, policyAlternatives, MetadataImporterQuotas.Defaults); diff --git a/System.ServiceModel/System/ServiceModel/Description/MessageContractExporter.cs b/System.ServiceModel/System/ServiceModel/Description/MessageContractExporter.cs index e4a23bcc0..b92b7b207 100644 --- a/System.ServiceModel/System/ServiceModel/Description/MessageContractExporter.cs +++ b/System.ServiceModel/System/ServiceModel/Description/MessageContractExporter.cs @@ -511,7 +511,7 @@ string GetMessageName(MessageDescription messageDescription) string operationName = contractContext.GetOperation(operation).Name; string callbackString = operation.IsServerInitiated() ? "Callback" : string.Empty; - // [....]: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_' + // Microsoft: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_' if (messageDescription.Direction == MessageDirection.Input) messageNameBase = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}_{1}_Input{2}Message", portTypeName, operationName, callbackString); @@ -539,7 +539,7 @@ protected string GetFaultMessageName(string faultName) { string portTypeName = contractContext.WsdlPortType.Name; string operationName = contractContext.GetOperation(operation).Name; - // [....]: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_' + // Microsoft: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_' string faultNameBase = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}_{1}_{2}_FaultMessage", portTypeName, operationName, faultName); WsdlNS.ServiceDescription wsdl = contractContext.WsdlPortType.ServiceDescription; diff --git a/System.ServiceModel/System/ServiceModel/Description/MetadataSection.cs b/System.ServiceModel/System/ServiceModel/Description/MetadataSection.cs index 87e7f37da..8c33e75db 100644 --- a/System.ServiceModel/System/ServiceModel/Description/MetadataSection.cs +++ b/System.ServiceModel/System/ServiceModel/Description/MetadataSection.cs @@ -92,7 +92,7 @@ public static MetadataSection CreateFromPolicy(XmlElement policy, string identif if (!IsPolicyElement(policy)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("policy", -#pragma warning suppress 56506 // [....], policy cannot be null at this point since it has been validated above. +#pragma warning suppress 56506 // Microsoft, policy cannot be null at this point since it has been validated above. SR.GetString(SR.SFxBadMetadataMustBePolicy, MetadataStrings.WSPolicy.NamespaceUri, MetadataStrings.WSPolicy.Elements.Policy, policy.NamespaceURI, policy.LocalName)); } diff --git a/System.ServiceModel/System/ServiceModel/Description/PolicyReader.cs b/System.ServiceModel/System/ServiceModel/Description/PolicyReader.cs index 469c6d6be..9b60b7643 100644 --- a/System.ServiceModel/System/ServiceModel/Description/PolicyReader.cs +++ b/System.ServiceModel/System/ServiceModel/Description/PolicyReader.cs @@ -21,7 +21,7 @@ public abstract partial class MetadataImporter internal delegate void PolicyWarningHandler(XmlElement contextAssertion, string warningMessage); - // Consider, [....], make this public? + // Consider, Microsoft, make this public? internal event PolicyWarningHandler PolicyWarningOccured; internal IEnumerable> NormalizePolicy(IEnumerable policyAssertions) @@ -92,7 +92,7 @@ IEnumerable> ReadNode(XmlNode node, XmlElement contextAs string warningMsg = SR.GetString(SR.UnrecognizedPolicyElementInNamespace, node.Name, node.NamespaceURI); metadataImporter.PolicyWarningOccured.Invoke(contextAssertion, warningMsg); break; - //consider [....], add more error handling here. default? + //consider Microsoft, add more error handling here. default? } return nodes; } @@ -365,7 +365,7 @@ public T Current { get { -#pragma warning suppress 56503 // [....], IEnumerator guidelines, Current throws exception before calling MoveNext +#pragma warning suppress 56503 // Microsoft, IEnumerator guidelines, Current throws exception before calling MoveNext throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoValue0))); } } diff --git a/System.ServiceModel/System/ServiceModel/Description/ServiceEndpoint.cs b/System.ServiceModel/System/ServiceModel/Description/ServiceEndpoint.cs index cd369d242..d8c3dca4e 100644 --- a/System.ServiceModel/System/ServiceModel/Description/ServiceEndpoint.cs +++ b/System.ServiceModel/System/ServiceModel/Description/ServiceEndpoint.cs @@ -105,7 +105,7 @@ public string Name } else if (binding != null) { - // [....]: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_' + // Microsoft: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_' return String.Format(CultureInfo.InvariantCulture, "{0}_{1}", new XmlName(Binding.Name).EncodedName, Contract.Name); } else diff --git a/System.ServiceModel/System/ServiceModel/Description/SoapHelper.cs b/System.ServiceModel/System/ServiceModel/Description/SoapHelper.cs index 61868f6c8..d18c4927e 100644 --- a/System.ServiceModel/System/ServiceModel/Description/SoapHelper.cs +++ b/System.ServiceModel/System/ServiceModel/Description/SoapHelper.cs @@ -186,7 +186,7 @@ private static EnvelopeVersion GetSoapVersionState(WsdlNS.Binding wsdlBinding, W static class SoapConverter { - // [....], this could be simplified if we used generics. + // Microsoft, this could be simplified if we used generics. internal static void ConvertExtensions(WsdlNS.ServiceDescriptionFormatExtensionCollection extensions, EnvelopeVersion version, ConvertExtension conversionMethod) { bool foundOne = false; diff --git a/System.ServiceModel/System/ServiceModel/Description/TaskOperationDescriptionValidator.cs b/System.ServiceModel/System/ServiceModel/Description/TaskOperationDescriptionValidator.cs index 70f610065..2d1827ef8 100644 --- a/System.ServiceModel/System/ServiceModel/Description/TaskOperationDescriptionValidator.cs +++ b/System.ServiceModel/System/ServiceModel/Description/TaskOperationDescriptionValidator.cs @@ -15,7 +15,7 @@ internal static void Validate(OperationDescription operationDescription, bool is { if (isForService) { - // no other method ([....], async) is allowed to co-exist with a task-based method on the server-side. + // no other method (sync, async) is allowed to co-exist with a task-based method on the server-side. EnsureNoSyncMethod(operationDescription); EnsureNoBeginEndMethod(operationDescription); } diff --git a/System.ServiceModel/System/ServiceModel/Description/TypeLoader.cs b/System.ServiceModel/System/ServiceModel/Description/TypeLoader.cs index 105821f4e..45d56cc05 100644 --- a/System.ServiceModel/System/ServiceModel/Description/TypeLoader.cs +++ b/System.ServiceModel/System/ServiceModel/Description/TypeLoader.cs @@ -771,13 +771,13 @@ internal static Attribute GetFormattingAttribute(ICustomAttributeProvider attrPr return defaultFormatAttribute; } - //[....] and Async should follow the rules: + //Sync and Async should follow the rules: // 1. Parameter match // 2. Async cannot have behaviors (verification happens later in ProcessOpMethod - behaviors haven't yet been loaded here) // 3. Async cannot have known types // 4. Async cannot have known faults - // 5. [....] and Async have to match on OneWay status - // 6. [....] and Async have to match Action and ReplyAction + // 5. Sync and Async have to match on OneWay status + // 6. Sync and Async have to match Action and ReplyAction void VerifyConsistency(OperationConsistencyVerifier verifier) { verifier.VerifyParameterLength(); @@ -860,7 +860,7 @@ OperationDescription CreateOperationDescription(ContractDescription contractDesc existingOp.TaskTResult = newOp.TaskTResult; if (existingOp.SyncMethod != null) { - // Task vs. [....] + // Task vs. Sync VerifyConsistency(new SyncTaskOperationConsistencyVerifier(existingOp, newOp)); } else @@ -876,7 +876,7 @@ OperationDescription CreateOperationDescription(ContractDescription contractDesc existingOp.EndMethod = newOp.EndMethod; if (existingOp.SyncMethod != null) { - // Async vs. [....] + // Async vs. Sync VerifyConsistency(new SyncAsyncOperationConsistencyVerifier(existingOp, newOp)); } else @@ -894,12 +894,12 @@ OperationDescription CreateOperationDescription(ContractDescription contractDesc newOp.TaskTResult = existingOp.TaskTResult; if (existingOp.TaskMethod != null) { - // [....] vs. Task + // Sync vs. Task VerifyConsistency(new SyncTaskOperationConsistencyVerifier(newOp, existingOp)); } else { - // [....] vs. Async + // Sync vs. Async VerifyConsistency(new SyncAsyncOperationConsistencyVerifier(newOp, existingOp)); } return newOp; diff --git a/System.ServiceModel/System/ServiceModel/Description/WsdlExporter.cs b/System.ServiceModel/System/ServiceModel/Description/WsdlExporter.cs index 656fc85a7..bb0dc9be8 100644 --- a/System.ServiceModel/System/ServiceModel/Description/WsdlExporter.cs +++ b/System.ServiceModel/System/ServiceModel/Description/WsdlExporter.cs @@ -991,7 +991,7 @@ internal static string FindOrCreatePrefix(string prefixBase, string ns, params W int i = 0; prefix = prefixBase + i.ToString(CultureInfo.InvariantCulture); - //[....], consider do we need to check at higher scopes as well? + //Microsoft, consider do we need to check at higher scopes as well? while (PrefixExists(scopes[0].Namespaces.ToArray(), prefix)) prefix = prefixBase + (++i).ToString(CultureInfo.InvariantCulture); } diff --git a/System.ServiceModel/System/ServiceModel/Description/WsdlImporter.cs b/System.ServiceModel/System/ServiceModel/Description/WsdlImporter.cs index cf5abf7fb..f980585bc 100644 --- a/System.ServiceModel/System/ServiceModel/Description/WsdlImporter.cs +++ b/System.ServiceModel/System/ServiceModel/Description/WsdlImporter.cs @@ -1189,7 +1189,7 @@ internal static XmlQualifiedName GetBindingName(WsdlNS.Binding wsdlBinding) internal static XmlQualifiedName GetBindingName(WsdlNS.Port wsdlPort) { - // [....]: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_' + // Microsoft: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_' XmlName xmlName = new XmlName(string.Format(CultureInfo.InvariantCulture, "{0}_{1}", wsdlPort.Service.Name, wsdlPort.Name), true /*isEncoded*/); return new XmlQualifiedName(xmlName.EncodedName, wsdlPort.Service.ServiceDescription.TargetNamespace); } @@ -1233,7 +1233,7 @@ internal static XmlName GetOperationMessageName(WsdlNS.OperationMessage wsdlOper } else { - // [....]: why this is an Assert, and not an exception? + // Microsoft: why this is an Assert, and not an exception? Fx.Assert("Unsupported WSDL OM (More than 2 OperationMessages encountered in an Operation or WsdlOM is invalid)"); } // names the come from service description documents have to be valid NCNames; XmlName.ctor will validate. @@ -1920,7 +1920,7 @@ Exception CreateAlreadyFaultedException(WsdlNS.NamedItem item) static Exception CreateExtensionException(IWsdlImportExtension importer, Exception e) { string errorMessage = SR.GetString(SR.WsdlExtensionImportError, importer.GetType().FullName, e.Message); - //consider [....], allow internal exceptions to throw WsdlImportException and handle it in some special way? + //consider Microsoft, allow internal exceptions to throw WsdlImportException and handle it in some special way? return new InvalidOperationException(errorMessage, e); } diff --git a/System.ServiceModel/System/ServiceModel/Diagnostics/TraceUtility.cs b/System.ServiceModel/System/ServiceModel/Diagnostics/TraceUtility.cs index ef7c00c40..299c74696 100644 --- a/System.ServiceModel/System/ServiceModel/Diagnostics/TraceUtility.cs +++ b/System.ServiceModel/System/ServiceModel/Diagnostics/TraceUtility.cs @@ -545,8 +545,8 @@ internal static ServiceModelActivity ExtractActivity(Message message) (message.State != MessageState.Closed)) { object property; - - if (message.Properties.TryGetValue(TraceUtility.ActivityIdKey, out property)) + + if (message.GetProperty(TraceUtility.ActivityIdKey, out property)) { retval = property as ServiceModelActivity; } @@ -603,7 +603,7 @@ internal static ServiceModelActivity ExtractAndRemoveActivity(Message message) { // If the property is just removed, the item is disposed and we don't want the thing // to be disposed of. - message.Properties[TraceUtility.ActivityIdKey] = false; + message.SetProperty(TraceUtility.ActivityIdKey, false); } return retval; } @@ -659,7 +659,7 @@ internal static void SetActivity(Message message, ServiceModelActivity activity) { if (DiagnosticUtility.ShouldUseActivity && message != null && message.State != MessageState.Closed) { - message.Properties[TraceUtility.ActivityIdKey] = activity; + message.SetProperty(TraceUtility.ActivityIdKey, activity); } } diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/ActionMessageFilterTable.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/ActionMessageFilterTable.cs index 089152443..9f4d8c9c0 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/ActionMessageFilterTable.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/ActionMessageFilterTable.cs @@ -111,7 +111,7 @@ public void Add(ActionMessageFilter filter, TFilterData data) this.filters.Add(filter, data); List filters; -#pragma warning suppress 56506 // [....], Actions will never be null +#pragma warning suppress 56506 // Microsoft, Actions will never be null if (filter.Actions.Count == 0) { this.always.Add(filter); @@ -426,7 +426,7 @@ public bool Remove(ActionMessageFilter filter) if (this.filters.Remove(filter)) { -#pragma warning suppress 56506 // [....], ActionMessageFilter.Actions can never be null +#pragma warning suppress 56506 // Microsoft, ActionMessageFilter.Actions can never be null if (filter.Actions.Count == 0) { this.always.Remove(filter); @@ -436,9 +436,9 @@ public bool Remove(ActionMessageFilter filter) List filters; for (int i = 0; i < filter.Actions.Count; ++i) { -#pragma warning suppress 56506 // [....], PreSharp generates a false error here +#pragma warning suppress 56506 // Microsoft, PreSharp generates a false error here filters = this.actions[filter.Actions[i]]; -#pragma warning suppress 56506 // [....], filters can never be null +#pragma warning suppress 56506 // Microsoft, filters can never be null if (filters.Count == 1) { this.actions.Remove(filter.Actions[i]); diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/DuplexChannelBinder.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/DuplexChannelBinder.cs index 8a9955bd5..e6b36c43f 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/DuplexChannelBinder.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/DuplexChannelBinder.cs @@ -30,7 +30,7 @@ class DuplexChannelBinder : IChannelBinder List requests; List timedOutRequests; ChannelHandler channelHandler; - volatile bool requestAborted; + bool requestAborted; internal DuplexChannelBinder(IDuplexChannel channel, IRequestReplyCorrelator correlator) { @@ -207,25 +207,32 @@ public void CloseAfterFault(TimeSpan timeout) void AbortRequests() { IDuplexRequest[] array = null; + lock (this.ThisLock) { if (this.requests != null) { array = this.requests.ToArray(); - - foreach (IDuplexRequest request in array) - { - request.Abort(); - } + this.requests = null; } - this.requests = null; + this.requestAborted = true; } + bool hadRequests = array != null && array.Length > 0; + + if (hadRequests) + { + foreach (IDuplexRequest request in array) + { + request.Abort(); + } + } + // Remove requests from the correlator since the channel might be either faulting or aborting, // We are not going to get a reply for these requests. If they are not removed from the correlator, this will cause a leak. // This operation does not have to be under the lock - if (array != null && array.Length > 0) + if (hadRequests) { RequestReplyCorrelator requestReplyCorrelator = this.correlator as RequestReplyCorrelator; if (requestReplyCorrelator != null) @@ -537,7 +544,7 @@ public Message Request(Message message, TimeSpan timeout) } } - // ASSUMPTION: ([....]) caller holds lock (this.mutex) + // ASSUMPTION: (Microsoft) caller holds lock (this.mutex) void RequestStarting(Message message, IDuplexRequest request) { if (request != null) @@ -552,7 +559,7 @@ void RequestStarting(Message message, IDuplexRequest request) } - // ASSUMPTION: ([....]) caller holds lock (this.mutex) + // ASSUMPTION: (Microsoft) caller holds lock (this.mutex) void RequestCompleting(IDuplexRequest request) { this.pending--; @@ -1473,7 +1480,7 @@ public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object public void EndClose(IAsyncResult result) { - // don't need to lock here since BeginClose is the [....]-point + // don't need to lock here since BeginClose is the sync-point if (this.closeState.TryUserClose()) { this.innerChannel.EndClose(result); diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/EndpointAddressMessageFilter.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/EndpointAddressMessageFilter.cs index c61e56fb9..049a1b784 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/EndpointAddressMessageFilter.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/EndpointAddressMessageFilter.cs @@ -92,7 +92,7 @@ public override bool Match(Message message) } // To -#pragma warning suppress 56506 // [....], Message.Headers can never be null +#pragma warning suppress 56506 // Microsoft, Message.Headers can never be null Uri to = message.Headers.To; Uri actingAs = this.address.Uri; diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/EndpointAddressMessageFilterTable.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/EndpointAddressMessageFilterTable.cs index b3d707904..7f5e509b8 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/EndpointAddressMessageFilterTable.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/EndpointAddressMessageFilterTable.cs @@ -153,7 +153,7 @@ public virtual void Add(EndpointAddressMessageFilter filter, TFilterData data) this.candidates.Add(filter, can); CandidateSet cset; -#pragma warning suppress 56506 // [....], EndpointAddressMessageFilter.Address can never be null +#pragma warning suppress 56506 // Microsoft, EndpointAddressMessageFilter.Address can never be null Uri soapToAddress = filter.Address.Uri; if (filter.IncludeHostNameInComparison) { @@ -181,7 +181,7 @@ protected void IncrementQNameCount(CandidateSet cset, EndpointAddress address) // Update the QName ref count QName qname; int cnt; -#pragma warning suppress 56506 // [....], EndpointAddressMessageFilter.Address can never be null +#pragma warning suppress 56506 // Microsoft, EndpointAddressMessageFilter.Address can never be null for (int i = 0; i < address.Headers.Count; ++i) { AddressHeader parameter = address.Headers[i]; @@ -719,7 +719,7 @@ public virtual bool Remove(EndpointAddressMessageFilter filter) } Candidate can = this.candidates[filter]; -#pragma warning suppress 56506 // [....], EndpointAddressMessageFilter.Address can never be null +#pragma warning suppress 56506 // Microsoft, EndpointAddressMessageFilter.Address can never be null Uri soapToAddress = filter.Address.Uri; CandidateSet cset = null; @@ -761,7 +761,7 @@ protected void DecrementQNameCount(CandidateSet cset, EndpointAddress address) { // Adjust QName counts QName qname; -#pragma warning suppress 56506 // [....], EndpointAddress.Headers can never be null +#pragma warning suppress 56506 // Microsoft, EndpointAddress.Headers can never be null for (int i = 0; i < address.Headers.Count; ++i) { AddressHeader parameter = address.Headers[i]; diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/ImmutableDispatchRuntime.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/ImmutableDispatchRuntime.cs index caf32a627..60d24111d 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/ImmutableDispatchRuntime.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/ImmutableDispatchRuntime.cs @@ -1144,7 +1144,7 @@ void ProcessMessage5(ref MessageRpc rpc) { if (!rpc.Operation.IsSynchronous) { - // If async call completes in [....], it tells us through the gate below + // If async call completes in sync, it tells us through the gate below rpc.PrepareInvokeContinueGate(); } diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/InputChannelBinder.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/InputChannelBinder.cs index 9a7e2012f..b27cc867c 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/InputChannelBinder.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/InputChannelBinder.cs @@ -50,7 +50,7 @@ public EndpointAddress RemoteAddress { get { -#pragma warning suppress 56503 // [....], the property is really not implemented, cannot lie, API not public +#pragma warning suppress 56503 // Microsoft, the property is really not implemented, cannot lie, API not public throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); } } diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/MessageFilterTable.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/MessageFilterTable.cs index 3f1dd3be1..ebe6801b6 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/MessageFilterTable.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/MessageFilterTable.cs @@ -153,7 +153,7 @@ public void Add(MessageFilter filter, TFilterData data, int priority) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("filter", SR.GetString(SR.FilterExists)); } -#pragma warning suppress 56506 // [....], PreSharp generates a false warning here +#pragma warning suppress 56506 // Microsoft, PreSharp generates a false warning here Type filterType = filter.GetType(); Type tableType = null; IMessageFilterTable table = null; diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/OperationInvokerBehavior.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/OperationInvokerBehavior.cs index 2bfeafdac..2bcb3ceae 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/OperationInvokerBehavior.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/OperationInvokerBehavior.cs @@ -41,7 +41,7 @@ void IOperationBehavior.ApplyDispatchBehavior(OperationDescription description, { if (description.BeginMethod != null) { - // both [....] and async methods are present on the contract, check the preference + // both sync and async methods are present on the contract, check the preference OperationBehaviorAttribute operationBehaviorAttribue = description.Behaviors.Find(); if ((operationBehaviorAttribue != null) && operationBehaviorAttribue.PreferAsyncInvocation) { @@ -54,7 +54,7 @@ void IOperationBehavior.ApplyDispatchBehavior(OperationDescription description, } else { - // only [....] method is present on the contract + // only sync method is present on the contract dispatch.Invoker = new SyncMethodInvoker(description.SyncMethod); } } diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/OutputChannelBinder.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/OutputChannelBinder.cs index 4c94fe775..e4a25a96a 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/OutputChannelBinder.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/OutputChannelBinder.cs @@ -43,7 +43,7 @@ public EndpointAddress LocalAddress { get { -#pragma warning suppress 56503 // [....], the property is really not implemented, cannot lie, API not public +#pragma warning suppress 56503 // Microsoft, the property is really not implemented, cannot lie, API not public throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); } } diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/PrefixEndpointAddressMessageFilter.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/PrefixEndpointAddressMessageFilter.cs index 53855e359..91f21729a 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/PrefixEndpointAddressMessageFilter.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/PrefixEndpointAddressMessageFilter.cs @@ -85,7 +85,7 @@ public override bool Match(Message message) } // To -#pragma warning suppress 56506 // [....], Message.Headers can never be null +#pragma warning suppress 56506 // Microsoft, Message.Headers can never be null Uri to = message.Headers.To; object o; diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/PrefixEndpointAddressMessageFilterTable.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/PrefixEndpointAddressMessageFilterTable.cs index d360c4ba4..5b8d787e7 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/PrefixEndpointAddressMessageFilterTable.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/PrefixEndpointAddressMessageFilterTable.cs @@ -59,7 +59,7 @@ public void Add(PrefixEndpointAddressMessageFilter filter, TFilterData data) Candidate can = new Candidate(filter, data, mask, filter.HeaderLookup); this.candidates.Add(filter, can); -#pragma warning suppress 56506 // [....], PrefixEndpointAddressMessageFilter.Address can never be null +#pragma warning suppress 56506 // Microsoft, PrefixEndpointAddressMessageFilter.Address can never be null Uri soapToAddress = filter.Address.Uri; CandidateSet cset; @@ -134,7 +134,7 @@ public bool Remove(PrefixEndpointAddressMessageFilter filter) } Candidate can = this.candidates[filter]; -#pragma warning suppress 56506 // [....], PrefixEndpointAddressMessageFilter.Address can never be null +#pragma warning suppress 56506 // Microsoft, PrefixEndpointAddressMessageFilter.Address can never be null Uri soapToAddress = filter.Address.Uri; CandidateSet cset = null; diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/PrimitiveOperationFormatter.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/PrimitiveOperationFormatter.cs index 738725817..beddbbcfc 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/PrimitiveOperationFormatter.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/PrimitiveOperationFormatter.cs @@ -46,7 +46,7 @@ public PrimitiveOperationFormatter(OperationDescription description, bool isRpc) OperationFormatter.Validate(description, isRpc, false/*isEncoded*/); this.operation = description; -#pragma warning suppress 56506 // [....], OperationDescription.Messages never be null +#pragma warning suppress 56506 // Microsoft, OperationDescription.Messages never be null this.requestMessage = description.Messages[0]; if (description.Messages.Count == 2) this.responseMessage = description.Messages[1]; @@ -290,7 +290,7 @@ public static bool IsContractSupported(OperationDescription description) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("description"); OperationDescription operation = description; -#pragma warning suppress 56506 // [....], OperationDescription.Messages never be null +#pragma warning suppress 56506 // Microsoft, OperationDescription.Messages never be null MessageDescription requestMessage = description.Messages[0]; MessageDescription responseMessage = null; if (description.Messages.Count == 2) diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/QueryFunctions.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/QueryFunctions.cs index e3335d236..046eea89a 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/QueryFunctions.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/QueryFunctions.cs @@ -55,7 +55,7 @@ internal class XsltFunctionCallOpcode : Opcode List iterList; - // REFACTOR, [....], make this a function on QueryValueModel + // REFACTOR, Microsoft, make this a function on QueryValueModel internal XsltFunctionCallOpcode(XsltContext context, IXsltContextFunction function, int argCount) : base(OpcodeID.XsltFunction) { @@ -138,7 +138,7 @@ internal override Opcode Eval(ProcessingContext context) } else { - // PERF, [....], see if we can cache these arrays to avoid allocations + // PERF, Microsoft, see if we can cache these arrays to avoid allocations object[] xsltArgs = new object[this.argCount]; int iterationCount = context.TopArg.Count; for (int iteration = 0; iteration < iterationCount; ++iteration) @@ -1210,7 +1210,7 @@ internal static void Translate(ProcessingContext context) StackFrame argKeys = context.SecondArg; StackFrame argValues = context[2]; - // PERF, [....], this is really slow. + // PERF, Microsoft, this is really slow. StringBuilder builder = new StringBuilder(); while (argSource.basePtr <= argSource.endPtr) { diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/QueryNode.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/QueryNode.cs index 0ee7900aa..f56c2737a 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/QueryNode.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/QueryNode.cs @@ -140,7 +140,7 @@ internal enum NodeSequenceItemFlags : byte NodesetLast = 0x01, } - // PERF, [....], Remove when generic sort works + // PERF, Microsoft, Remove when generic sort works // Used to sort in document order #if NO internal class NodeSequenceItemObjectComparer : IComparer @@ -908,7 +908,7 @@ internal void SortNodes() { this.Merge(false); - // PERF, [....], make this work + // PERF, Microsoft, make this work //Array.Sort(this.items, 0, this.count, NodeSequence.Comparer); Array.Sort(this.items, 0, this.count, NodeSequence.ObjectComparer); @@ -974,7 +974,7 @@ internal NodeSequence Union(ProcessingContext context, NodeSequence otherSeq) return seq; /* - // PERF, [....], I think we can do the merge ourselves and avoid the sort. + // PERF, Microsoft, I think we can do the merge ourselves and avoid the sort. // Need to verify that the sequences are always in document order. for(int i = 0; i < this.count; ++i) { @@ -1055,13 +1055,13 @@ public override XPathNavigator Current { if (this.index == 0) { -#pragma warning suppress 56503 // [....], postponing the public change +#pragma warning suppress 56503 // Microsoft, postponing the public change throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryProcessingException(QueryProcessingError.Unexpected, SR.GetString(SR.QueryContextNotSupportedInSequences))); } if (this.index > this.data.seq.Count) { -#pragma warning suppress 56503 // [....], postponing the public change +#pragma warning suppress 56503 // Microsoft, postponing the public change throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.QueryAfterNodes))); } // @@ -1156,13 +1156,13 @@ public object Current { if (this.iter.CurrentPosition == 0) { -#pragma warning suppress 56503 // [....], postponing the public change +#pragma warning suppress 56503 // Microsoft, postponing the public change throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.QueryBeforeNodes))); } if (this.iter.CurrentPosition > this.iter.Count) { -#pragma warning suppress 56503 // [....], postponing the public change +#pragma warning suppress 56503 // Microsoft, postponing the public change throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.QueryAfterNodes))); } diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/QueryProcessor.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/QueryProcessor.cs index 54818a997..6df5f8ce1 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/QueryProcessor.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/QueryProcessor.cs @@ -457,7 +457,7 @@ internal QueryProcessor(QueryMatcher matcher) this.matcher = matcher; this.flags = QueryProcessingFlags.Match; - // PERF, [....], see if we can just let these to their default init + // PERF, Microsoft, see if we can just let these to their default init this.messageAction = null; //this.messageAddress = null; //this.messageVia = null; @@ -510,7 +510,7 @@ internal SeekableXPathNavigator ContextNode } else { -#pragma warning suppress 56503 // [....], property is more readable for this +#pragma warning suppress 56503 // Microsoft, property is more readable for this throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new QueryProcessingException(QueryProcessingError.Unexpected)); } this.counter = this.contextNode as INodeCounter; diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/QuerySelectOp.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/QuerySelectOp.cs index e835c3651..133eb048b 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/QuerySelectOp.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/QuerySelectOp.cs @@ -44,7 +44,7 @@ internal bool IsCompressable { get { - // PERF, [....], weaken guard? + // PERF, Microsoft, weaken guard? return QueryAxisType.Self == this.axis.Type || QueryAxisType.Child == this.axis.Type; //return ((QueryAxisType.Self == this.axis.Type) || ((this.axis.Type != QueryAxisType.DescendantOrSelf || this.axis.Type != QueryAxisType.Descendant)&& 0 != ((QueryNodeType.Element | QueryNodeType.Root) & this.type))); } diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/QuerySubExprEliminator.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/QuerySubExprEliminator.cs index 790a61eb0..40a6970b4 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/QuerySubExprEliminator.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/QuerySubExprEliminator.cs @@ -278,8 +278,8 @@ internal void Write(TextWriter outStream) internal class SubExprHeader : SubExpr { - // WS, [....], Can probably combine these - // WS, [....], Make this data structure less ugly (if possible) + // WS, Microsoft, Can probably combine these + // WS, Microsoft, Make this data structure less ugly (if possible) Dictionary>> nameLookup; Dictionary indexLookup; @@ -329,7 +329,7 @@ internal override void EvalSpecial(ProcessingContext context) context.SaveVariable(this.var, context.Processor.ElapsedCount(marker)); } - // WS, [....], see if we can put this array in the processor to save + // WS, Microsoft, see if we can put this array in the processor to save // an allocation. Perhaps we can use the variables slot we're going to fill NodeSequence[] childSequences = new NodeSequence[this.children.Count]; NodeSequence seq = context.Sequences[context.TopSequenceArg.basePtr].Sequence; diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/QueryUtil.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/QueryUtil.cs index 6efce98ed..6327b5d0d 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/QueryUtil.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/QueryUtil.cs @@ -657,7 +657,7 @@ internal void Exchange(T old, T replace) } else { - // PERF, [....], can this be made more efficient? Does it need to be? + // PERF, Microsoft, can this be made more efficient? Does it need to be? Remove(old); Insert(replace); } @@ -704,7 +704,7 @@ void InsertAt(int index, T item) } else if (this.buffer.Length == this.size) { - // PERF, [....], how should we choose a new size? + // PERF, Microsoft, how should we choose a new size? T[] tmp = new T[this.size + 1]; if (index == 0) diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/ReplyChannelBinder.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/ReplyChannelBinder.cs index fc2e8ea3f..3c15855a7 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/ReplyChannelBinder.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/ReplyChannelBinder.cs @@ -50,7 +50,7 @@ public EndpointAddress RemoteAddress { get { -#pragma warning suppress 56503 // [....], the property is really not implemented, cannot lie, API not public +#pragma warning suppress 56503 // Microsoft, the property is really not implemented, cannot lie, API not public throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); } } diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/SecurityValidationBehavior.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/SecurityValidationBehavior.cs index 0d0cb0f2c..82a56eaf5 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/SecurityValidationBehavior.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/SecurityValidationBehavior.cs @@ -235,7 +235,7 @@ static public void ValidateSecurityBinding(SecurityBindingElement sbe, Binding b if (sbe is SymmetricSecurityBindingElement || sbe is AsymmetricSecurityBindingElement) { // check to see if we are streaming - // ([....] 53690): need to have a general way get the transfer Mode from the binding + // (Microsoft 53690): need to have a general way get the transfer Mode from the binding // TransferMode transferMode = binding.GetProperty(new BindingParameterCollection()); if (GetTransferMode(binding) != TransferMode.Buffered) { diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/SeekableMessageNavigator.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/SeekableMessageNavigator.cs index 9066da02b..7e37baf4e 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/SeekableMessageNavigator.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/SeekableMessageNavigator.cs @@ -138,7 +138,7 @@ internal SeekableMessageNavigator(Message msg, int countMax, XmlSpace space, boo // The base uri of the element // This is usually associated with the URI of the original data's location - // WS, [....], look into what readers from messages surface. If it's always null, we can save + // WS, Microsoft, look into what readers from messages surface. If it's always null, we can save // some memory public override string BaseURI { @@ -183,7 +183,7 @@ public override long CurrentPosition while (n != p.elem) { - // PERF, [....], we might be able to get rid of this check by tweaking the position + // PERF, Microsoft, we might be able to get rid of this check by tweaking the position // validator if (n == NullIndex) { @@ -779,7 +779,7 @@ public override bool MoveToFirstAttribute() // Move the navigator to the first child of the current node. public override bool MoveToFirstChild() { - // PERF, [....], do we need this check? The null check may be enough + // PERF, Microsoft, do we need this check? The null check may be enough // Only valid for the root or an element node if (this.location == RootIndex || this.dom.nodes[this.location].type == XPathNodeType.Element) { @@ -894,7 +894,7 @@ public override bool MoveToNamespace(string name) n = this.dom.nodes[n].nextSibling; } - // PERF, [....], can we just clear? + // PERF, Microsoft, can we just clear? // We didn't find it, so restore the namespace stack for (int i = 0; i < nsCount; ++i) { @@ -1483,7 +1483,7 @@ Position DecodePosition(long pos) // Get the index of the next namespace that matches the scope // This function populates the namespace stack too - // PERF, [....], see if we can have this function set the current location too + // PERF, Microsoft, see if we can have this function set the current location too int FindNamespace(int parent, int ns, XPathNamespaceScope scope) { bool done = false; @@ -1932,7 +1932,7 @@ int ReadChildNodes(XmlReader reader, int parent, int parentNS) int n = NullIndex; do { - // PERF, [....], reorder cases so more common ones are earlier + // PERF, Microsoft, reorder cases so more common ones are earlier switch (reader.NodeType) { case XmlNodeType.Element: @@ -2118,7 +2118,7 @@ void Increase() } } - // PERF, [....], find a better way to implement and have internal + // PERF, Microsoft, find a better way to implement and have internal void INodeCounter.Increase() { Increase(); diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/StreamFormatter.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/StreamFormatter.cs index a11a8f82e..37c3276d2 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/StreamFormatter.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/StreamFormatter.cs @@ -332,7 +332,7 @@ public override long Length { get { -#pragma warning suppress 56503 // [....], not a seekable stream, it is ok to throw NotSupported in this case +#pragma warning suppress 56503 // Microsoft, not a seekable stream, it is ok to throw NotSupported in this case throw TraceUtility.ThrowHelperError(new NotSupportedException(), this.message); } } diff --git a/System.ServiceModel/System/ServiceModel/Dispatcher/XPathMessageContext.cs b/System.ServiceModel/System/ServiceModel/Dispatcher/XPathMessageContext.cs index 1222eb30b..18a71af65 100644 --- a/System.ServiceModel/System/ServiceModel/Dispatcher/XPathMessageContext.cs +++ b/System.ServiceModel/System/ServiceModel/Dispatcher/XPathMessageContext.cs @@ -162,7 +162,7 @@ public override IXsltContextFunction ResolveFunction(string prefix, string name, if (argTypes == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("argTypes"); - // PERF, [....], factor ns if all same + // PERF, Microsoft, factor ns if all same string ns = LookupNamespace(prefix); for (int i = 0; i < functions.Length; ++i) { @@ -1254,7 +1254,7 @@ internal override void InvokeInternal(ProcessingContext context, int argCount) { do { - // PERF, [....], this will be faster if I cache the envelope namespace to do the + // PERF, Microsoft, this will be faster if I cache the envelope namespace to do the // actor lookup by hand long pos = nav.CurrentPosition; string navActor = XPathMessageFunctionActor.ExtractFromNavigator(nav); @@ -1283,7 +1283,7 @@ public override object Invoke(XsltContext xsltContext, object[] args, XPathNavig return docContext.Evaluate(expr); #if NO - // PERF, [....], I drafted this implementation before we found out that a bug in the Fx implementation would + // PERF, Microsoft, I drafted this implementation before we found out that a bug in the Fx implementation would // prevent us from constructing an XPathNodeIterator that they would accept. I'm keeping it // around in the hope that I will be able to use it by M5.4. If not, it will be deleted. diff --git a/System.ServiceModel/System/ServiceModel/EndpointAddress.cs b/System.ServiceModel/System/ServiceModel/EndpointAddress.cs index 26583d152..dd22acb14 100644 --- a/System.ServiceModel/System/ServiceModel/EndpointAddress.cs +++ b/System.ServiceModel/System/ServiceModel/EndpointAddress.cs @@ -342,7 +342,7 @@ public void ApplyTo(Message message) // NOTE: UserInfo, Query, and Fragment are ignored when comparing Uris as addresses // this is the WCF logic for comparing Uris that represent addresses - // this method must be kept in [....] with UriGetHashCode + // this method must be kept in sync with UriGetHashCode internal static bool UriEquals(Uri u1, Uri u2, bool ignoreCase, bool includeHostInComparison) { return UriEquals(u1, u2, ignoreCase, includeHostInComparison, true); @@ -393,7 +393,7 @@ internal static bool UriEquals(Uri u1, Uri u2, bool ignoreCase, bool includeHost return string.Compare(u1Path, 0, u2Path, 0, u1Len, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) == 0; } - // this method must be kept in [....] with UriEquals + // this method must be kept in sync with UriEquals internal static int UriGetHashCode(Uri uri, bool includeHostInComparison) { return UriGetHashCode(uri, includeHostInComparison, true); diff --git a/System.ServiceModel/System/ServiceModel/FaultReason.cs b/System.ServiceModel/System/ServiceModel/FaultReason.cs index cbac59f62..409b9c824 100644 --- a/System.ServiceModel/System/ServiceModel/FaultReason.cs +++ b/System.ServiceModel/System/ServiceModel/FaultReason.cs @@ -72,7 +72,7 @@ public FaultReasonText GetMatchingTranslation() return GetMatchingTranslation(CultureInfo.CurrentCulture); } - // [....], This function should always return a translation so that a fault can be surfaced. + // Microsoft, This function should always return a translation so that a fault can be surfaced. public FaultReasonText GetMatchingTranslation(CultureInfo cultureInfo) { if (cultureInfo == null) diff --git a/System.ServiceModel/System/ServiceModel/LocalAppContextSwitches.cs b/System.ServiceModel/System/ServiceModel/LocalAppContextSwitches.cs index 323304ff6..ced8931dd 100644 --- a/System.ServiceModel/System/ServiceModel/LocalAppContextSwitches.cs +++ b/System.ServiceModel/System/ServiceModel/LocalAppContextSwitches.cs @@ -15,10 +15,12 @@ internal static class LocalAppContextSwitches private const string DisableExplicitConnectionCloseHeaderString = "Switch.System.ServiceModel.DisableExplicitConnectionCloseHeader"; private const string AllowUnsignedToHeaderString = "Switch.System.ServiceModel.AllowUnsignedToHeader"; private const string DisableCngCertificatesString = "Switch.System.ServiceModel.DisableCngCertificates"; + internal const string DisableUsingServicePointManagerSecurityProtocolsString = "Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols"; private static int disableExplicitConnectionCloseHeader; private static int allowUnsignedToHeader; private static int disableCngCertificates; + private static int disableUsingServicePointManagerSecurityProtocols; public static bool DisableExplicitConnectionCloseHeader { @@ -47,6 +49,15 @@ public static bool DisableCngCertificates } } + public static bool DisableUsingServicePointManagerSecurityProtocols + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return LocalAppContext.GetCachedSwitchValue(DisableUsingServicePointManagerSecurityProtocolsString, ref disableUsingServicePointManagerSecurityProtocols); + } + } + public static void SetDefaultsLessOrEqual_452() { #pragma warning disable BCL0012 diff --git a/System.ServiceModel/System/ServiceModel/OperationContext.cs b/System.ServiceModel/System/ServiceModel/OperationContext.cs index c08a1200c..58c994dd7 100644 --- a/System.ServiceModel/System/ServiceModel/OperationContext.cs +++ b/System.ServiceModel/System/ServiceModel/OperationContext.cs @@ -100,7 +100,7 @@ public static OperationContext Current set { - if (ShouldUseAsyncLocalContext) + if (ShouldUseAsyncLocalContext && value != null && value.isAsyncFlowEnabled) { OperationContext.currentAsyncLocalContext.Value = value; } @@ -125,11 +125,11 @@ internal static Holder CurrentHolder } } - private static bool ShouldUseAsyncLocalContext + internal static bool ShouldUseAsyncLocalContext { get { - return CurrentHolder.Context == null && OperationContext.currentAsyncLocalContext.Value != null && OperationContext.currentAsyncLocalContext.Value.isAsyncFlowEnabled; + return !ServiceModelAppSettings.DisableOperationContextAsyncFlow && CurrentHolder.Context == null && OperationContext.currentAsyncLocalContext.Value != null && OperationContext.currentAsyncLocalContext.Value.isAsyncFlowEnabled; } } @@ -359,8 +359,16 @@ internal void ClearClientReplyNoThrow() internal static void EnableAsyncFlow() { - CurrentHolder.Context.isAsyncFlowEnabled = true; - currentAsyncLocalContext.Value = CurrentHolder.Context; + EnableAsyncFlow(CurrentHolder.Context); + } + + internal static void EnableAsyncFlow(OperationContext oc) + { + if (oc != null) + { + oc.isAsyncFlowEnabled = true; + currentAsyncLocalContext.Value = oc; + } } internal static void DisableAsyncFlow() diff --git a/System.ServiceModel/System/ServiceModel/OperationContextScope.cs b/System.ServiceModel/System/ServiceModel/OperationContextScope.cs index 3d12f54c8..e386e5868 100644 --- a/System.ServiceModel/System/ServiceModel/OperationContextScope.cs +++ b/System.ServiceModel/System/ServiceModel/OperationContextScope.cs @@ -10,12 +10,16 @@ namespace System.ServiceModel public sealed class OperationContextScope : IDisposable { + [ThreadStatic] + static OperationContextScope legacyCurrentScope; + static AsyncLocal currentScope = new AsyncLocal(); OperationContext currentContext; bool disposed; readonly OperationContext originalContext = OperationContext.Current; - readonly OperationContextScope originalScope = OperationContextScope.currentScope.Value; + readonly OperationContextScope originalScope = OperationContextScope.CurrentScope; + readonly Thread thread = Thread.CurrentThread; public OperationContextScope(IContextChannel channel) { @@ -27,6 +31,26 @@ public OperationContextScope(OperationContext context) this.PushContext(context); } + private static OperationContextScope CurrentScope + { + get + { + return ServiceModelAppSettings.DisableOperationContextAsyncFlow ? legacyCurrentScope : currentScope.Value; + } + + set + { + if (ServiceModelAppSettings.DisableOperationContextAsyncFlow) + { + legacyCurrentScope = value; + } + else + { + currentScope.Value = value; + } + } + } + public void Dispose() { if (!this.disposed) @@ -38,20 +62,31 @@ public void Dispose() void PushContext(OperationContext context) { + bool isAsyncFlowEnabled = OperationContext.ShouldUseAsyncLocalContext; + this.currentContext = context; - OperationContextScope.currentScope.Value = this; + + if (isAsyncFlowEnabled) + { + OperationContext.EnableAsyncFlow(this.currentContext); + } + + CurrentScope = this; OperationContext.Current = this.currentContext; } void PopContext() { - if (OperationContextScope.currentScope.Value != this) + if (ServiceModelAppSettings.DisableOperationContextAsyncFlow && this.thread != Thread.CurrentThread) + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInvalidContextScopeThread0))); + + if (CurrentScope != this) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInterleavedContextScopes0))); if (OperationContext.Current != this.currentContext) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxContextModifiedInsideScope0))); - OperationContextScope.currentScope.Value = this.originalScope; + CurrentScope = this.originalScope; OperationContext.Current = this.originalContext; if (this.currentContext != null) diff --git a/System.ServiceModel/System/ServiceModel/Security/CryptoHelper.cs b/System.ServiceModel/System/ServiceModel/Security/CryptoHelper.cs index 7c0b7a8cb..8bc85e1e2 100644 --- a/System.ServiceModel/System/ServiceModel/Security/CryptoHelper.cs +++ b/System.ServiceModel/System/ServiceModel/Security/CryptoHelper.cs @@ -181,7 +181,7 @@ static CryptoAlgorithmType GetAlgorithmType(string algorithm) catch (InvalidOperationException) { algorithmObject = null; - // We ---- the exception and continue. + // We swallow the exception and continue. } if (algorithmObject != null) { @@ -284,7 +284,7 @@ internal static bool IsSymmetricSupportedAlgorithm(string algorithm, int keySize catch (InvalidOperationException) { algorithmObject = null; - // We ---- the exception and continue. + // We swallow the exception and continue. } if (algorithmObject != null) { diff --git a/System.ServiceModel/System/ServiceModel/Security/SecuritySessionSecurityTokenProvider.cs b/System.ServiceModel/System/ServiceModel/Security/SecuritySessionSecurityTokenProvider.cs index 175f07c58..4f2357a44 100644 --- a/System.ServiceModel/System/ServiceModel/Security/SecuritySessionSecurityTokenProvider.cs +++ b/System.ServiceModel/System/ServiceModel/Security/SecuritySessionSecurityTokenProvider.cs @@ -865,9 +865,9 @@ public SessionOperationAsyncResult(SecuritySessionSecurityTokenProvider requesto /* * Session issuance/renewal consists of the following steps (some may be async): - * 1. Create a channel ([....]) + * 1. Create a channel (sync) * 2. Open the channel (async) - * 3. Create the request to send to server ([....]) + * 3. Create the request to send to server (sync) * 4. Send the message and get reply (async) * 5. Process the reply to get the token * 6. Close the channel (async) and complete the async result diff --git a/System.ServiceModel/System/ServiceModel/Security/SecurityUtils.cs b/System.ServiceModel/System/ServiceModel/Security/SecurityUtils.cs index b62aceefc..98a912c3c 100644 --- a/System.ServiceModel/System/ServiceModel/Security/SecurityUtils.cs +++ b/System.ServiceModel/System/ServiceModel/Security/SecurityUtils.cs @@ -284,7 +284,7 @@ static class SecurityUtils volatile static bool isSslValidationRequirementDetermined = false; static readonly int MinimumSslCipherStrength = 128; - // these are kept in [....] with IIS70 + // these are kept in sync with IIS70 public const string AuthTypeNTLM = "NTLM"; public const string AuthTypeNegotiate = "Negotiate"; public const string AuthTypeKerberos = "Kerberos"; @@ -1472,7 +1472,7 @@ internal static void FixNetworkCredential(ref NetworkCredential credential) } } - // WORKAROUND, [....], VSWhidbey 561276: The first NetworkCredential must be created in a lock. + // WORKAROUND, Microsoft, VSWhidbey 561276: The first NetworkCredential must be created in a lock. internal static void PrepareNetworkCredential() { if (dummyNetworkCredential == null) @@ -1692,7 +1692,7 @@ static void OnOpen(IAsyncResult result) { thisPtr.communicationObject.EndOpen(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) @@ -1767,7 +1767,7 @@ static void OnClose(IAsyncResult result) { thisPtr.communicationObject.EndClose(result); } -#pragma warning suppress 56500 // [....], transferring exception to another thread +#pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) diff --git a/System.ServiceModel/System/ServiceModel/Security/TlsnegoTokenAuthenticator.cs b/System.ServiceModel/System/ServiceModel/Security/TlsnegoTokenAuthenticator.cs index 6fe464402..688b509f6 100644 --- a/System.ServiceModel/System/ServiceModel/Security/TlsnegoTokenAuthenticator.cs +++ b/System.ServiceModel/System/ServiceModel/Security/TlsnegoTokenAuthenticator.cs @@ -170,8 +170,17 @@ protected override void ValidateIncomingBinaryNegotiation(BinaryNegotiation inco protected override SspiNegotiationTokenAuthenticatorState CreateSspiState(byte[] incomingBlob, string incomingValueTypeUri) { - TlsSspiNegotiation tlsNegotiation = new TlsSspiNegotiation(SchProtocols.TlsServer | SchProtocols.Ssl3Server, + TlsSspiNegotiation tlsNegotiation = null; + if (LocalAppContextSwitches.DisableUsingServicePointManagerSecurityProtocols) + { + tlsNegotiation = new TlsSspiNegotiation(SchProtocols.TlsServer | SchProtocols.Ssl3Server, this.serverToken.Certificate, this.ClientTokenAuthenticator != null); + } + else + { + var protocol = (SchProtocols)System.Net.ServicePointManager.SecurityProtocol & SchProtocols.ServerMask; + tlsNegotiation = new TlsSspiNegotiation(protocol, this.serverToken.Certificate, this.ClientTokenAuthenticator != null); + } // Echo only for TrustFeb2005 and ValueType mismatch if (this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005 && this.NegotiationValueType.Value != incomingValueTypeUri) diff --git a/System.ServiceModel/System/ServiceModel/Security/TlsnegoTokenProvider.cs b/System.ServiceModel/System/ServiceModel/Security/TlsnegoTokenProvider.cs index 628bada91..cfd4485a9 100644 --- a/System.ServiceModel/System/ServiceModel/Security/TlsnegoTokenProvider.cs +++ b/System.ServiceModel/System/ServiceModel/Security/TlsnegoTokenProvider.cs @@ -74,7 +74,16 @@ SspiNegotiationTokenProviderState CreateTlsSspiState(X509SecurityToken token) { clientCertificate = token.Certificate; } - TlsSspiNegotiation tlsNegotiation = new TlsSspiNegotiation(String.Empty, SchProtocols.Ssl3Client | SchProtocols.TlsClient, clientCertificate); + TlsSspiNegotiation tlsNegotiation = null; + if(LocalAppContextSwitches.DisableUsingServicePointManagerSecurityProtocols) + { + tlsNegotiation = new TlsSspiNegotiation(String.Empty, SchProtocols.Ssl3Client | SchProtocols.TlsClient, clientCertificate); + } + else + { + var protocol = (SchProtocols)System.Net.ServicePointManager.SecurityProtocol & SchProtocols.ClientMask; + tlsNegotiation = new TlsSspiNegotiation(String.Empty, protocol, clientCertificate); + } return new SspiNegotiationTokenProviderState(tlsNegotiation); } diff --git a/System.ServiceModel/System/ServiceModel/Security/WSSecurityPolicy.cs b/System.ServiceModel/System/ServiceModel/Security/WSSecurityPolicy.cs index 417886dd3..5c559bb53 100644 --- a/System.ServiceModel/System/ServiceModel/Security/WSSecurityPolicy.cs +++ b/System.ServiceModel/System/ServiceModel/Security/WSSecurityPolicy.cs @@ -2923,7 +2923,7 @@ public void ResolveTokenIssuerPolicy(MetadataImporter importer, PolicyConversion return; } WsdlImporter wsdlImporter; - // NOTE: [....], Policy import/export is seperate from WSDL however, this policy importer + // NOTE: Microsoft, Policy import/export is seperate from WSDL however, this policy importer // invokes the WsdlImporter. In the event that the current MetadataImporter is a WsdlImporter, // we should use it's collection of extensions for the import process. Other wise WsdlImporter currentWsdlImporter = importer as WsdlImporter; diff --git a/System.ServiceModel/System/ServiceModel/Security/WSTrustServiceContract.cs b/System.ServiceModel/System/ServiceModel/Security/WSTrustServiceContract.cs index 1bd584b28..f601b50e1 100644 --- a/System.ServiceModel/System/ServiceModel/Security/WSTrustServiceContract.cs +++ b/System.ServiceModel/System/ServiceModel/Security/WSTrustServiceContract.cs @@ -1351,7 +1351,7 @@ public Message EndTrustFeb2005ValidateResponse(IAsyncResult ar) internal class ProcessCoreAsyncResult : AsyncResult { // - // Encapsulate the local variables in the [....] version of ProcessCore as fields. + // Encapsulate the local variables in the sync version of ProcessCore as fields. // WSTrustServiceContract _trustServiceContract; DispatchContext _dispatchContext; diff --git a/System.ServiceModel/System/ServiceModel/ServiceModelAppSettings.cs b/System.ServiceModel/System/ServiceModel/ServiceModelAppSettings.cs index 19fba5c99..950c5fecd 100644 --- a/System.ServiceModel/System/ServiceModel/ServiceModelAppSettings.cs +++ b/System.ServiceModel/System/ServiceModel/ServiceModelAppSettings.cs @@ -16,14 +16,17 @@ internal static class ServiceModelAppSettings internal const string EnsureUniquePerformanceCounterInstanceNamesString = "wcf:ensureUniquePerformanceCounterInstanceNames"; internal const string UseConfiguredTransportSecurityHeaderLayoutString = "wcf:useConfiguredTransportSecurityHeaderLayout"; internal const string UseBestMatchNamedPipeUriString = "wcf:useBestMatchNamedPipeUri"; + internal const string DisableOperationContextAsyncFlowString = "wcf:disableOperationContextAsyncFlow"; const bool DefaultHttpTransportPerFactoryConnectionPool = false; const bool DefaultEnsureUniquePerformanceCounterInstanceNames = false; const bool DefaultUseConfiguredTransportSecurityHeaderLayout = false; const bool DefaultUseBestMatchNamedPipeUri = false; + const bool DefaultDisableOperationContextAsyncFlow = true; static bool httpTransportPerFactoryConnectionPool; static bool ensureUniquePerformanceCounterInstanceNames; static bool useConfiguredTransportSecurityHeaderLayout; static bool useBestMatchNamedPipeUri; + static bool disableOperationContextAsyncFlow; static volatile bool settingsInitalized = false; static object appSettingsLock = new object(); @@ -47,6 +50,15 @@ internal static bool EnsureUniquePerformanceCounterInstanceNames } } + internal static bool DisableOperationContextAsyncFlow + { + get + { + EnsureSettingsLoaded(); + return disableOperationContextAsyncFlow; + } + } + internal static bool UseConfiguredTransportSecurityHeaderLayout { get @@ -97,6 +109,11 @@ static void EnsureSettingsLoaded() ensureUniquePerformanceCounterInstanceNames = DefaultEnsureUniquePerformanceCounterInstanceNames; } + if ((appSettingsSection == null) || !bool.TryParse(appSettingsSection[DisableOperationContextAsyncFlowString], out disableOperationContextAsyncFlow)) + { + disableOperationContextAsyncFlow = DefaultDisableOperationContextAsyncFlow; + } + if ((appSettingsSection == null) || !bool.TryParse(appSettingsSection[UseConfiguredTransportSecurityHeaderLayoutString], out useConfiguredTransportSecurityHeaderLayout)) { useConfiguredTransportSecurityHeaderLayout = DefaultUseConfiguredTransportSecurityHeaderLayout; diff --git a/System.ServiceModel/System/ServiceModel/Syndication/Rss20FeedFormatter.cs b/System.ServiceModel/System/ServiceModel/Syndication/Rss20FeedFormatter.cs index a417e2b9d..a7bfdc2a4 100644 --- a/System.ServiceModel/System/ServiceModel/Syndication/Rss20FeedFormatter.cs +++ b/System.ServiceModel/System/ServiceModel/Syndication/Rss20FeedFormatter.cs @@ -1124,7 +1124,7 @@ void WriteFeed(XmlWriter writer) // if there's a single author with an email address, then serialize as the managingEditor // else serialize the authors as Atom extensions -#pragma warning disable 56506 // [....]: this.Feed.Authors is never null +#pragma warning disable 56506 // Microsoft: this.Feed.Authors is never null if ((this.Feed.Authors.Count == 1) && (this.Feed.Authors[0].Email != null)) #pragma warning restore 56506 { @@ -1149,7 +1149,7 @@ void WriteFeed(XmlWriter writer) writer.WriteEndElement(); } -#pragma warning disable 56506 // [....]: this.Feed.Categories is never null +#pragma warning disable 56506 // Microsoft: this.Feed.Categories is never null for (int i = 0; i < this.Feed.Categories.Count; ++i) #pragma warning restore 56506 { @@ -1161,7 +1161,7 @@ void WriteFeed(XmlWriter writer) writer.WriteElementString(Rss20Constants.GeneratorTag, this.Feed.Generator); } -#pragma warning disable 56506 // [....]: this.Feed.Contributors is never null +#pragma warning disable 56506 // Microsoft: this.Feed.Contributors is never null if (this.Feed.Contributors.Count > 0) #pragma warning restore 56506 { @@ -1263,7 +1263,7 @@ void WriteItemContents(XmlWriter writer, SyndicationItem item, Uri feedBaseUri) WriteAlternateLink(writer, firstAlternateLink, (item.BaseUri != null ? item.BaseUri : feedBaseUri)); } -#pragma warning disable 56506 // [....], item.Authors is never null +#pragma warning disable 56506 // Microsoft, item.Authors is never null if (item.Authors.Count == 1 && !string.IsNullOrEmpty(item.Authors[0].Email)) #pragma warning restore 56506 { @@ -1281,7 +1281,7 @@ void WriteItemContents(XmlWriter writer, SyndicationItem item, Uri feedBaseUri) } } -#pragma warning disable 56506 // [....], item.Categories is never null +#pragma warning disable 56506 // Microsoft, item.Categories is never null for (int i = 0; i < item.Categories.Count; ++i) #pragma warning restore 56506 { @@ -1409,7 +1409,7 @@ void WriteItemContents(XmlWriter writer, SyndicationItem item, Uri feedBaseUri) } } -#pragma warning disable 56506 // [....], item.COntributors is never null +#pragma warning disable 56506 // Microsoft, item.COntributors is never null if (item.Contributors.Count > 0) #pragma warning restore 56506 { diff --git a/System.Web.ApplicationServices/ApplicationServicesStrings.resx b/System.Web.ApplicationServices/ApplicationServicesStrings.resx new file mode 100644 index 000000000..3455657fa --- /dev/null +++ b/System.Web.ApplicationServices/ApplicationServicesStrings.resx @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + You must specify a non-autogenerated machine key to store passwords in the encrypted format. Either specify a different passwordFormat, or change the machineKey configuration to use a non-autogenerated decryption key. + + + The E-mail address is already in use. + + + The provider user key is already in use. + + + The username is already in use. + + + The password-answer supplied is invalid. + + + The E-mail supplied is invalid. + + + The password supplied is invalid. Passwords must conform to the password strength requirements configured for the default provider. + + + The provider user key supplied is invalid. It must be of type System.Guid. + + + The password-question supplied is invalid. Note that the current provider configuration requires a valid password question and answer. As a result, a CreateUser overload that accepts question and answer parameters must also be used. + + + The username supplied is invalid. + + + No Error. + + + The membership provider name specified is invalid. + + + The user was rejected. + + + The parameter '{0}' must not be empty. + + + This member is not supported on the .NET Framework Client Profile. + + + The Provider encountered an unknown error. + + + Provider must implement the class '{0}'. + + + The assembly '{0}' did not contain an assembly-level CustomLoaderAttribute. + + + Custom loaders can only be used by fully-trusted applications (<trust level="Full" />). + + + The host forbids the use of custom loaders. + + + The provided type '{0}' must implement the ICustomLoader interface. + + \ No newline at end of file diff --git a/System.Web.DataVisualization/Common/Annotation/AnnotationBase.cs b/System.Web.DataVisualization/Common/Annotation/AnnotationBase.cs new file mode 100644 index 000000000..57f8649f2 --- /dev/null +++ b/System.Web.DataVisualization/Common/Annotation/AnnotationBase.cs @@ -0,0 +1,4437 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: Annotation.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: Annotation, AnnotationPositionChangingEventArgs +// +// Purpose: Base class for all anotation objects. Provides +// basic set of properties and methods. +// +// Reviewed: +// +//=================================================================== + +#region Used namespace +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Globalization; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL +using System.ComponentModel.Design.Serialization; +using System.Reflection; +using System.Windows.Forms; + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Enumerations + + /// + /// Annotation object selection points style. + /// + /// + /// Enumeration is for internal use only and should not be part of the documentation. + /// + internal enum SelectionPointsStyle + { + /// + /// Selection points are displayed top left and bottom right corners + /// + TwoPoints, + + /// + /// Selection points are displayed on all sides and corners of the rectangle. + /// + Rectangle, + } + + /// + /// Annotation object resizing\moving mode. + /// + /// + /// Enumeration is for internal use only and should not be part of the documentation. + /// + internal enum ResizingMode + { + /// + /// Top Left selection handle is used. + /// + TopLeftHandle = 0, + /// + /// Top selection handle is used. + /// + TopHandle = 1, + /// + /// Top Right selection handle is used. + /// + TopRightHandle = 2, + /// + /// Right selection handle is used. + /// + RightHandle = 3, + /// + /// Bottom Right selection handle is used. + /// + BottomRightHandle = 4, + /// + /// Bottom selection handle is used. + /// + BottomHandle = 5, + /// + /// Bottom Left selection handle is used. + /// + BottomLeftHandle = 6, + /// + /// Left selection handle is used. + /// + LeftHandle = 7, + /// + /// Anchor selection handle is used. + /// + AnchorHandle = 8, + /// + /// No selection handles used - moving mode. + /// + Moving = 16, + /// + /// Moving points of the annotation path. + /// + MovingPathPoints = 32, + /// + /// No moving or resizing. + /// + None = 64, + } + +#endregion + + /// + /// Annotation is an abstract class that defines properties and methods + /// common to all annotations. + /// + /// + /// All annotations are derived from the Annotation class, which can be + /// used to set properties common to all annotation objects (e.g. color, position, + /// anchoring and others). + /// + [ + SRDescription("DescriptionAttributeAnnotation_Annotation"), + DefaultProperty("Name"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif +#if !Microsoft_CONTROL + public abstract class Annotation : ChartNamedElement, IChartMapArea +#else + public abstract class Annotation : ChartNamedElement +#endif + { + #region Fields + + + // Name of the chart area the annotation is clipped to + private string _clipToChartArea = Constants.NotSetValue; + + // Indicates that annotation is selected + private bool _isSelected = false; + + // Indicates that annotation size is defined in relative chart coordinates + private bool _isSizeAlwaysRelative = true; + + // Position attribute fields + private double _x = double.NaN; + private double _y = double.NaN; + private double _width = double.NaN; + private double _height = double.NaN; + + // Annotation axes attaching fields + private string _axisXName = String.Empty; + private string _axisYName = String.Empty; + private Axis _axisX = null; + private Axis _axisY = null; + + // Visual attribute fields + private bool _visible = true; + private ContentAlignment _alignment = ContentAlignment.MiddleCenter; + private Color _foreColor = Color.Black; + private FontCache _fontCache = new FontCache(); + private Font _textFont; + private TextStyle _textStyle = TextStyle.Default; + internal Color lineColor = Color.Black; + private int _lineWidth = 1; + private ChartDashStyle _lineDashStyle = ChartDashStyle.Solid; + private Color _backColor = Color.Empty; + private ChartHatchStyle _backHatchStyle = ChartHatchStyle.None; + private GradientStyle _backGradientStyle = GradientStyle.None; + private Color _backSecondaryColor = Color.Empty; + private Color _shadowColor = Color.FromArgb(128, 0, 0, 0); + private int _shadowOffset = 0; + + // Anchor position attribute fields + private string _anchorDataPointName = String.Empty; + private DataPoint _anchorDataPoint = null; + private DataPoint _anchorDataPoint2 = null; + private double _anchorX = double.NaN; + private double _anchorY = double.NaN; + internal double anchorOffsetX = 0.0; + internal double anchorOffsetY = 0.0; + internal ContentAlignment anchorAlignment = ContentAlignment.BottomCenter; + + // Selection handles position (starting top-left and moving clockwise) + internal RectangleF[] selectionRects = null; + + // Annotation tooltip + private string _tooltip = String.Empty; + + // Selection handles size + internal const int selectionMarkerSize = 6; + + // Pre calculated relative position of annotation and anchor point + internal RectangleF currentPositionRel = new RectangleF(float.NaN, float.NaN, float.NaN, float.NaN); + internal PointF currentAnchorLocationRel = new PointF(float.NaN, float.NaN); + + // Smart labels style + private AnnotationSmartLabelStyle _smartLabelStyle = null; + + // Index of last selected point in the annotation path + internal int currentPathPointIndex = -1; + + // Group this annotation belongs too + internal AnnotationGroup annotationGroup = null; + +#if Microsoft_CONTROL + + // Selection and editing permissions + private bool _allowSelecting = false; + private bool _allowMoving = false; + private bool _allowAnchorMoving = false; + private bool _allowResizing = false; + private bool _allowTextEditing = false; + private bool _allowPathEditing = false; + +#endif //Microsoft_CONTROL + +#if Microsoft_CONTROL + + // Indicates that annotation position was changed. Flag used to fire events. + internal bool positionChanged = false; + + // Relative location of last placement position + internal PointF lastPlacementPosition = PointF.Empty; + + // Relative location of annotation anchor, when it's started to move + internal PointF startMoveAnchorLocationRel = PointF.Empty; + +#endif // Microsoft_CONTROL + + // Relative position of annotation, when it's started to move/resize + internal RectangleF startMovePositionRel = RectangleF.Empty; + + // Relative position of annotation, when it's started to move/resize + internal GraphicsPath startMovePathRel = null; + +#if !Microsoft_CONTROL + + // Annotation map area attributes + private string _url = String.Empty; + private string _mapAreaAttributes = String.Empty; + private string _postbackValue = String.Empty; + +#endif // !Microsoft_CONTROL + + /// + /// Limit of annotation width and height. + /// + internal static double WidthHightLimit = 290000000; + + #endregion + + #region Constructors + /// + /// Initializes a new instance of the class. + /// + protected Annotation() + { + _textFont = _fontCache.DefaultFont; + } + + #endregion + + #region Properties + + #region Miscellaneous + + /// + /// Gets or sets an annotation's unique name. + /// + /// + /// A string that represents an annotation's unique name. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + SRDescription("DescriptionAttributeName4"), + ParenthesizePropertyNameAttribute(true), + ] + public override string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation Style + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotation_AnnotationType"), + ] + public abstract string AnnotationType + { + get; + } + + + /// + /// Gets or sets the name of the chart area which an annotation is clipped to. + /// + /// + /// A string which represents the name of an existing chart area. + /// + /// + /// If the chart area name is specified, an annotation will only be drawn inside the + /// plotting area of the chart area specified. All parts of the annotation + /// outside of the plotting area will be clipped. + /// + /// To disable chart area clipping, set the property to "NotSet" or an empty string. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(Constants.NotSetValue), + SRDescription("DescriptionAttributeAnnotationClipToChartArea"), + TypeConverter(typeof(LegendAreaNameConverter)) + ] + virtual public string ClipToChartArea + { + get + { + return _clipToChartArea; + } + set + { + if (value != _clipToChartArea) + { + if (String.IsNullOrEmpty(value)) + { + _clipToChartArea = Constants.NotSetValue; + } + else + { + if (Chart != null && Chart.ChartAreas != null) + { + Chart.ChartAreas.VerifyNameReference(value); + } + _clipToChartArea = value; + } + this.Invalidate(); + } + } + } + + + /// + /// Gets or sets the smart labels style of an annotation. + /// + /// + /// An object that represents an annotation's + /// smart labels style properties. + /// + /// + /// Smart labels are used to prevent an annotation from overlapping data point labels + /// and other annotations. + /// + /// Note that data point labels must also have smart labels enabled. + /// + /// + [ + Browsable(true), + SRCategory("CategoryAttributeMisc"), + Bindable(true), + SRDescription("DescriptionAttributeSmartLabels"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + ] + public AnnotationSmartLabelStyle SmartLabelStyle + { + get + { + if (this._smartLabelStyle == null) + { + this._smartLabelStyle = new AnnotationSmartLabelStyle(this); + } + return _smartLabelStyle; + } + set + { + value.chartElement = this; + _smartLabelStyle = value; + this.Invalidate(); + } + } + + /// + /// Gets the group, if any, the annotation belongs to. + /// + [ + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + ] + public AnnotationGroup AnnotationGroup + { + get { return this.annotationGroup; } + } + + #endregion + + #region Position + + /// + /// Gets or sets a flag that specifies whether the size of an annotation is always + /// defined in relative chart coordinates. + /// + /// + /// + /// + /// True if an annotation's and are always + /// in chart relative coordinates, false otherwise. + /// + /// + /// An annotation's width and height may be set in relative chart or axes coordinates. + /// By default, relative chart coordinates are used. + /// + /// To use axes coordinates for size set the IsSizeAlwaysRelative property to + /// false and either anchor the annotation to a data point or set the + /// or properties. + /// + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(true), + SRDescription("DescriptionAttributeSizeAlwaysRelative"), + ] + virtual public bool IsSizeAlwaysRelative + { + get + { + return _isSizeAlwaysRelative; + } + set + { + _isSizeAlwaysRelative = value; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets the X coordinate of an annotation. + /// + /// + /// + /// + /// A Double value that represents the X coordinate of an annotation. + /// + /// + /// The X coordinate of an annotation is in relative chart coordinates or axes coordinates. Chart + /// relative coordinates are used by default. + /// + /// To use axes coordinates, anchor + /// an annotation to a data point using the property, or + /// set the annotation axes using the or properties. + /// + /// + /// Set the X position to Double.NaN ("NotSet") to achieve automatic position calculation + /// when the annotation is anchored using the property or + /// the and properties. + /// + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(double.NaN), + SRDescription("DescriptionAttributeAnnotationBaseX"), + RefreshPropertiesAttribute(RefreshProperties.All), + TypeConverter(typeof(DoubleNanValueConverter)), + ] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "X")] + virtual public double X + { + get + { + return _x; + } + set + { + _x = value; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets the Y coordinate of an annotation. + /// + /// + /// + /// + /// A Double value that represents the Y coordinate of an annotation. + /// + /// + /// The Y coordinate of an annotation is in relative chart coordinates or axes coordinates. Chart + /// relative coordinates are used by default. + /// + /// To use axes coordinates, anchor + /// an annotation to a data point using the property, or + /// set the annotation axes using the or properties. + /// + /// + /// Set the Y position to Double.NaN ("NotSet") to achieve automatic position calculation + /// when the annotation is anchored using the property or + /// the and properties. + /// + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(double.NaN), + SRDescription("DescriptionAttributeAnnotationBaseY"), + RefreshPropertiesAttribute(RefreshProperties.All), + TypeConverter(typeof(DoubleNanValueConverter)), + ] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Y")] + virtual public double Y + { + get + { + return _y; + } + set + { + _y = value; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets an annotation's width. + /// + /// + /// + /// + /// A Double value that represents an annotation's width. + /// + /// + /// An annotation's width can be a negative value, in which case the annotation orientation + /// is switched. + /// + /// Annotation width can be in relative chart or axes coordinates. Chart + /// relative coordinates are used by default. + /// + /// + /// To use axes coordinates, anchor + /// an annotation to a data point using the property, or + /// set the annotation axes using the or properties + /// and set the property to false. + /// + /// + /// Set the width to Double.NaN ("NotSet") to achieve automatic size calculation for + /// annotations with text. The size will automatically be calculated based on + /// the annotation text and font size. + /// + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(double.NaN), + SRDescription("DescriptionAttributeAnnotationWidth"), + RefreshPropertiesAttribute(RefreshProperties.All), + TypeConverter(typeof(DoubleNanValueConverter)), + ] + virtual public double Width + { + get + { + return _width; + } + set + { + if (value < -WidthHightLimit || value > WidthHightLimit) + { + throw new ArgumentException(SR.ExceptionValueMustBeInRange("Width", (-WidthHightLimit).ToString(CultureInfo.CurrentCulture), WidthHightLimit.ToString(CultureInfo.CurrentCulture))); + } + _width = value; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets an annotation's height. + /// + /// + /// + /// + /// A Double value that represents an annotation's height. + /// + /// + /// An annotation's height can be a negative value, in which case the annotation orientation + /// is switched. + /// + /// Annotation height can be in relative chart or axes coordinates. Chart + /// relative coordinates are used by default. + /// + /// + /// To use axes coordinates, anchor + /// an annotation to a data point using the property, or + /// set the annotation axes using the or properties + /// and set the property to false. + /// + /// + /// Set the height to Double.NaN ("NotSet") to achieve automatic size calculation for + /// annotations with text. The size will automatically be calculated based on + /// the annotation text and font size. + /// + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(double.NaN), + SRDescription("DescriptionAttributeAnnotationHeight"), + RefreshPropertiesAttribute(RefreshProperties.All), + TypeConverter(typeof(DoubleNanValueConverter)), + ] + virtual public double Height + { + get + { + return _height; + } + set + { + if (value < -WidthHightLimit || value > WidthHightLimit) + { + throw new ArgumentException(SR.ExceptionValueMustBeInRange("Height", (-WidthHightLimit).ToString(CultureInfo.CurrentCulture), WidthHightLimit.ToString(CultureInfo.CurrentCulture))); + } + _height = value; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets an annotation position's right boundary. + /// + /// + /// + /// + /// A Double value that represents the position of an annotation's right boundary. + /// + /// + /// To use axes coordinates, anchor + /// an annotation to a data point using the property, or + /// set the annotation axes using the or properties + /// and set the property to false. + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(double.NaN), + SRDescription("DescriptionAttributeRight3"), + RefreshPropertiesAttribute(RefreshProperties.All), + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + TypeConverter(typeof(DoubleNanValueConverter)), + ] + virtual public double Right + { + get + { + return _x + _width; + } + set + { + _width = value - _x; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets an annotation position's bottom boundary. + /// + /// + /// + /// + /// A Double value that represents the position of an annotation's bottom boundary. + /// + /// + /// To use axes coordinates, anchor + /// an annotation to a data point using the property, or + /// set the annotation axes using the or properties + /// and set the property to false. + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(double.NaN), + SRDescription("DescriptionAttributeBottom"), + RefreshPropertiesAttribute(RefreshProperties.All), + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + TypeConverter(typeof(DoubleNanValueConverter)), + ] + virtual public double Bottom + { + get + { + return _y + _height; + } + set + { + _height = value - _y; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + #endregion + + #region Visual Attributes + +#if Microsoft_CONTROL + /// + /// Gets or sets a flag that determines if an annotation is selected. + /// + /// + /// + /// True if the annotation is selected, false otherwise. + /// +#else + /// + /// Gets or sets a flag that determines if an annotation is selected. + /// + /// + /// True if the annotation is selected, false otherwise. + /// +#endif // Microsoft_CONTROL + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(false), + Browsable(false), + SRDescription("DescriptionAttributeSelected"), + ] + virtual public bool IsSelected + { + get + { + return _isSelected; + } + set + { + _isSelected = value; + Invalidate(); + } + } + + /// + /// Gets or sets an annotation selection points style. + /// + /// + /// A value that represents annotation + /// selection style. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(SelectionPointsStyle.Rectangle), + ParenthesizePropertyNameAttribute(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeSelectionPointsStyle"), + ] + virtual internal SelectionPointsStyle SelectionPointsStyle + { + get + { + return SelectionPointsStyle.Rectangle; + } + } + + /// + /// Gets or sets a flag that specifies whether an annotation is visible. + /// + /// + /// True if the annotation is visible, false otherwise. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(true), + SRDescription("DescriptionAttributeVisible"), + ParenthesizePropertyNameAttribute(true), + ] + virtual public bool Visible + { + get + { + return _visible; + } + set + { + _visible = value; + Invalidate(); + } + } + + /// + /// Gets or sets an annotation's content alignment. + /// + /// + /// A value that represents the content alignment. + /// + /// + /// This property is used to align text for , , + /// and objects, and to align + /// a non-scaled image inside an object. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(ContentAlignment), "MiddleCenter"), + SRDescription("DescriptionAttributeAlignment"), + ] + virtual public ContentAlignment Alignment + { + get + { + return _alignment; + } + set + { + _alignment = value; + Invalidate(); + } + } + + /// + /// Gets or sets the text color of an annotation. + /// + /// + /// + /// A value used for the text color of an annotation. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeForeColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + virtual public Color ForeColor + { + get + { + return _foreColor; + } + set + { + _foreColor = value; + Invalidate(); + } + } + + /// + /// Gets or sets the font of an annotation's text. + /// + /// + /// + /// A object used for an annotation's text. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"), + SRDescription("DescriptionAttributeTextFont"), + ] + virtual public Font Font + { + get + { + return _textFont; + } + set + { + _textFont = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets an annotation's text style. + /// + /// + /// + /// + /// A value used to draw an annotation's text. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(TextStyle), "Default"), + SRDescription("DescriptionAttributeTextStyle"), + ] + virtual public TextStyle TextStyle + { + get + { + return _textStyle; + } + set + { + _textStyle = value; + Invalidate(); + } + } + + /// + /// Gets or sets the color of an annotation line. + /// + /// + /// + /// + /// A value used to draw an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLineColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + virtual public Color LineColor + { + get + { + return lineColor; + } + set + { + lineColor = value; + Invalidate(); + } + } + + /// + /// Gets or sets the width of an annotation line. + /// + /// + /// + /// + /// An integer value defining the width of an annotation line in pixels. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(1), + SRDescription("DescriptionAttributeLineWidth"), + ] + virtual public int LineWidth + { + get + { + return _lineWidth; + } + set + { + if(value < 0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAnnotationLineWidthIsNegative)); + } + _lineWidth = value; + Invalidate(); + } + } + + /// + /// Gets or sets the style of an annotation line. + /// + /// + /// + /// + /// A value used to draw an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeLineDashStyle"), + ] + virtual public ChartDashStyle LineDashStyle + { + get + { + return _lineDashStyle; + } + set + { + _lineDashStyle = value; + Invalidate(); + } + } + + /// + /// Gets or sets the background color of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + virtual public Color BackColor + { + get + { + return _backColor; + } + set + { + _backColor = value; + Invalidate(); + } + } + + /// + /// Gets or sets the background hatch style of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + /// + /// Two colors are used to draw the hatching, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackHatchStyle"), + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + virtual public ChartHatchStyle BackHatchStyle + { + get + { + return _backHatchStyle; + } + set + { + _backHatchStyle = value; + Invalidate(); + } + } + /// + /// Gets or sets the background gradient style of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + /// + /// Two colors are used to draw the gradient, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackGradientStyle"), + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + virtual public GradientStyle BackGradientStyle + { + get + { + return _backGradientStyle; + } + set + { + _backGradientStyle = value; + Invalidate(); + } + } + + /// + /// Gets or sets the secondary background color of an annotation. + /// + /// + /// + /// + /// + /// A value used for the secondary color of an annotation background with + /// hatching or gradient fill. + /// + /// + /// This color is used with when or + /// are used. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + virtual public Color BackSecondaryColor + { + get + { + return _backSecondaryColor; + } + set + { + _backSecondaryColor = value; + Invalidate(); + } + } + + /// + /// Gets or sets the color of an annotation's shadow. + /// + /// + /// + /// A value used to draw an annotation's shadow. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), "128,0,0,0"), + SRDescription("DescriptionAttributeShadowColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + virtual public Color ShadowColor + { + get + { + return _shadowColor; + } + set + { + _shadowColor = value; + Invalidate(); + } + } + + /// + /// Gets or sets the offset between an annotation and its shadow. + /// + /// + /// + /// An integer value that represents the offset between an annotation and its shadow. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(0), + SRDescription("DescriptionAttributeShadowOffset"), + ] + virtual public int ShadowOffset + { + get + { + return _shadowOffset; + } + set + { + _shadowOffset = value; + Invalidate(); + } + } + + #endregion + + #region Axes Attaching + + /// + /// Gets or sets the name of the X axis which an annotation is attached to. + /// + /// + /// A string value that represents the name of the X axis which an annotation + /// is attached to. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAnchorAxes"), + DefaultValue(""), + Browsable(false), + Bindable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + SRDescription("DescriptionAttributeAxisXName"), + ] + virtual public string AxisXName + { + get + { + if(_axisXName.Length == 0 && _axisX != null) + { + _axisXName = GetAxisName(_axisX); + } + return _axisXName; + } + set + { + _axisXName = value; + _axisX = null; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets the name of the Y axis which an annotation is attached to. + /// + /// + /// A string value that represents the name of the Y axis which an annotation + /// is attached to. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAnchorAxes"), + Browsable(false), + Bindable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DefaultValue(""), + SRDescription("DescriptionAttributeAxisYName"), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + ] + virtual public string AxisYName + { + get + { + // Always return empty string to prevent property serialization + // "YAxisName" property will be used instead. + return string.Empty; + } + set + { + this.YAxisName = value; + } + } + + + /// + /// Gets or sets the name of the Y axis which an annotation is attached to. + /// NOTE: "AxisYName" property was used before but the name was changed to solve the + /// duplicated hash value during the serialization with the "TitleSeparator" property. + /// + /// + /// A string value that represents the name of the Y axis which an annotation + /// is attached to. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAnchorAxes"), + Browsable(false), + Bindable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DefaultValue(""), + SRDescription("DescriptionAttributeAxisYName"), + ] + virtual public string YAxisName + { + get + { + if(_axisYName.Length == 0 && _axisY != null) + { + _axisYName = GetAxisName(_axisY); + } + return _axisYName; + } + set + { + _axisYName = value; + _axisY = null; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets the X axis which an annotation is attached to. + /// + /// + /// + /// + /// object which an annotation is attached to. + /// + /// + /// When an annotation is attached to an axis, its X position is always in + /// axis coordinates. To define an annotation's size in axis coordinates as well, + /// make sure the property is set to false. + /// + /// Set this value to null or nothing to disable attachment to the axis. + /// + /// + [ + SRCategory("CategoryAttributeAnchorAxes"), + DefaultValue(null), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAxisX"), + Editor(Editors.AnnotationAxisUITypeEditor.Editor, Editors.AnnotationAxisUITypeEditor.Base), + TypeConverter(typeof(AnnotationAxisValueConverter)), + ] + virtual public Axis AxisX + { + get + { + if(_axisX == null && _axisXName.Length > 0) + { + _axisX = GetAxisByName(_axisXName); + } + return _axisX; + } + set + { + _axisX = value; + _axisXName = String.Empty; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets the Y axis which an annotation is attached to. + /// + /// + /// + /// + /// object which an annotation is attached to. + /// + /// + /// When an annotation is attached to an axis, its Y position is always in + /// axis coordinates. To define an annotation's size in axis coordinates as well, + /// make sure property is set to false. + /// + /// Set this value to null or nothing to disable annotation attachment to an axis. + /// + /// + [ + SRCategory("CategoryAttributeAnchorAxes"), + DefaultValue(null), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAxisY"), + Editor(Editors.AnnotationAxisUITypeEditor.Editor, Editors.AnnotationAxisUITypeEditor.Base), + TypeConverter(typeof(AnnotationAxisValueConverter)), + ] + virtual public Axis AxisY + { + get + { + if(_axisY == null && _axisYName.Length > 0) + { + _axisY = GetAxisByName(_axisYName); + } + return _axisY; + } + set + { + _axisY = value; + _axisYName = String.Empty; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + #endregion + + #region Anchor + + /// + /// Gets or sets the name of a data point which an annotation is anchored to. + /// + /// + /// A string value that represents the name of the data point which an + /// annotation is anchored to. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAnchor"), + Browsable(false), + Bindable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DefaultValue(""), + SRDescription("DescriptionAttributeAnchorDataPointName"), + ] + virtual public string AnchorDataPointName + { + get + { + if(_anchorDataPointName.Length == 0 && _anchorDataPoint != null) + { + _anchorDataPointName = GetDataPointName(_anchorDataPoint); + } + return _anchorDataPointName; + } + set + { + _anchorDataPointName = value; + _anchorDataPoint = null; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets the data point an annotation is anchored to. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// A object an annotation is anchored to. + /// + /// + /// The annotation is anchored to the X and Y values of the specified data point, + /// and automatically uses the same axes coordinates as the data point. + /// + /// To automatically position an annotation relative to an anchor point, make sure + /// its and properties are set to Double.NaN. + /// The property may be used to change an annotation's + /// automatic position alignment to an anchor point. The and + /// properties may be used to add extra spacing. + /// + /// + /// When using this property, make sure the and + /// properties are set to Double.NaN (they have precedence). + /// + /// + /// Set this value to null or nothing to disable annotation anchoring to a data point. + /// + /// + [ + SRCategory("CategoryAttributeAnchor"), + DefaultValue(null), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnchorDataPoint"), + Editor(Editors.AnchorPointUITypeEditor.Editor, Editors.AnchorPointUITypeEditor.Base), + TypeConverter(typeof(AnchorPointValueConverter)), + ] + virtual public DataPoint AnchorDataPoint + { + get + { + if(_anchorDataPoint == null && _anchorDataPointName.Length > 0) + { + _anchorDataPoint = GetDataPointByName(_anchorDataPointName); + } + return _anchorDataPoint; + } + set + { + _anchorDataPoint = value; + _anchorDataPointName = String.Empty; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets the X coordinate the annotation is anchored to. + /// + /// + /// + /// + /// + /// + /// + /// A double value that represents the X coordinate which an annotation is anchored to. + /// + /// + /// The annotation is anchored to the X coordinate specified in relative or axis coordinates, + /// depending on the property value. + /// + /// To automatically position an annotation relative to an anchor point, make sure + /// its property is set to Double.NaN. + /// The property may be used to change the annotation's + /// automatic position alignment to the anchor point. The and + /// properties may be used to add extra spacing. + /// + /// + /// This property has a higher priority than the property. + /// + /// + /// Set this value to Double.NaN to disable annotation anchoring to the value. + /// + /// + [ + SRCategory("CategoryAttributeAnchor"), + DefaultValue(double.NaN), + SRDescription("DescriptionAttributeAnchorX"), + RefreshPropertiesAttribute(RefreshProperties.All), + TypeConverter(typeof(DoubleNanValueConverter)), + ] + virtual public double AnchorX + { + get + { + return _anchorX; + } + set + { + _anchorX = value; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets the Y coordinate which an annotation is anchored to. + /// + /// + /// + /// + /// + /// + /// + /// A double value that represents the Y coordinate which an annotation is anchored to. + /// + /// + /// The annotation is anchored to the Y coordinate specified in relative or axis coordinates, + /// depending on the property value. + /// + /// To automatically position an annotation relative to an anchor point, make sure + /// its property is set to Double.NaN. + /// The property may be used to change the annotation's + /// automatic position alignment to the anchor point. The and + /// properties may be used to add extra spacing. + /// + /// + /// This property has a higher priority than the property. + /// + /// + /// Set this value to Double.NaN to disable annotation anchoring to the value. + /// + /// + [ + SRCategory("CategoryAttributeAnchor"), + DefaultValue(double.NaN), + SRDescription("DescriptionAttributeAnchorY"), + RefreshPropertiesAttribute(RefreshProperties.All), + TypeConverter(typeof(DoubleNanValueConverter)), + ] + virtual public double AnchorY + { + get + { + return _anchorY; + } + set + { + _anchorY = value; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets the x-coordinate offset between the positions of an annotation and its anchor point. + /// + /// + /// + /// + /// + /// + /// A double value that represents the x-coordinate offset between the positions of an annotation and its anchor point. + /// + /// + /// The annotation must be anchored using the or + /// properties, and its property must be set + /// to Double.NaN. + /// + [ + SRCategory("CategoryAttributeAnchor"), + DefaultValue(0.0), + SRDescription("DescriptionAttributeAnchorOffsetX3"), + RefreshPropertiesAttribute(RefreshProperties.All), + ] + virtual public double AnchorOffsetX + { + get + { + return anchorOffsetX; + } + set + { + if(value > 100.0 || value < -100.0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAnnotationAnchorOffsetInvalid)); + } + anchorOffsetX = value; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets the y-coordinate offset between the positions of an annotation and its anchor point. + /// + /// + /// + /// + /// + /// + /// A double value that represents the y-coordinate offset between the positions of an annotation and its anchor point. + /// + /// + /// Annotation must be anchored using or + /// properties and it's property must be set + /// to Double.NaN. + /// + [ + SRCategory("CategoryAttributeAnchor"), + DefaultValue(0.0), + SRDescription("DescriptionAttributeAnchorOffsetY3"), + RefreshPropertiesAttribute(RefreshProperties.All), + ] + virtual public double AnchorOffsetY + { + get + { + return anchorOffsetY; + } + set + { + if(value > 100.0 || value < -100.0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAnnotationAnchorOffsetInvalid)); + } + anchorOffsetY = value; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + /// + /// Gets or sets an annotation position's alignment to the anchor point. + /// + /// + /// + /// + /// + /// + /// + /// A value that represents the annotation's alignment to + /// the anchor point. + /// + /// + /// The annotation must be anchored using either , or the + /// and properties. Its and + /// properties must be set to Double.NaN. + /// + [ + SRCategory("CategoryAttributeAnchor"), + DefaultValue(typeof(ContentAlignment), "BottomCenter"), + SRDescription("DescriptionAttributeAnchorAlignment"), + ] + virtual public ContentAlignment AnchorAlignment + { + get + { + return anchorAlignment; + } + set + { + anchorAlignment = value; + this.ResetCurrentRelativePosition(); + Invalidate(); + } + } + + #endregion // Anchoring + + #region Editing Permissions + +#if Microsoft_CONTROL + + /// + /// Gets or sets a flag that specifies whether an annotation may be selected + /// with a mouse by the end user. + /// + /// + /// True if the annotation may be selected, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAllowSelecting"), + ] + virtual public bool AllowSelecting + { + get + { + return _allowSelecting; + } + set + { + _allowSelecting = value; + } + } + + /// + /// Gets or sets a flag that specifies whether an annotation may be moved + /// with a mouse by the end user. + /// + /// + /// True if the annotation may be moved, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAllowMoving"), + ] + virtual public bool AllowMoving + { + get + { + return _allowMoving; + } + set + { + _allowMoving = value; + } + } + + /// + /// Gets or sets a flag that specifies whether an annotation anchor may be moved + /// with a mouse by the end user. + /// + /// + /// True if the annotation anchor may be moved, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAllowAnchorMoving3"), + ] + virtual public bool AllowAnchorMoving + { + get + { + return _allowAnchorMoving; + } + set + { + _allowAnchorMoving = value; + } + } + + /// + /// Gets or sets a flag that specifies whether an annotation may be resized + /// with a mouse by the end user. + /// + /// + /// True if the annotation may be resized, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAllowResizing"), + ] + virtual public bool AllowResizing + { + get + { + return _allowResizing; + } + set + { + _allowResizing = value; + } + } + + /// + /// Gets or sets a flag that specifies whether an annotation's text may be edited + /// when the end user double clicks on the text. + /// + /// + /// True if the annotation text may be edited, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAllowTextEditing"), + ] + virtual public bool AllowTextEditing + { + get + { + return _allowTextEditing; + } + set + { + _allowTextEditing = value; + } + } + + /// + /// Gets or sets a flag that specifies whether a polygon annotation's points + /// may be moved with a mouse by the end user. + /// + /// + /// True if the polygon annotation's points may be moved, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAllowPathEditing3"), + ] + virtual public bool AllowPathEditing + { + get + { + return _allowPathEditing; + } + set + { + _allowPathEditing = value; + } + } + +#endif // Microsoft_CONTROL + + #endregion + + #region Interactivity + + /// + /// Gets or sets an annotation's tooltip text. + /// + /// + /// A string value. + /// + /// + /// Special keywords can be used in the text when an annotation is anchored to + /// a data point using the property. For a listing of + /// these keywords, refer to the "Annotations" help topic. + /// + [ + + SRCategory("CategoryAttributeMisc"), + DefaultValue(""), + SRDescription("DescriptionAttributeToolTip"), + ] + virtual public string ToolTip + { + get + { + return _tooltip; + } + set + { + _tooltip = value; + + } + } + +#if !Microsoft_CONTROL + + /// + /// Gets or sets an annotation's Url. + /// + /// + /// A string value. + /// + /// + /// Special keywords can be used when an annotation is anchored to + /// a data point using the property. For a listing of + /// these keywords, refer to the "Annotations" help topic. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(""), + SRDescription("DescriptionAttributeUrl"), + ] + virtual public string Url + { + get + { + return _url; + } + set + { + _url = value; + + } + } + + /// + /// Gets or sets an annotation's map area attributes. + /// + /// + /// A string value. + /// + /// + /// This string will be added to the attributes of the image map generated + /// for the annotation. + /// + /// Special keywords can be used when an annotation is anchored to + /// a data point using the property. For a listing of + /// these keywords, refer to the "Annotations" help topic. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(""), + SRDescription("DescriptionAttributeMapAreaAttributes"), + ] + virtual public string MapAreaAttributes + { + get + { + return _mapAreaAttributes; + } + set + { + _mapAreaAttributes = value; + + } + } + + /// + /// Gets or sets the postback value which can be processed on click event. + /// + /// The value which is passed to click event as argument. + [DefaultValue("")] + [SRCategory(SR.Keys.CategoryAttributeMapArea)] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + public string PostBackValue + { + get + { + return this._postbackValue; + } + set + { + this._postbackValue = value; + } + } + + +#endif // !Microsoft_CONTROL + + #endregion // Interactivity + + #endregion + + #region Methods + + #region Painting + + /// + /// Paints the annotation object using the specified graphics. + /// + /// + /// A object used to paint the annotation object. + /// + /// + /// Reference to the annotation's control owner. + /// + abstract internal void Paint(Chart chart, ChartGraphics graphics); + + /// + /// Paints annotation selection markers. + /// + /// Chart graphics used for painting. + /// Selection rectangle. + /// Selection path. + virtual internal void PaintSelectionHandles(ChartGraphics chartGraphics, RectangleF rect, GraphicsPath path) + { + // Define markers appearance style + Color markerBorderColor = Color.Black; + Color markerColor = Color.FromArgb(200, 255, 255, 255); + MarkerStyle markerStyle = MarkerStyle.Square; + int markerSize = selectionMarkerSize; + Boolean selected = this.IsSelected; + + SizeF markerSizeRel = chartGraphics.GetRelativeSize(new SizeF(markerSize, markerSize)); + if (this.Common.ProcessModePaint && + !this.Common.ChartPicture.isPrinting) + { + // Clear selection rectangles + this.selectionRects = null; + + // Check if annotation is selected + if (selected) + { + // Create selection rectangles + this.selectionRects = new RectangleF[9]; + + // Draw selection handles for single dimension annotations like line. + if(this.SelectionPointsStyle == SelectionPointsStyle.TwoPoints) + { + // Save selection handles position in array elements 0 and 4 + this.selectionRects[(int)ResizingMode.TopLeftHandle] = new RectangleF( + rect.X - markerSizeRel.Width/2f, + rect.Y - markerSizeRel.Height/2f, + markerSizeRel.Width, + markerSizeRel.Height); + this.selectionRects[(int)ResizingMode.BottomRightHandle] = new RectangleF( + rect.Right - markerSizeRel.Width/2f, + rect.Bottom - markerSizeRel.Height/2f, + markerSizeRel.Width, + markerSizeRel.Height); + + + // Draw selection handle + chartGraphics.DrawMarkerRel( + rect.Location, + markerStyle, + markerSize, + markerColor, + markerBorderColor, + 1, + "", + Color.Empty, + 0, + Color.FromArgb(128, 0, 0, 0), + RectangleF.Empty); + + chartGraphics.DrawMarkerRel( + new PointF(rect.Right, rect.Bottom), + markerStyle, + markerSize, + markerColor, + markerBorderColor, + 1, + "", + Color.Empty, + 0, + Color.FromArgb(128, 0, 0, 0), + RectangleF.Empty); + } + else if(this.SelectionPointsStyle == SelectionPointsStyle.Rectangle) + { + for(int index = 0; index < 8; index++) + { + // Get handle position + PointF handlePosition = PointF.Empty; + switch((ResizingMode)index) + { + case ResizingMode.TopLeftHandle: + handlePosition = rect.Location; + break; + case ResizingMode.TopHandle: + handlePosition = new PointF(rect.X + rect.Width / 2f, rect.Y); + break; + case ResizingMode.TopRightHandle: + handlePosition = new PointF(rect.Right, rect.Y); + break; + case ResizingMode.RightHandle: + handlePosition = new PointF(rect.Right, rect.Y + rect.Height / 2f); + break; + case ResizingMode.BottomRightHandle: + handlePosition = new PointF(rect.Right, rect.Bottom); + break; + case ResizingMode.BottomHandle: + handlePosition = new PointF(rect.X + rect.Width / 2f, rect.Bottom); + break; + case ResizingMode.BottomLeftHandle: + handlePosition = new PointF(rect.X, rect.Bottom); + break; + case ResizingMode.LeftHandle: + handlePosition = new PointF(rect.X, rect.Y + rect.Height / 2f); + break; + } + + // Save selection handles position in array elements 0 and 4 + this.selectionRects[index] = new RectangleF( + handlePosition.X - markerSizeRel.Width/2f, + handlePosition.Y - markerSizeRel.Height/2f, + markerSizeRel.Width, + markerSizeRel.Height); + + // Draw selection handle + chartGraphics.DrawMarkerRel( + handlePosition, + markerStyle, + markerSize, + markerColor, + markerBorderColor, + 1, + "", + Color.Empty, + 0, + Color.FromArgb(128, 0, 0, 0), + RectangleF.Empty); + } + } + + + //******************************************************************** + //** Draw anchor selection handle + //******************************************************************** + + // Get vertical and horizontal axis + Axis vertAxis = null; + Axis horizAxis = null; + GetAxes(ref vertAxis, ref horizAxis); + + // Get anchor position + double anchorX = double.NaN; + double anchorY = double.NaN; + bool relativeX = false; + bool relativeY = false; + this.GetAnchorLocation(ref anchorX, ref anchorY, ref relativeX, ref relativeY); + + // Convert anchor location to relative coordinates + if(!double.IsNaN(anchorX) && !double.IsNaN(anchorY)) + { + if( !relativeX && horizAxis != null ) + { + anchorX = horizAxis.ValueToPosition(anchorX); + } + if( !relativeY && vertAxis != null ) + { + anchorY = vertAxis.ValueToPosition(anchorY); + } + + // Apply 3D transforamtion if required + ChartArea chartArea = null; + if(horizAxis != null && horizAxis.ChartArea != null) + { + chartArea = horizAxis.ChartArea; + } + if(vertAxis != null && vertAxis.ChartArea != null) + { + chartArea = vertAxis.ChartArea; + } + if(chartArea != null && + chartArea.Area3DStyle.Enable3D == true && + !chartArea.chartAreaIsCurcular && + chartArea.requireAxes && + chartArea.matrix3D.IsInitialized()) + { + // Get anotation Z coordinate (use scene depth or anchored point Z position) + float positionZ = chartArea.areaSceneDepth; + if (this.AnchorDataPoint != null && this.AnchorDataPoint.series != null) + { + float depth = 0f; + chartArea.GetSeriesZPositionAndDepth( + this.AnchorDataPoint.series, + out depth, + out positionZ); + positionZ += depth / 2f; + } + + // Define 3D points of annotation object + Point3D[] annot3DPoints = new Point3D[1]; + annot3DPoints[0] = new Point3D((float)anchorX, (float)anchorY, positionZ); + + // Tranform cube coordinates + chartArea.matrix3D.TransformPoints(annot3DPoints); + + // Get transformed coordinates + anchorX = annot3DPoints[0].X; + anchorY = annot3DPoints[0].Y; + } + + // Save selection handles position in array elements 0 and 4 + this.selectionRects[(int)ResizingMode.AnchorHandle] = new RectangleF( + (float)anchorX - markerSizeRel.Width/2f, + (float)anchorY - markerSizeRel.Height/2f, + markerSizeRel.Width, + markerSizeRel.Height); + + // Draw circular selection handle + chartGraphics.DrawMarkerRel( + new PointF((float)anchorX, (float)anchorY), + MarkerStyle.Cross, + selectionMarkerSize + 3, + markerColor, + markerBorderColor, + 1, + "", + Color.Empty, + 0, + Color.FromArgb(128, 0, 0, 0), + RectangleF.Empty); + } + +#if Microsoft_CONTROL + + //******************************************************************** + //** Draw path selection handles + //******************************************************************** + if(path != null && AllowPathEditing) + { + // Create selection rectangles for each point + PointF[] pathPoints = path.PathPoints; + RectangleF[] newSelectionRects = new RectangleF[pathPoints.Length + 9]; + + // Copy previous rectangles (first nine elements) + for(int index = 0; index < this.selectionRects.Length; index++) + { + newSelectionRects[index] = this.selectionRects[index]; + } + this.selectionRects = newSelectionRects; + + // Loop through all points + for(int index = 0; index < pathPoints.Length; index++) + { + // Get handle position + PointF handlePosition = chartGraphics.GetRelativePoint(pathPoints[index]); + + // Save selection handles position in array elements 0 and 4 + this.selectionRects[9 + index] = new RectangleF( + handlePosition.X - markerSizeRel.Width/2f, + handlePosition.Y - markerSizeRel.Height/2f, + markerSizeRel.Width, + markerSizeRel.Height); + + // Draw selection handle + chartGraphics.DrawMarkerRel( + handlePosition, + MarkerStyle.Circle, + selectionMarkerSize + 1, + markerColor, + markerBorderColor, + 1, + "", + Color.Empty, + 0, + Color.FromArgb(128, 0, 0, 0), + RectangleF.Empty); + } + } + +#endif // Microsoft_CONTROL + + } + } + } + + #endregion + + #region Position and Size + + /// + /// Resizes an annotation according to its content size. + /// + /// + /// Sets the annotation width and height to fit the specified text. This method applies to + /// , , + /// and objects only. + /// + virtual public void ResizeToContent() + { + RectangleF position = GetContentPosition(); + if(!double.IsNaN(position.Width)) + { + this.Width = position.Width; + } + if(!double.IsNaN(position.Height)) + { + this.Height = position.Height; + } + } + + /// + /// Gets an annotation's content position. + /// + /// Annotation's content size. + virtual internal RectangleF GetContentPosition() + { + return new RectangleF(float.NaN, float.NaN, float.NaN, float.NaN); + } + + /// + /// Gets an annotation's anchor point location. + /// + /// Returns the anchor X coordinate. + /// Returns the anchor Y coordinate. + /// Indicates if X coordinate is in relative chart coordinates. + /// Indicates if Y coordinate is in relative chart coordinates. + private void GetAnchorLocation(ref double anchorX, ref double anchorY, ref bool inRelativeAnchorX, ref bool inRelativeAnchorY) + { + anchorX = this.AnchorX; + anchorY = this.AnchorY; + + if(this.AnchorDataPoint != null && + this.AnchorDataPoint.series != null && + this.Chart != null && + this.Chart.chartPicture != null) + { + // Anchor data point is not allowed for gropped annotations + if(this.AnnotationGroup != null) + { + throw (new InvalidOperationException(SR.ExceptionAnnotationGroupedAnchorDataPointMustBeEmpty)); + } + + // Get data point relative coordinate + if( double.IsNaN(anchorX) || double.IsNaN(anchorY)) + { + // Get X value from data point + if( double.IsNaN(anchorX) ) + { + anchorX = this.AnchorDataPoint.positionRel.X; + inRelativeAnchorX = true; + } + + // Get Y value from data point + if( double.IsNaN(anchorY) ) + { + anchorY = this.AnchorDataPoint.positionRel.Y; + inRelativeAnchorY = true; + } + } + } + } + + /// + /// Gets annotation object position in relative coordinates. + /// + /// Returns annotation location. + /// Returns annotation size. + /// Returns annotation anchor point location. + virtual internal void GetRelativePosition(out PointF location, out SizeF size, out PointF anchorLocation) + { + bool saveCurrentPosition = true; + + //*********************************************************************** + //** Check if position was precalculated + //*********************************************************************** + if(!double.IsNaN(currentPositionRel.X) && !double.IsNaN(currentPositionRel.X)) + { + location = currentPositionRel.Location; + size = currentPositionRel.Size; + anchorLocation = currentAnchorLocationRel; + return; + } + + //*********************************************************************** + //** Get vertical and horizontal axis + //*********************************************************************** + Axis vertAxis = null; + Axis horizAxis = null; + GetAxes(ref vertAxis, ref horizAxis); + + //*********************************************************************** + //** Check if annotation was anchored to 2 points. + //*********************************************************************** + if(this._anchorDataPoint != null && + this._anchorDataPoint2 != null) + { + // Annotation size is in axis coordinates + this.IsSizeAlwaysRelative = false; + + // Set annotation size + this.Height = + vertAxis.PositionToValue(this._anchorDataPoint2.positionRel.Y, false) - + vertAxis.PositionToValue(this._anchorDataPoint.positionRel.Y, false); + this.Width = + horizAxis.PositionToValue(this._anchorDataPoint2.positionRel.X, false) - + horizAxis.PositionToValue(this._anchorDataPoint.positionRel.X, false); + + // Reset second anchor point after setting width and height + this._anchorDataPoint2 = null; + } + + //*********************************************************************** + //** Flags which indicate that coordinate was already transformed + //** into chart relative coordinate system. + //*********************************************************************** + bool inRelativeX = false; + bool inRelativeY = false; + bool inRelativeWidth = (_isSizeAlwaysRelative) ? true : false; + bool inRelativeHeight = (_isSizeAlwaysRelative) ? true : false; + bool inRelativeAnchorX = false; + bool inRelativeAnchorY = false; + + //*********************************************************************** + //** Get anchoring coordinates from anchored Data Point. + //*********************************************************************** + double anchorX = this.AnchorX; + double anchorY = this.AnchorY; + GetAnchorLocation(ref anchorX, ref anchorY, ref inRelativeAnchorX, ref inRelativeAnchorY); + + //*********************************************************************** + //** Calculate scaling and translation for the annotations in the group. + //*********************************************************************** + AnnotationGroup group = this.AnnotationGroup; + PointF groupLocation = PointF.Empty; + double groupScaleX = 1.0; + double groupScaleY = 1.0; + if(group != null) + { + // Do not save relative position of annotations inside the group + saveCurrentPosition = false; + + // Take relative position of the group + SizeF groupSize = SizeF.Empty; + PointF groupAnchorLocation = PointF.Empty; + group.GetRelativePosition(out groupLocation, out groupSize, out groupAnchorLocation); + + // Calculate Scale + groupScaleX = groupSize.Width / 100.0; + groupScaleY = groupSize.Height / 100.0; + } + + + //*********************************************************************** + //** Get annotation automatic size. + //*********************************************************************** + double relativeWidth = this._width; + double relativeHeight = this._height; + + // Get annotation content position + RectangleF contentPosition = GetContentPosition(); + + // Set annotation size if not set to custom value + if( double.IsNaN(relativeWidth) ) + { + relativeWidth = contentPosition.Width; + inRelativeWidth = true; + } + else + { + relativeWidth *= groupScaleX; + } + if( double.IsNaN(relativeHeight) ) + { + relativeHeight = contentPosition.Height; + inRelativeHeight = true; + } + else + { + relativeHeight *= groupScaleY; + } + + //*********************************************************************** + //** Provide "dummy" size at design time + //*********************************************************************** + if(this.Chart != null && this.Chart.IsDesignMode()) + { + if(this.IsSizeAlwaysRelative || + (vertAxis == null && horizAxis == null) ) + { + if(double.IsNaN(relativeWidth)) + { + relativeWidth = 20.0; + saveCurrentPosition = false; + } + if(double.IsNaN(relativeHeight)) + { + relativeHeight = 20.0; + saveCurrentPosition = false; + } + } + } + + //*********************************************************************** + //** Get annotation location. + //*********************************************************************** + double relativeX = this.X; + double relativeY = this.Y; + + // Check if annotation location Y coordinate is defined + if( double.IsNaN(relativeY) && !double.IsNaN(anchorY) ) + { + inRelativeY = true; + double relativeAnchorY = anchorY; + if(!inRelativeAnchorY && vertAxis != null) + { + relativeAnchorY = vertAxis.ValueToPosition(anchorY); + } + if(this.AnchorAlignment == ContentAlignment.TopCenter || + this.AnchorAlignment == ContentAlignment.TopLeft || + this.AnchorAlignment == ContentAlignment.TopRight) + { + relativeY = relativeAnchorY + this.AnchorOffsetY; + relativeY *= groupScaleY; + } + else if(this.AnchorAlignment == ContentAlignment.BottomCenter || + this.AnchorAlignment == ContentAlignment.BottomLeft || + this.AnchorAlignment == ContentAlignment.BottomRight) + { + relativeY = relativeAnchorY - this.AnchorOffsetY; + relativeY *= groupScaleY; + if(relativeHeight != 0f && !double.IsNaN(relativeHeight)) + { + if(inRelativeHeight) + { + relativeY -= relativeHeight; + } + else if(vertAxis != null) + { + float yValue = (float)vertAxis.PositionToValue(relativeY); + float bottomRel = (float)vertAxis.ValueToPosition(yValue + relativeHeight); + relativeY -= bottomRel - relativeY; + } + } + } + else + { + relativeY = relativeAnchorY + this.AnchorOffsetY; + relativeY *= groupScaleY; + if(relativeHeight != 0f && !double.IsNaN(relativeHeight)) + { + if(inRelativeHeight) + { + relativeY -= relativeHeight/2f; + } + else if(vertAxis != null) + { + float yValue = (float)vertAxis.PositionToValue(relativeY); + float bottomRel = (float)vertAxis.ValueToPosition(yValue + relativeHeight); + relativeY -= (bottomRel - relativeY) / 2f; + } + } + } + } + else + { + relativeY *= groupScaleY; + } + + // Check if annotation location X coordinate is defined + if( double.IsNaN(relativeX) && !double.IsNaN(anchorX) ) + { + inRelativeX = true; + double relativeAnchorX = anchorX; + if(!inRelativeAnchorX && horizAxis != null) + { + relativeAnchorX = horizAxis.ValueToPosition(anchorX); + } + if(this.AnchorAlignment == ContentAlignment.BottomLeft || + this.AnchorAlignment == ContentAlignment.MiddleLeft || + this.AnchorAlignment == ContentAlignment.TopLeft) + { + relativeX = relativeAnchorX + this.AnchorOffsetX; + relativeX *= groupScaleX; + } + else if(this.AnchorAlignment == ContentAlignment.BottomRight || + this.AnchorAlignment == ContentAlignment.MiddleRight || + this.AnchorAlignment == ContentAlignment.TopRight) + { + relativeX = relativeAnchorX - this.AnchorOffsetX; + relativeX *= groupScaleX; + if(relativeWidth != 0f && !double.IsNaN(relativeWidth)) + { + if(inRelativeWidth) + { + relativeX -= relativeWidth; + } + else if(horizAxis != null) + { + float xValue = (float)horizAxis.PositionToValue(relativeX); + relativeX -= horizAxis.ValueToPosition(xValue + relativeWidth) - relativeX; + } + } + } + else + { + relativeX = relativeAnchorX + this.AnchorOffsetX; + relativeX *= groupScaleX; + if(relativeWidth != 0f && !double.IsNaN(relativeWidth)) + { + if(inRelativeWidth) + { + relativeX -= relativeWidth/2f; + } + else if(horizAxis != null) + { + float xValue = (float)horizAxis.PositionToValue(relativeX); + relativeX -= (horizAxis.ValueToPosition(xValue + relativeWidth) - relativeX) / 2f; + } + } + } + } + else + { + relativeX *= groupScaleX; + } + + // Translate + relativeX += groupLocation.X; + relativeY += groupLocation.Y; + + //*********************************************************************** + //** Get annotation automatic location. + //*********************************************************************** + + // Set annotation size if not set to custom value + if( double.IsNaN(relativeX) ) + { + relativeX = contentPosition.X * groupScaleX; + inRelativeX = true; + } + if( double.IsNaN(relativeY) ) + { + relativeY = contentPosition.Y * groupScaleY; + inRelativeY = true; + } + + //*********************************************************************** + //** Convert coordinates from axes values to relative coordinates. + //*********************************************************************** + + // Check if values are set in axis values + if(horizAxis != null) + { + if(!inRelativeX) + { + relativeX = horizAxis.ValueToPosition(relativeX); + } + if(!inRelativeAnchorX) + { + anchorX = horizAxis.ValueToPosition(anchorX); + } + if(!inRelativeWidth) + { + relativeWidth = horizAxis.ValueToPosition( + horizAxis.PositionToValue(relativeX, false) + relativeWidth) - relativeX; + } + } + if(vertAxis != null) + { + if(!inRelativeY) + { + relativeY = vertAxis.ValueToPosition(relativeY); + } + if(!inRelativeAnchorY) + { + anchorY = vertAxis.ValueToPosition(anchorY); + } + if(!inRelativeHeight) + { + relativeHeight = vertAxis.ValueToPosition( + vertAxis.PositionToValue(relativeY, false) + relativeHeight) - relativeY; + } + } + bool isTextAnnotation = this is TextAnnotation; + //*********************************************************************** + //** Apply 3D transforamtion if required + //*********************************************************************** + ChartArea chartArea = null; + if(horizAxis != null && horizAxis.ChartArea != null) + { + chartArea = horizAxis.ChartArea; + } + if(vertAxis != null && vertAxis.ChartArea != null) + { + chartArea = vertAxis.ChartArea; + } + if(chartArea != null && + chartArea.Area3DStyle.Enable3D == true && + !chartArea.chartAreaIsCurcular && + chartArea.requireAxes && + chartArea.matrix3D.IsInitialized()) + { + // Get anotation Z coordinate (use scene depth or anchored point Z position) + float positionZ = chartArea.areaSceneDepth; + if(this.AnchorDataPoint != null && this.AnchorDataPoint.series != null) + { + float depth = 0f; + chartArea.GetSeriesZPositionAndDepth( + this.AnchorDataPoint.series, + out depth, + out positionZ); + positionZ += depth / 2f; + } + + // Define 3D points of annotation object + Point3D[] annot3DPoints = new Point3D[3]; + annot3DPoints[0] = new Point3D((float)relativeX, (float)relativeY, positionZ); + annot3DPoints[1] = new Point3D((float)(relativeX + relativeWidth), (float)(relativeY + relativeHeight), positionZ); + annot3DPoints[2] = new Point3D((float)anchorX, (float)anchorY, positionZ); + + // Tranform cube coordinates + chartArea.matrix3D.TransformPoints( annot3DPoints ); + + // Get transformed coordinates + relativeX = annot3DPoints[0].X; + relativeY = annot3DPoints[0].Y; + anchorX = annot3DPoints[2].X; + anchorY = annot3DPoints[2].Y; + + // Don't adjust size for text annotation + if (!(isTextAnnotation && this.IsSizeAlwaysRelative)) + { + relativeWidth = annot3DPoints[1].X - relativeX; + relativeHeight = annot3DPoints[1].Y - relativeY; + } + } + + //*********************************************************************** + //** Provide "dummy" position at design time + //*********************************************************************** + if(this.Chart != null && this.Chart.IsDesignMode()) + { + if(double.IsNaN(relativeX)) + { + relativeX = groupLocation.X; + saveCurrentPosition = false; + } + if(double.IsNaN(relativeY)) + { + relativeY = groupLocation.Y; + saveCurrentPosition = false; + } + if(double.IsNaN(relativeWidth)) + { + relativeWidth = 20.0 * groupScaleX; + saveCurrentPosition = false; + } + if(double.IsNaN(relativeHeight)) + { + relativeHeight = 20.0 * groupScaleY; + saveCurrentPosition = false; + } + } + + //*********************************************************************** + //** Initialize returned values + //*********************************************************************** + location = new PointF( (float)relativeX, (float)relativeY ); + size = new SizeF( (float)relativeWidth, (float)relativeHeight ); + anchorLocation = new PointF( (float)anchorX, (float)anchorY ); + + //*********************************************************************** + //** Adjust text based annotaion position using SmartLabelStyle. + //*********************************************************************** + // Check if smart labels are enabled + if (this.SmartLabelStyle.Enabled && isTextAnnotation && + group == null) + { + // Anchor point must be set + if(!double.IsNaN(anchorX) && !double.IsNaN(anchorY) && + double.IsNaN(this.X) && double.IsNaN(this.Y)) + { + if(this.Chart != null && + this.Chart.chartPicture != null) + { + // Remember old movement distance restriction + double oldMinMovingDistance = this.SmartLabelStyle.MinMovingDistance; + double oldMaxMovingDistance = this.SmartLabelStyle.MaxMovingDistance; + + // Increase annotation moving restrictions according to the anchor offset + PointF anchorOffsetAbs = this.GetGraphics().GetAbsolutePoint( + new PointF((float)this.AnchorOffsetX, (float)this.AnchorOffsetY)); + float maxAnchorOffsetAbs = Math.Max(anchorOffsetAbs.X, anchorOffsetAbs.Y); + if(maxAnchorOffsetAbs > 0.0) + { + this.SmartLabelStyle.MinMovingDistance += maxAnchorOffsetAbs; + this.SmartLabelStyle.MaxMovingDistance += maxAnchorOffsetAbs; + } + + // Adjust label position using SmartLabelStyle algorithm + LabelAlignmentStyles labelAlignment = LabelAlignmentStyles.Bottom; + using (StringFormat format = new StringFormat()) + { + SizeF markerSizeRel = new SizeF((float)this.AnchorOffsetX, (float)this.AnchorOffsetY); + PointF newlocation = this.Chart.chartPicture.annotationSmartLabel.AdjustSmartLabelPosition( + this.Common, + this.Chart.chartPicture.ChartGraph, + chartArea, + this.SmartLabelStyle, + location, + size, + format, + anchorLocation, + markerSizeRel, + labelAlignment, + (this is CalloutAnnotation)); + + // Restore old movement distance restriction + this.SmartLabelStyle.MinMovingDistance = oldMinMovingDistance; + this.SmartLabelStyle.MaxMovingDistance = oldMaxMovingDistance; + + // Check if annotation should be hidden + if (newlocation.IsEmpty) + { + location = new PointF(float.NaN, float.NaN); + } + else + { + // Get new position using alignment in format + RectangleF newPosition = this.Chart.chartPicture.annotationSmartLabel.GetLabelPosition( + this.Chart.chartPicture.ChartGraph, + newlocation, + size, + format, + false); + + // Set new location + location = newPosition.Location; + } + } + } + } + else + { + // Add annotation position into the list (to prevent overlapping) + using (StringFormat format = new StringFormat()) + { + this.Chart.chartPicture.annotationSmartLabel.AddSmartLabelPosition( + this.Chart.chartPicture.ChartGraph, + location, + size, + format); + } + } + } + + //*********************************************************************** + //** Save calculated position + //*********************************************************************** + if(saveCurrentPosition) + { + currentPositionRel = new RectangleF(location, size); + currentAnchorLocationRel = new PointF(anchorLocation.X, anchorLocation.Y); + } + } + +#if Microsoft_CONTROL + /// + /// Set annotation object position using rectangle in relative coordinates. + /// Automatically converts relative coordinates to axes values if required. + /// + /// Position in relative coordinates. + /// Anchor location in relative coordinates. + internal void SetPositionRelative(RectangleF position, PointF anchorPoint) + { + SetPositionRelative(position, anchorPoint, false); + } +#endif // Microsoft_CONTROL + + /// + /// Set annotation object position using rectangle in relative coordinates. + /// Automatically converts relative coordinates to axes values if required. + /// + /// Position in relative coordinates. + /// Anchor location in relative coordinates. + /// Indicates if position changing was a result of the user input. + internal void SetPositionRelative(RectangleF position, PointF anchorPoint, bool userInput) + { + double newX = position.X; + double newY = position.Y; + double newRight = position.Right; + double newBottom = position.Bottom; + double newWidth = position.Width; + double newHeight = position.Height; + double newAnchorX = anchorPoint.X; + double newAnchorY = anchorPoint.Y; + + //*********************************************************************** + //** Set pre calculated position and anchor location + //*********************************************************************** + this.currentPositionRel = new RectangleF(position.Location, position.Size); + this.currentAnchorLocationRel = new PointF(anchorPoint.X, anchorPoint.Y); + + //*********************************************************************** + //** Get vertical and horizontal axis + //*********************************************************************** + Axis vertAxis = null; + Axis horizAxis = null; + GetAxes(ref vertAxis, ref horizAxis); + + //*********************************************************************** + //** Disable anchoring to point and axes in 3D + //** This is done due to the issues of moving elements in 3D space. + //*********************************************************************** + ChartArea chartArea = null; + if(horizAxis != null && horizAxis.ChartArea != null) + { + chartArea = horizAxis.ChartArea; + } + if(vertAxis != null && vertAxis.ChartArea != null) + { + chartArea = vertAxis.ChartArea; + } + if(chartArea != null && chartArea.Area3DStyle.Enable3D == true) + { + // If anchor point was set - get its relative position and use it as an anchor point + if(this.AnchorDataPoint != null) + { + bool inRelativeCoordX = true; + bool inRelativeCoordY = true; + this.GetAnchorLocation(ref newAnchorX, ref newAnchorY, ref inRelativeCoordX, ref inRelativeCoordY); + this.currentAnchorLocationRel = new PointF((float)newAnchorX, (float)newAnchorY); + } + + // In 3D always use relative annotation coordinates + // Disconnect annotation from axes and anchor point + this.AnchorDataPoint = null; + this.AxisX = null; + this.AxisY = null; + horizAxis = null; + vertAxis = null; + } + + + //*********************************************************************** + //** Convert relative coordinates to axis values + //*********************************************************************** + if(horizAxis != null) + { + newX = horizAxis.PositionToValue(newX, false); + if(!double.IsNaN(newAnchorX)) + { + newAnchorX = horizAxis.PositionToValue(newAnchorX, false); + } + + // Adjust for the IsLogarithmic axis + if( horizAxis.IsLogarithmic ) + { + newX = Math.Pow( horizAxis.logarithmBase, newX ); + if(!double.IsNaN(newAnchorX)) + { + newAnchorX = Math.Pow( horizAxis.logarithmBase, newAnchorX ); + } + } + + if(!this.IsSizeAlwaysRelative) + { + if(float.IsNaN(position.Right) && + !float.IsNaN(position.Width) && + !float.IsNaN(anchorPoint.X) ) + { + newRight = horizAxis.PositionToValue(anchorPoint.X + position.Width, false); + if( horizAxis.IsLogarithmic ) + { + newRight = Math.Pow( horizAxis.logarithmBase, newRight ); + } + newWidth = newRight - newAnchorX; + } + else + { + newRight = horizAxis.PositionToValue(position.Right, false); + if( horizAxis.IsLogarithmic ) + { + newRight = Math.Pow( horizAxis.logarithmBase, newRight ); + } + newWidth = newRight - newX; + } + } + } + if(vertAxis != null) + { + newY = vertAxis.PositionToValue(newY, false); + if(!double.IsNaN(newAnchorY)) + { + newAnchorY = vertAxis.PositionToValue(newAnchorY, false); + } + + // NOTE: Fixes issue #4113 + // Adjust for the IsLogarithmic axis + if( vertAxis.IsLogarithmic ) + { + newY = Math.Pow( vertAxis.logarithmBase, newY ); + if(!double.IsNaN(newAnchorY)) + { + newAnchorY = Math.Pow( vertAxis.logarithmBase, newAnchorY ); + } + } + + if(!this.IsSizeAlwaysRelative) + { + if(float.IsNaN(position.Bottom) && + !float.IsNaN(position.Height) && + !float.IsNaN(anchorPoint.Y) ) + { + newBottom = vertAxis.PositionToValue(anchorPoint.Y + position.Height, false); + if( vertAxis.IsLogarithmic ) + { + newBottom = Math.Pow( vertAxis.logarithmBase, newBottom ); + } + newHeight = newBottom - newAnchorY; + } + else + { + newBottom = vertAxis.PositionToValue(position.Bottom, false); + if( vertAxis.IsLogarithmic ) + { + newBottom = Math.Pow( vertAxis.logarithmBase, newBottom ); + } + newHeight = newBottom - newY; + } + } + } + + // Fire position changing event when position changed by user. + if(userInput) + { +#if Microsoft_CONTROL + // Set flag that annotation position was changed + this.positionChanged = true; + + // Fire position changing event + if(this.Chart != null) + { + AnnotationPositionChangingEventArgs args = new AnnotationPositionChangingEventArgs(); + args.NewLocationX = newX; + args.NewLocationY = newY; + args.NewSizeWidth = newWidth; + args.NewSizeHeight = newHeight; + args.NewAnchorLocationX = newAnchorX; + args.NewAnchorLocationY = newAnchorY; + args.Annotation = this; + + if(this.Chart.OnAnnotationPositionChanging(ref args)) + { + // Get user changed position/anchor + newX = args.NewLocationX; + newY = args.NewLocationY; + newWidth = args.NewSizeWidth; + newHeight = args.NewSizeHeight; + newAnchorX = args.NewAnchorLocationX; + newAnchorY = args.NewAnchorLocationY; + } + } +#endif // Microsoft_CONTROL + } + + // Adjust location & size + this.X = newX; + this.Y = newY; + this.Width = newWidth; + this.Height = newHeight; + this.AnchorX = newAnchorX; + this.AnchorY = newAnchorY; + + // Invalidate annotation + this.Invalidate(); + + return; + } + /// + /// Adjust annotation location and\or size as a result of user action. + /// + /// Distance to resize/move the annotation. + /// Resizing mode. + virtual internal void AdjustLocationSize(SizeF movingDistance, ResizingMode resizeMode) + { + AdjustLocationSize(movingDistance, resizeMode, true); + } + + /// + /// Adjust annotation location and\or size as a result of user action. + /// + /// Distance to resize/move the annotation. + /// Resizing mode. + /// Distance is in pixels, otherwise relative. + virtual internal void AdjustLocationSize(SizeF movingDistance, ResizingMode resizeMode, bool pixelCoord) + { + AdjustLocationSize(movingDistance, resizeMode, pixelCoord, false); + } + + /// + /// Adjust annotation location and\or size as a result of user action. + /// + /// Distance to resize/move the annotation. + /// Resizing mode. + /// Distance is in pixels, otherwise relative. + /// Indicates if position changing was a result of the user input. + virtual internal void AdjustLocationSize(SizeF movingDistance, ResizingMode resizeMode, bool pixelCoord, bool userInput) + { + if(!movingDistance.IsEmpty) + { + // Convert pixel coordinates into relative + if(pixelCoord) + { + movingDistance = Chart.chartPicture.ChartGraph.GetRelativeSize(movingDistance); + } + + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + if(userInput) + { +#if Microsoft_CONTROL + if(this.startMovePositionRel.X == 0f && + this.startMovePositionRel.Y == 0f && + this.startMovePositionRel.Width == 0f && + this.startMovePositionRel.Height == 0f) + { + GetRelativePosition(out firstPoint, out size, out anchorPoint); + this.startMovePositionRel = new RectangleF(firstPoint, size); + this.startMoveAnchorLocationRel = new PointF(anchorPoint.X, anchorPoint.Y); + } + firstPoint = this.startMovePositionRel.Location; + size = this.startMovePositionRel.Size; + anchorPoint = this.startMoveAnchorLocationRel; +#else // Microsoft_CONTROL + GetRelativePosition(out firstPoint, out size, out anchorPoint); +#endif // Microsoft_CONTROL + + } + else + { + GetRelativePosition(out firstPoint, out size, out anchorPoint); + } + + if(resizeMode == ResizingMode.TopLeftHandle) + { + firstPoint.X -= movingDistance.Width; + firstPoint.Y -= movingDistance.Height; + size.Width += movingDistance.Width; + size.Height += movingDistance.Height; + } + else if(resizeMode == ResizingMode.TopHandle) + { + firstPoint.Y -= movingDistance.Height; + size.Height += movingDistance.Height; + } + else if(resizeMode == ResizingMode.TopRightHandle) + { + firstPoint.Y -= movingDistance.Height; + size.Width -= movingDistance.Width; + size.Height += movingDistance.Height; + } + else if(resizeMode == ResizingMode.RightHandle) + { + size.Width -= movingDistance.Width; + } + else if(resizeMode == ResizingMode.BottomRightHandle) + { + size.Width -= movingDistance.Width; + size.Height -= movingDistance.Height; + } + else if(resizeMode == ResizingMode.BottomHandle) + { + size.Height -= movingDistance.Height; + } + else if(resizeMode == ResizingMode.BottomLeftHandle) + { + firstPoint.X -= movingDistance.Width; + size.Width += movingDistance.Width; + size.Height -= movingDistance.Height; + } + else if(resizeMode == ResizingMode.LeftHandle) + { + firstPoint.X -= movingDistance.Width; + size.Width += movingDistance.Width; + } + else if(resizeMode == ResizingMode.AnchorHandle) + { + anchorPoint.X -= movingDistance.Width; + anchorPoint.Y -= movingDistance.Height; + } + else if(resizeMode == ResizingMode.Moving) + { + firstPoint.X -= movingDistance.Width; + firstPoint.Y -= movingDistance.Height; + } + + // Make sure we do not override automatic Width and Heigth + if(resizeMode == ResizingMode.Moving) + { + if( double.IsNaN(this.Width) ) + { + size.Width = float.NaN; + } + if( double.IsNaN(this.Height) ) + { + size.Height = float.NaN; + } + } + + // Make sure we do not override automatic X and Y + if(resizeMode == ResizingMode.AnchorHandle) + { + if( double.IsNaN(this.X) ) + { + firstPoint.X = float.NaN; + } + if( double.IsNaN(this.Y) ) + { + firstPoint.Y = float.NaN; + } + } + else if(double.IsNaN(this.AnchorX) || double.IsNaN(this.AnchorY) ) + { + anchorPoint = new PointF(float.NaN, float.NaN); + } + + // Set annotation position from rectangle in relative coordinates + SetPositionRelative(new RectangleF(firstPoint, size), anchorPoint, userInput); + } + return; + } + + #endregion + + #region Anchor Point and Axes Converters + + /// + /// Checks if annotation draw anything in the anchor position (except selection handle) + /// + /// True if annotation "connects" itself and anchor point visually. + virtual internal bool IsAnchorDrawn() + { + return false; + } + + /// + /// Gets data point by name. + /// + /// Data point name to find. + /// Data point. + internal DataPoint GetDataPointByName(string dataPointName) + { + DataPoint dataPoint = null; + + if (Chart != null && dataPointName.Length > 0) + { + // Split series name and point index + int separatorIndex = dataPointName.IndexOf("\\r", StringComparison.Ordinal); + if (separatorIndex > 0) + { + string seriesName = dataPointName.Substring(0, separatorIndex); + string pointIndex = dataPointName.Substring(separatorIndex + 2); + + int index; + if (int.TryParse(pointIndex, NumberStyles.Any, CultureInfo.InvariantCulture, out index)) + { + dataPoint = Chart.Series[seriesName].Points[index]; + } + } + } + + return dataPoint; + } + + /// + /// Gets axis by name. + /// + /// Axis name to find. + /// Data point. + private Axis GetAxisByName(string axisName) + { + Debug.Assert(axisName != null, "GetAxisByName: handed a null axis name"); + + Axis axis = null; + + try + { + if (Chart != null && axisName.Length > 0) + { + // Split series name and point index + int separatorIndex = axisName.IndexOf("\\r", StringComparison.Ordinal); + if (separatorIndex > 0) + { + string areaName = axisName.Substring(0, separatorIndex); + string axisType = axisName.Substring(separatorIndex + 2); + switch ((AxisName)Enum.Parse(typeof(AxisName), axisType)) + { + case (AxisName.X): + axis = Chart.ChartAreas[areaName].AxisX; + break; + case (AxisName.Y): + axis = Chart.ChartAreas[areaName].AxisY; + break; + case (AxisName.X2): + axis = Chart.ChartAreas[areaName].AxisX2; + break; + case (AxisName.Y2): + axis = Chart.ChartAreas[areaName].AxisY2; + break; + } + } + } + } + catch (ArgumentNullException) + { + axis = null; + } + catch (ArgumentException) + { + axis = null; + } + + return axis; + } + + /// + /// Gets data point unique name. + /// + /// Data point to get the name for. + /// Data point name. + internal string GetDataPointName(DataPoint dataPoint) + { + string name = String.Empty; + if(dataPoint.series != null) + { + int pointIndex = dataPoint.series.Points.IndexOf(dataPoint); + if(pointIndex >= 0) + { + name = dataPoint.series.Name + + "\\r" + + pointIndex.ToString(CultureInfo.InvariantCulture); + } + } + return name; + } + + /// + /// Gets axis unique name. + /// + /// Axis to get the name for. + /// Axis name. + private string GetAxisName(Axis axis) + { + string name = String.Empty; + if(axis.ChartArea != null) + { + name = axis.ChartArea.Name + + "\\r" + + axis.AxisName.ToString(); + } + return name; + } + + #endregion + + #region Z Order Methods + + /// + /// Sends an annotation to the back of all annotations. + /// + /// + virtual public void SendToBack() + { + // Find collection of annotation objects this annotation belongs too + AnnotationCollection collection = null; + if(Chart != null) + { + collection = Chart.Annotations; + } + + // Check if annotation belongs to the group + AnnotationGroup group = AnnotationGroup; + if(group != null) + { + collection = group.Annotations; + } + + // Check if annotation is found + if(collection != null) + { + Annotation annot = collection.FindByName(this.Name); + if(annot != null) + { + // Reinsert annotation at the beginning of the collection + collection.Remove(annot); + collection.Insert(0, annot); + } + } + } + + /// + /// Brings an annotation to the front of all annotations. + /// + /// + virtual public void BringToFront() + { + // Find collection of annotation objects this annotation belongs too + AnnotationCollection collection = null; + if(Chart != null) + { + collection = Chart.Annotations; + } + + // Check if annotation belongs to the group + AnnotationGroup group = AnnotationGroup; + if(group != null) + { + collection = group.Annotations; + } + + // Check if annotation is found + if(collection != null) + { + Annotation annot = collection.FindByName(this.Name); + if(annot != null) + { + // Reinsert annotation at the end of the collection + collection.Remove(annot); + collection.Add(this); + } + } + } + + #endregion // Z Order Methods + + #region Group Related Methods + + #endregion // Group Related Methods + + #region SmartLabelStyle methods + + /// + /// Adds anchor position to the list. Used to check SmartLabelStyle overlapping. + /// + /// List to add to. + internal void AddSmartLabelMarkerPositions(ArrayList list) + { + // Anchor position is added to the list of non-overlapped markers + if(this.Visible && this.IsAnchorDrawn()) + { + // Get vertical and horizontal axis + Axis vertAxis = null; + Axis horizAxis = null; + GetAxes(ref vertAxis, ref horizAxis); + + // Get anchor position + double anchorX = double.NaN; + double anchorY = double.NaN; + bool relativeX = false; + bool relativeY = false; + this.GetAnchorLocation(ref anchorX, ref anchorY, ref relativeX, ref relativeY); + + // Convert anchor location to relative coordinates + if(!double.IsNaN(anchorX) && !double.IsNaN(anchorY)) + { + if( !relativeX && horizAxis != null ) + { + anchorX = horizAxis.ValueToPosition(anchorX); + } + if( !relativeY && vertAxis != null ) + { + anchorY = vertAxis.ValueToPosition(anchorY); + } + + // Apply 3D transforamtion if required + ChartArea chartArea = null; + if(horizAxis != null && horizAxis.ChartArea != null) + { + chartArea = horizAxis.ChartArea; + } + if(vertAxis != null && vertAxis.ChartArea != null) + { + chartArea = vertAxis.ChartArea; + } + if(chartArea != null && + chartArea.Area3DStyle.Enable3D == true && + !chartArea.chartAreaIsCurcular && + chartArea.requireAxes && + chartArea.matrix3D.IsInitialized()) + { + // Get anotation Z coordinate (use scene depth or anchored point Z position) + float positionZ = chartArea.areaSceneDepth; + if(this.AnchorDataPoint != null && this.AnchorDataPoint.series != null) + { + float depth = 0f; + chartArea.GetSeriesZPositionAndDepth( + this.AnchorDataPoint.series, + out depth, + out positionZ); + positionZ += depth / 2f; + } + + // Define 3D points of annotation object + Point3D[] annot3DPoints = new Point3D[1]; + annot3DPoints[0] = new Point3D((float)anchorX, (float)anchorY, positionZ); + + // Tranform cube coordinates + chartArea.matrix3D.TransformPoints( annot3DPoints ); + + // Get transformed coordinates + anchorX = annot3DPoints[0].X; + anchorY = annot3DPoints[0].Y; + } + + // Save selection handles position in array elements 0 and 4 + if(this.GetGraphics() != null) + { + SizeF markerSizeRel = this.GetGraphics().GetRelativeSize( + new SizeF(1f, 1f)); + RectangleF anchorRect = new RectangleF( + (float)anchorX - markerSizeRel.Width/2f, + (float)anchorY - markerSizeRel.Height/2f, + markerSizeRel.Width, + markerSizeRel.Height); + + list.Add(anchorRect); + } + } + } + } + + #endregion + + #region Public Anchoring Methods + + /// + /// Anchors an annotation to a data point. + /// + /// + /// + /// + /// + /// to be anchored to. + /// + /// + /// Anchors an annotation to the specified data point. + /// + public void SetAnchor(DataPoint dataPoint) + { + SetAnchor(dataPoint, null); + } + + /// + /// Anchors an annotation to two data points. + /// + /// + /// + /// + /// + /// First anchor . + /// + /// + /// Second anchor . + /// + /// + /// Anchors an annotation's top/left and bottom/right corners to the + /// specified data points. + /// + public void SetAnchor(DataPoint dataPoint1, DataPoint dataPoint2) + { + // Set annotation position to automatic + this.X = double.NaN; + this.Y = double.NaN; + + // Reset anchor point if any + this.AnchorX = double.NaN; + this.AnchorY = double.NaN; + + // Set anchor point + this.AnchorDataPoint = dataPoint1; + + // Get vertical and horizontal axis + Axis vertAxis = null; + Axis horizAxis = null; + GetAxes(ref vertAxis, ref horizAxis); + + // Set Width and Height in axis coordinates + if(dataPoint2 != null && dataPoint1 != null) + { + this._anchorDataPoint2 = dataPoint2; + } + + // Invalidate annotation + this.Invalidate(); + } + + #endregion // Public Anchoring Methods + + #region Placement Methods + +#if Microsoft_CONTROL + + /// + /// Begins end user placement of an annotation using the mouse. + /// + /// + /// When this method is called, the end user is allowed to place an annotation using the + /// mouse. + /// + /// Placement will finish when the end user specifies all required points, or + /// the method is called. + /// + virtual public void BeginPlacement() + { + // Can't place annotations inside the group + if(this.AnnotationGroup != null) + { + throw (new InvalidOperationException(SR.ExceptionAnnotationGroupedUnableToStartPlacement)); + } + + if(this.Chart != null) + { + // Set the annotation object which is currently placed + this.Chart.Annotations.placingAnnotation = this; + } + else + { + throw (new InvalidOperationException(SR.ExceptionAnnotationNotInCollection)); + } + + } + + /// + /// Ends user placement of an annotation. + /// + /// + /// Ends an annotation placement operation previously started by a + /// method call. + /// + /// Calling this method is not required, since placement will automatically + /// end when an end user enters all required points. However, it is useful when an annotation + /// placement operation needs to be aborted for some reason. + /// + /// + virtual public void EndPlacement() + { + if(this.Chart != null) + { + // Reset currently placed annotation object + this.Chart.Annotations.placingAnnotation = null; + + // Restore default cursor + this.Chart.Cursor = this.Chart.defaultCursor; + + // Clear last placement mouse position + this.lastPlacementPosition = PointF.Empty; + + // Fire annotation placed event + this.Chart.OnAnnotationPlaced(this); + } + } + + /// + /// Handles mouse down event during annotation placement. + /// + /// Mouse cursor position in pixels. + /// Mouse button down. + internal virtual void PlacementMouseDown(PointF point, MouseButtons buttons) + { + if(buttons == MouseButtons.Right) + { + // Stop any pacement + this.EndPlacement(); + } + if(buttons == MouseButtons.Left && + IsValidPlacementPosition(point.X, point.Y)) + { + if(this.lastPlacementPosition.IsEmpty) + { + // Remeber position where mouse was clicked + this.lastPlacementPosition = this.GetGraphics().GetRelativePoint(point); + + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + this.GetRelativePosition(out firstPoint, out size, out anchorPoint); + + // Set annotation X, Y coordinate + if(this.AllowMoving) + { + firstPoint = this.GetGraphics().GetRelativePoint(point); + + // Do not change default position + if(double.IsNaN(this.AnchorX)) + { + anchorPoint.X = float.NaN; + } + if(double.IsNaN(this.AnchorY)) + { + anchorPoint.Y = float.NaN; + } + + } + else if(this.AllowAnchorMoving) + { + anchorPoint = this.GetGraphics().GetRelativePoint(point); + + // Do not change default position + if(double.IsNaN(this.X)) + { + firstPoint.X = float.NaN; + } + if(double.IsNaN(this.Y)) + { + firstPoint.Y = float.NaN; + } + } + + // Do not change default size + if(double.IsNaN(this.Width)) + { + size.Width = float.NaN; + } + if(double.IsNaN(this.Height)) + { + size.Height = float.NaN; + } + + // Set annotation position + this.positionChanged = true; + this.SetPositionRelative( + new RectangleF(firstPoint, size), + anchorPoint, + true); + + // Invalidate and update the chart + if(Chart != null) + { + Invalidate(); + Chart.UpdateAnnotations(); + } + } + } + } + + /// + /// Handles mouse up event during annotation placement. + /// + /// Mouse cursor position in pixels. + /// Mouse button Up. + /// Return true when placing finished. + internal virtual bool PlacementMouseUp(PointF point, MouseButtons buttons) + { + bool result = false; + if(buttons == MouseButtons.Left) + { + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + this.GetRelativePosition(out firstPoint, out size, out anchorPoint); + + if(this.AllowResizing) + { + PointF pointRel = this.GetGraphics().GetRelativePoint(point); + size = new SizeF( + pointRel.X - this.lastPlacementPosition.X, + pointRel.Y - this.lastPlacementPosition.Y); + } + else + { + // Do not change default size + if(double.IsNaN(this.Width)) + { + size.Width = float.NaN; + } + if(double.IsNaN(this.Height)) + { + size.Height = float.NaN; + } + } + + // Do not change default position + if(double.IsNaN(this.X)) + { + firstPoint.X = float.NaN; + } + if(double.IsNaN(this.Y)) + { + firstPoint.Y = float.NaN; + } + if(double.IsNaN(this.AnchorX)) + { + anchorPoint.X = float.NaN; + } + if(double.IsNaN(this.AnchorY)) + { + anchorPoint.Y = float.NaN; + } + + // Set annotation position + this.positionChanged = true; + this.SetPositionRelative( + new RectangleF(firstPoint, size), + anchorPoint, + true); + + // End placement + if(!size.IsEmpty || !this.AllowResizing) + { + result = true; + this.EndPlacement(); + } + + // Invalidate and update the chart + if(Chart != null) + { + Invalidate(); + Chart.UpdateAnnotations(); + } + } + + return result; + } + + /// + /// Handles mouse move event during annotation placement. + /// + /// Mouse cursor position in pixels. + internal virtual void PlacementMouseMove(PointF point) + { + // Check if annotation was moved + if( this.GetGraphics() != null && + !this.lastPlacementPosition.IsEmpty) + { + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + this.GetRelativePosition(out firstPoint, out size, out anchorPoint); + + if(this.AllowResizing) + { + PointF pointRel = this.GetGraphics().GetRelativePoint(point); + size = new SizeF( + pointRel.X - this.lastPlacementPosition.X, + pointRel.Y - this.lastPlacementPosition.Y); + } + + // Do not change default position + if(double.IsNaN(this.X)) + { + firstPoint.X = float.NaN; + } + if(double.IsNaN(this.Y)) + { + firstPoint.Y = float.NaN; + } + if(double.IsNaN(this.AnchorX)) + { + anchorPoint.X = float.NaN; + } + if(double.IsNaN(this.AnchorY)) + { + anchorPoint.Y = float.NaN; + } + + // Set annotation position + this.positionChanged = true; + this.SetPositionRelative( + new RectangleF(firstPoint, size), + anchorPoint, + true); + + // Invalidate and update the chart + if(this.Chart != null) + { + Invalidate(); + this.Chart.UpdateAnnotations(); + } + } + } + + /// + /// Checks if specified position is valid for placement. + /// + /// X coordinate. + /// Y coordinate. + /// True if annotation can be placed at specified coordinates. + virtual internal bool IsValidPlacementPosition(float x, float y) + { + if(this.Chart != null && + this.GetGraphics() != null) + { + // Check if cursor is over the area where placement allowed + // If so - change cursor to cross + RectangleF placementRect = new RectangleF(0f, 0f, 100f, 100f); + if(this.ClipToChartArea.Length > 0 && + this.ClipToChartArea != Constants.NotSetValue) + { + ChartArea area = Chart.ChartAreas[this.ClipToChartArea]; + placementRect = area.PlotAreaPosition.ToRectangleF(); + } + placementRect = this.GetGraphics().GetAbsoluteRectangle(placementRect); + if(placementRect.Contains(x, y)) + { + return true; + } + } + return false; + } + +#endif // Microsoft_CONTROL + + #endregion // Placement Methods + + #region Helper Methods + + /// + /// Helper method that checks if annotation is visible. + /// + /// True if annotation is visible. + internal bool IsVisible() + { + if(this.Visible) + { + if(this.Chart != null) + { + // Check if annotation is anchored to the data point + ChartArea area = null; + if(this.AnchorDataPoint != null && + this.AnchorDataPoint.series != null) + { + if(this.Chart.ChartAreas.IndexOf(this.AnchorDataPoint.series.ChartArea) >= 0) + { + area = this.Chart.ChartAreas[this.AnchorDataPoint.series.ChartArea]; + } + } + if(area == null && + this._anchorDataPoint2 != null && + this._anchorDataPoint2.series != null) + { + if(this.Chart.ChartAreas.IndexOf(this._anchorDataPoint2.series.ChartArea) >= 0) + { + area = this.Chart.ChartAreas[this._anchorDataPoint2.series.ChartArea]; + } + } + + // Check if annotation uses chart area axis values + if(area == null && this.AxisX != null) + { + area = this.AxisX.ChartArea; + } + if(area == null && this.AxisY != null) + { + area = this.AxisY.ChartArea; + } + + // Check if associated area is visible + if(area != null && + !area.Visible) + { + return false; + } + } + + + return true; + } + return false; + } + + /// + /// Resets pre-calculated annotation position. + /// + internal void ResetCurrentRelativePosition() + { + this.currentPositionRel = new RectangleF(float.NaN, float.NaN, float.NaN, float.NaN); + this.currentAnchorLocationRel = new PointF(float.NaN, float.NaN); + } + + /// + /// Replaces predefined keyword inside the string with their values if + /// annotation is anchored to the data point. + /// + /// Original string with keywords. + /// Modified string. + internal string ReplaceKeywords(string strOriginal) + { + if(this.AnchorDataPoint != null) + { + return this.AnchorDataPoint.ReplaceKeywords(strOriginal); + } + return strOriginal; + } + + /// + /// Checks if anchor point of the annotation is visible. + /// + /// True if anchor point is visible. + internal bool IsAnchorVisible() + { + // Get axes objects + Axis vertAxis = null; + Axis horizAxis = null; + GetAxes(ref vertAxis, ref horizAxis); + + // Get anchor position + bool inRelativeAnchorX = false; + bool inRelativeAnchorY = false; + double anchorX = this.AnchorX; + double anchorY = this.AnchorY; + GetAnchorLocation(ref anchorX, ref anchorY, ref inRelativeAnchorX, ref inRelativeAnchorY); + + // Check if anchor is set + if( !double.IsNaN(anchorX) && !double.IsNaN(anchorY) ) + { + // Check if anchor is in axes coordinates + if(this.AnchorDataPoint != null || + this.AxisX != null || + this.AxisY != null) + { + // Convert anchor point to relative coordinates + if(!inRelativeAnchorX && horizAxis != null) + { + anchorX = horizAxis.ValueToPosition(anchorX); + } + if(!inRelativeAnchorY && vertAxis != null) + { + anchorY = vertAxis.ValueToPosition(anchorY); + } + + // Get chart area + ChartArea chartArea = null; + if(horizAxis != null) + { + chartArea = horizAxis.ChartArea; + } + if(chartArea == null && vertAxis != null) + { + chartArea = vertAxis.ChartArea; + } + + // Apply 3D transforamtion if required + if(chartArea != null && chartArea.Area3DStyle.Enable3D == true) + { + if(!chartArea.chartAreaIsCurcular && + chartArea.requireAxes && + chartArea.matrix3D.IsInitialized()) + { + // Get anotation Z coordinate (use scene depth or anchored point Z position) + float positionZ = chartArea.areaSceneDepth; + if (this.AnchorDataPoint != null && this.AnchorDataPoint.series != null) + { + float depth = 0f; + chartArea.GetSeriesZPositionAndDepth( + this.AnchorDataPoint.series, + out depth, + out positionZ); + positionZ += depth / 2f; + } + + // Define 3D points of annotation object + Point3D[] annot3DPoints = new Point3D[1]; + annot3DPoints[0] = new Point3D((float)anchorX, (float)anchorY, positionZ); + + // Tranform cube coordinates + chartArea.matrix3D.TransformPoints(annot3DPoints); + + // Get transformed coordinates + anchorX = annot3DPoints[0].X; + anchorY = annot3DPoints[0].Y; + } + } + + // Get plot rectangle position and inflate it slightly + // to solve any float rounding issues. + RectangleF rect = chartArea.PlotAreaPosition.ToRectangleF(); + rect.Inflate(0.00001f, 0.00001f); + + // Check if anchor point is in the plotting area + if(!rect.Contains((float)anchorX, (float)anchorY)) + { + return false; + } + } + } + + return true; + } + + /// + /// Returns chart graphics objects. + /// + /// Chart graphics object. + internal ChartGraphics GetGraphics() + { + if (this.Common != null) + { + return this.Common.graph; + } + return null; + } +#if Microsoft_CONTROL + /// + /// Checks if provided pixel coordinate is contained in one of the + /// selection handles rectangle. + /// + /// Coordinate in pixels. + /// Resizing mode. + internal ResizingMode GetSelectionHandle(PointF point) + { + ResizingMode resizingMode = ResizingMode.None; + + if( this.Common != null && + this.Common.graph != null) + { + // Convert point to relative coordinates + point = this.Common.graph.GetRelativePoint(point); + + // Check if point is in one of the selection handles + if(this.selectionRects != null) + { + for(int index = 0; index < this.selectionRects.Length; index++) + { + if(!this.selectionRects[index].IsEmpty && + this.selectionRects[index].Contains(point)) + { + if(index > (int)ResizingMode.AnchorHandle) + { + resizingMode = ResizingMode.MovingPathPoints; + this.currentPathPointIndex = index - 9; + } + else + { + resizingMode = (ResizingMode)index; + } + } + } + } + } + + return resizingMode; + } +#endif //Microsoft_CONTROL + /// + /// Gets data point X or Y axis. + /// + /// Data point to get the axis for. + /// X or Y axis to get. + /// Data point axis. + private Axis GetDataPointAxis(DataPoint dataPoint, AxisName axisName) + { + if (dataPoint != null && dataPoint.series != null && Chart != null) + { + // Get data point chart area + ChartArea chartArea = Chart.ChartAreas[dataPoint.series.ChartArea]; + + // Get point X axis + if ((axisName == AxisName.X || axisName == AxisName.X2) && + !chartArea.switchValueAxes) + { + return chartArea.GetAxis(axisName, dataPoint.series.XAxisType, dataPoint.series.XSubAxisName); + } + else + { + return chartArea.GetAxis(axisName, dataPoint.series.YAxisType, dataPoint.series.YSubAxisName); + } + } + return null; + } + + /// + /// Gets annotation vertical and horizontal axes. + /// + /// Returns annotation vertical axis or null. + /// Returns annotation horizontal axis or null. + internal void GetAxes(ref Axis vertAxis, ref Axis horizAxis) + { + vertAxis = null; + horizAxis = null; + + if(this.AxisX != null && this.AxisX.ChartArea != null) + { + if(this.AxisX.ChartArea.switchValueAxes) + { + vertAxis = this.AxisX; + } + else + { + horizAxis = this.AxisX; + } + } + if(this.AxisY != null && this.AxisY.ChartArea != null) + { + if(this.AxisY.ChartArea.switchValueAxes) + { + horizAxis = this.AxisY; + } + else + { + vertAxis = this.AxisY; + } + } + + // Get axes from attached data point + if(this.AnchorDataPoint != null) + { + if(horizAxis == null) + { + horizAxis = GetDataPointAxis(this.AnchorDataPoint, AxisName.X); + + // For chart types like Bar, RangeBar and others, position of X and Y axes are flipped + if (horizAxis != null && horizAxis.ChartArea != null && horizAxis.ChartArea.switchValueAxes) + { + horizAxis = GetDataPointAxis(this.AnchorDataPoint, AxisName.Y); + } + } + if(vertAxis == null) + { + vertAxis = GetDataPointAxis(this.AnchorDataPoint, AxisName.Y); + + // For chart types like Bar, RangeBar and others, position of X and Y axes are flipped + if (vertAxis != null && vertAxis.ChartArea != null && vertAxis.ChartArea.switchValueAxes) + { + vertAxis = GetDataPointAxis(this.AnchorDataPoint, AxisName.X); + } + } + } + + // No axes coordinate system for grouped annotations + if(vertAxis != null || horizAxis != null) + { + if(this.AnnotationGroup != null) + { + throw (new InvalidOperationException(SR.ExceptionAnnotationGroupedAxisMustBeEmpty)); + } + } + } + + #endregion + + #endregion + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + //Free managed resources + if (_fontCache != null) + { + _fontCache.Dispose(); + _fontCache = null; + } + } + base.Dispose(disposing); + } + + + #endregion + } + +#if Microsoft_CONTROL + + /// + /// This class is used to stores position changing event data for an annotation. + /// + /// + /// Provides additional data like the new annotation and anchor position when an end user + /// is moving the annotation with the mouse. + /// + /// Can be used to restrict annotation movement, or snap the annotation position to + /// specific points. + /// + /// + [ + SRDescription("DescriptionAttributeAnnotationPositionChangingEventArgs_AnnotationPositionChangingEventArgs"), + ] + public class AnnotationPositionChangingEventArgs : EventArgs + { + #region Fields + + private Annotation _Annotation = null; + /// + /// Gets or sets the annotation the event is fired for. + /// + public Annotation Annotation + { + get { return _Annotation; } + set { _Annotation = value; } + } + + private double _NewLocationX = 0.0; + /// + /// Gets or sets the new X location of the annotation. + /// + public double NewLocationX + { + get { return _NewLocationX; } + set { _NewLocationX = value; } + } + + private double _NewLocationY = 0.0; + /// + /// Gets or sets the new Y location of the annotation. + /// + public double NewLocationY + { + get { return _NewLocationY; } + set { _NewLocationY = value; } + } + + private double _NewSizeWidth = 0.0; + /// + /// Gets or sets the new width of the annotation. + /// + public double NewSizeWidth + { + get { return _NewSizeWidth; } + set { _NewSizeWidth = value; } + } + + private double _NewSizeHeight = 0.0; + /// + /// Gets or sets the new height of the annotation. + /// + public double NewSizeHeight + { + get { return _NewSizeHeight; } + set { _NewSizeHeight = value; } + } + + private double _NewAnchorLocationX = 0.0; + /// + /// Gets or sets the new annotation anchor point X location. + /// + public double NewAnchorLocationX + { + get { return _NewAnchorLocationX; } + set { _NewAnchorLocationX = value; } + } + + private double _NewAnchorLocationY = 0.0; + /// + /// Gets or sets the new annotation anchor point Y location. + /// + public double NewAnchorLocationY + { + get { return _NewAnchorLocationY; } + set { _NewAnchorLocationY = value; } + } + + #endregion // Fields + + #region Properties + + + /// + /// Gets or sets the new location and size of the annotation. + /// + [ + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + ] + public RectangleF NewPosition + { + get + { + return new RectangleF( + (float)this.NewLocationX, + (float)this.NewLocationY, + (float)this.NewSizeWidth, + (float)this.NewSizeHeight); + } + set + { + this.NewLocationX = value.X; + this.NewLocationY = value.Y; + this.NewSizeWidth = value.Width; + this.NewSizeHeight = value.Height; + } + } + + /// + /// Gets or sets the new anchor location of the annotation. + /// + [ + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + ] + public PointF NewAnchorLocation + { + get + { + return new PointF( + (float)this.NewAnchorLocationX, + (float)this.NewAnchorLocationY); + } + set + { + this.NewAnchorLocationX = value.X; + this.NewAnchorLocationY = value.Y; + } + } + + #endregion // Properties + } + +#endif //Microsoft_CONTROL +} diff --git a/System.Web.DataVisualization/Common/Annotation/AnnotationCollection.cs b/System.Web.DataVisualization/Common/Annotation/AnnotationCollection.cs new file mode 100644 index 000000000..398aedd61 --- /dev/null +++ b/System.Web.DataVisualization/Common/Annotation/AnnotationCollection.cs @@ -0,0 +1,844 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: AnnotationCollection.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: AnnotationCollection, AnnotationCollectionEditor +// +// Purpose: Collection of annotation objects. +// +// Reviewed: +// +//=================================================================== + +#region Used namespace +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL +using System.Windows.Forms; + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif +{ + /// + /// AnnotationCollection is a collection that stores chart annotation objects. + /// + /// + /// + /// All chart annotations are stored in this collection. It is exposed as + /// a property of the chart. It is also used to + /// store annotations inside the class. + /// + /// This class includes methods for adding, inserting, iterating and removing annotations. + /// + /// + [ + SRDescription("DescriptionAttributeAnnotations3"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class AnnotationCollection : ChartNamedElementCollection + { + #region Fields + + /// + /// Group this collection belongs too + /// + internal AnnotationGroup AnnotationGroup { get; set; } + +#if Microsoft_CONTROL + + // Annotation object that was last clicked on + internal Annotation lastClickedAnnotation = null; + + // Start point of annotation moving or resizing + private PointF _movingResizingStartPoint = PointF.Empty; + + // Current resizing mode + private ResizingMode _resizingMode = ResizingMode.None; + + // Annotation object which is currently placed on the chart + internal Annotation placingAnnotation = null; + +#endif + + #endregion + + #region Construction and Initialization + + /// + /// Initializes a new instance of the class. + /// + /// The parent chart element. + internal AnnotationCollection(IChartElement parent) : base(parent) + { + } + + #endregion + + #region Items Inserting and Removing Notification methods + + /// + /// Initializes the specified item. + /// + /// The item. + internal override void Initialize(Annotation item) + { + if (item != null) + { + TextAnnotation textAnnotation = item as TextAnnotation; + if (textAnnotation != null && string.IsNullOrEmpty(textAnnotation.Text) && Chart != null && Chart.IsDesignMode()) + { + textAnnotation.Text = item.Name; + } + + //If the collection belongs to annotation group we need to pass a ref to this group to all the child annotations + if (this.AnnotationGroup != null) + { + item.annotationGroup = this.AnnotationGroup; + } + + item.ResetCurrentRelativePosition(); + } + base.Initialize(item); + } + + /// + /// Deinitializes the specified item. + /// + /// The item. + internal override void Deinitialize(Annotation item) + { + if (item != null) + { + item.annotationGroup = null; + item.ResetCurrentRelativePosition(); + } + base.Deinitialize(item); + } + + + /// + /// Finds an annotation in the collection by name. + /// + /// + /// Name of the annotation to find. + /// + /// + /// object, or null (or nothing) if it does not exist. + /// + public override Annotation FindByName(string name) + { + foreach(Annotation annotation in this) + { + // Compare annotation name + if(annotation.Name == name) + { + return annotation; + } + + // Check if annotation is a group + AnnotationGroup annotationGroup = annotation as AnnotationGroup; + if(annotationGroup != null) + { + Annotation result = annotationGroup.Annotations.FindByName(name); + if(result != null) + { + return result; + } + } + } + + return null; + } + + #endregion + + #region Painting + + /// + /// Paints all annotation objects in the collection. + /// + /// Chart graphics used for painting. + /// Indicates that only annotation objects are redrawn. + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification="This parameter is used when compiling for the Microsoft version of Chart")] + internal void Paint(ChartGraphics chartGraph, bool drawAnnotationOnly) + { +#if Microsoft_CONTROL + ChartPicture chartPicture = this.Chart.chartPicture; + + // Restore previous background using double buffered bitmap + if(!chartPicture.isSelectionMode && + this.Count > 0 /*&& + !this.Chart.chartPicture.isPrinting*/) + { + chartPicture.backgroundRestored = true; + Rectangle chartPosition = new Rectangle(0, 0, chartPicture.Width, chartPicture.Height); + if(chartPicture.nonTopLevelChartBuffer == null || !drawAnnotationOnly) + { + // Dispose previous bitmap + if(chartPicture.nonTopLevelChartBuffer != null) + { + chartPicture.nonTopLevelChartBuffer.Dispose(); + chartPicture.nonTopLevelChartBuffer = null; + } + + // Copy chart area plotting rectangle from the chart's dubble buffer image into area dubble buffer image + if (this.Chart.paintBufferBitmap != null && + this.Chart.paintBufferBitmap.Size.Width >= chartPosition.Size.Width && + this.Chart.paintBufferBitmap.Size.Height >= chartPosition.Size.Height) + { + chartPicture.nonTopLevelChartBuffer = this.Chart.paintBufferBitmap.Clone( + chartPosition, this.Chart.paintBufferBitmap.PixelFormat); + } + } + else if(drawAnnotationOnly && chartPicture.nonTopLevelChartBuffer != null) + { + // Restore previous background + this.Chart.paintBufferBitmapGraphics.DrawImageUnscaled( + chartPicture.nonTopLevelChartBuffer, + chartPosition); + } + } +#endif // Microsoft_CONTROL + + // Draw all annotation objects + foreach(Annotation annotation in this) + { + // Reset calculated relative position + annotation.ResetCurrentRelativePosition(); + + if(annotation.IsVisible()) + { + bool resetClip = false; + + // Check if anchor point ----osiated with plot area is inside the scaleView + if(annotation.IsAnchorVisible()) + { + // Set annotation object clipping + if(annotation.ClipToChartArea.Length > 0 && + annotation.ClipToChartArea != Constants.NotSetValue && + Chart != null) + { + int areaIndex = Chart.ChartAreas.IndexOf(annotation.ClipToChartArea); + if( areaIndex >= 0 ) + { + // Get chart area object + ChartArea chartArea = Chart.ChartAreas[areaIndex]; + chartGraph.SetClip(chartArea.PlotAreaPosition.ToRectangleF()); + resetClip = true; + } + } + + // Start Svg Selection mode + string url = String.Empty; +#if !Microsoft_CONTROL + url = annotation.Url; +#endif // !Microsoft_CONTROL + chartGraph.StartHotRegion( + annotation.ReplaceKeywords(url), + annotation.ReplaceKeywords(annotation.ToolTip) ); + + // Draw annotation object + annotation.Paint(Chart, chartGraph); + + + // End Svg Selection mode + chartGraph.EndHotRegion( ); + + // Reset clipping region + if(resetClip) + { + chartGraph.ResetClip(); + } + } + } + } + } + + #endregion + + #region Mouse Events Handlers + +#if Microsoft_CONTROL + + /// + /// Mouse was double clicked. + /// + internal void OnDoubleClick() + { + if(lastClickedAnnotation != null && + lastClickedAnnotation.AllowTextEditing) + { + TextAnnotation textAnnotation = lastClickedAnnotation as TextAnnotation; + + if(textAnnotation == null) + { + AnnotationGroup group = lastClickedAnnotation as AnnotationGroup; + + if (group != null) + { + // Try to edit text annotation in the group + foreach (Annotation annot in group.Annotations) + { + TextAnnotation groupAnnot = annot as TextAnnotation; + if (groupAnnot != null && + groupAnnot.AllowTextEditing) + { + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + groupAnnot.GetRelativePosition(out firstPoint, out size, out anchorPoint); + RectangleF textPosition = new RectangleF(firstPoint, size); + + // Check if last clicked coordinate is inside this text annotation + if (groupAnnot.GetGraphics() != null && + textPosition.Contains(groupAnnot.GetGraphics().GetRelativePoint(this._movingResizingStartPoint))) + { + textAnnotation = groupAnnot; + lastClickedAnnotation = textAnnotation; + break; + } + } + } + } + } + + if(textAnnotation != null) + { + // Start annotation text editing + textAnnotation.BeginTextEditing(); + } + } + } + + /// + /// Checks if specified point is contained by any of the selection handles. + /// + /// Point which is tested in pixel coordinates. + /// Handle containing the point or None. + /// Annotation that contains the point or Null. + internal Annotation HitTestSelectionHandles(PointF point, ref ResizingMode resizingMode) + { + Annotation annotation = null; + + if( Common != null && + Common.graph != null) + { + PointF pointRel = Common.graph.GetRelativePoint(point); + foreach(Annotation annot in this) + { + // Reset selcted path point + annot.currentPathPointIndex = -1; + + // Check if annotation is selected + if(annot.IsSelected) + { + if(annot.selectionRects != null) + { + for(int index = 0; index < annot.selectionRects.Length; index++) + { + if(!annot.selectionRects[index].IsEmpty && + annot.selectionRects[index].Contains(pointRel)) + { + annotation = annot; + if(index > (int)ResizingMode.AnchorHandle) + { + resizingMode = ResizingMode.MovingPathPoints; + annot.currentPathPointIndex = index - 9; + } + else + { + resizingMode = (ResizingMode)index; + } + } + } + } + } + } + } + return annotation; + } + + /// + /// Mouse button pressed in the control. + /// + /// Event arguments. + /// Returns true if event is handled and no further processing required. + internal void OnMouseDown(MouseEventArgs e, ref bool isHandled) + { + // Reset last clicked annotation object and stop text editing + if(lastClickedAnnotation != null) + { + TextAnnotation textAnnotation = lastClickedAnnotation as TextAnnotation; + if(textAnnotation != null) + { + // Stop annotation text editing + textAnnotation.StopTextEditing(); + } + lastClickedAnnotation = null; + } + + // Check if in annotation placement mode + if( this.placingAnnotation != null) + { + // Process mouse down + this.placingAnnotation.PlacementMouseDown(new PointF(e.X, e.Y), e.Button); + + // Set handled flag + isHandled = true; + return; + } + + // Process only left mouse buttons + if(e.Button == MouseButtons.Left) + { + bool updateRequired = false; + this._resizingMode = ResizingMode.None; + + // Check if mouse buton was pressed in any selection handles areas + Annotation annotation = + HitTestSelectionHandles(new PointF(e.X, e.Y), ref this._resizingMode); + + // Check if mouse button was pressed over one of the annotation objects + if(annotation == null && this.Count > 0) + { + HitTestResult result = this.Chart.HitTest(e.X, e.Y, ChartElementType.Annotation); + if(result != null && result.ChartElementType == ChartElementType.Annotation) + { + annotation = (Annotation)result.Object; + } + } + + // Unselect all annotations if mouse clicked outside any annotations + if(annotation == null || !annotation.IsSelected) + { + if((Control.ModifierKeys & Keys.Control) != Keys.Control && + (Control.ModifierKeys & Keys.Shift) != Keys.Shift) + { + foreach (Annotation annot in this.Chart.Annotations) + { + if(annot != annotation && annot.IsSelected) + { + annot.IsSelected = false; + updateRequired = true; + + // Call selection changed notification + if (this.Chart != null) + { + this.Chart.OnAnnotationSelectionChanged(annot); + } + } + } + } + } + + // Process mouse action in the annotation object + if(annotation != null) + { + // Mouse down event handled + isHandled = true; + + // Select/Unselect annotation + Annotation selectableAnnotation = annotation; + if(annotation.AnnotationGroup != null) + { + // Select annotation group when click on any child annotations + selectableAnnotation = annotation.AnnotationGroup; + } + if(!selectableAnnotation.IsSelected && selectableAnnotation.AllowSelecting) + { + selectableAnnotation.IsSelected = true; + updateRequired = true; + + // Call selection changed notification + if (this.Chart != null) + { + this.Chart.OnAnnotationSelectionChanged(selectableAnnotation); + } + } + else if((Control.ModifierKeys & Keys.Control) == Keys.Control || + (Control.ModifierKeys & Keys.Shift) == Keys.Shift) + { + selectableAnnotation.IsSelected = false; + updateRequired = true; + + // Call selection changed notification + if (this.Chart != null) + { + this.Chart.OnAnnotationSelectionChanged(selectableAnnotation); + } + } + + // Remember last clicked and selected annotation + lastClickedAnnotation = annotation; + + // Rember mouse position + this._movingResizingStartPoint = new PointF(e.X, e.Y); + + // Start moving, repositioning or resizing of annotation + if(annotation.IsSelected) + { + // Check if one of selection handles was clicked on + this._resizingMode = annotation.GetSelectionHandle(this._movingResizingStartPoint); + if(!annotation.AllowResizing && + this._resizingMode >= ResizingMode.TopLeftHandle && + this._resizingMode <= ResizingMode.LeftHandle) + { + this._resizingMode = ResizingMode.None; + } + if(!annotation.AllowAnchorMoving && + this._resizingMode == ResizingMode.AnchorHandle) + { + this._resizingMode = ResizingMode.None; + } + if(this._resizingMode == ResizingMode.None && annotation.AllowMoving) + { + // Annotation moving mode + this._resizingMode = ResizingMode.Moving; + } + } + else + { + if(this._resizingMode == ResizingMode.None && annotation.AllowMoving) + { + // Do not allow moving child annotations inside the group. + // Only the whole group can be selected, resized or repositioned. + if (annotation.AnnotationGroup != null) + { + // Move the group instead + lastClickedAnnotation = annotation.AnnotationGroup; + } + + // Annotation moving mode + this._resizingMode = ResizingMode.Moving; + } + } + } + + // Update chart + if(updateRequired) + { + // Invalidate and update the chart + this.Chart.Invalidate(true); + this.Chart.UpdateAnnotations(); + } + } + } + + /// + /// Mouse button released in the control. + /// + /// Event arguments. + internal void OnMouseUp(MouseEventArgs e) + { + // Check if in annotation placement mode + if( this.placingAnnotation != null) + { + if(!this.placingAnnotation.PlacementMouseUp(new PointF(e.X, e.Y), e.Button)) + { + return; + } + } + + if(e.Button == MouseButtons.Left) + { + // Reset moving sizing start point + this._movingResizingStartPoint = PointF.Empty; + this._resizingMode = ResizingMode.None; + } + + // Loop through all annotation objects + for(int index = 0; index < this.Count; index++) + { + Annotation annotation = this[index]; + + // NOTE: Automatic deleting feature was disabled. -AG. + /* + // Delete all annotation objects moved outside clipping region + if( annotation.outsideClipRegion ) + { + this.List.RemoveAt(index); + --index; + } + */ + + // Reset start position/location fields + annotation.startMovePositionRel = RectangleF.Empty; + annotation.startMoveAnchorLocationRel = PointF.Empty; + if(annotation.startMovePathRel != null) + { + annotation.startMovePathRel.Dispose(); + annotation.startMovePathRel = null; + } + + // Fire position changed event + if( annotation.positionChanged ) + { + annotation.positionChanged = false; + if (this.Chart != null) + { + this.Chart.OnAnnotationPositionChanged(annotation); + } + } + } + } + + /// + /// Mouse moved in the control. + /// + /// Event arguments. + internal void OnMouseMove(MouseEventArgs e) + { + // Check if in annotation placement mode + if(this.placingAnnotation != null) + { + System.Windows.Forms.Cursor newCursor = this.Chart.Cursor; + if(this.placingAnnotation.IsValidPlacementPosition(e.X, e.Y)) + { + newCursor = Cursors.Cross; + } + else + { + newCursor = this.Chart.defaultCursor; + } + + // Set current chart cursor + if (newCursor != this.Chart.Cursor) + { + System.Windows.Forms.Cursor tmpCursor = this.Chart.defaultCursor; + this.Chart.Cursor = newCursor; + this.Chart.defaultCursor = tmpCursor; + } + + this.placingAnnotation.PlacementMouseMove(new PointF(e.X, e.Y)); + + return; + } + + // Check if currently resizing/moving annotation + if(!this._movingResizingStartPoint.IsEmpty && + this._resizingMode != ResizingMode.None) + { + // Calculate how far the mouse was moved + SizeF moveDistance = new SizeF( + this._movingResizingStartPoint.X - e.X, + this._movingResizingStartPoint.Y - e.Y ); + + // Update location of all selected annotation objects + foreach(Annotation annot in this) + { + if(annot.IsSelected && + ( (this._resizingMode == ResizingMode.MovingPathPoints && annot.AllowPathEditing) || + (this._resizingMode == ResizingMode.Moving && annot.AllowMoving) || + (this._resizingMode == ResizingMode.AnchorHandle && annot.AllowAnchorMoving) || + (this._resizingMode >= ResizingMode.TopLeftHandle && this._resizingMode <= ResizingMode.LeftHandle && annot.AllowResizing) ) ) + { + annot.AdjustLocationSize(moveDistance, this._resizingMode, true, true); + } + } + + // Move last clicked non-selected annotation + if(lastClickedAnnotation != null && + !lastClickedAnnotation.IsSelected) + { + if(this._resizingMode == ResizingMode.Moving && + lastClickedAnnotation.AllowMoving) + { + lastClickedAnnotation.AdjustLocationSize(moveDistance, this._resizingMode, true, true); + } + } + + // Invalidate and update the chart + this.Chart.Invalidate(true); + this.Chart.UpdateAnnotations(); + } + else if(this.Count > 0) + { + // Check if currently placing annotation from the UserInterface + bool process = true; + + if(process) + { + // Check if mouse pointer is over the annotation selection handle + ResizingMode currentResizingMode = ResizingMode.None; + Annotation annotation = + HitTestSelectionHandles(new PointF(e.X, e.Y), ref currentResizingMode); + + // Check if mouse pointer over the annotation object movable area + if(annotation == null) + { + HitTestResult result = this.Chart.HitTest(e.X, e.Y, ChartElementType.Annotation); + if(result != null && result.ChartElementType == ChartElementType.Annotation) + { + annotation = (Annotation)result.Object; + if(annotation != null) + { + // Check if annotation is in the collection + if(this.Contains(annotation)) + { + currentResizingMode = ResizingMode.Moving; + if(annotation.AllowMoving == false) + { + // Movement is not allowed + annotation = null; + currentResizingMode = ResizingMode.None; + } + } + } + } + } + // Set mouse cursor + SetResizingCursor(annotation, currentResizingMode); + } + } + } + + /// + /// Sets mouse cursor shape. + /// + /// Annotation object. + /// Resizing mode. + private void SetResizingCursor(Annotation annotation, ResizingMode currentResizingMode) + { + // Change current cursor + if(this.Chart != null) + { + System.Windows.Forms.Cursor newCursor = this.Chart.Cursor; + if(annotation != null) + { + if(currentResizingMode == ResizingMode.MovingPathPoints && + annotation.AllowPathEditing) + { + newCursor = Cursors.Cross; + } + + if(currentResizingMode == ResizingMode.Moving && + annotation.AllowMoving) + { + newCursor = Cursors.SizeAll; + } + + if(currentResizingMode == ResizingMode.AnchorHandle && + annotation.AllowAnchorMoving) + { + newCursor = Cursors.Cross; + } + + if(currentResizingMode != ResizingMode.Moving && + annotation.AllowResizing) + { + if(annotation.SelectionPointsStyle == SelectionPointsStyle.TwoPoints) + { + if(currentResizingMode == ResizingMode.TopLeftHandle || + currentResizingMode == ResizingMode.BottomRightHandle) + { + newCursor = Cursors.Cross; + } + } + else + { + if(currentResizingMode == ResizingMode.TopLeftHandle || + currentResizingMode == ResizingMode.BottomRightHandle) + { + newCursor = Cursors.SizeNWSE; + } + else if(currentResizingMode == ResizingMode.TopRightHandle || + currentResizingMode == ResizingMode.BottomLeftHandle) + { + newCursor = Cursors.SizeNESW; + } + else if(currentResizingMode == ResizingMode.TopHandle || + currentResizingMode == ResizingMode.BottomHandle) + { + newCursor = Cursors.SizeNS; + } + else if(currentResizingMode == ResizingMode.LeftHandle || + currentResizingMode == ResizingMode.RightHandle) + { + newCursor = Cursors.SizeWE; + } + } + } + } + else + { + newCursor = this.Chart.defaultCursor; + } + + // Set current chart cursor + if (newCursor != this.Chart.Cursor) + { + System.Windows.Forms.Cursor tmpCursor = this.Chart.defaultCursor; + this.Chart.Cursor = newCursor; + this.Chart.defaultCursor = tmpCursor; + } + } + } + +#endif // Microsoft_CONTROL + + #endregion + + #region Event handlers + internal void ChartAreaNameReferenceChanged(object sender, NameReferenceChangedEventArgs e) + { + // If all the chart areas are removed and then a new one is inserted - Annotations don't get bound to it by default + if (e.OldElement == null) + return; + + foreach (Annotation annotation in this) + { + if (annotation.ClipToChartArea == e.OldName) + annotation.ClipToChartArea = e.NewName; + + AnnotationGroup group = annotation as AnnotationGroup; + if (group != null) + { + group.Annotations.ChartAreaNameReferenceChanged(sender, e); + } + } + } + #endregion + + } +} diff --git a/System.Web.DataVisualization/Common/Annotation/ArrowAnnotation.cs b/System.Web.DataVisualization/Common/Annotation/ArrowAnnotation.cs new file mode 100644 index 000000000..96b6a2e68 --- /dev/null +++ b/System.Web.DataVisualization/Common/Annotation/ArrowAnnotation.cs @@ -0,0 +1,471 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ArrowAnnotation.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ArrowAnnotation +// +// Purpose: Arrow annotation classes. +// +// Reviewed: +// +//=================================================================== + +#region Used namespace +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +#if Microsoft_CONTROL +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting + +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Enumeration + + /// + /// Arrow annotation styles. + /// + /// + [ + SRDescription("DescriptionAttributeArrowStyle_ArrowStyle") + ] + public enum ArrowStyle + { + /// + /// Simple arrow. + /// + Simple, + + /// + /// Arrow pointing in two directions. + /// + DoubleArrow, + + /// + /// Arrow with a tail. + /// + Tailed, + } + + #endregion // Enumeration + + /// + /// ArrowAnnotation is a class class that represents an arrow annotation. + /// + /// + /// Arrow annotations can be used to connect to points on the chart or highlight a + /// single chart area. Different arrow styles and sizes may be applied. + /// + [ + SRDescription("DescriptionAttributeArrowAnnotation_ArrowAnnotation"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class ArrowAnnotation : Annotation + { + #region Fields + + // Annotation arrow style + private ArrowStyle _arrowStyle = ArrowStyle.Simple; + + // Annotation arrow size + private int _arrowSize = 5; + + #endregion + + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public ArrowAnnotation() + : base() + { + base.AnchorAlignment = ContentAlignment.TopLeft; + } + + #endregion + + #region Properties + + #region Arrow properties + + /// + /// Gets or sets the arrow style of an arrow annotation. + /// + /// + /// + /// of an annotation. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ArrowStyle.Simple), + SRDescription("DescriptionAttributeArrowAnnotation_ArrowStyle"), + ParenthesizePropertyNameAttribute(true), + ] + virtual public ArrowStyle ArrowStyle + { + get + { + return _arrowStyle; + } + set + { + _arrowStyle = value; + Invalidate(); + } + } + + /// + /// Gets or sets the arrow size in pixels of an arrow annotation. + /// + /// + /// + /// Integer value that represents arrow size (thickness) in pixels. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(5), + SRDescription("DescriptionAttributeArrowAnnotation_ArrowSize"), + ParenthesizePropertyNameAttribute(true), + ] + virtual public int ArrowSize + { + get + { + return _arrowSize; + } + set + { + if(value <= 0) + { + throw(new ArgumentOutOfRangeException("value", SR.ExceptionAnnotationArrowSizeIsZero)); + } + if(value > 100) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAnnotationArrowSizeMustBeLessThen100)); + } + _arrowSize = value; + Invalidate(); + } + } + + + #endregion // Arrow properties + + #region Anchor + + /// + /// Gets or sets an annotation position's alignment to the anchor point. + /// + /// + /// + /// + /// + /// + /// + /// A value that represents the annotation's alignment to + /// the anchor point. + /// + /// + /// The annotation must be anchored using either , or the + /// and properties. Its and + /// properties must be set to Double.NaN. + /// + [ + SRCategory("CategoryAttributeAnchor"), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DefaultValue(typeof(ContentAlignment), "TopLeft"), + SRDescription("DescriptionAttributeAnchorAlignment"), + ] + override public ContentAlignment AnchorAlignment + { + get + { + return base.AnchorAlignment; + } + set + { + base.AnchorAlignment = value; + } + } + + #endregion // Anchoring + + #region Other + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "Arrow"; + } + } + + /// + /// Gets or sets annotation selection points style. + /// + /// + /// A value that represents annotation + /// selection style. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(SelectionPointsStyle.Rectangle), + ParenthesizePropertyNameAttribute(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeSelectionPointsStyle"), + ] + override internal SelectionPointsStyle SelectionPointsStyle + { + get + { + return SelectionPointsStyle.TwoPoints; + } + } + + #endregion + + #endregion + + #region Methods + + /// + /// Paints annotation object on specified graphics. + /// + /// + /// A used to paint annotation object. + /// + /// + /// Reference to the control. + /// + override internal void Paint(Chart chart, ChartGraphics graphics) + { + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height); + + // Create selection rectangle + RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y)); + + // Check if text position is valid + if( float.IsNaN(firstPoint.X) || + float.IsNaN(firstPoint.Y) || + float.IsNaN(secondPoint.X) || + float.IsNaN(secondPoint.Y) ) + { + return; + } + + // Get arrow shape path + using (GraphicsPath arrowPathAbs = GetArrowPath(graphics, selectionRect)) + { + + // Draw arrow shape + if (this.Common.ProcessModePaint) + { + graphics.DrawPathAbs( + arrowPathAbs, + (this.BackColor.IsEmpty) ? Color.White : this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + this.LineWidth, + this.LineDashStyle, + PenAlignment.Center, + this.ShadowOffset, + this.ShadowColor); + } + + // Process hot region + if (this.Common.ProcessModeRegions) + { + // Use callout defined hot region + this.Common.HotRegionsList.AddHotRegion( + graphics, + arrowPathAbs, + false, + ReplaceKeywords(this.ToolTip), +#if Microsoft_CONTROL + String.Empty, + String.Empty, + String.Empty, +#else // Microsoft_CONTROL + ReplaceKeywords(this.Url), + ReplaceKeywords(this.MapAreaAttributes), + ReplaceKeywords(this.PostBackValue), +#endif // Microsoft_CONTROL + this, + ChartElementType.Annotation); + } + + // Paint selection handles + PaintSelectionHandles(graphics, selectionRect, null); + } + } + + /// + /// Get arrow path for the specified annotation position + /// + /// + /// + /// + private GraphicsPath GetArrowPath( + ChartGraphics graphics, + RectangleF position) + { + // Get absolute position + RectangleF positionAbs = graphics.GetAbsoluteRectangle(position); + PointF firstPoint = positionAbs.Location; + PointF secondPoint = new PointF(positionAbs.Right, positionAbs.Bottom); + + // Calculate arrow length + float deltaX = secondPoint.X - firstPoint.X; + float deltaY = secondPoint.Y - firstPoint.Y; + float arrowLength = (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY); + + // Create unrotated graphics path for the arrow started at the annotation location + // and going to the right for the length of the rotated arrow. + GraphicsPath path = new GraphicsPath(); + + PointF[] points = null; + float pointerRatio = 2.1f; + if(this.ArrowStyle == ArrowStyle.Simple) + { + points = new PointF[] { + firstPoint, + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y - this.ArrowSize*pointerRatio), + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y - this.ArrowSize), + new PointF(firstPoint.X + arrowLength, firstPoint.Y - this.ArrowSize), + new PointF(firstPoint.X + arrowLength, firstPoint.Y + this.ArrowSize), + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y + this.ArrowSize), + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y + this.ArrowSize*pointerRatio) }; + } + else if(this.ArrowStyle == ArrowStyle.DoubleArrow) + { + points = new PointF[] { + firstPoint, + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y - this.ArrowSize*pointerRatio), + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y - this.ArrowSize), + new PointF(firstPoint.X + arrowLength - this.ArrowSize*pointerRatio, firstPoint.Y - this.ArrowSize), + new PointF(firstPoint.X + arrowLength - this.ArrowSize*pointerRatio, firstPoint.Y - this.ArrowSize*pointerRatio), + new PointF(firstPoint.X + arrowLength, firstPoint.Y), + new PointF(firstPoint.X + arrowLength - this.ArrowSize*pointerRatio, firstPoint.Y + this.ArrowSize*pointerRatio), + new PointF(firstPoint.X + arrowLength - this.ArrowSize*pointerRatio, firstPoint.Y + this.ArrowSize), + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y + this.ArrowSize), + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y + this.ArrowSize*pointerRatio) }; + } + else if(this.ArrowStyle == ArrowStyle.Tailed) + { + float tailRatio = 2.1f; + points = new PointF[] { + firstPoint, + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y - this.ArrowSize*pointerRatio), + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y - this.ArrowSize), + new PointF(firstPoint.X + arrowLength, firstPoint.Y - this.ArrowSize*tailRatio), + new PointF(firstPoint.X + arrowLength - this.ArrowSize*tailRatio, firstPoint.Y), + new PointF(firstPoint.X + arrowLength, firstPoint.Y + this.ArrowSize*tailRatio), + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y + this.ArrowSize), + new PointF(firstPoint.X + this.ArrowSize*pointerRatio, firstPoint.Y + this.ArrowSize*pointerRatio) }; + } + else + { + throw (new InvalidOperationException(SR.ExceptionAnnotationArrowStyleUnknown)); + } + + path.AddLines(points); + path.CloseAllFigures(); + + // Calculate arrow angle + float angle = (float)(Math.Atan(deltaY / deltaX) * 180f / Math.PI); + if(deltaX < 0) + { + angle += 180f; + } + + // Rotate arrow path around the first point + using( Matrix matrix = new Matrix() ) + { + matrix.RotateAt(angle, firstPoint); + path.Transform(matrix); + } + + return path; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Annotation/CalloutAnnotation.cs b/System.Web.DataVisualization/Common/Annotation/CalloutAnnotation.cs new file mode 100644 index 000000000..3f5dcc688 --- /dev/null +++ b/System.Web.DataVisualization/Common/Annotation/CalloutAnnotation.cs @@ -0,0 +1,1901 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: CalloutAnnotation.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: CalloutAnnotation +// +// Purpose: Callout annotation classes. +// +// Reviewed: +// +//=================================================================== + +#region Used namespace +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +#if Microsoft_CONTROL +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting + +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Enumerations + + /// + /// Annotation callout style. + /// + /// + [ + SRDescription("DescriptionAttributeCalloutStyle_CalloutStyle"), + ] + public enum CalloutStyle + { + /// + /// Callout text is underlined and a line is pointing to the anchor point. + /// + SimpleLine, + + /// + /// Border is drawn around text and a line is pointing to the anchor point. + /// + Borderline, + + /// + /// Callout text is inside the cloud and smaller clouds are pointing to the anchor point. + /// + Cloud, + + /// + /// Rectangle is drawn around the callout text, which is connected with the anchor point. + /// + Rectangle, + + /// + /// Rounded rectangle is drawn around the callout text, which is connected with the anchor point. + /// + RoundedRectangle, + + /// + /// Ellipse is drawn around the callout text, which is connected with the anchor point. + /// + Ellipse, + + /// + /// Perspective rectangle is drawn around the callout text, which is connected with the anchor point. + /// + Perspective, + } + + #endregion + + /// + /// CalloutAnnotation is a class class that represents a callout annotation. + /// + /// + /// Callout annotation is the only annotation that draws a connection between the + /// annotation position and anchor point. It can display text and automatically + /// calculate the required size. Different are supported. + /// + [ + SRDescription("DescriptionAttributeCalloutAnnotation_CalloutAnnotation"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class CalloutAnnotation : TextAnnotation + { + #region Fields + + // Callout anchor type + private LineAnchorCapStyle _calloutAnchorCap = LineAnchorCapStyle.Arrow; + + // Callout drawing style + private CalloutStyle _calloutStyle = CalloutStyle.Rectangle; + + // Cloud shape path + private static GraphicsPath _cloudPath = null; + + // Cloud shape outline path + private static GraphicsPath _cloudOutlinePath = null; + + // Cloud shape boundary rectangle + private static RectangleF _cloudBounds = RectangleF.Empty; + + #endregion + + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public CalloutAnnotation() + : base() + { + // Changing default values of properties + this.anchorOffsetX = 3.0; + this.anchorOffsetY = 3.0; + this.anchorAlignment = ContentAlignment.BottomLeft; + } + + #endregion + + #region Properties + + #region Callout properties + + /// + /// Gets or sets the annotation callout style. + /// + /// + /// of the annotation. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(CalloutStyle.Rectangle), + SRDescription("DescriptionAttributeCalloutAnnotation_CalloutStyle"), + ParenthesizePropertyNameAttribute(true), + ] + virtual public CalloutStyle CalloutStyle + { + get + { + return _calloutStyle; + } + set + { + _calloutStyle = value; + this.ResetCurrentRelativePosition(); + + // Reset content size to empty + contentSize = SizeF.Empty; + + Invalidate(); + } + } + + /// + /// Gets or sets the anchor cap style of a callout line. + /// + /// + /// A value used as the anchor cap of a callout line. + /// + /// + /// This property sets the anchor cap of the line connecting an annotation to + /// its anchor point. It only applies when SimpleLine or BorderLine + /// are used. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(LineAnchorCapStyle.Arrow), + SRDescription("DescriptionAttributeCalloutAnnotation_CalloutAnchorCap"), + ] + virtual public LineAnchorCapStyle CalloutAnchorCap + { + get + { + return _calloutAnchorCap; + } + set + { + _calloutAnchorCap = value; + Invalidate(); + } + } + #endregion // Callout properties + + #region Applicable Annotation Appearance Attributes (set as Browsable) + + /// + /// Gets or sets the color of an annotation line. + /// + /// + /// + /// + /// A value used to draw an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLineColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color LineColor + { + get + { + return base.LineColor; + } + set + { + base.LineColor = value; + } + } + + /// + /// Gets or sets the width of an annotation line. + /// + /// + /// + /// + /// An integer value defining the width of an annotation line in pixels. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeLineWidth"), + ] + override public int LineWidth + { + get + { + return base.LineWidth; + } + set + { + base.LineWidth = value; + + } + } + + /// + /// Gets or sets the style of an annotation line. + /// + /// + /// + /// + /// A value used to draw an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeLineDashStyle"), + ] + override public ChartDashStyle LineDashStyle + { + get + { + return base.LineDashStyle; + } + set + { + base.LineDashStyle = value; + } + } + + /// + /// Gets or sets the background color of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + + /// + /// Gets or sets the background hatch style of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + /// + /// Two colors are used to draw the hatching, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackHatchStyle"), + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + override public ChartHatchStyle BackHatchStyle + { + get + { + return base.BackHatchStyle; + } + set + { + base.BackHatchStyle = value; + } + } + + /// + /// Gets or sets the background gradient style of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + /// + /// Two colors are used to draw the gradient, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackGradientStyle"), + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + override public GradientStyle BackGradientStyle + { + get + { + return base.BackGradientStyle; + } + set + { + base.BackGradientStyle = value; + } + } + + /// + /// Gets or sets the secondary background color of an annotation. + /// + /// + /// + /// + /// + /// A value used for the secondary color of an annotation background with + /// hatching or gradient fill. + /// + /// + /// This color is used with when or + /// are used. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackSecondaryColor + { + get + { + return base.BackSecondaryColor; + } + set + { + base.BackSecondaryColor = value; + } + } + + #endregion + + #region Anchor + + /// + /// Gets or sets the x-coordinate offset between the positions of an annotation and its anchor point. + /// + /// + /// + /// + /// + /// + /// A double value that represents the x-coordinate offset between the positions of an annotation and its anchor point. + /// + /// + /// The annotation must be anchored using the or + /// properties, and its property must be set + /// to Double.NaN. + /// + [ + SRCategory("CategoryAttributeAnchor"), + DefaultValue(3.0), + SRDescription("DescriptionAttributeCalloutAnnotation_AnchorOffsetX"), + RefreshPropertiesAttribute(RefreshProperties.All), + ] + override public double AnchorOffsetX + { + get + { + return base.AnchorOffsetX; + } + set + { + base.AnchorOffsetX = value; + } + } + + /// + /// Gets or sets the y-coordinate offset between the positions of an annotation and its anchor point. + /// + /// + /// + /// + /// + /// + /// A double value that represents the y-coordinate offset between the positions of an annotation and its anchor point. + /// + /// + /// Annotation must be anchored using or + /// properties and its property must be set + /// to Double.NaN. + /// + [ + SRCategory("CategoryAttributeAnchor"), + DefaultValue(3.0), + SRDescription("DescriptionAttributeCalloutAnnotation_AnchorOffsetY"), + RefreshPropertiesAttribute(RefreshProperties.All), + ] + override public double AnchorOffsetY + { + get + { + return base.AnchorOffsetY; + } + set + { + base.AnchorOffsetY = value; + } + } + + /// + /// Gets or sets an annotation position's alignment to the anchor point. + /// + /// + /// + /// + /// + /// + /// + /// A value that represents the annotation's alignment to + /// the anchor point. + /// + /// + /// The annotation must be anchored using either , or the + /// and properties. Its and + /// properties must be set to Double.NaN. + /// + [ + SRCategory("CategoryAttributeAnchor"), + DefaultValue(typeof(ContentAlignment), "BottomLeft"), + SRDescription("DescriptionAttributeAnchorAlignment"), + ] + override public ContentAlignment AnchorAlignment + { + get + { + return base.AnchorAlignment; + } + set + { + base.AnchorAlignment = value; + } + } + + #endregion // Anchoring + + #region Other + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "Callout"; + } + } + + /// + /// Gets or sets annotation selection points style. + /// + /// + /// A value that represents annotation + /// selection style. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(SelectionPointsStyle.Rectangle), + ParenthesizePropertyNameAttribute(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeSelectionPointsStyle"), + ] + override internal SelectionPointsStyle SelectionPointsStyle + { + get + { + return SelectionPointsStyle.Rectangle; + } + } + + #endregion + + #endregion + + #region Methods + + #region Text Spacing + + /// + /// Gets text spacing on four different sides in relative coordinates. + /// + /// Indicates that spacing is in annotation relative coordinates. + /// Rectangle with text spacing values. + internal override RectangleF GetTextSpacing(out bool annotationRelative) + { + RectangleF spacing = base.GetTextSpacing(out annotationRelative); + if(this._calloutStyle == CalloutStyle.Cloud || + this._calloutStyle == CalloutStyle.Ellipse) + { + spacing = new RectangleF(4f, 4f, 4f, 4f); + annotationRelative = true; + } + else if(this._calloutStyle == CalloutStyle.RoundedRectangle) + { + spacing = new RectangleF(1f, 1f, 1f, 1f); + annotationRelative = true; + } + + return spacing; + } + + #endregion // Text Spacing + + #region Painting + + /// + /// Paints annotation object on specified graphics. + /// + /// + /// A used to paint annotation object. + /// + /// + /// Reference to the control. + /// + override internal void Paint(Chart chart, ChartGraphics graphics) + { + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height); + + // Create selection rectangle + RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y)); + + // Adjust negative rectangle width and height + RectangleF rectanglePosition = new RectangleF(selectionRect.Location, selectionRect.Size); + if(rectanglePosition.Width < 0) + { + rectanglePosition.X = rectanglePosition.Right; + rectanglePosition.Width = -rectanglePosition.Width; + } + if(rectanglePosition.Height < 0) + { + rectanglePosition.Y = rectanglePosition.Bottom; + rectanglePosition.Height = -rectanglePosition.Height; + } + + // Check if position is valid + if( float.IsNaN(rectanglePosition.X) || + float.IsNaN(rectanglePosition.Y) || + float.IsNaN(rectanglePosition.Right) || + float.IsNaN(rectanglePosition.Bottom) ) + { + return; + } + + // Paint different style of callouts + GraphicsPath hotRegionPathAbs = null; + if(this.Common.ProcessModePaint) + { + switch(this._calloutStyle) + { + case(CalloutStyle.SimpleLine): + hotRegionPathAbs = DrawRectangleLineCallout( + graphics, + rectanglePosition, + anchorPoint, + false); + break; + case(CalloutStyle.Borderline): + hotRegionPathAbs = DrawRectangleLineCallout( + graphics, + rectanglePosition, + anchorPoint, + true); + break; + case(CalloutStyle.Perspective): + hotRegionPathAbs = DrawPerspectiveCallout( + graphics, + rectanglePosition, + anchorPoint); + break; + case(CalloutStyle.Cloud): + hotRegionPathAbs = DrawCloudCallout( + graphics, + rectanglePosition, + anchorPoint); + break; + case(CalloutStyle.Rectangle): + hotRegionPathAbs = DrawRectangleCallout( + graphics, + rectanglePosition, + anchorPoint); + break; + case(CalloutStyle.Ellipse): + hotRegionPathAbs = DrawRoundedRectCallout( + graphics, + rectanglePosition, + anchorPoint, + true); + break; + case(CalloutStyle.RoundedRectangle): + hotRegionPathAbs = DrawRoundedRectCallout( + graphics, + rectanglePosition, + anchorPoint, + false); + break; + } + } + + if(this.Common.ProcessModeRegions) + { + if(hotRegionPathAbs != null) + { + // If there is more then one graphical path split them and create + // image maps for every graphical path separately. + GraphicsPathIterator iterator = new GraphicsPathIterator(hotRegionPathAbs); + + // There is more then one path. + using (GraphicsPath subPath = new GraphicsPath()) + { + while (iterator.NextMarker(subPath) > 0) + { + // Use callout defined hot region + this.Common.HotRegionsList.AddHotRegion( + graphics, + subPath, + false, + ReplaceKeywords(this.ToolTip), +#if Microsoft_CONTROL + String.Empty, + String.Empty, + String.Empty, +#else // Microsoft_CONTROL + ReplaceKeywords(this.Url), + ReplaceKeywords(this.MapAreaAttributes), + ReplaceKeywords(this.PostBackValue), +#endif // Microsoft_CONTROL + this, + ChartElementType.Annotation); + + // Reset current path + subPath.Reset(); + } + } + } + else + { + // Use rectangular hot region + this.Common.HotRegionsList.AddHotRegion( + rectanglePosition, + ReplaceKeywords(this.ToolTip), +#if Microsoft_CONTROL + String.Empty, + String.Empty, + String.Empty, +#else // Microsoft_CONTROL + ReplaceKeywords(this.Url), + ReplaceKeywords(this.MapAreaAttributes), + ReplaceKeywords(this.PostBackValue), +#endif // Microsoft_CONTROL + this, + ChartElementType.Annotation, + String.Empty); + } + } + + //Clean up + if (hotRegionPathAbs != null) + hotRegionPathAbs.Dispose(); + + // Paint selection handles + PaintSelectionHandles(graphics, selectionRect, null); + } + + /// + /// Draws Rounded rectangle or Ellipse style callout. + /// + /// Chart graphics. + /// Position of annotation objet. + /// Anchor location. + /// True if ellipse shape should be used. + /// Hot region of the callout. + private GraphicsPath DrawRoundedRectCallout( + ChartGraphics graphics, + RectangleF rectanglePosition, + PointF anchorPoint, + bool isEllipse) + { + // Get absolute position + RectangleF rectanglePositionAbs = graphics.GetAbsoluteRectangle(rectanglePosition); + + // NOTE: Fix for issue #6692. + // Do not draw the callout if size is not set. This may happen if callou text is set to empty string. + if (rectanglePositionAbs.Width <= 0 || rectanglePositionAbs.Height <= 0) + { + return null; + } + + // Create ellipse path + GraphicsPath ellipsePath = new GraphicsPath(); + if(isEllipse) + { + // Add ellipse shape + ellipsePath.AddEllipse(rectanglePositionAbs); + } + else + { + // Add rounded rectangle shape + float radius = Math.Min(rectanglePositionAbs.Width, rectanglePositionAbs.Height); + radius /= 5f; + ellipsePath = this.CreateRoundedRectPath(rectanglePositionAbs, radius); + } + + // Draw perspective polygons from anchoring point + if(!float.IsNaN(anchorPoint.X) && !float.IsNaN(anchorPoint.Y)) + { + // Check if point is inside annotation position + if(!rectanglePosition.Contains(anchorPoint.X, anchorPoint.Y)) + { + // Get absolute anchor point + PointF anchorPointAbs = graphics.GetAbsolutePoint(new PointF(anchorPoint.X, anchorPoint.Y)); + + // Flatten ellipse path + ellipsePath.Flatten(); + + // Find point in the path closest to the anchor point + PointF[] points = ellipsePath.PathPoints; + int closestPointIndex = 0; + int index = 0; + float currentDistance = float.MaxValue; + foreach(PointF point in points) + { + float deltaX = point.X - anchorPointAbs.X; + float deltaY = point.Y - anchorPointAbs.Y; + float distance = deltaX * deltaX + deltaY * deltaY; + if(distance < currentDistance) + { + currentDistance = distance; + closestPointIndex = index; + } + ++ index; + } + + // Change point to the anchor location + points[closestPointIndex] = anchorPointAbs; + + // Recreate ellipse path + ellipsePath.Reset(); + ellipsePath.AddLines(points); + ellipsePath.CloseAllFigures(); + } + } + + // Draw ellipse + graphics.DrawPathAbs( + ellipsePath, + this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + this.LineWidth, + this.LineDashStyle, + PenAlignment.Center, + this.ShadowOffset, + this.ShadowColor); + + // Draw text + DrawText(graphics, rectanglePosition, true, false); + + return ellipsePath; + } + + /// + /// Draws Rectangle style callout. + /// + /// Chart graphics. + /// Position of annotation objet. + /// Anchor location. + /// Hot region of the callout. + private GraphicsPath DrawRectangleCallout( + ChartGraphics graphics, + RectangleF rectanglePosition, + PointF anchorPoint) + { + // Create path for the rectangle connected with anchor point. + GraphicsPath hotRegion = null; + bool anchorVisible = false; + if(!float.IsNaN(anchorPoint.X) && !float.IsNaN(anchorPoint.Y)) + { + // Get relative size of a pixel + SizeF pixelSize = graphics.GetRelativeSize(new SizeF(1f, 1f)); + + // Increase annotation position rectangle by 1 pixel + RectangleF inflatedPosition = new RectangleF(rectanglePosition.Location, rectanglePosition.Size); + inflatedPosition.Inflate(pixelSize); + + // Check if point is inside annotation position + if(!inflatedPosition.Contains(anchorPoint.X, anchorPoint.Y)) + { + anchorVisible = true; + + // Get absolute position + RectangleF rectanglePositionAbs = graphics.GetAbsoluteRectangle(rectanglePosition); + + // Get absolute anchor point + PointF anchorPointAbs = graphics.GetAbsolutePoint(new PointF(anchorPoint.X, anchorPoint.Y)); + + // Calculate anchor pointer thicness + float size = Math.Min(rectanglePositionAbs.Width, rectanglePositionAbs.Height); + size /= 4f; + + // Create shape points + PointF[] points = new PointF[7]; + if(anchorPoint.X < rectanglePosition.X && + anchorPoint.Y > rectanglePosition.Bottom) + { + points[0] = rectanglePositionAbs.Location; + points[1] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y); + points[2] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom); + points[3] = new PointF(rectanglePositionAbs.X + size, rectanglePositionAbs.Bottom); + points[4] = anchorPointAbs; + points[5] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom - size); + points[6] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom - size); + } + else if(anchorPoint.X >= rectanglePosition.X && + anchorPoint.X <= rectanglePosition.Right && + anchorPoint.Y > rectanglePosition.Bottom) + { + points[0] = rectanglePositionAbs.Location; + points[1] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y); + points[2] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom); + points[3] = new PointF(rectanglePositionAbs.X + rectanglePositionAbs.Width / 2f + size, rectanglePositionAbs.Bottom); + points[4] = anchorPointAbs; + points[5] = new PointF(rectanglePositionAbs.X + rectanglePositionAbs.Width / 2f - size, rectanglePositionAbs.Bottom); + points[6] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + } + else if(anchorPoint.X > rectanglePosition.Right && + anchorPoint.Y > rectanglePosition.Bottom) + { + points[0] = rectanglePositionAbs.Location; + points[1] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y); + points[2] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom - size); + points[3] = anchorPointAbs; + points[4] = new PointF(rectanglePositionAbs.Right - size, rectanglePositionAbs.Bottom); + points[5] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + points[6] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + } + else if(anchorPoint.X > rectanglePosition.Right && + anchorPoint.Y <= rectanglePosition.Bottom && + anchorPoint.Y >= rectanglePosition.Y) + { + points[0] = rectanglePositionAbs.Location; + points[1] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y); + points[2] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y + rectanglePositionAbs.Height / 2f - size); + points[3] = anchorPointAbs; + points[4] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y + rectanglePositionAbs.Height / 2f + size); + points[5] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom); + points[6] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + } + else if(anchorPoint.X > rectanglePosition.Right && + anchorPoint.Y < rectanglePosition.Y) + { + points[0] = rectanglePositionAbs.Location; + points[1] = new PointF(rectanglePositionAbs.Right - size, rectanglePositionAbs.Y); + points[2] = anchorPointAbs; + points[3] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y + size); + points[4] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom); + points[5] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + points[6] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + } + else if(anchorPoint.X >= rectanglePosition.X && + anchorPoint.X <= rectanglePosition.Right && + anchorPoint.Y < rectanglePosition.Y) + { + points[0] = rectanglePositionAbs.Location; + points[1] = new PointF(rectanglePositionAbs.X + rectanglePositionAbs.Width/2f - size, rectanglePositionAbs.Y); + points[2] = anchorPointAbs; + points[3] = new PointF(rectanglePositionAbs.X + rectanglePositionAbs.Width/2f + size, rectanglePositionAbs.Y); + points[4] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y); + points[5] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom); + points[6] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + } + else if(anchorPoint.X < rectanglePosition.X && + anchorPoint.Y < rectanglePosition.Y) + { + points[0] = anchorPointAbs; + points[1] = new PointF(rectanglePositionAbs.X + size, rectanglePositionAbs.Y); + points[2] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y); + points[3] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom); + points[4] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + points[5] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Y + size); + points[6] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Y + size); + } + else if(anchorPoint.X < rectanglePosition.X && + anchorPoint.Y >= rectanglePosition.Y && + anchorPoint.Y <= rectanglePosition.Bottom) + { + points[0] = rectanglePositionAbs.Location; + points[1] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y); + points[2] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom); + points[3] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + points[4] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Y + rectanglePositionAbs.Height/2f + size ); + points[5] = anchorPointAbs; + points[6] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Y + rectanglePositionAbs.Height/2f - size ); + } + + // Create graphics path of the callout + hotRegion = new GraphicsPath(); + + hotRegion.AddLines(points); + hotRegion.CloseAllFigures(); + + // Draw callout + graphics.DrawPathAbs( + hotRegion, + this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + this.LineWidth, + this.LineDashStyle, + PenAlignment.Center, + this.ShadowOffset, + this.ShadowColor); + + } + } + + // Draw rectangle if anchor is not visible + if(!anchorVisible) + { + graphics.FillRectangleRel( + rectanglePosition, + this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + this.LineWidth, + this.LineDashStyle, + this.ShadowColor, + this.ShadowOffset, + PenAlignment.Center); + + // Get hot region + hotRegion = new GraphicsPath(); + hotRegion.AddRectangle( graphics.GetAbsoluteRectangle(rectanglePosition) ); + } + + // Draw text + DrawText(graphics, rectanglePosition, false, false); + + return hotRegion; + } + + /// + /// Draws Perspective style callout. + /// + /// Chart graphics. + /// Position of annotation objet. + /// Anchor location. + /// Hot region of the cloud. + private GraphicsPath DrawCloudCallout( + ChartGraphics graphics, + RectangleF rectanglePosition, + PointF anchorPoint) + { + // Get absolute position + RectangleF rectanglePositionAbs = graphics.GetAbsoluteRectangle(rectanglePosition); + + // Draw perspective polygons from anchoring point + if(!float.IsNaN(anchorPoint.X) && !float.IsNaN(anchorPoint.Y)) + { + // Check if point is inside annotation position + if(!rectanglePosition.Contains(anchorPoint.X, anchorPoint.Y)) + { + // Get center point of the cloud + PointF cloudCenterAbs = graphics.GetAbsolutePoint( + new PointF( + rectanglePosition.X + rectanglePosition.Width / 2f, + rectanglePosition.Y + rectanglePosition.Height / 2f) ); + + // Calculate absolute ellipse size and position + SizeF ellipseSize = graphics.GetAbsoluteSize( + new SizeF(rectanglePosition.Width, rectanglePosition.Height)); + ellipseSize.Width /= 10f; + ellipseSize.Height /= 10f; + PointF anchorPointAbs = graphics.GetAbsolutePoint( + new PointF(anchorPoint.X, anchorPoint.Y)); + PointF ellipseLocation = anchorPointAbs; + + // Get distance between anchor point and center of the cloud + float dxAbs = anchorPointAbs.X - cloudCenterAbs.X; + float dyAbs = anchorPointAbs.Y - cloudCenterAbs.Y; + + PointF point = PointF.Empty; + if(anchorPoint.Y < rectanglePosition.Y) + { + point = GetIntersectionY(cloudCenterAbs, anchorPointAbs, rectanglePositionAbs.Y); + if(point.X < rectanglePositionAbs.X) + { + point = GetIntersectionX(cloudCenterAbs, anchorPointAbs, rectanglePositionAbs.X); + } + else if(point.X > rectanglePositionAbs.Right) + { + point = GetIntersectionX(cloudCenterAbs, anchorPointAbs, rectanglePositionAbs.Right); + } + } + else if(anchorPoint.Y > rectanglePosition.Bottom) + { + point = GetIntersectionY(cloudCenterAbs, anchorPointAbs, rectanglePositionAbs.Bottom); + if(point.X < rectanglePositionAbs.X) + { + point = GetIntersectionX(cloudCenterAbs, anchorPointAbs, rectanglePositionAbs.X); + } + else if(point.X > rectanglePositionAbs.Right) + { + point = GetIntersectionX(cloudCenterAbs, anchorPointAbs, rectanglePositionAbs.Right); + } + } + else + { + if(anchorPoint.X < rectanglePosition.X) + { + point = GetIntersectionX(cloudCenterAbs, anchorPointAbs, rectanglePositionAbs.X); + } + else + { + point = GetIntersectionX(cloudCenterAbs, anchorPointAbs, rectanglePositionAbs.Right); + } + } + + SizeF size = new SizeF(Math.Abs(cloudCenterAbs.X - point.X), Math.Abs(cloudCenterAbs.Y - point.Y)); + if(dxAbs > 0) + dxAbs -= size.Width; + else + dxAbs += size.Width; + + if(dyAbs > 0) + dyAbs -= size.Height; + else + dyAbs += size.Height; + + + // Draw 3 smaller ellipses from anchor point to the cloud + for(int index = 0; index < 3; index++) + { + using( GraphicsPath path = new GraphicsPath() ) + { + // Create ellipse path + path.AddEllipse( + ellipseLocation.X - ellipseSize.Width / 2f, + ellipseLocation.Y - ellipseSize.Height / 2f, + ellipseSize.Width, + ellipseSize.Height); + + // Draw ellipse + graphics.DrawPathAbs( + path, + this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + 1, // this.LineWidth, NOTE: Cloud supports only 1 pixel border + this.LineDashStyle, + PenAlignment.Center, + this.ShadowOffset, + this.ShadowColor); + + // Adjust ellipse size + ellipseSize.Width *= 1.5f; + ellipseSize.Height *= 1.5f; + + // Adjust next ellipse position + ellipseLocation.X -= dxAbs / 3f + (index * (dxAbs / 10f) ); + ellipseLocation.Y -= dyAbs / 3f + (index * (dyAbs / 10f) ); + } + } + } + } + + // Draw cloud + GraphicsPath pathCloud = GetCloudPath(rectanglePositionAbs); + graphics.DrawPathAbs( + pathCloud, + this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + 1, // this.LineWidth, NOTE: Cloud supports only 1 pixel border + this.LineDashStyle, + PenAlignment.Center, + this.ShadowOffset, + this.ShadowColor); + + // Draw cloud outline (Do not draw in SVG or Flash Animation) + { + using(GraphicsPath pathCloudOutline = GetCloudOutlinePath(rectanglePositionAbs)) + { + graphics.DrawPathAbs( + pathCloudOutline, + this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + 1, // this.LineWidth, NOTE: Cloud supports only 1 pixel border + this.LineDashStyle, + PenAlignment.Center); + } + } + + // Draw text + DrawText(graphics, rectanglePosition, true, false); + + return pathCloud; + } + + /// + /// Draws Perspective style callout. + /// + /// Chart graphics. + /// Position of annotation objet. + /// Anchor location. + /// Hot region of the cloud. + private GraphicsPath DrawPerspectiveCallout( + ChartGraphics graphics, + RectangleF rectanglePosition, + PointF anchorPoint) + { + // Draw rectangle + graphics.FillRectangleRel( + rectanglePosition, + this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + this.LineWidth, + this.LineDashStyle, + this.ShadowColor, + 0, // Shadow is never drawn + PenAlignment.Center); + + // Create hot region path + GraphicsPath hotRegion = new GraphicsPath(); + hotRegion.AddRectangle( graphics.GetAbsoluteRectangle(rectanglePosition) ); + + // Draw text + DrawText(graphics, rectanglePosition, false, false); + + // Draw perspective polygons from anchoring point + if(!float.IsNaN(anchorPoint.X) && !float.IsNaN(anchorPoint.Y)) + { + // Check if point is inside annotation position + if(!rectanglePosition.Contains(anchorPoint.X, anchorPoint.Y)) + { + Color[] perspectivePathColors = new Color[2]; + Color color = (this.BackColor.IsEmpty) ? Color.White : this.BackColor; + perspectivePathColors[0] = graphics.GetBrightGradientColor(color, 0.6); + perspectivePathColors[1] = graphics.GetBrightGradientColor(color, 0.8); + GraphicsPath[] perspectivePaths = new GraphicsPath[2]; + using(perspectivePaths[0] = new GraphicsPath()) + { + using(perspectivePaths[1] = new GraphicsPath()) + { + // Convert coordinates to absolute + RectangleF rectanglePositionAbs = graphics.GetAbsoluteRectangle(rectanglePosition); + PointF anchorPointAbs = graphics.GetAbsolutePoint(anchorPoint); + + // Create paths of perspective + if(anchorPoint.Y < rectanglePosition.Y) + { + PointF[] points1 = new PointF[3]; + points1[0] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Y); + points1[1] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y); + points1[2] = new PointF(anchorPointAbs.X, anchorPointAbs.Y); + perspectivePaths[0].AddLines(points1); + if(anchorPoint.X < rectanglePosition.X) + { + PointF[] points2 = new PointF[3]; + points2[0] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + points2[1] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Y); + points2[2] = new PointF(anchorPointAbs.X, anchorPointAbs.Y); + perspectivePaths[1].AddLines(points2); + } + else if(anchorPoint.X > rectanglePosition.Right) + { + PointF[] points2 = new PointF[3]; + points2[0] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom); + points2[1] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y); + points2[2] = new PointF(anchorPointAbs.X, anchorPointAbs.Y); + perspectivePaths[1].AddLines(points2); + } + } + else if(anchorPoint.Y > rectanglePosition.Bottom) + { + PointF[] points1 = new PointF[3]; + points1[0] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + points1[1] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom); + points1[2] = new PointF(anchorPointAbs.X, anchorPointAbs.Y); + perspectivePaths[0].AddLines(points1); + if(anchorPoint.X < rectanglePosition.X) + { + PointF[] points2 = new PointF[3]; + points2[0] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + points2[1] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Y); + points2[2] = new PointF(anchorPointAbs.X, anchorPointAbs.Y); + perspectivePaths[1].AddLines(points2); + } + else if(anchorPoint.X > rectanglePosition.Right) + { + PointF[] points2 = new PointF[3]; + points2[0] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom); + points2[1] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y); + points2[2] = new PointF(anchorPointAbs.X, anchorPointAbs.Y); + perspectivePaths[1].AddLines(points2); + } + } + else + { + if(anchorPoint.X < rectanglePosition.X) + { + PointF[] points2 = new PointF[3]; + points2[0] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Bottom); + points2[1] = new PointF(rectanglePositionAbs.X, rectanglePositionAbs.Y); + points2[2] = new PointF(anchorPointAbs.X, anchorPointAbs.Y); + perspectivePaths[1].AddLines(points2); + } + else if(anchorPoint.X > rectanglePosition.Right) + { + PointF[] points2 = new PointF[3]; + points2[0] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Bottom); + points2[1] = new PointF(rectanglePositionAbs.Right, rectanglePositionAbs.Y); + points2[2] = new PointF(anchorPointAbs.X, anchorPointAbs.Y); + perspectivePaths[1].AddLines(points2); + } + } + + // Draw paths if non-empty + int index = 0; + foreach(GraphicsPath path in perspectivePaths) + { + if(path.PointCount > 0) + { + path.CloseAllFigures(); + graphics.DrawPathAbs( + path, + perspectivePathColors[index], + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + this.LineWidth, + this.LineDashStyle, + PenAlignment.Center); + + // Add area to hot region path + hotRegion.SetMarkers(); + hotRegion.AddPath( path, false ); + } + ++index; + } + } + } + } + } + + return hotRegion; + } + + /// + /// Draws SimpleLine or BorderLine style callout. + /// + /// Chart graphics. + /// Position of annotation objet. + /// Anchor location. + /// If true draws BorderLine style, otherwise SimpleLine. + /// Hot region of the cloud. + private GraphicsPath DrawRectangleLineCallout( + ChartGraphics graphics, + RectangleF rectanglePosition, + PointF anchorPoint, + bool drawRectangle) + { + // Rectangle mode + if(drawRectangle) + { + // Draw rectangle + graphics.FillRectangleRel( + rectanglePosition, + this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + this.LineWidth, + this.LineDashStyle, + this.ShadowColor, + this.ShadowOffset, + PenAlignment.Center); + + // Draw text + DrawText(graphics, rectanglePosition, false, false); + } + else + { + // Draw text + rectanglePosition = DrawText(graphics, rectanglePosition, false, true); + SizeF pixelSize = graphics.GetRelativeSize(new SizeF(2f, 2f)); + rectanglePosition.Inflate(pixelSize); + } + + // Create hot region path + GraphicsPath hotRegion = new GraphicsPath(); + hotRegion.AddRectangle( graphics.GetAbsoluteRectangle(rectanglePosition) ); + + // Define position of text underlying line + PointF textLinePoint1 = new PointF(rectanglePosition.X, rectanglePosition.Bottom); + PointF textLinePoint2 = new PointF(rectanglePosition.Right, rectanglePosition.Bottom); + + // Draw line to the anchor point + if(!float.IsNaN(anchorPoint.X) && !float.IsNaN(anchorPoint.Y)) + { + // Check if point is inside annotation position + if(!rectanglePosition.Contains(anchorPoint.X, anchorPoint.Y)) + { + PointF lineSecondPoint = PointF.Empty; + if(anchorPoint.X < rectanglePosition.X) + { + lineSecondPoint.X = rectanglePosition.X; + } + else if(anchorPoint.X > rectanglePosition.Right) + { + lineSecondPoint.X = rectanglePosition.Right; + } + else + { + lineSecondPoint.X = rectanglePosition.X + rectanglePosition.Width / 2f; + } + + if(anchorPoint.Y < rectanglePosition.Y) + { + lineSecondPoint.Y = rectanglePosition.Y; + } + else if(anchorPoint.Y > rectanglePosition.Bottom) + { + lineSecondPoint.Y = rectanglePosition.Bottom; + } + else + { + lineSecondPoint.Y = rectanglePosition.Y + rectanglePosition.Height / 2f; + } + + // Set line caps + bool capChanged = false; + LineCap oldStartCap = LineCap.Flat; + if(this.CalloutAnchorCap != LineAnchorCapStyle.None) + { + // Save old pen + capChanged = true; + oldStartCap = graphics.Pen.StartCap; + + // Apply anchor cap settings + if(this.CalloutAnchorCap == LineAnchorCapStyle.Arrow) + { + // Adjust arrow size for small line width + if(this.LineWidth < 4) + { + int adjustment = 3 - this.LineWidth; + graphics.Pen.StartCap = LineCap.Custom; + graphics.Pen.CustomStartCap = new AdjustableArrowCap( + this.LineWidth + adjustment, + this.LineWidth + adjustment, + true); + } + else + { + graphics.Pen.StartCap = LineCap.ArrowAnchor; + } + } + else if(this.CalloutAnchorCap == LineAnchorCapStyle.Diamond) + { + graphics.Pen.StartCap = LineCap.DiamondAnchor; + } + else if(this.CalloutAnchorCap == LineAnchorCapStyle.Round) + { + graphics.Pen.StartCap = LineCap.RoundAnchor; + } + else if(this.CalloutAnchorCap == LineAnchorCapStyle.Square) + { + graphics.Pen.StartCap = LineCap.SquareAnchor; + } + } + + // Draw callout line + graphics.DrawLineAbs( + this.LineColor, + this.LineWidth, + this.LineDashStyle, + graphics.GetAbsolutePoint(anchorPoint), + graphics.GetAbsolutePoint(lineSecondPoint), + this.ShadowColor, + this.ShadowOffset); + + // Create hot region path + using( GraphicsPath linePath = new GraphicsPath() ) + { + linePath.AddLine( + graphics.GetAbsolutePoint(anchorPoint), + graphics.GetAbsolutePoint(lineSecondPoint) ); + + linePath.Widen(new Pen(Color.Black, this.LineWidth + 2)); + hotRegion.SetMarkers(); + hotRegion.AddPath( linePath, false ); + } + + // Restore line caps + if(capChanged) + { + graphics.Pen.StartCap = oldStartCap; + } + + // Adjust text underlying line position + if(anchorPoint.Y < rectanglePosition.Y) + { + textLinePoint1.Y = rectanglePosition.Y; + textLinePoint2.Y = rectanglePosition.Y; + } + else if(anchorPoint.Y > rectanglePosition.Y && + anchorPoint.Y < rectanglePosition.Bottom) + { + textLinePoint1.Y = rectanglePosition.Y; + textLinePoint2.Y = rectanglePosition.Bottom; + if(anchorPoint.X < rectanglePosition.X) + { + textLinePoint1.X = rectanglePosition.X; + textLinePoint2.X = rectanglePosition.X; + } + else + { + textLinePoint1.X = rectanglePosition.Right; + textLinePoint2.X = rectanglePosition.Right; + } + } + } + + // Draw text underlying line + if(!drawRectangle) + { + graphics.DrawLineAbs( + this.LineColor, + this.LineWidth, + this.LineDashStyle, + graphics.GetAbsolutePoint(textLinePoint1), + graphics.GetAbsolutePoint(textLinePoint2), + this.ShadowColor, + this.ShadowOffset); + + // Create hot region path + using( GraphicsPath linePath = new GraphicsPath() ) + { + linePath.AddLine( + graphics.GetAbsolutePoint(textLinePoint1), + graphics.GetAbsolutePoint(textLinePoint2) ); + + linePath.Widen(new Pen(Color.Black, this.LineWidth + 2)); + hotRegion.SetMarkers(); + hotRegion.AddPath( linePath, false ); + } + + } + } + + return hotRegion; + } + + #endregion // Painting + + #region Anchor Methods + + /// + /// Checks if annotation draw anything in the anchor position (except selection handle) + /// + /// True if annotation "connects" itself and anchor point visually. + override internal bool IsAnchorDrawn() + { + return true; + } + + #endregion // Anchor Methods + + #region Helper methods + + /// + /// Gets cloud callout outline graphics path. + /// + /// Absolute position of the callout cloud. + /// Cloud outline path. + private static GraphicsPath GetCloudOutlinePath(RectangleF position) + { + if(_cloudOutlinePath == null) + { + GetCloudPath(position); + } + + // Translate and sacle original path to fit specified position + GraphicsPath resultPath = (GraphicsPath)_cloudOutlinePath.Clone(); + Matrix matrix = new Matrix(); + matrix.Translate(-_cloudBounds.X, -_cloudBounds.Y); + resultPath.Transform(matrix); + matrix = new Matrix(); + matrix.Translate(position.X, position.Y); + matrix.Scale(position.Width / _cloudBounds.Width, position.Height / _cloudBounds.Height); + resultPath.Transform(matrix); + + return resultPath; + } + + /// + /// Gets cloud callout graphics path. + /// + /// Absolute position of the callout cloud. + /// Cloud path. + private static GraphicsPath GetCloudPath(RectangleF position) + { + // Check if cloud path was already created + if(_cloudPath == null) + { + // Create cloud path + _cloudPath = new GraphicsPath(); + + _cloudPath.AddBezier(1689.5f, 1998.6f, 1581.8f, 2009.4f, 1500f, 2098.1f, 1500f, 2204f); + + _cloudPath.AddBezier(1500f, 2204f, 1499.9f, 2277.2f, 1539.8f, 2345.1f, 1604.4f, 2382.1f); + + _cloudPath.AddBezier(1603.3f, 2379.7f, 1566.6f, 2417.8f, 1546.2f, 2468.1f, 1546.2f, 2520.1f); + _cloudPath.AddBezier(1546.2f, 2520.1f, 1546.2f, 2633.7f, 1641.1f, 2725.7f, 1758.1f, 2725.7f); + _cloudPath.AddBezier(1758.1f, 2725.7f, 1766.3f, 2725.6f, 1774.6f, 2725.2f, 1782.8f, 2724.2f); + + _cloudPath.AddBezier(1781.7f, 2725.6f, 1848.5f, 2839.4f, 1972.8f, 2909.7f, 2107.3f, 2909.7f); + _cloudPath.AddBezier(2107.3f, 2909.7f, 2175.4f, 2909.7f, 2242.3f, 2891.6f, 2300.6f, 2857.4f); + + _cloudPath.AddBezier(2300f, 2857.6f, 2360.9f, 2946.5f, 2463.3f, 2999.7f, 2572.9f, 2999.7f); + _cloudPath.AddBezier(2572.9f, 2999.7f, 2717.5f, 2999.7f, 2845.2f, 2907.4f, 2887.1f, 2772.5f); + + _cloudPath.AddBezier(2887.4f, 2774.3f, 2932.1f, 2801.4f, 2983.6f, 2815.7f, 3036.3f, 2815.7f); + _cloudPath.AddBezier(3036.3f, 2815.7f, 3190.7f, 2815.7f, 3316.3f, 2694.8f, 3317.5f, 2544.8f); + + _cloudPath.AddBezier(3317f, 2544.1f, 3479.2f, 2521.5f, 3599.7f, 2386.5f, 3599.7f, 2227.2f); + _cloudPath.AddBezier(3599.7f, 2227.2f, 3599.7f, 2156.7f, 3575.7f, 2088.1f, 3531.6f, 2032.2f); + + _cloudPath.AddBezier(3530.9f, 2032f, 3544.7f, 2000.6f, 3551.9f, 1966.7f, 3551.9f, 1932.5f); + _cloudPath.AddBezier(3551.9f, 1932.5f, 3551.9f, 1818.6f, 3473.5f, 1718.8f, 3360.7f, 1688.8f); + + _cloudPath.AddBezier(3361.6f, 1688.3f, 3341.4f, 1579.3f, 3243.5f, 1500f, 3129.3f, 1500f); + _cloudPath.AddBezier(3129.3f, 1500f, 3059.8f, 1499.9f, 2994f, 1529.6f, 2949.1f, 1580.9f); + + _cloudPath.AddBezier(2949.5f, 1581.3f, 2909.4f, 1530f, 2847f, 1500f, 2780.8f, 1500f); + _cloudPath.AddBezier(2780.8f, 1500f, 2700.4f, 1499.9f, 2626.8f, 1544.2f, 2590.9f, 1614.2f); + + _cloudPath.AddBezier(2591.7f, 1617.6f, 2543.2f, 1571.1f, 2477.9f, 1545.1f, 2409.8f, 1545.1f); + _cloudPath.AddBezier(2409.8f, 1545.1f, 2313.9f, 1545.1f, 2225.9f, 1596.6f, 2180.8f, 1679f); + + _cloudPath.AddBezier(2180.1f, 1680.7f, 2129.7f, 1652f, 2072.4f, 1636.9f, 2014.1f, 1636.9f); + _cloudPath.AddBezier(2014.1f, 1636.9f, 1832.8f, 1636.9f, 1685.9f, 1779.8f, 1685.9f, 1956f); + _cloudPath.AddBezier(1685.9f, 1956f, 1685.8f, 1970.4f, 1686.9f, 1984.8f, 1688.8f, 1999f); + + _cloudPath.CloseAllFigures(); + + + // Create cloud outline path + _cloudOutlinePath = new GraphicsPath(); + + _cloudOutlinePath.AddBezier(1604.4f, 2382.1f, 1636.8f, 2400.6f, 1673.6f, 2410.3f, 1711.2f, 2410.3f); + _cloudOutlinePath.AddBezier(1711.2f, 2410.3f, 1716.6f, 2410.3f, 1722.2f, 2410.2f, 1727.6f, 2409.8f); + + _cloudOutlinePath.StartFigure(); + _cloudOutlinePath.AddBezier(1782.8f, 2724.2f, 1801.3f, 2722.2f, 1819.4f, 2717.7f, 1836.7f, 2711f); + + _cloudOutlinePath.StartFigure(); + _cloudOutlinePath.AddBezier(2267.6f, 2797.2f, 2276.1f, 2818.4f, 2287f, 2838.7f, 2300f, 2857.6f); + + _cloudOutlinePath.StartFigure(); + _cloudOutlinePath.AddBezier(2887.1f, 2772.5f, 2893.8f, 2750.9f, 2898.1f, 2728.7f, 2900f, 2706.3f); + + // NOTE: This cloud segment overlaps text too much. Removed for now! + //cloudOutlinePath.StartFigure(); + //cloudOutlinePath.AddBezier(3317.5f, 2544.8f, 3317.5f, 2544f, 3317.6f, 2543.3f, 3317.6f, 2542.6f); + //cloudOutlinePath.AddBezier(3317.6f, 2542.6f, 3317.6f, 2438.1f, 3256.1f, 2342.8f, 3159.5f, 2297f); + + _cloudOutlinePath.StartFigure(); + _cloudOutlinePath.AddBezier(3460.5f, 2124.9f, 3491f, 2099.7f, 3515f, 2067.8f, 3530.9f, 2032f); + + _cloudOutlinePath.StartFigure(); + _cloudOutlinePath.AddBezier(3365.3f, 1732.2f, 3365.3f, 1731.1f, 3365.4f, 1730.1f, 3365.4f, 1729f); + _cloudOutlinePath.AddBezier(3365.4f, 1729f, 3365.4f, 1715.3f, 3364.1f, 1701.7f, 3361.6f, 1688.3f); + + _cloudOutlinePath.StartFigure(); + _cloudOutlinePath.AddBezier(2949.1f, 1580.9f, 2934.4f, 1597.8f, 2922.3f, 1616.6f, 2913.1f, 1636.9f); + _cloudOutlinePath.CloseFigure(); + + _cloudOutlinePath.StartFigure(); + _cloudOutlinePath.AddBezier(2590.9f, 1614.2f, 2583.1f, 1629.6f, 2577.2f, 1645.8f, 2573.4f, 1662.5f); + + _cloudOutlinePath.StartFigure(); + _cloudOutlinePath.AddBezier(2243.3f, 1727.5f, 2224.2f, 1709.4f, 2203f, 1693.8f, 2180.1f, 1680.7f); + + _cloudOutlinePath.StartFigure(); + _cloudOutlinePath.AddBezier(1688.8f, 1999f, 1691.1f, 2015.7f, 1694.8f, 2032.2f, 1699.9f, 2048.3f); + + _cloudOutlinePath.CloseAllFigures(); + + // Get cloud path bounds + _cloudBounds = _cloudPath.GetBounds(); + } + + // Translate and sacle original path to fit specified position + GraphicsPath resultPath = (GraphicsPath)_cloudPath.Clone(); + Matrix matrix = new Matrix(); + matrix.Translate(-_cloudBounds.X, -_cloudBounds.Y); + resultPath.Transform(matrix); + matrix = new Matrix(); + matrix.Translate(position.X, position.Y); + matrix.Scale(position.Width / _cloudBounds.Width, position.Height / _cloudBounds.Height); + resultPath.Transform(matrix); + + return resultPath; + } + + /// + /// Gets intersection point coordinates between point line and and horizontal + /// line specified by Y coordinate. + /// + /// First data point. + /// Second data point. + /// Y coordinate. + /// Intersection point coordinates. + internal static PointF GetIntersectionY(PointF firstPoint, PointF secondPoint, float pointY) + { + PointF intersectionPoint = new PointF(); + intersectionPoint.Y = pointY; + intersectionPoint.X = (pointY - firstPoint.Y) * + (secondPoint.X - firstPoint.X) / + (secondPoint.Y - firstPoint.Y) + + firstPoint.X; + return intersectionPoint; + } + + /// + /// Gets intersection point coordinates between point line and and vertical + /// line specified by X coordinate. + /// + /// First data point. + /// Second data point. + /// X coordinate. + /// Intersection point coordinates. + internal static PointF GetIntersectionX(PointF firstPoint, PointF secondPoint, float pointX) + { + PointF intersectionPoint = new PointF(); + intersectionPoint.X = pointX; + intersectionPoint.Y = (pointX - firstPoint.X) * + (secondPoint.Y - firstPoint.Y) / + (secondPoint.X - firstPoint.X) + + firstPoint.Y; + return intersectionPoint; + } + + /// + /// Adds a horizontal or vertical line into the path as multiple segments. + /// + /// Graphics path. + /// First point X coordinate. + /// First point Y coordinate. + /// Second point X coordinate. + /// Second point Y coordinate. + /// Number of segments to add. + private void PathAddLineAsSegments(GraphicsPath path, float x1, float y1, float x2, float y2, int segments) + { + if(x1 == x2) + { + float distance = (y2 - y1) / segments; + for(int index = 0; index < segments; index++) + { + path.AddLine(x1, y1, x1, y1 + distance); + y1 += distance; + } + } + else if(y1 == y2) + { + float distance = (x2 - x1) / segments; + for(int index = 0; index < segments; index++) + { + path.AddLine(x1, y1, x1 + distance, y1); + x1 += distance; + } + } + else + { + throw (new InvalidOperationException(SR.ExceptionAnnotationPathAddLineAsSegmentsInvalid)); + } + } + /// + /// Helper function which creates a rounded rectangle path. + /// Extra points are added on the sides to allow anchor connection. + /// + /// Rectangle coordinates. + /// Corner radius. + /// Graphics path object. + private GraphicsPath CreateRoundedRectPath(RectangleF rect, float cornerRadius) + { + // Create rounded rectangle path + GraphicsPath path = new GraphicsPath(); + int segments = 10; + PathAddLineAsSegments(path, rect.X+cornerRadius, rect.Y, rect.Right-cornerRadius, rect.Y, segments); + + path.AddArc(rect.Right-2f*cornerRadius, rect.Y, 2f*cornerRadius, 2f*cornerRadius, 270, 90); + + PathAddLineAsSegments(path, rect.Right, rect.Y + cornerRadius, rect.Right, rect.Bottom - cornerRadius, segments); + + path.AddArc(rect.Right-2f*cornerRadius, rect.Bottom-2f*cornerRadius, 2f*cornerRadius, 2f*cornerRadius, 0, 90); + + PathAddLineAsSegments(path, rect.Right-cornerRadius, rect.Bottom, rect.X + cornerRadius, rect.Bottom, segments); + + path.AddArc(rect.X, rect.Bottom-2f*cornerRadius, 2f*cornerRadius, 2f*cornerRadius, 90, 90); + + PathAddLineAsSegments(path, rect.X, rect.Bottom-cornerRadius, rect.X, rect.Y+cornerRadius, segments); + + path.AddArc(rect.X, rect.Y, 2f*cornerRadius, 2f*cornerRadius, 180, 90); + + return path; + } + + #endregion // Helper methods + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Annotation/GroupAnnotation.cs b/System.Web.DataVisualization/Common/Annotation/GroupAnnotation.cs new file mode 100644 index 000000000..cf4965e15 --- /dev/null +++ b/System.Web.DataVisualization/Common/Annotation/GroupAnnotation.cs @@ -0,0 +1,995 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: GroupAnnotation.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: AnnotationGroup +// +// Purpose: Annotation group class. +// +// Reviewed: +// +//=================================================================== + +#region Used namespace +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +#if Microsoft_CONTROL +using System.Windows.Forms; +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting + +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// AnnotationGroup is a class that represents an annotation group. + /// + /// + /// This class is a collection of annotations, and can be used + /// to manipulate annotations relative to each other. + /// + [ + SRDescription("DescriptionAttributeAnnotationGroup_AnnotationGroup"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class AnnotationGroup : Annotation + { + #region Fields + + // Collection of annotations in the group + internal AnnotationCollection annotations = null; + + #endregion + + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public AnnotationGroup() + : base() + { + annotations = new AnnotationCollection(this); + annotations.AnnotationGroup = this; + } + + #endregion + + #region Miscellaneous Properties + + /// + /// Gets or sets the name of the chart area which an annotation is clipped to. + /// + /// + /// A string which represents the name of an existing chart area. + /// + /// + /// If the chart area name is specified, an annotation will only be drawn inside the + /// plotting area of the chart area specified. All parts of the annotation + /// outside of the plotting area will be clipped. + /// + /// To disable chart area clipping, set the property to "NotSet" or an empty string. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(Constants.NotSetValue), + SRDescription("DescriptionAttributeAnnotationGroup_ClipToChartArea"), + TypeConverter(typeof(LegendAreaNameConverter)), + Browsable(false), + ] + override public string ClipToChartArea + { + get + { + return base.ClipToChartArea; + } + set + { + base.ClipToChartArea = value; + foreach(Annotation annotation in this.annotations) + { + annotation.ClipToChartArea = value; + } + } + } + + #endregion + + #region Position Properties + + /// + /// Gets or sets a flag that specifies whether the size of an annotation is always + /// defined in relative chart coordinates. + /// + /// + /// + /// + /// True if an annotation's and are always + /// in chart relative coordinates, false otherwise. + /// + /// + /// An annotation's width and height may be set in relative chart or axes coordinates. + /// By default, relative chart coordinates are used. + /// + /// To use axes coordinates for size set the IsSizeAlwaysRelative property to + /// false and either anchor the annotation to a data point or set the + /// or properties. + /// + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(true), + SRDescription("DescriptionAttributeAnnotationGroup_SizeAlwaysRelative"), + ] + override public bool IsSizeAlwaysRelative + { + get + { + return base.IsSizeAlwaysRelative; + } + set + { + base.IsSizeAlwaysRelative = value; + } + } + + #endregion + + #region Visual Properties + +#if Microsoft_CONTROL + /// + /// Gets or sets a flag that determines if an annotation is selected. + /// + /// + /// + /// True if the annotation is selected, false otherwise. + /// +#else + /// + /// Gets or sets a flag that determines if an annotation is selected. + /// + /// + /// True if the annotation is selected, false otherwise. + /// +#endif // Microsoft_CONTROL + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(false), + Browsable(false), + SRDescription("DescriptionAttributeAnnotationGroup_Selected"), + ] + override public bool IsSelected + { + get + { + return base.IsSelected; + } + set + { + base.IsSelected = value; + + // Clear selection for all annotations in the group + foreach(Annotation annotation in this.annotations) + { + annotation.IsSelected = false; + } + } + } + + /// + /// Gets or sets a flag that specifies whether an annotation is visible. + /// + /// + /// True if the annotation is visible, false otherwise. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(true), + SRDescription("DescriptionAttributeAnnotationGroup_Visible"), + ParenthesizePropertyNameAttribute(true), + ] + override public bool Visible + { + get + { + return base.Visible; + } + set + { + base.Visible = value; + } + } + + /// + /// Gets or sets an annotation's content alignment. + /// + /// + /// A value that represents the content alignment. + /// + /// + /// This property is used to align text for , , + /// and objects, and to align + /// a non-scaled image inside an object. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(ContentAlignment), "MiddleCenter"), + SRDescription("DescriptionAttributeAlignment"), + Browsable(false), + ] + override public ContentAlignment Alignment + { + get + { + return base.Alignment; + } + set + { + base.Alignment = value; + foreach(Annotation annotation in this.annotations) + { + annotation.Alignment = value; + } + } + } + + /// + /// Gets or sets an annotation's text style. + /// + /// + /// + /// + /// A value used to draw an annotation's text. + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override TextStyle TextStyle + { + get + { + return base.TextStyle; + } + set + { + base.TextStyle = value; + } + } + + /// + /// Gets or sets the text color of an annotation. + /// + /// + /// + /// A value used for the text color of an annotation. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeForeColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + Browsable(false), + ] + override public Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + foreach(Annotation annotation in this.annotations) + { + annotation.ForeColor = value; + } + } + } + + /// + /// Gets or sets the font of an annotation's text. + /// + /// + /// + /// A object used for an annotation's text. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"), + SRDescription("DescriptionAttributeTextFont"), + Browsable(false), + ] + override public Font Font + { + get + { + return base.Font; + } + set + { + base.Font = value; + foreach(Annotation annotation in this.annotations) + { + annotation.Font = value; + } + } + } + + /// + /// Gets or sets the color of an annotation line. + /// + /// + /// + /// + /// A value used to draw an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLineColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + Browsable(false), + ] + override public Color LineColor + { + get + { + return base.LineColor; + } + set + { + base.LineColor = value; + foreach(Annotation annotation in this.annotations) + { + annotation.LineColor = value; + } + } + } + + /// + /// Gets or sets the width of an annotation line. + /// + /// + /// + /// + /// An integer value defining the width of an annotation line in pixels. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(1), + SRDescription("DescriptionAttributeLineWidth"), + Browsable(false), + ] + override public int LineWidth + { + get + { + return base.LineWidth; + } + set + { + base.LineWidth = value; + foreach(Annotation annotation in this.annotations) + { + annotation.LineWidth = value; + } + } + } + + /// + /// Gets or sets the style of an annotation line. + /// + /// + /// + /// + /// A value used to draw an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeLineDashStyle"), + Browsable(false), + ] + override public ChartDashStyle LineDashStyle + { + get + { + return base.LineDashStyle; + } + set + { + base.LineDashStyle = value; + foreach(Annotation annotation in this.annotations) + { + annotation.LineDashStyle = value; + } + } + } + + /// + /// Gets or sets the background color of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + Browsable(false), + ] + override public Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + foreach(Annotation annotation in this.annotations) + { + annotation.BackColor = value; + } + } + } + + /// + /// Gets or sets the background hatch style of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + /// + /// Two colors are used to draw the hatching, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackHatchStyle"), + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base), + Browsable(false), + ] + override public ChartHatchStyle BackHatchStyle + { + get + { + return base.BackHatchStyle; + } + set + { + base.BackHatchStyle = value; + foreach(Annotation annotation in this.annotations) + { + annotation.BackHatchStyle = value; + } + } + } + + /// + /// Gets or sets the background gradient style of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + /// + /// Two colors are used to draw the gradient, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackGradientStyle"), + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base), + Browsable(false), + ] + override public GradientStyle BackGradientStyle + { + get + { + return base.BackGradientStyle; + } + set + { + base.BackGradientStyle = value; + foreach(Annotation annotation in this.annotations) + { + annotation.BackGradientStyle = value; + } + } + } + + /// + /// Gets or sets the secondary background color of an annotation. + /// + /// + /// + /// + /// + /// A value used for the secondary color of an annotation background with + /// hatching or gradient fill. + /// + /// + /// This color is used with when or + /// are used. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + Browsable(false), + ] + override public Color BackSecondaryColor + { + get + { + return base.BackSecondaryColor; + } + set + { + base.BackSecondaryColor = value; + foreach(Annotation annotation in this.annotations) + { + annotation.BackSecondaryColor = value; + } + } + } + + /// + /// Gets or sets the color of an annotation's shadow. + /// + /// + /// + /// A value used to draw an annotation's shadow. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), "128,0,0,0"), + SRDescription("DescriptionAttributeShadowColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + Browsable(false), + ] + override public Color ShadowColor + { + get + { + return base.ShadowColor; + } + set + { + base.ShadowColor = value; + foreach(Annotation annotation in this.annotations) + { + annotation.ShadowColor = value; + } + } + } + + /// + /// Gets or sets the offset between an annotation and its shadow. + /// + /// + /// + /// An integer value that represents the offset between an annotation and its shadow. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(0), + SRDescription("DescriptionAttributeShadowOffset"), + Browsable(false), + ] + override public int ShadowOffset + { + get + { + return base.ShadowOffset; + } + set + { + base.ShadowOffset = value; + foreach(Annotation annotation in this.annotations) + { + annotation.ShadowOffset = value; + } + } + } + + #endregion + + #region Editing Permissions Properties + +#if Microsoft_CONTROL + + /// + /// Gets or sets a flag that specifies whether an annotation may be selected + /// with a mouse by the end user. + /// + /// + /// True if the annotation may be selected, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAllowSelecting"), + ] + override public bool AllowSelecting + { + get + { + return base.AllowSelecting; + } + set + { + base.AllowSelecting = value; + } + } + + /// + /// Gets or sets a flag that specifies whether an annotation may be moved + /// with a mouse by the end user. + /// + /// + /// True if the annotation may be moved, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAllowMoving"), + ] + override public bool AllowMoving + { + get + { + return base.AllowMoving; + } + set + { + base.AllowMoving = value; + } + } + /// + /// Gets or sets a flag that specifies whether an annotation anchor may be moved + /// with a mouse by the end user. + /// + /// + /// True if the annotation anchor may be moved, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAnnotationGroup_AllowAnchorMoving"), + ] + override public bool AllowAnchorMoving + { + get + { + return base.AllowAnchorMoving; + } + set + { + base.AllowAnchorMoving = value; + } + } + + /// + /// Gets or sets a flag that specifies whether an annotation may be resized + /// with a mouse by the end user. + /// + /// + /// True if the annotation may be resized, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAllowResizing"), + ] + override public bool AllowResizing + { + get + { + return base.AllowResizing; + } + set + { + base.AllowResizing = value; + } + } + + /// + /// Gets or sets a flag that specifies whether an annotation's text may be edited + /// when the end user double clicks on the text. + /// + /// + /// True if the annotation text may be edited, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAllowTextEditing"), + ] + override public bool AllowTextEditing + { + get + { + return base.AllowTextEditing; + } + set + { + base.AllowTextEditing = value; + } + } + + /// + /// Gets or sets a flag that specifies whether a polygon annotation's points + /// may be moved with a mouse by the end user. + /// + /// + /// True if the polygon annotation's points may be moved, false otherwise. + /// + [ + SRCategory("CategoryAttributeEditing"), + DefaultValue(false), + SRDescription("DescriptionAttributeAnnotationGroup_AllowPathEditing"), + ] + override public bool AllowPathEditing + { + get + { + return base.AllowPathEditing; + } + set + { + base.AllowPathEditing = value; + } + } + +#endif // Microsoft_CONTROL + + #endregion + + #region Other Properties + + /// + /// Gets the collection of annotations in the group. + /// + /// + /// An object. + /// + /// + /// Note that the coordinates of all annotations in the group are relative to the + /// group annotation. + /// + [ + SRCategory("CategoryAttributeAnnotations"), + SRDescription("DescriptionAttributeAnnotationGroup_Annotations"), + Editor(Editors.AnnotationCollectionEditor.Editor, Editors.AnnotationCollectionEditor.Base), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else // Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif // Microsoft_CONTROL + ] + public AnnotationCollection Annotations + { + get + { + return annotations; + } + } + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "Group"; + } + } + + /// + /// Gets or sets annotation selection points style. + /// + /// + /// A value that represents annotation + /// selection style. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(SelectionPointsStyle.Rectangle), + ParenthesizePropertyNameAttribute(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeSelectionPointsStyle"), + ] + override internal SelectionPointsStyle SelectionPointsStyle + { + get + { + return SelectionPointsStyle.Rectangle; + } + } + + #endregion + + #region Methods + + /// + /// Paints an annotation object using the specified graphics. + /// + /// + /// A object, used to paint the annotation object. + /// + /// + /// Reference to the control. + /// + override internal void Paint(Chart chart, ChartGraphics graphics) + { + // Paint all annotations in the group + foreach(Annotation annotation in this.annotations) + { + annotation.Paint(chart, graphics); + } + + if( (this.Common.ProcessModePaint && this.IsSelected) || + this.Common.ProcessModeRegions ) + { + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height); + + // Create selection rectangle + RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y)); + + // Check rectangle orientation + if(selectionRect.Width < 0) + { + selectionRect.X = selectionRect.Right; + selectionRect.Width = -selectionRect.Width; + } + if(selectionRect.Height < 0) + { + selectionRect.Y = selectionRect.Bottom; + selectionRect.Height = -selectionRect.Height; + } + + // Check if text position is valid + if( selectionRect.IsEmpty || + float.IsNaN(selectionRect.X) || + float.IsNaN(selectionRect.Y) || + float.IsNaN(selectionRect.Right) || + float.IsNaN(selectionRect.Bottom) ) + { + return; + } + + if(this.Common.ProcessModeRegions) + { + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + selectionRect, + ReplaceKeywords(this.ToolTip), +#if Microsoft_CONTROL + String.Empty, + String.Empty, + String.Empty, +#else // Microsoft_CONTROL + ReplaceKeywords(this.Url), + ReplaceKeywords(this.MapAreaAttributes), + ReplaceKeywords(this.PostBackValue), +#endif // Microsoft_CONTROL + this, + ChartElementType.Annotation, + String.Empty); + } + + // Paint selection handles + PaintSelectionHandles(graphics, selectionRect, null); + } + } + + #endregion // Methods + + #region IDisposable override + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + //Clean up managed resources + if (this.annotations != null) + { + this.annotations.Dispose(); + this.annotations = null; + } + } + base.Dispose(disposing); + } + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Annotation/ImageAnnotation.cs b/System.Web.DataVisualization/Common/Annotation/ImageAnnotation.cs new file mode 100644 index 000000000..b19820f90 --- /dev/null +++ b/System.Web.DataVisualization/Common/Annotation/ImageAnnotation.cs @@ -0,0 +1,730 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ImageAnnotation.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ImageAnnotation +// +// Purpose: Image annotation classes. +// +// Reviewed: +// +//=================================================================== + +#region Used namespace +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +#if Microsoft_CONTROL +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting + +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// ImageAnnotation is a class that represents an image annotation. + /// + [ + SRDescription("DescriptionAttributeImageAnnotation_ImageAnnotation"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class ImageAnnotation : Annotation + { + #region Fields + + // Annotation image name + private string _imageName = String.Empty; + + // Image wrapping mode + private ChartImageWrapMode _imageWrapMode = ChartImageWrapMode.Scaled; + + // Image transparent color + private Color _imageTransparentColor = Color.Empty; + + #endregion + + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public ImageAnnotation() + : base() + { + } + + #endregion + + #region Properties + + #region Image properties + + /// + /// Gets or sets the name of an annotation's image. + /// + /// + /// + /// A string value representing the name of an annotation's image. + /// + /// + /// The name can be a file name, URL for the web control or a name from + /// the class. + /// + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(""), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + SRDescription("DescriptionAttributeImageAnnotation_Image"), + ] + public virtual string Image + { + get + { + return _imageName; + } + set + { + _imageName = value; + this.Invalidate(); + } + } + + + /// + /// Gets or sets the drawing mode of the image. + /// + /// + /// A value that defines the drawing mode of the image. + /// + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(ChartImageWrapMode.Scaled), + SRDescription("DescriptionAttributeImageWrapMode"), + ] + public ChartImageWrapMode ImageWrapMode + { + get + { + return _imageWrapMode; + } + set + { + _imageWrapMode = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a color which will be replaced with a transparent color while drawing the image. + /// + /// + /// A value which will be replaced with a transparent color while drawing the image. + /// + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + public Color ImageTransparentColor + { + get + { + return _imageTransparentColor; + } + set + { + _imageTransparentColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets an annotation's content alignment. + /// + /// + /// A value that represents the content alignment. + /// + /// + /// This property is used to align text for , , + /// and objects, and to align + /// a non-scaled image inside an object. + /// + [ + SRCategory("CategoryAttributeImage"), + DefaultValue(typeof(ContentAlignment), "MiddleCenter"), + SRDescription("DescriptionAttributeImageAnnotation_Alignment"), + ] + override public ContentAlignment Alignment + { + get + { + return base.Alignment; + } + set + { + base.Alignment = value; + Invalidate(); + } + } + + /// + /// Gets or sets an annotation's text style. + /// + /// + /// + /// + /// A value used to draw an annotation's text. + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override TextStyle TextStyle + { + get + { + return base.TextStyle; + } + set + { + base.TextStyle = value; + } + } + + #endregion // Image properties + + #region Other + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "Image"; + } + } + + /// + /// Gets or sets annotation selection points style. + /// + /// + /// A value that represents annotation + /// selection style. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(SelectionPointsStyle.Rectangle), + ParenthesizePropertyNameAttribute(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeSelectionPointsStyle"), + ] + override internal SelectionPointsStyle SelectionPointsStyle + { + get + { + return SelectionPointsStyle.Rectangle; + } + } + + #endregion + + #region Non Applicable Annotation Appearance Attributes (set as Non-Browsable) + + /// + /// Not applicable to this type of annotation. + /// + /// + /// + /// A value. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), "Black"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + } + } + + /// + /// Not applicable to this type of annotation. + /// + /// + /// A object. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"), + ] + override public Font Font + { + get + { + return base.Font; + } + set + { + base.Font = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + override public ChartHatchStyle BackHatchStyle + { + get + { + return base.BackHatchStyle; + } + set + { + base.BackHatchStyle = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + override public GradientStyle BackGradientStyle + { + get + { + return base.BackGradientStyle; + } + set + { + base.BackGradientStyle = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackSecondaryColor + { + get + { + return base.BackSecondaryColor; + } + set + { + base.BackSecondaryColor = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), "Black"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color LineColor + { + get + { + return base.LineColor; + } + set + { + base.LineColor = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(1), + Browsable(false), + SRDescription("DescriptionAttributeLineWidth"), + ] + override public int LineWidth + { + get + { + return base.LineWidth; + } + set + { + base.LineWidth = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeLineDashStyle"), + ] + override public ChartDashStyle LineDashStyle + { + get + { + return base.LineDashStyle; + } + set + { + base.LineDashStyle = value; + } + } + + + #endregion + + #endregion + + #region Methods + + #region Painting + + /// + /// Paints the annotation object on the specified graphics. + /// + /// + /// A object, used to paint the annotation object. + /// + /// + /// Reference to the owner control. + /// + override internal void Paint(Chart chart, ChartGraphics graphics) + { + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height); + + // Create selection rectangle + RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y)); + + // Get position + RectangleF rectanglePosition = new RectangleF(selectionRect.Location, selectionRect.Size); + if(rectanglePosition.Width < 0) + { + rectanglePosition.X = rectanglePosition.Right; + rectanglePosition.Width = -rectanglePosition.Width; + } + if(rectanglePosition.Height < 0) + { + rectanglePosition.Y = rectanglePosition.Bottom; + rectanglePosition.Height = -rectanglePosition.Height; + } + + // Check if position is valid + if( float.IsNaN(rectanglePosition.X) || + float.IsNaN(rectanglePosition.Y) || + float.IsNaN(rectanglePosition.Right) || + float.IsNaN(rectanglePosition.Bottom) ) + { + return; + } + + if(this.Common.ProcessModePaint) + { + // Draw "empty" image at design time + if(this._imageName.Length == 0 && this.Chart.IsDesignMode() ) + { + graphics.FillRectangleRel( + rectanglePosition, + this.BackColor, + this.BackHatchStyle, + this._imageName, + this._imageWrapMode, + this._imageTransparentColor, + GetImageAlignment(this.Alignment), + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + this.LineWidth, + this.LineDashStyle, + this.ShadowColor, + this.ShadowOffset, + PenAlignment.Center); + + // Draw text + using( Brush textBrush = new SolidBrush(this.ForeColor) ) + { + using (StringFormat format = new StringFormat(StringFormat.GenericTypographic)) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + format.FormatFlags = StringFormatFlags.LineLimit; + format.Trimming = StringTrimming.EllipsisCharacter; + graphics.DrawStringRel( + "(no image)", + this.Font, + textBrush, + rectanglePosition, + format); + } + } + } + else + { + // Draw image + graphics.FillRectangleRel( + rectanglePosition, + Color.Transparent, + this.BackHatchStyle, + this._imageName, + this._imageWrapMode, + this._imageTransparentColor, + GetImageAlignment(this.Alignment), + this.BackGradientStyle, + Color.Transparent, + Color.Transparent, + 0, + this.LineDashStyle, + this.ShadowColor, + this.ShadowOffset, + PenAlignment.Center); + } + } + + if(this.Common.ProcessModeRegions) + { + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + rectanglePosition, + ReplaceKeywords(this.ToolTip), +#if Microsoft_CONTROL + String.Empty, + String.Empty, + String.Empty, +#else // Microsoft_CONTROL + ReplaceKeywords(this.Url), + ReplaceKeywords(this.MapAreaAttributes), + ReplaceKeywords(this.PostBackValue), +#endif // Microsoft_CONTROL + this, + ChartElementType.Annotation, + String.Empty); + } + + // Paint selection handles + PaintSelectionHandles(graphics, selectionRect, null); + } + + /// + /// Coverts ContentAlignment enumeration to ChartImageAlignmentStyle enumeration. + /// + /// Content alignment. + /// Image content alignment. + private ChartImageAlignmentStyle GetImageAlignment(ContentAlignment alignment) + { + if(alignment == ContentAlignment.TopLeft) + { + return ChartImageAlignmentStyle.TopLeft; + } + else if(alignment == ContentAlignment.TopCenter) + { + return ChartImageAlignmentStyle.Top; + } + else if(alignment == ContentAlignment.TopRight) + { + return ChartImageAlignmentStyle.TopRight; + } + else if(alignment == ContentAlignment.MiddleRight) + { + return ChartImageAlignmentStyle.Right; + } + else if(alignment == ContentAlignment.BottomRight) + { + return ChartImageAlignmentStyle.BottomRight; + } + else if(alignment == ContentAlignment.BottomCenter) + { + return ChartImageAlignmentStyle.Bottom; + } + else if(alignment == ContentAlignment.BottomLeft) + { + return ChartImageAlignmentStyle.BottomLeft; + } + else if(alignment == ContentAlignment.MiddleLeft) + { + return ChartImageAlignmentStyle.Left; + } + return ChartImageAlignmentStyle.Center; + } + + #endregion // Painting + + #region Content Size + + /// + /// Gets text annotation content size based on the text and font. + /// + /// Annotation content position. + override internal RectangleF GetContentPosition() + { + // Check image size + if(this.Image.Length > 0) + { + // Try loading image and getting its size + try + { + if(this.Chart != null) + { + ImageLoader imageLoader = this.Common.ImageLoader; + + if(imageLoader != null) + { + ChartGraphics chartGraphics = this.GetGraphics(); + + if (chartGraphics != null) + { + SizeF absSize = new SizeF(); + + if (imageLoader.GetAdjustedImageSize(this.Image, chartGraphics.Graphics, ref absSize)) + { + SizeF imageSize = chartGraphics.GetRelativeSize(absSize); + return new RectangleF(float.NaN, float.NaN, imageSize.Width, imageSize.Height); + } + } + } + } + } + catch(ArgumentException) + { + // ArgumentException is thrown by LoadImage in certain situations when it can't load the image + } + } + + return new RectangleF(float.NaN, float.NaN, float.NaN, float.NaN); + } + + #endregion + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Annotation/LineAnnotation.cs b/System.Web.DataVisualization/Common/Annotation/LineAnnotation.cs new file mode 100644 index 000000000..358492888 --- /dev/null +++ b/System.Web.DataVisualization/Common/Annotation/LineAnnotation.cs @@ -0,0 +1,910 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: LineAnnotation.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: LineAnnotation, VerticalLineAnnotation, +// HorizontalLineAnnotation +// +// Purpose: Line annotation class. +// +// Reviewed: +// +//=================================================================== + +#region Used namespace +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// LineAnnotation is a class that represents a line annotation. + /// + [ + SRDescription("DescriptionAttributeLineAnnotation_LineAnnotation"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class LineAnnotation : Annotation + { + #region Fields + + // Indicates that an infinitive line should be drawn through 2 specified points. + private bool _isInfinitive = false; + + // Line start/end caps + private LineAnchorCapStyle _startCap = LineAnchorCapStyle.None; + private LineAnchorCapStyle _endCap = LineAnchorCapStyle.None; + + #endregion + + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public LineAnnotation() + : base() + { + this.anchorAlignment = ContentAlignment.TopLeft; + } + + #endregion + + #region Properties + + #region Line Visual Attributes + + /// + /// Gets or sets a flag that indicates if an infinitive line should be drawn. + /// + /// + /// True if a line should be drawn infinitively through 2 points provided, false otherwise. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(false), + SRDescription("DescriptionAttributeDrawInfinitive"), + ] + virtual public bool IsInfinitive + { + get + { + return _isInfinitive; + } + set + { + _isInfinitive = value; + Invalidate(); + } + } + + /// + /// Gets or sets a cap style used at the start of an annotation line. + /// + /// + /// + /// A value, used for a cap style used at the start of an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(LineAnchorCapStyle.None), + SRDescription("DescriptionAttributeStartCap3"), + ] + virtual public LineAnchorCapStyle StartCap + { + get + { + return _startCap; + } + set + { + _startCap = value; + Invalidate(); + } + } + + /// + /// Gets or sets a cap style used at the end of an annotation line. + /// + /// + /// + /// A value, used for a cap style used at the end of an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(LineAnchorCapStyle.None), + SRDescription("DescriptionAttributeStartCap3"), + ] + virtual public LineAnchorCapStyle EndCap + { + get + { + return _endCap; + } + set + { + _endCap = value; + Invalidate(); + } + } + + #endregion + + #region Non Applicable Annotation Appearance Attributes (set as Non-Browsable) + + /// + /// Not applicable to this annotation type. + /// + /// + /// A value. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(ContentAlignment), "MiddleCenter"), + ] + override public ContentAlignment Alignment + { + get + { + return base.Alignment; + } + set + { + base.Alignment = value; + } + } + + /// + /// Gets or sets an annotation's text style. + /// + /// + /// + /// + /// A value used to draw an annotation's text. + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override TextStyle TextStyle + { + get + { + return base.TextStyle; + } + set + { + base.TextStyle = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + /// + /// + /// A value. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeForeColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + /// + /// + /// A object. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"), + ] + override public Font Font + { + get + { + return base.Font; + } + set + { + base.Font = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + /// + /// A value. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + override public ChartHatchStyle BackHatchStyle + { + get + { + return base.BackHatchStyle; + } + set + { + base.BackHatchStyle = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + override public GradientStyle BackGradientStyle + { + get + { + return base.BackGradientStyle; + } + set + { + base.BackGradientStyle = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackSecondaryColor + { + get + { + return base.BackSecondaryColor; + } + set + { + base.BackSecondaryColor = value; + } + } + + #endregion + + #region Position + + /// + /// Gets or sets a flag that specifies whether the size of an annotation is always + /// defined in relative chart coordinates. + /// + /// + /// + /// + /// True if an annotation's and are always + /// in chart relative coordinates, false otherwise. + /// + /// + /// An annotation's width and height may be set in relative chart or axes coordinates. + /// By default, relative chart coordinates are used. + /// + /// To use axes coordinates for size set the IsSizeAlwaysRelative property to + /// false and either anchor the annotation to a data point or set the + /// or properties. + /// + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(true), + SRDescription("DescriptionAttributeSizeAlwaysRelative3"), + ] + override public bool IsSizeAlwaysRelative + { + get + { + return base.IsSizeAlwaysRelative; + } + set + { + base.IsSizeAlwaysRelative = value; + } + } + + #endregion // Position + + #region Anchor + + /// + /// Gets or sets an annotation position's alignment to the anchor point. + /// + /// + /// + /// + /// + /// + /// + /// A value that represents the annotation's alignment to + /// the anchor point. + /// + /// + /// The annotation must be anchored using either , or the + /// and properties. Its and + /// properties must be set to Double.NaN. + /// + [ + SRCategory("CategoryAttributeAnchor"), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DefaultValue(typeof(ContentAlignment), "TopLeft"), + SRDescription("DescriptionAttributeAnchorAlignment"), + ] + override public ContentAlignment AnchorAlignment + { + get + { + return base.AnchorAlignment; + } + set + { + base.AnchorAlignment = value; + } + } + + #endregion // Anchoring + + #region Other + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "Line"; + } + } + + /// + /// Gets or sets an annotation's selection points style. + /// + /// + /// A value that represents the annotation + /// selection style. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(SelectionPointsStyle.Rectangle), + ParenthesizePropertyNameAttribute(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeSelectionPointsStyle"), + ] + override internal SelectionPointsStyle SelectionPointsStyle + { + get + { + return SelectionPointsStyle.TwoPoints; + } + } + + #endregion + + #endregion + + #region Methods + + /// + /// Adjusts the two coordinates of the line. + /// + /// First line coordinate. + /// Second line coordinate. + /// Selection rectangle. + virtual internal void AdjustLineCoordinates(ref PointF point1, ref PointF point2, ref RectangleF selectionRect) + { + // Adjust line points to draw infinitive line + if(IsInfinitive) + { + if(Math.Round(point1.X , 3) == Math.Round(point2.X, 3)) + { + point1.Y = (point1.Y < point2.Y) ? 0f : 100f; + point2.Y = (point1.Y < point2.Y) ? 100f : 0f; + } + else if(Math.Round(point1.Y , 3) == Math.Round(point2.Y, 3)) + { + point1.X = (point1.X < point2.X) ? 0f : 100f; + point2.X = (point1.X < point2.X) ? 100f : 0f; + } + else + { + // Calculate intersection point of the line with two bounaries Y = 0 and Y = 100 + PointF intersectionPoint1 = PointF.Empty; + intersectionPoint1.Y = 0f; + intersectionPoint1.X = (0f - point1.Y) * + (point2.X - point1.X) / + (point2.Y - point1.Y) + + point1.X; + PointF intersectionPoint2 = PointF.Empty; + intersectionPoint2.Y = 100f; + intersectionPoint2.X = (100f - point1.Y) * + (point2.X - point1.X) / + (point2.Y - point1.Y) + + point1.X; + + // Select point closect to the intersection + point1 = (point1.Y < point2.Y) ? intersectionPoint1 : intersectionPoint2; + point2 = (point1.Y < point2.Y) ? intersectionPoint2 : intersectionPoint1; + } + } + } + + /// + /// Paints an annotation object on the specified graphics. + /// + /// + /// A object, used to paint an annotation object. + /// + /// + /// Reference to the owner control. + /// + override internal void Paint(Chart chart, ChartGraphics graphics) + { + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height); + + // Create selection rectangle + RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y)); + + // Adjust coordinates + AdjustLineCoordinates(ref firstPoint, ref secondPoint, ref selectionRect); + + // Check if text position is valid + if( float.IsNaN(firstPoint.X) || + float.IsNaN(firstPoint.Y) || + float.IsNaN(secondPoint.X) || + float.IsNaN(secondPoint.Y) ) + { + return; + } + + // Set line caps + bool capChanged = false; + LineCap oldStartCap = LineCap.Flat; + LineCap oldEndCap = LineCap.Flat; + if(this._startCap != LineAnchorCapStyle.None || + this._endCap != LineAnchorCapStyle.None) + { + capChanged = true; + oldStartCap = graphics.Pen.StartCap; + oldEndCap = graphics.Pen.EndCap; + + // Apply anchor cap settings + if(this._startCap == LineAnchorCapStyle.Arrow) + { + // Adjust arrow size for small line width + if(this.LineWidth < 4) + { + int adjustment = 3 - this.LineWidth; + graphics.Pen.StartCap = LineCap.Custom; + graphics.Pen.CustomStartCap = new AdjustableArrowCap( + this.LineWidth + adjustment, + this.LineWidth + adjustment, + true); + } + else + { + graphics.Pen.StartCap = LineCap.ArrowAnchor; + } + } + else if(this._startCap == LineAnchorCapStyle.Diamond) + { + graphics.Pen.StartCap = LineCap.DiamondAnchor; + } + else if(this._startCap == LineAnchorCapStyle.Round) + { + graphics.Pen.StartCap = LineCap.RoundAnchor; + } + else if(this._startCap == LineAnchorCapStyle.Square) + { + graphics.Pen.StartCap = LineCap.SquareAnchor; + } + if(this._endCap == LineAnchorCapStyle.Arrow) + { + // Adjust arrow size for small line width + if(this.LineWidth < 4) + { + int adjustment = 3 - this.LineWidth; + graphics.Pen.EndCap = LineCap.Custom; + graphics.Pen.CustomEndCap = new AdjustableArrowCap( + this.LineWidth + adjustment, + this.LineWidth + adjustment, + true); + } + else + { + graphics.Pen.EndCap = LineCap.ArrowAnchor; + } + } + else if(this._endCap == LineAnchorCapStyle.Diamond) + { + graphics.Pen.EndCap = LineCap.DiamondAnchor; + } + else if(this._endCap == LineAnchorCapStyle.Round) + { + graphics.Pen.EndCap = LineCap.RoundAnchor; + } + else if(this._endCap == LineAnchorCapStyle.Square) + { + graphics.Pen.EndCap = LineCap.SquareAnchor; + } + } + + if(this.Common.ProcessModePaint) + { + // Draw line + graphics.DrawLineRel( + this.LineColor, + this.LineWidth, + this.LineDashStyle, + firstPoint, + secondPoint, + this.ShadowColor, + this.ShadowOffset); + } + + if(this.Common.ProcessModeRegions) + { + // Create line graphics path + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLine( + graphics.GetAbsolutePoint(firstPoint), + graphics.GetAbsolutePoint(secondPoint)); + using (Pen pen = (Pen)graphics.Pen.Clone()) + { + // Increase pen size by 2 pixels + pen.DashStyle = DashStyle.Solid; + pen.Width += 2; + try + { + path.Widen(pen); + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + } + + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + graphics, + path, + false, + ReplaceKeywords(this.ToolTip), +#if Microsoft_CONTROL + String.Empty, + String.Empty, + String.Empty, +#else // Microsoft_CONTROL + ReplaceKeywords(this.Url), + ReplaceKeywords(this.MapAreaAttributes), + ReplaceKeywords(this.PostBackValue), +#endif // Microsoft_CONTROL + this, + ChartElementType.Annotation); + } + } + + + // Restore line caps + if(capChanged) + { + graphics.Pen.StartCap = oldStartCap; + graphics.Pen.EndCap = oldEndCap; + } + + // Paint selection handles + PaintSelectionHandles(graphics, selectionRect, null); + } + + #endregion + } + + /// + /// VerticalLineAnnotation is a class that represents a vertical line annotation. + /// + [ + SRDescription("DescriptionAttributeVerticalLineAnnotation_VerticalLineAnnotation"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class VerticalLineAnnotation : LineAnnotation + { + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public VerticalLineAnnotation() + : base() + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "VerticalLine"; + } + } + + #endregion + + #region Methods + + /// + /// Adjusts the two coordinates of the line. + /// + /// First line coordinate. + /// Second line coordinate. + /// Selection rectangle. + override internal void AdjustLineCoordinates(ref PointF point1, ref PointF point2, ref RectangleF selectionRect) + { + // Make line vertical + point2.X = point1.X; + selectionRect.Width = 0f; + + // Call base class + base.AdjustLineCoordinates(ref point1, ref point2, ref selectionRect); + } + + #region Content Size + + /// + /// Gets text annotation content size based on the text and font. + /// + /// Annotation content position. + override internal RectangleF GetContentPosition() + { + return new RectangleF(float.NaN, float.NaN, 0f, float.NaN); + } + + #endregion // Content Size + + #endregion + } + + /// + /// HorizontalLineAnnotation is a class that represents a horizontal line annotation. + /// + [ + SRDescription("DescriptionAttributeHorizontalLineAnnotation_HorizontalLineAnnotation"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class HorizontalLineAnnotation : LineAnnotation + { + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public HorizontalLineAnnotation() + : base() + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "HorizontalLine"; + } + } + + #endregion + + #region Methods + + /// + /// Adjusts the two coordinates of the line. + /// + /// First line coordinate. + /// Second line coordinate. + /// Selection rectangle. + override internal void AdjustLineCoordinates(ref PointF point1, ref PointF point2, ref RectangleF selectionRect) + { + // Make line horizontal + point2.Y = point1.Y; + selectionRect.Height = 0f; + + // Call base class + base.AdjustLineCoordinates(ref point1, ref point2, ref selectionRect); + } + + #region Content Size + + /// + /// Gets text annotation content size based on the text and font. + /// + /// Annotation content position. + override internal RectangleF GetContentPosition() + { + return new RectangleF(float.NaN, float.NaN, float.NaN, 0f); + } + + #endregion // Content Size + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Annotation/PolygonAnnotation.cs b/System.Web.DataVisualization/Common/Annotation/PolygonAnnotation.cs new file mode 100644 index 000000000..27ef81c12 --- /dev/null +++ b/System.Web.DataVisualization/Common/Annotation/PolygonAnnotation.cs @@ -0,0 +1,1739 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: RectangleAnnotation.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: PolylineAnnotation, PolygonAnnotation +// +// Purpose: Polyline and polygon annotation classes. +// +// Reviewed: +// +//=================================================================== + +#region Used namespace +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +using System.Diagnostics.CodeAnalysis; +#if Microsoft_CONTROL +using System.Windows.Forms; +using System.Globalization; +using System.Reflection; +using System.ComponentModel.Design.Serialization; +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; +using System.Collections.ObjectModel; + +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +using System.Web.UI.DataVisualization.Charting.Borders3D; +using System.Collections.ObjectModel; +#endif + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting + +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// PolylineAnnotation is a class that represents a polyline annotation. + /// + [ + SRDescription("DescriptionAttributePolylineAnnotation_PolylineAnnotation"), + ] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Polyline")] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class PolylineAnnotation : Annotation + { + #region Fields + + // Path with polygon points. + private GraphicsPath _defaultGraphicsPath = new GraphicsPath(); + private GraphicsPath _graphicsPath; + + // Indicates that path was changed + internal bool pathChanged = false; + + // Collection of path points exposed at design-time + private AnnotationPathPointCollection _pathPoints; + + // Indicate that filled polygon must be drawn + internal bool isPolygon = false; + + // Indicates that annotation will be placed using free-draw style + internal bool isFreeDrawPlacement = false; + + // Line start/end caps + private LineAnchorCapStyle _startCap = LineAnchorCapStyle.None; + private LineAnchorCapStyle _endCap = LineAnchorCapStyle.None; + + #endregion + + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public PolylineAnnotation() + : base() + { + _pathPoints = new AnnotationPathPointCollection(this); + + _graphicsPath = _defaultGraphicsPath; + } + + #endregion + + #region Properties + + #region Polyline Visual Attributes + + /// + /// Gets or sets a cap style used at the start of an annotation line. + /// + /// + /// + /// A value used for a cap style used at the start of an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(LineAnchorCapStyle.None), + SRDescription("DescriptionAttributeStartCap3"), + ] + virtual public LineAnchorCapStyle StartCap + { + get + { + return _startCap; + } + set + { + _startCap = value; + Invalidate(); + } + } + + /// + /// Gets or sets a cap style used at the end of an annotation line. + /// + /// + /// + /// A value used for a cap style used at the end of an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(LineAnchorCapStyle.None), + SRDescription("DescriptionAttributeStartCap3"), + ] + virtual public LineAnchorCapStyle EndCap + { + get + { + return _endCap; + } + set + { + _endCap = value; + Invalidate(); + } + } + + #endregion + + #region Non Applicable Annotation Appearance Attributes (set as Non-Browsable) + + /// + /// Not applicable to this annotation type. + /// + /// + /// A value. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(ContentAlignment), "MiddleCenter"), + ] + override public ContentAlignment Alignment + { + get + { + return base.Alignment; + } + set + { + base.Alignment = value; + } + } + + /// + /// Gets or sets an annotation's text style. + /// + /// + /// + /// + /// A value used to draw an annotation's text. + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override TextStyle TextStyle + { + get + { + return base.TextStyle; + } + set + { + base.TextStyle = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + /// + /// + /// A value. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeForeColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color ForeColor + { + get + { + return base.ForeColor; + } + set + { + base.ForeColor = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + /// + /// + /// A object. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"), + ] + override public Font Font + { + get + { + return base.Font; + } + set + { + base.Font = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + override public ChartHatchStyle BackHatchStyle + { + get + { + return base.BackHatchStyle; + } + set + { + base.BackHatchStyle = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + override public GradientStyle BackGradientStyle + { + get + { + return base.BackGradientStyle; + } + set + { + base.BackGradientStyle = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackSecondaryColor + { + get + { + return base.BackSecondaryColor; + } + set + { + base.BackSecondaryColor = value; + } + } + + #endregion + + #region Other + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "Polyline"; + } + } + + /// + /// Gets or sets an annotation selection points style. + /// + /// + /// A value that represents the annotation + /// selection style. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(SelectionPointsStyle.Rectangle), + ParenthesizePropertyNameAttribute(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeSelectionPointsStyle"), + ] + override internal SelectionPointsStyle SelectionPointsStyle + { + get + { + return SelectionPointsStyle.Rectangle; + } + } + + /// + /// Gets or sets a flag that determines whether an annotation should be placed using the free-draw mode. + /// + /// + /// True if an annotation should be placed using free-draw mode, + /// false otherwise. Defaults to false. + /// + /// + /// Two different placement modes are supported when the Annotation.BeginPlacement + /// method is called. Set this property to true to switch from the default + /// mode to free-draw mode, which allows the caller to free-draw while moving the mouse cursor. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(false), + SRDescription("DescriptionAttributeFreeDrawPlacement"), +#if !Microsoft_CONTROL + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never), +#endif // !Microsoft_CONTROL + ] + virtual public bool IsFreeDrawPlacement + { + get + { + return isFreeDrawPlacement; + } + set + { + isFreeDrawPlacement = value; + } + } + + /// + /// Gets or sets the path points of a polyline at run-time. + /// + /// + /// A object with the polyline shape. + /// + /// + /// A polyline must use coordinates relative to an annotation object, where (0,0) is + /// the top-left coordinates and (100,100) is the bottom-right coordinates of the annotation. + /// + /// This property is not accessible at design time (at design-time, use the + /// property instead). + /// + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(null), + SRDescription("DescriptionAttributePath"), + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + ] + virtual public GraphicsPath GraphicsPath + { + get + { + return _graphicsPath; + } + set + { + _graphicsPath = value; + this.pathChanged = true; + } + } + + /// + /// Gets or sets the path points of the polyline at design-time. + /// + /// + /// An object with the polyline shape. + /// + /// + /// A polyline must use coordinates relative to an annotation object, where (0,0) is + /// the top-left coordinates and (100,100) is the bottom-right coordinates of the annotation. + /// + /// This property is not accessible at runtime (at runtime, use the + /// property instead). + /// + /// + [ + SRCategory("CategoryAttributePosition"), + SRDescription("DescriptionAttributePathPoints"), + EditorBrowsableAttribute(EditorBrowsableState.Never), + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty) +#endif + ] + public AnnotationPathPointCollection GraphicsPathPoints + { + get + { + if(this.pathChanged || + _graphicsPath.PointCount != _pathPoints.Count) + { + // Recreate collection from graphics path + _pathPoints.annotation = null; + _pathPoints.Clear(); + if (_graphicsPath.PointCount > 0 ) + { + PointF[] points = _graphicsPath.PathPoints; + byte[] types = _graphicsPath.PathTypes; + for (int index = 0; index < points.Length; index++) + { + _pathPoints.Add(new AnnotationPathPoint(points[index].X, points[index].Y, types[index])); + } + } + _pathPoints.annotation = this; + } + return _pathPoints; + } + } + + #endregion + + #endregion + + #region Methods + + #region Painting + + /// + /// Paints an annotation object on the specified graphics. + /// + /// + /// A object, used to paint an annotation object. + /// + /// + /// Reference to the owner control. + /// + override internal void Paint(Chart chart, ChartGraphics graphics) + { + // Check for empty path + if(_graphicsPath.PointCount == 0) + { + return; + } + + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height); + + // Create selection rectangle + RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y)); + + // Get position + RectangleF rectanglePosition = new RectangleF(selectionRect.Location, selectionRect.Size); + if(rectanglePosition.Width < 0) + { + rectanglePosition.X = rectanglePosition.Right; + rectanglePosition.Width = -rectanglePosition.Width; + } + if(rectanglePosition.Height < 0) + { + rectanglePosition.Y = rectanglePosition.Bottom; + rectanglePosition.Height = -rectanglePosition.Height; + } + + // Check if position is valid + if( float.IsNaN(rectanglePosition.X) || + float.IsNaN(rectanglePosition.Y) || + float.IsNaN(rectanglePosition.Right) || + float.IsNaN(rectanglePosition.Bottom) ) + { + return; + } + + // Get annotation absolute position + RectangleF rectanglePositionAbs = graphics.GetAbsoluteRectangle(rectanglePosition); + + // Calculate scaling + float groupScaleX = rectanglePositionAbs.Width / 100.0f; + float groupScaleY = rectanglePositionAbs.Height / 100.0f; + + // Convert path to pixel coordinates + PointF[] pathPoints = _graphicsPath.PathPoints; + byte[] pathTypes = _graphicsPath.PathTypes; + for(int pointIndex = 0; pointIndex < pathPoints.Length; pointIndex++) + { + pathPoints[pointIndex].X = rectanglePositionAbs.X + pathPoints[pointIndex].X * groupScaleX; + pathPoints[pointIndex].Y = rectanglePositionAbs.Y + pathPoints[pointIndex].Y * groupScaleY; + } + + using (GraphicsPath pathAbs = new GraphicsPath(pathPoints, pathTypes)) + { + + // Set line caps + bool capChanged = false; + LineCap oldStartCap = LineCap.Flat; + LineCap oldEndCap = LineCap.Flat; + if (!this.isPolygon) + { + if (this._startCap != LineAnchorCapStyle.None || + this._endCap != LineAnchorCapStyle.None) + { + capChanged = true; + oldStartCap = graphics.Pen.StartCap; + oldEndCap = graphics.Pen.EndCap; + + // Apply anchor cap settings + if (this._startCap == LineAnchorCapStyle.Arrow) + { + // Adjust arrow size for small line width + if (this.LineWidth < 4) + { + int adjustment = 3 - this.LineWidth; + graphics.Pen.StartCap = LineCap.Custom; + graphics.Pen.CustomStartCap = new AdjustableArrowCap( + this.LineWidth + adjustment, + this.LineWidth + adjustment, + true); + } + else + { + graphics.Pen.StartCap = LineCap.ArrowAnchor; + } + } + else if (this._startCap == LineAnchorCapStyle.Diamond) + { + graphics.Pen.StartCap = LineCap.DiamondAnchor; + } + else if (this._startCap == LineAnchorCapStyle.Round) + { + graphics.Pen.StartCap = LineCap.RoundAnchor; + } + else if (this._startCap == LineAnchorCapStyle.Square) + { + graphics.Pen.StartCap = LineCap.SquareAnchor; + } + if (this._endCap == LineAnchorCapStyle.Arrow) + { + // Adjust arrow size for small line width + if (this.LineWidth < 4) + { + int adjustment = 3 - this.LineWidth; + graphics.Pen.EndCap = LineCap.Custom; + graphics.Pen.CustomEndCap = new AdjustableArrowCap( + this.LineWidth + adjustment, + this.LineWidth + adjustment, + true); + } + else + { + graphics.Pen.EndCap = LineCap.ArrowAnchor; + } + } + else if (this._endCap == LineAnchorCapStyle.Diamond) + { + graphics.Pen.EndCap = LineCap.DiamondAnchor; + } + else if (this._endCap == LineAnchorCapStyle.Round) + { + graphics.Pen.EndCap = LineCap.RoundAnchor; + } + else if (this._endCap == LineAnchorCapStyle.Square) + { + graphics.Pen.EndCap = LineCap.SquareAnchor; + } + } + } + + // Painting mode + if (this.Common.ProcessModePaint) + { + if (this.isPolygon) + { + // Draw polygon + pathAbs.CloseAllFigures(); + graphics.DrawPathAbs( + pathAbs, + this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + this.LineWidth, + this.LineDashStyle, + PenAlignment.Center, + this.ShadowOffset, + this.ShadowColor); + } + else + { + // Draw polyline + graphics.DrawPathAbs( + pathAbs, + Color.Transparent, + ChartHatchStyle.None, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + this.LineColor, + this.LineWidth, + this.LineDashStyle, + PenAlignment.Center, + this.ShadowOffset, + this.ShadowColor); + } + } + + if (this.Common.ProcessModeRegions) + { + // Create line graphics path + GraphicsPath selectionPath = null; + GraphicsPath newPath = null; + + if (this.isPolygon) + { + selectionPath = pathAbs; + } + else + { + newPath = new GraphicsPath(); + selectionPath = newPath; + selectionPath.AddPath(pathAbs, false); + using (Pen pen = (Pen)graphics.Pen.Clone()) + { + // Increase pen size by 2 pixels + pen.DashStyle = DashStyle.Solid; + pen.Width += 2; + try + { + selectionPath.Widen(pen); + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + } + } + + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + graphics, + selectionPath, + false, + ReplaceKeywords(this.ToolTip), +#if Microsoft_CONTROL + String.Empty, + String.Empty, + String.Empty, +#else // Microsoft_CONTROL + ReplaceKeywords(this.Url), + ReplaceKeywords(this.MapAreaAttributes), + ReplaceKeywords(this.PostBackValue), +#endif // Microsoft_CONTROL + this, + ChartElementType.Annotation); + + //Clean up + if (newPath != null) + newPath.Dispose(); + } + + // Restore line caps + if (capChanged) + { + graphics.Pen.StartCap = oldStartCap; + graphics.Pen.EndCap = oldEndCap; + } + + // Paint selection handles + PaintSelectionHandles(graphics, rectanglePosition, pathAbs); + } + } + + #endregion // Painting + + #region Position Changing +#if Microsoft_CONTROL + /// + /// Changes annotation position, so it exactly matches the bounary of the + /// polyline path. + /// + private void ResizeToPathBoundary() + { + if(_graphicsPath.PointCount > 0) + { + // Get current annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + + // Get path boundary and convert it to relative coordinates + RectangleF pathBoundary = _graphicsPath.GetBounds(); + pathBoundary.X *= size.Width / 100f; + pathBoundary.Y *= size.Height / 100f; + pathBoundary.X += firstPoint.X; + pathBoundary.Y += firstPoint.Y; + pathBoundary.Width *= size.Width / 100f; + pathBoundary.Height *= size.Height / 100f; + + // Scale all current points + using( Matrix matrix = new Matrix() ) + { + matrix.Scale(size.Width/pathBoundary.Width, size.Height/pathBoundary.Height); + matrix.Translate(-pathBoundary.X, -pathBoundary.Y); + _graphicsPath.Transform(matrix); + } + + // Set new position for annotation + this.SetPositionRelative(pathBoundary, anchorPoint); + } + } +#endif //Microsoft_CONTROL + /// + /// Adjust annotation location and\or size as a result of user action. + /// + /// Distance to resize/move the annotation. + /// Resizing mode. + /// Distance is in pixels, otherwise relative. + /// Indicates if position changing was a result of the user input. + override internal void AdjustLocationSize(SizeF movingDistance, ResizingMode resizeMode, bool pixelCoord, bool userInput) + { + // Call base class when not resizing the path points + if(resizeMode != ResizingMode.MovingPathPoints) + { + base.AdjustLocationSize(movingDistance, resizeMode, pixelCoord, userInput); + return; + } + + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + + // Remember path before moving operation + if(userInput == true && startMovePathRel == null) + { +#if Microsoft_CONTROL + this.startMovePathRel = (GraphicsPath)_graphicsPath.Clone(); + this.startMovePositionRel = new RectangleF(firstPoint, size); + this.startMoveAnchorLocationRel = new PointF(anchorPoint.X, anchorPoint.Y); + +#endif // Microsoft_CONTROL + } + + // Convert moving distance to coordinates relative to the anotation + if(pixelCoord) + { + movingDistance = this.GetGraphics().GetRelativeSize(movingDistance); + } + movingDistance.Width /= startMovePositionRel.Width / 100.0f; + movingDistance.Height /= startMovePositionRel.Height / 100.0f; + + // Get path points and adjust position of one of them + if(_graphicsPath.PointCount > 0) + { + GraphicsPath pathToMove = (userInput) ? startMovePathRel : _graphicsPath; + PointF[] pathPoints = pathToMove.PathPoints; + byte[] pathTypes = pathToMove.PathTypes; + + for(int pointIndex = 0; pointIndex < pathPoints.Length; pointIndex++) + { + // Adjust position + if( currentPathPointIndex == pointIndex || + currentPathPointIndex < 0 || + currentPathPointIndex >= pathPoints.Length ) + { + pathPoints[pointIndex].X -= movingDistance.Width; + pathPoints[pointIndex].Y -= movingDistance.Height; + } + } + +#if Microsoft_CONTROL + + // Adjust annotation position to the boundary of the path + if(userInput && this.AllowResizing) + { + // Get path bounds in relative coordinates + _defaultGraphicsPath.Dispose(); + _defaultGraphicsPath = new GraphicsPath(pathPoints, pathTypes); + _graphicsPath = _defaultGraphicsPath; + + RectangleF pathBounds = _graphicsPath.GetBounds(); + pathBounds.X *= startMovePositionRel.Width / 100f; + pathBounds.Y *= startMovePositionRel.Height / 100f; + pathBounds.X += startMovePositionRel.X; + pathBounds.Y += startMovePositionRel.Y; + pathBounds.Width *= startMovePositionRel.Width / 100f; + pathBounds.Height *= startMovePositionRel.Height / 100f; + + // Set new annotation position + this.SetPositionRelative(pathBounds, anchorPoint); + + // Adjust path point position + for(int pointIndex = 0; pointIndex < pathPoints.Length; pointIndex++) + { + + pathPoints[pointIndex].X = startMovePositionRel.X + pathPoints[pointIndex].X * (startMovePositionRel.Width / 100f); + pathPoints[pointIndex].Y = startMovePositionRel.Y + pathPoints[pointIndex].Y * (startMovePositionRel.Height / 100f); + + pathPoints[pointIndex].X = (pathPoints[pointIndex].X - pathBounds.X) / (pathBounds.Width / 100f); + pathPoints[pointIndex].Y = (pathPoints[pointIndex].Y - pathBounds.Y) / (pathBounds.Height / 100f); + } + } + +#endif // Microsoft_CONTROL + +#if Microsoft_CONTROL + // Position changed + this.positionChanged = true; +#endif // Microsoft_CONTROL + + // Recreate path with new points + _defaultGraphicsPath.Dispose(); + _defaultGraphicsPath = new GraphicsPath(pathPoints, pathTypes); + _graphicsPath = _defaultGraphicsPath; + this.pathChanged = true; + + // Invalidate annotation + this.Invalidate(); + } + } + + #endregion // Position Changing + + #region Placement Methods + +#if Microsoft_CONTROL + + /// + /// Ends user placement of an annotation. + /// + /// + /// Ends an annotation placement operation previously started by a + /// method call. + /// + /// Calling this method is not required, since placement will automatically + /// end when an end user enters all required points. However, it is useful when an annotation + /// placement operation needs to be aborted for some reason. + /// + /// + override public void EndPlacement() + { + // Call base method + base.EndPlacement(); + + // Position was changed + if(this.Chart != null) + { + this.Chart.OnAnnotationPositionChanged(this); + } + + // Reset last placement position + this.lastPlacementPosition = PointF.Empty; + + // Resize annotation to the boundary of the polygon + ResizeToPathBoundary(); + + // Position changed + this.positionChanged = true; + } + + /// + /// Handles mouse down event during annotation placement. + /// + /// Mouse cursor position in pixels. + /// Mouse button down. + internal override void PlacementMouseDown(PointF point, MouseButtons buttons) + { + // Call base class method if path editing is not allowed + if(!this.AllowPathEditing) + { + base.PlacementMouseDown(point, buttons); + return; + } + + if(buttons == MouseButtons.Right) + { + // Stop pacement + this.EndPlacement(); + } + if(buttons == MouseButtons.Left && + IsValidPlacementPosition(point.X, point.Y)) + { + // Convert coordinate to relative + PointF newPoint = this.GetGraphics().GetRelativePoint(point); + + if(this.lastPlacementPosition.IsEmpty) + { + // Set annotation coordinates to full chart + this.X = 0f; + this.Y = 0f; + this.Width = 100f; + this.Height = 100f; + + // Remeber position where mouse was clicked + this.lastPlacementPosition = newPoint; + } + else + { + if(this.lastPlacementPosition.X == newPoint.X && + this.lastPlacementPosition.Y == newPoint.Y) + { + // Stop pacement + this.EndPlacement(); + } + } + + // Add a line from prev. position to current into the path + using( GraphicsPath tmpPath = new GraphicsPath() ) + { + PointF firstPoint = this.lastPlacementPosition; + if(_graphicsPath.PointCount > 1) + { + firstPoint = _graphicsPath.GetLastPoint(); + } + tmpPath.AddLine(firstPoint, newPoint); + _graphicsPath.AddPath(tmpPath, true); + } + + // Remember last position + this.lastPlacementPosition = newPoint; + + // Invalidate and update the chart + if(Chart != null) + { + Invalidate(); + Chart.UpdateAnnotations(); + } + } + } + + /// + /// Handles mouse up event during annotation placement. + /// + /// Mouse cursor position in pixels. + /// Mouse button Up. + /// Return true when placing finished. + internal override bool PlacementMouseUp(PointF point, MouseButtons buttons) + { + // Call base class method if path editing is not allowed + if(!this.AllowPathEditing) + { + return base.PlacementMouseUp(point, buttons); + } + + if(buttons == MouseButtons.Left && + isFreeDrawPlacement) + { + // Stop pacement + this.EndPlacement(); + + } + + return false; + } + + /// + /// Handles mouse move event during annotation placement. + /// + /// Mouse cursor position in pixels. + internal override void PlacementMouseMove(PointF point) + { + // Call base class method if path editing is not allowed + if(!this.AllowPathEditing) + { + base.PlacementMouseMove(point); + return; + } + + // Check if annotation was moved + if( this.GetGraphics() != null && + _graphicsPath.PointCount > 0 && + !this.lastPlacementPosition.IsEmpty) + { + // Convert coordinate to relative + PointF newPoint = this.GetGraphics().GetRelativePoint(point); + if(this.isFreeDrawPlacement) + { + // Add new point + using( GraphicsPath tmpPath = new GraphicsPath() ) + { + PointF firstPoint = this.lastPlacementPosition; + if(_graphicsPath.PointCount > 1) + { + firstPoint = _graphicsPath.GetLastPoint(); + } + tmpPath.AddLine(firstPoint, newPoint); + _graphicsPath.AddPath(tmpPath, true); + } + } + else + { + // Adjust last point position + PointF[] pathPoints = _graphicsPath.PathPoints; + byte[] pathTypes = _graphicsPath.PathTypes; + pathPoints[pathPoints.Length - 1] = newPoint; + + _defaultGraphicsPath.Dispose(); + _defaultGraphicsPath = new GraphicsPath(pathPoints, pathTypes); + _graphicsPath = _defaultGraphicsPath; + + } + + // Position changed + this.positionChanged = true; + + // Invalidate and update the chart + if(this.Chart != null) + { + Invalidate(); + this.Chart.UpdateAnnotations(); + } + } + } + +#endif // Microsoft_CONTROL + + #endregion // Placement Methods + + #endregion + + #region IDisposable override + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_defaultGraphicsPath != null) + { + _defaultGraphicsPath.Dispose(); + _defaultGraphicsPath = null; + } + if (_pathPoints != null) + { + _pathPoints.Dispose(); + _pathPoints = null; + } + + } + base.Dispose(disposing); + } + #endregion + + } + + /// + /// PolygonAnnotation is a class that represents a polygon annotation. + /// + [ + SRDescription("DescriptionAttributePolygonAnnotation_PolygonAnnotation"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class PolygonAnnotation : PolylineAnnotation + { + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public PolygonAnnotation() + : base() + { + this.isPolygon = true; + } + + #endregion + + #region Properties + + #region Non Applicable Annotation Appearance Attributes (set as Non-Browsable) + + /// + /// Not applicable to this annotation type. + /// + /// + /// + /// A value. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(LineAnchorCapStyle.None), + ] + override public LineAnchorCapStyle StartCap + { + get + { + return base.StartCap; + } + set + { + base.StartCap = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + /// + /// + /// A value. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(LineAnchorCapStyle.None), + ] + override public LineAnchorCapStyle EndCap + { + get + { + return base.EndCap; + } + set + { + base.EndCap = value; + } + } + + #endregion + + #region Applicable Annotation Appearance Attributes (set as Browsable) + + /// + /// Gets or sets the background color of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + + /// + /// Gets or sets the background hatch style of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + /// + /// Two colors are used to draw the hatching, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackHatchStyle"), + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + override public ChartHatchStyle BackHatchStyle + { + get + { + return base.BackHatchStyle; + } + set + { + base.BackHatchStyle = value; + } + } + + /// + /// Gets or sets the background gradient style of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + /// + /// Two colors are used to draw the gradient, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackGradientStyle"), + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + override public GradientStyle BackGradientStyle + { + get + { + return base.BackGradientStyle; + } + set + { + base.BackGradientStyle = value; + } + } + + /// + /// Gets or sets the secondary background color of an annotation. + /// + /// + /// + /// + /// + /// A value used for the secondary color of an annotation background with + /// hatching or gradient fill. + /// + /// + /// This color is used with when or + /// are used. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackSecondaryColor + { + get + { + return base.BackSecondaryColor; + } + set + { + base.BackSecondaryColor = value; + } + } + + #endregion + + #region Other + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "Polygon"; + } + } + + /// + /// Gets or sets an annotation's selection points style. + /// + /// + /// A value that represents an annotation's + /// selection style. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(SelectionPointsStyle.Rectangle), + ParenthesizePropertyNameAttribute(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeSelectionPointsStyle"), + ] + override internal SelectionPointsStyle SelectionPointsStyle + { + get + { + return SelectionPointsStyle.Rectangle; + } + } + + #endregion + + #endregion + } + + /// AnnotationPathPointCollection is a collection of polyline + /// annotation path points, and is only available via the GraphicsPathPoints + /// property at design-time. + /// + /// + /// This collection is used at design-time only, and uses serialization to expose the + /// shape of the polyline and polygon via their GraphicsPathPoints collection property. + /// At run-time, use Path property to set the path of a polyline or polygon + /// + [ + SRDescription("DescriptionAttributeAnnotationPathPointCollection_AnnotationPathPointCollection"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class AnnotationPathPointCollection : ChartElementCollection + { + #region Fields + + internal PolylineAnnotation annotation = null; + private GraphicsPath _graphicsPath = null; + + #endregion // Fields + + #region Constructors + + /// + /// Default public constructor. + /// + public AnnotationPathPointCollection(PolylineAnnotation annotation) + : base(annotation) + { + this.annotation = annotation; + } + + #endregion // Constructors + + #region Methods + + /// + /// Forces the invalidation of the chart element + /// + public override void Invalidate() + { + if (this.annotation != null) + { + //Dispose previously instantiated graphics path + if (this._graphicsPath != null) + { + this._graphicsPath.Dispose(); + this._graphicsPath = null; + } + + // Recreate polyline annotation path + if (this.Count > 0) + { + PointF[] points = new PointF[this.Count]; + byte[] types = new byte[this.Count]; + for (int index = 0; index < this.Count; index++) + { + points[index] = new PointF(this[index].X, this[index].Y); + types[index] = this[index].PointType; + } + this._graphicsPath = new GraphicsPath(points, types); + } + else + { + this._graphicsPath = new GraphicsPath(); + } + + // Invalidate annotation + this.annotation.GraphicsPath = this._graphicsPath; + this.annotation.Invalidate(); + } + base.Invalidate(); + } + + #endregion // Methods + + #region IDisposable Members + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Free up managed resources + if (this._graphicsPath != null) + { + this._graphicsPath.Dispose(); + this._graphicsPath = null; + } + } + base.Dispose(disposing); + } + + #endregion + } + + /// + /// The AnnotationPathPoint class represents a path point of a polyline or polygon, + /// and is stored in their GraphicsPathPoints property, which is only available at design-time. + /// + /// + /// At run-time, use Path property to set the path of a polyline or polygon. + /// + [ + SRDescription("DescriptionAttributeAnnotationPathPoint_AnnotationPathPoint"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class AnnotationPathPoint: ChartElement + { + #region Fields + + // Point X value + private float _x = 0f; + + // Point Y value + private float _y = 0f; + + // Point type + private byte _pointType = 1; + + #endregion // Fields + + #region Constructors + + /// + /// Default public constructor. + /// + public AnnotationPathPoint() + { + } + + /// + /// Constructor that takes X and Y parameters. + /// + /// Point's X value. + /// Point's Y value. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification="X and Y are cartesian coordinates and well understood")] + public AnnotationPathPoint(float x, float y) + { + this._x = x; + this._y = y; + } + + /// + /// Constructor that takes X, Y and point type parameters. + /// + /// Point's X value. + /// Point's Y value. + /// Point type. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public AnnotationPathPoint(float x, float y, byte type) + { + this._x = x; + this._y = y; + this._pointType = type; + } + + #endregion // Constructors + + #region Properties + + /// + /// Gets or sets an annotation path point's X coordinate. + /// + /// + /// A float value for the point's X coordinate. + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(0f), + Browsable(true), + SRDescription("DescriptionAttributeAnnotationPathPoint_X"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + ] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "X")] + public float X + { + get + { + return _x; + } + set + { + _x = value; + } + } + + /// + /// Gets or sets an annotation path point's Y coordinate. + /// + /// + /// A float value for the point's Y coordinate. + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(0f), + Browsable(true), + SRDescription("DescriptionAttributeAnnotationPathPoint_Y"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + ] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Y")] + public float Y + { + get + { + return _y; + } + set + { + _y = value; + } + } + + /// + /// Gets or sets an annotation path point's type. + /// + /// + /// A byte value. + /// + /// + /// See the enumeration for more details. + /// + [ + SRCategory("CategoryAttributePosition"), + DefaultValue(typeof(byte), "1"), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + SRDescription("DescriptionAttributeAnnotationPathPoint_Name"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + ] + public byte PointType + { + get + { + return _pointType; + } + set + { + _pointType = value; + } + } + + /// + /// Gets or sets an annotation path point's name. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue("PathPoint"), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + SRDescription("DescriptionAttributeAnnotationPathPoint_Name"), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + ] + public string Name + { + get + { + return "PathPoint"; + } + } + + #endregion // Properties + + } +} diff --git a/System.Web.DataVisualization/Common/Annotation/RectangleAnnotation.cs b/System.Web.DataVisualization/Common/Annotation/RectangleAnnotation.cs new file mode 100644 index 000000000..870235e74 --- /dev/null +++ b/System.Web.DataVisualization/Common/Annotation/RectangleAnnotation.cs @@ -0,0 +1,722 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: RectangleAnnotation.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: RectangleAnnotation, EllipseAnnotation, +// Border3DAnnotation +// +// Purpose: Rectangle, Ellipse and 3DBorder annotation classes. +// +// Reviewed: +// +//=================================================================== + + +#region Used namespace +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +#if Microsoft_CONTROL +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting + +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// RectangleAnnotation is a class that represents a rectangle annotation. + /// + /// + /// A rectangle annotation can also display text inside the rectangle. + /// + [ + SRDescription("DescriptionAttributeRectangleAnnotation_RectangleAnnotation"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class RectangleAnnotation : TextAnnotation + { + #region Fields + + // Indicates that annotion rectangle should be drawn + internal bool isRectVisible = true; + + #endregion + + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public RectangleAnnotation() + : base() + { + } + + #endregion + + #region Properties + + #region Applicable Annotation Appearance Attributes (set as Browsable) + + /// + /// Gets or sets the color of an annotation line. + /// + /// + /// + /// + /// A value used to draw an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLineColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color LineColor + { + get + { + return base.LineColor; + } + set + { + base.LineColor = value; + } + } + + /// + /// Gets or sets the width of an annotation line. + /// + /// + /// + /// + /// An integer value defining the width of an annotation line in pixels. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeLineWidth"), + ] + override public int LineWidth + { + get + { + return base.LineWidth; + } + set + { + base.LineWidth = value; + + } + } + + /// + /// Gets or sets the style of an annotation line. + /// + /// + /// + /// + /// A value used to draw an annotation line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeLineDashStyle"), + ] + override public ChartDashStyle LineDashStyle + { + get + { + return base.LineDashStyle; + } + set + { + base.LineDashStyle = value; + } + } + + /// + /// Gets or sets the background color of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + + /// + /// Gets or sets the background hatch style of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + /// + /// Two colors are used to draw the hatching, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackHatchStyle"), + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + override public ChartHatchStyle BackHatchStyle + { + get + { + return base.BackHatchStyle; + } + set + { + base.BackHatchStyle = value; + } + } + + /// + /// Gets or sets the background gradient style of an annotation. + /// + /// + /// + /// + /// + /// A value used for the background of an annotation. + /// + /// + /// Two colors are used to draw the gradient, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackGradientStyle"), + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + override public GradientStyle BackGradientStyle + { + get + { + return base.BackGradientStyle; + } + set + { + base.BackGradientStyle = value; + } + } + + /// + /// Gets or sets the secondary background color of an annotation. + /// + /// + /// + /// + /// + /// A value used for the secondary color of an annotation background with + /// hatching or gradient fill. + /// + /// + /// This color is used with when or + /// are used. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackSecondaryColor + { + get + { + return base.BackSecondaryColor; + } + set + { + base.BackSecondaryColor = value; + } + } + + #endregion + + #region Other + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "Rectangle"; + } + } + + /// + /// Gets or sets an annotation's selection points style. + /// + /// + /// A value that represents the annotation + /// selection style. + /// + /// + /// This property is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(SelectionPointsStyle.Rectangle), + ParenthesizePropertyNameAttribute(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeSelectionPointsStyle"), + ] + override internal SelectionPointsStyle SelectionPointsStyle + { + get + { + return SelectionPointsStyle.Rectangle; + } + } + + #endregion + + #endregion + + #region Methods + + /// + /// Paints an annotation object on the specified graphics. + /// + /// + /// A object, used to paint an annotation object. + /// + /// + /// Reference to the control. + /// + override internal void Paint(Chart chart, ChartGraphics graphics) + { + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height); + + // Create selection rectangle + RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y)); + + // Get text position + RectangleF rectanglePosition = new RectangleF(selectionRect.Location, selectionRect.Size); + if(rectanglePosition.Width < 0) + { + rectanglePosition.X = rectanglePosition.Right; + rectanglePosition.Width = -rectanglePosition.Width; + } + if(rectanglePosition.Height < 0) + { + rectanglePosition.Y = rectanglePosition.Bottom; + rectanglePosition.Height = -rectanglePosition.Height; + } + + // Check if position is valid + if( float.IsNaN(rectanglePosition.X) || + float.IsNaN(rectanglePosition.Y) || + float.IsNaN(rectanglePosition.Right) || + float.IsNaN(rectanglePosition.Bottom) ) + { + return; + } + + if(this.isRectVisible && + this.Common.ProcessModePaint) + { + // Draw rectangle + graphics.FillRectangleRel( + rectanglePosition, + this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + this.LineWidth, + this.LineDashStyle, + this.ShadowColor, + this.ShadowOffset, + PenAlignment.Center, + this.isEllipse, + 1, + false); + } + + // Call base class to paint text, selection handles and process hot regions + base.Paint(chart, graphics); + } + + #endregion + } + + /// + /// EllipseAnnotation is a class that represents an ellipse annotation. + /// + /// + /// An ellipse annotation can also display text inside the ellipse. + /// + [ + SRDescription("DescriptionAttributeEllipseAnnotation_EllipseAnnotation"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class EllipseAnnotation : RectangleAnnotation + { + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public EllipseAnnotation() + : base() + { + this.isEllipse = true; + } + + #endregion + + #region Properties + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "Ellipse"; + } + } + + #endregion + } + + + /// + /// Border3DAnnotation is a class that represents an annotation with a 3D border. + /// + /// + /// A Border3D annotation can also display inner text. + /// + [ + SRDescription("DescriptionAttributeBorder3DAnnotation_Border3DAnnotation"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class Border3DAnnotation : RectangleAnnotation + { + #region Fields + + // 3D border properties + private BorderSkin _borderSkin; + + #endregion + + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public Border3DAnnotation() + : base() + { + this.isRectVisible = false; + this._borderSkin = new BorderSkin(this); + this._borderSkin.PageColor = Color.Transparent; + this._borderSkin.SkinStyle = BorderSkinStyle.Raised; + + // Change default appearance styles + this.lineColor = Color.Empty; + } + + #endregion + + #region Properties + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeAnnotationType"), + ] + public override string AnnotationType + { + get + { + return "Border3D"; + } + } + + /// + /// Gets or sets the skin style of the 3D border. + /// + /// + /// A + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(null), + SRDescription("DescriptionAttributeBorderSkin"), + NotifyParentPropertyAttribute(true), + TypeConverterAttribute(typeof(LegendConverter)), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content) + ] + public BorderSkin BorderSkin + { + get + { + return _borderSkin; + } + set + { + _borderSkin = value; + this.Invalidate(); + } + } + + #endregion + + #region Methods + + /// + /// Paints the annotation object on the specified graphics. + /// + /// + /// A + /// + /// + /// Reference to the control that owns the annotation. + /// + override internal void Paint(Chart chart, ChartGraphics graphics) + { + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height); + + // Create selection rectangle + RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y)); + + // Get text position + RectangleF rectanglePosition = new RectangleF(selectionRect.Location, selectionRect.Size); + if(rectanglePosition.Width < 0) + { + rectanglePosition.X = rectanglePosition.Right; + rectanglePosition.Width = -rectanglePosition.Width; + } + if(rectanglePosition.Height < 0) + { + rectanglePosition.Y = rectanglePosition.Bottom; + rectanglePosition.Height = -rectanglePosition.Height; + } + + // Check if position is valid + if( float.IsNaN(rectanglePosition.X) || + float.IsNaN(rectanglePosition.Y) || + float.IsNaN(rectanglePosition.Right) || + float.IsNaN(rectanglePosition.Bottom) ) + { + return; + } + + if(this.Common.ProcessModePaint) + { + // Do not draw border if size is less that 10 pixels + RectangleF absRectanglePosition = graphics.GetAbsoluteRectangle(rectanglePosition); + if(absRectanglePosition.Width > 30f && + absRectanglePosition.Height > 30f) + { + // Draw rectangle + graphics.Draw3DBorderRel( + _borderSkin, + rectanglePosition, + this.BackColor, + this.BackHatchStyle, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + this.BackGradientStyle, + this.BackSecondaryColor, + this.LineColor, + this.LineWidth, + this.LineDashStyle); + } + } + + // Call base class to paint text, selection handles and process hot regions + base.Paint(chart, graphics); + } + + /// + /// Gets text spacing on four different sides in relative coordinates. + /// + /// Indicates that spacing is in annotation relative coordinates. + /// Rectangle with text spacing values. + internal override RectangleF GetTextSpacing(out bool annotationRelative) + { + annotationRelative = false; + RectangleF rect = new RectangleF(3f, 3f, 3f, 3f); + if(GetGraphics() != null) + { + rect = GetGraphics().GetRelativeRectangle(rect); + } + + if(_borderSkin.SkinStyle != BorderSkinStyle.None && + this.GetGraphics() != null && + this.Chart != null && + this.Chart.chartPicture != null && + this.Common != null) + { + IBorderType border3D = this.Common.BorderTypeRegistry.GetBorderType(_borderSkin.SkinStyle.ToString()); + if(border3D != null) + { + // Adjust are position to the border size + RectangleF rectangle = new RectangleF(0f, 0f, 100f, 100f); + border3D.AdjustAreasPosition(this.GetGraphics(), ref rectangle); + rect = new RectangleF( + rectangle.X + 1, + rectangle.Y + 1, + 100f - rectangle.Right + 2, + 100f - rectangle.Bottom + 2); + } + } + + return rect; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Annotation/TextAnnotation.cs b/System.Web.DataVisualization/Common/Annotation/TextAnnotation.cs new file mode 100644 index 000000000..f53f82c72 --- /dev/null +++ b/System.Web.DataVisualization/Common/Annotation/TextAnnotation.cs @@ -0,0 +1,1263 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: TextAnnotation.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: TextAnnotation, AnnotationSmartLabelStyle +// +// Purpose: Text annotation class. +// +// Reviewed: +// +//=================================================================== + +#region Used namespace +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +using System.Security; + +#if Microsoft_CONTROL +using System.Windows.Forms; + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// TextAnnotation is a class that represents a text annotation. + /// + /// + /// Note that other annotations do display inner text (e.g. rectangle, + /// ellipse annotations.). + /// + [ + SRDescription("DescriptionAttributeTextAnnotation_TextAnnotation"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class TextAnnotation : Annotation + { + #region Fields + + // Annotation text + private string _text = ""; + + // Indicates multiline text + private bool _isMultiline = false; + + // Current content size + internal SizeF contentSize = SizeF.Empty; + + // Indicates that annotion is an ellipse + internal bool isEllipse = false; + +#if Microsoft_CONTROL + + // Control used to edit text + private TextBox _editTextBox = null; + +#endif // Microsoft_CONTROL + + #endregion + + #region Construction and Initialization + + /// + /// Default public constructor. + /// + public TextAnnotation() + : base() + { + } + + #endregion + + #region Properties + + #region Text Visual Attributes + + /// + /// Annotation's text. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(""), + SRDescription("DescriptionAttributeText"), + ] + virtual public string Text + { + get + { + return _text; + } + set + { + _text = value; + Invalidate(); + + // Reset content size to empty + contentSize = SizeF.Empty; + } + } + + /// + /// Indicates whether the annotation text is multiline. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(false), + SRDescription("DescriptionAttributeMultiline"), + ] + virtual public bool IsMultiline + { + get + { + return _isMultiline; + } + set + { + _isMultiline = value; + Invalidate(); + } + } + + /// + /// Gets or sets the font of an annotation's text. + /// + /// + /// + /// A object used for an annotation's text. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"), + SRDescription("DescriptionAttributeTextFont4"), + ] + override public Font Font + { + get + { + return base.Font; + } + set + { + base.Font = value; + + // Reset content size to empty + contentSize = SizeF.Empty; + } + } + + #endregion + + #region Non Applicable Annotation Appearance Attributes (set as Non-Browsable) + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), "Black"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color LineColor + { + get + { + return base.LineColor; + } + set + { + base.LineColor = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(1), + SRDescription("DescriptionAttributeLineWidth"), + ] + override public int LineWidth + { + get + { + return base.LineWidth; + } + set + { + base.LineWidth = value; + + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(ChartDashStyle.Solid), + ] + override public ChartDashStyle LineDashStyle + { + get + { + return base.LineDashStyle; + } + set + { + base.LineDashStyle = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + override public ChartHatchStyle BackHatchStyle + { + get + { + return base.BackHatchStyle; + } + set + { + base.BackHatchStyle = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + override public GradientStyle BackGradientStyle + { + get + { + return base.BackGradientStyle; + } + set + { + base.BackGradientStyle = value; + } + } + + /// + /// Not applicable to this annotation type. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color BackSecondaryColor + { + get + { + return base.BackSecondaryColor; + } + set + { + base.BackSecondaryColor = value; + } + } + + #endregion + + #region Other + + /// + /// Gets or sets an annotation's type name. + /// + /// + /// This property is used to get the name of each annotation type + /// (e.g. Line, Rectangle, Ellipse). + /// + /// This property is for internal use and is hidden at design and run time. + /// + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeTextAnnotation_AnnotationType"), + ] + public override string AnnotationType + { + get + { + return "Text"; + } + } + + /// + /// Annotation selection points style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(SelectionPointsStyle.Rectangle), + ParenthesizePropertyNameAttribute(true), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeSelectionPointsStyle"), + ] + override internal SelectionPointsStyle SelectionPointsStyle + { + get + { + return SelectionPointsStyle.Rectangle; + } + } + + #endregion + + #endregion + + #region Methods + + #region Painting + + /// + /// Paints an annotation object on the specified graphics. + /// + /// + /// A object, used to paint an annotation object. + /// + /// + /// Reference to the owner control. + /// + override internal void Paint(Chart chart, ChartGraphics graphics) + { + // Get annotation position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height); + + // Create selection rectangle + RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y)); + + // Get text position + RectangleF textPosition = new RectangleF(selectionRect.Location, selectionRect.Size); + if(textPosition.Width < 0) + { + textPosition.X = textPosition.Right; + textPosition.Width = -textPosition.Width; + } + if(textPosition.Height < 0) + { + textPosition.Y = textPosition.Bottom; + textPosition.Height = -textPosition.Height; + } + + // Check if text position is valid + if( textPosition.IsEmpty || + float.IsNaN(textPosition.X) || + float.IsNaN(textPosition.Y) || + float.IsNaN(textPosition.Right) || + float.IsNaN(textPosition.Bottom) ) + { + return; + } + + if(this.Common.ProcessModePaint) + { + DrawText(graphics, textPosition, false, false); + } + + if(this.Common.ProcessModeRegions) + { + // Add hot region + if(isEllipse) + { + using (GraphicsPath ellipsePath = new GraphicsPath()) + { + ellipsePath.AddEllipse(textPosition); + this.Common.HotRegionsList.AddHotRegion( + graphics, + ellipsePath, + true, + ReplaceKeywords(this.ToolTip), +#if Microsoft_CONTROL + String.Empty, + String.Empty, + String.Empty, +#else // Microsoft_CONTROL + ReplaceKeywords(this.Url), + ReplaceKeywords(this.MapAreaAttributes), + ReplaceKeywords(this.PostBackValue), +#endif // Microsoft_CONTROL + this, + ChartElementType.Annotation); + } + } + else + { + this.Common.HotRegionsList.AddHotRegion( + textPosition, + ReplaceKeywords(this.ToolTip), +#if Microsoft_CONTROL + String.Empty, + String.Empty, + String.Empty, +#else // Microsoft_CONTROL + ReplaceKeywords(this.Url), + ReplaceKeywords(this.MapAreaAttributes), + ReplaceKeywords(this.PostBackValue), +#endif // Microsoft_CONTROL + this, + ChartElementType.Annotation, + String.Empty); + } + } + + // Paint selection handles + PaintSelectionHandles(graphics, selectionRect, null); + } + + /// + /// Draws text in specified rectangle. + /// + /// Chart graphics. + /// Text position. + /// True if text allowed to be outside of position when centered. + /// True if position text must be returned by the method. + /// Text actual position if required. + internal RectangleF DrawText(ChartGraphics graphics, RectangleF textPosition, bool noSpacingForCenteredText, bool getTextPosition) + { + RectangleF textActualPosition = RectangleF.Empty; + + //*************************************************************** + //** Adjust text position uing text spacing + //*************************************************************** + bool annotationRelative = false; + RectangleF textSpacing = GetTextSpacing(out annotationRelative); + float spacingScaleX = 1f; + float spacingScaleY = 1f; + if(annotationRelative) + { + if(textPosition.Width > 25f) + { + spacingScaleX = textPosition.Width / 50f; + spacingScaleX = Math.Max(1f, spacingScaleX); + } + if(textPosition.Height > 25f) + { + spacingScaleY = textPosition.Height / 50f; + spacingScaleY = Math.Max(1f, spacingScaleY); + } + } + + RectangleF textPositionWithSpacing = new RectangleF(textPosition.Location, textPosition.Size); + textPositionWithSpacing.Width -= (textSpacing.Width + textSpacing.X) * spacingScaleX; + textPositionWithSpacing.X += textSpacing.X * spacingScaleX; + textPositionWithSpacing.Height -= (textSpacing.Height + textSpacing.Y) * spacingScaleY; + textPositionWithSpacing.Y += textSpacing.Y * spacingScaleY; + + //*************************************************************** + //** Replace new line characters + //*************************************************************** + string titleText = this.ReplaceKeywords(this.Text.Replace("\\n", "\n")); + + //*************************************************************** + //** Check if centered text require spacing. + //** Use only half of the spacing required. + //** Apply only for 1 line of text. + //*************************************************************** + if(noSpacingForCenteredText && + titleText.IndexOf('\n') == -1) + { + if(this.Alignment == ContentAlignment.MiddleCenter || + this.Alignment == ContentAlignment.MiddleLeft || + this.Alignment == ContentAlignment.MiddleRight) + { + textPositionWithSpacing.Y = textPosition.Y; + textPositionWithSpacing.Height = textPosition.Height; + textPositionWithSpacing.Height -= textSpacing.Height/2f + textSpacing.Y / 2f; + textPositionWithSpacing.Y += textSpacing.Y / 2f; + } + if(this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.MiddleCenter || + this.Alignment == ContentAlignment.TopCenter) + { + textPositionWithSpacing.X = textPosition.X; + textPositionWithSpacing.Width = textPosition.Width; + textPositionWithSpacing.Width -= textSpacing.Width/2f + textSpacing.X / 2f; + textPositionWithSpacing.X += textSpacing.X / 2f; + } + } + + // Draw text + using( Brush textBrush = new SolidBrush(this.ForeColor) ) + { + using (StringFormat format = new StringFormat(StringFormat.GenericTypographic)) + { + //*************************************************************** + //** Set text format + //*************************************************************** + format.FormatFlags = format.FormatFlags ^ StringFormatFlags.LineLimit; + format.Trimming = StringTrimming.EllipsisCharacter; + if (this.Alignment == ContentAlignment.BottomRight || + this.Alignment == ContentAlignment.MiddleRight || + this.Alignment == ContentAlignment.TopRight) + { + format.Alignment = StringAlignment.Far; + } + if (this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.MiddleCenter || + this.Alignment == ContentAlignment.TopCenter) + { + format.Alignment = StringAlignment.Center; + } + if (this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.BottomLeft || + this.Alignment == ContentAlignment.BottomRight) + { + format.LineAlignment = StringAlignment.Far; + } + if (this.Alignment == ContentAlignment.MiddleCenter || + this.Alignment == ContentAlignment.MiddleLeft || + this.Alignment == ContentAlignment.MiddleRight) + { + format.LineAlignment = StringAlignment.Center; + } + + //*************************************************************** + //** Set shadow color and offset + //*************************************************************** + Color textShadowColor = ChartGraphics.GetGradientColor(this.ForeColor, Color.Black, 0.8); + int textShadowOffset = 1; + TextStyle textStyle = this.TextStyle; + if (textStyle == TextStyle.Shadow && + ShadowOffset != 0) + { + // Draw shadowed text + textShadowColor = ShadowColor; + textShadowOffset = ShadowOffset; + } + + if (textStyle == TextStyle.Shadow) + { + textShadowColor = (textShadowColor.A != 255) ? textShadowColor : Color.FromArgb(textShadowColor.A / 2, textShadowColor); + } + + //*************************************************************** + //** Get text actual position + //*************************************************************** + if (getTextPosition) + { + // Measure text size + SizeF textSize = graphics.MeasureStringRel( + this.ReplaceKeywords(_text.Replace("\\n", "\n")), + this.Font, + textPositionWithSpacing.Size, + format); + + // Get text position + textActualPosition = new RectangleF(textPositionWithSpacing.Location, textSize); + if (this.Alignment == ContentAlignment.BottomRight || + this.Alignment == ContentAlignment.MiddleRight || + this.Alignment == ContentAlignment.TopRight) + { + textActualPosition.X += textPositionWithSpacing.Width - textSize.Width; + } + if (this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.MiddleCenter || + this.Alignment == ContentAlignment.TopCenter) + { + textActualPosition.X += (textPositionWithSpacing.Width - textSize.Width) / 2f; + } + if (this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.BottomLeft || + this.Alignment == ContentAlignment.BottomRight) + { + textActualPosition.Y += textPositionWithSpacing.Height - textSize.Height; + } + if (this.Alignment == ContentAlignment.MiddleCenter || + this.Alignment == ContentAlignment.MiddleLeft || + this.Alignment == ContentAlignment.MiddleRight) + { + textActualPosition.Y += (textPositionWithSpacing.Height - textSize.Height) / 2f; + } + + // Do not allow text to go outside annotation position + textActualPosition.Intersect(textPositionWithSpacing); + } + + RectangleF absPosition = graphics.GetAbsoluteRectangle(textPositionWithSpacing); + Title.DrawStringWithStyle( + graphics, + titleText, + this.TextStyle, + this.Font, + absPosition, + this.ForeColor, + textShadowColor, + textShadowOffset, + format, + TextOrientation.Auto + ); + } + } + + return textActualPosition; + } + + #endregion // Painting + + #region Text Editing + +#if Microsoft_CONTROL + + /// + /// Stops editing of the annotation text. + /// + /// + /// + /// Call this method to cancel text editing, which was started via a call to + /// the method, or after the end-user double-clicks + /// on the annotation. + /// + public void StopTextEditing() + { + // Check if text is currently edited + if(_editTextBox != null) + { + // Set annotation text + this.Text = _editTextBox.Text; + + // Remove and dispose the text box + try + { + _editTextBox.KeyDown -= new KeyEventHandler(OnTextBoxKeyDown); + _editTextBox.LostFocus -= new EventHandler(OnTextBoxLostFocus); + } + catch(SecurityException) + { + // Ignore security issues + } + + if(this.Chart.Controls.Contains(_editTextBox)) + { + TextBox tempControl = null; + try + { + // NOTE: Workaround .Net bug. Issue with appplication closing if + // active control is removed. + Form parentForm = this.Chart.FindForm(); + if(parentForm != null) + { + tempControl = new TextBox(); + tempControl.Visible = false; + + // Add temp. control as active + parentForm.Controls.Add(tempControl); + parentForm.ActiveControl = tempControl; + } + } + catch(SecurityException) + { + // Ignore security issues + } + + // Remove text editor + this.Chart.Controls.Remove(_editTextBox); + + // Dispose temp. text box + if(tempControl != null) + { + tempControl.Dispose(); + } + } + + // Dispose edit box + _editTextBox.Dispose(); + _editTextBox = null; + + // Raise notification event + if(this.Chart != null) + { + this.Chart.OnAnnotationTextChanged(this); + } + + // Update chart + if(this.Chart != null) + { + this.Chart.Invalidate(); + this.Chart.Update(); + } + + } + } + + /// + /// Handles event when focus is lost by the text editing control. + /// + /// Event sender. + /// Event arguments. + private void OnTextBoxLostFocus(object sender, EventArgs e) + { + StopTextEditing(); + } + + /// + /// Handles event when key is pressed in the text editing control. + /// + /// Event sender. + /// Event arguments. + private void OnTextBoxKeyDown(object sender, KeyEventArgs e) + { + if(e.KeyCode == Keys.Escape) + { + // Reset text and stop editing + _editTextBox.Text = this.Text; + StopTextEditing(); + } + else if(e.KeyCode == Keys.Enter && + this.IsMultiline == false) + { + // Stop editing + StopTextEditing(); + } + } + + /// + /// Begins editing the annotation's text by an end user. + /// + /// + /// + /// After calling this method, the annotation displays an editing box which allows + /// for editing of the annotation's text. + /// + /// Call the method to cancel this mode programatically. + /// Note that editing ends when the end-user hits the Enter key if multi-line + /// is false, or when the end-user clicks outside of the editing box if multi-line is true. + /// + /// + public void BeginTextEditing() + { + + if(this.Chart != null && this.AllowTextEditing) + { + // Dispose previous text box + if(_editTextBox != null) + { + if(this.Chart.Controls.Contains(_editTextBox)) + { + this.Chart.Controls.Remove(_editTextBox); + } + _editTextBox.Dispose(); + _editTextBox = null; + } + + // Create a text box inside the chart + _editTextBox = new TextBox(); + _editTextBox.Text = this.Text; + _editTextBox.Multiline = this.IsMultiline; + _editTextBox.Font = this.Font; + _editTextBox.BorderStyle = BorderStyle.FixedSingle; + _editTextBox.BackColor = Color.FromArgb(255, (this.BackColor.IsEmpty) ? Color.White : this.BackColor); + _editTextBox.ForeColor = Color.FromArgb(255, this.ForeColor); + + // Calculate text position in relative coordinates + PointF firstPoint = PointF.Empty; + PointF anchorPoint = PointF.Empty; + SizeF size = SizeF.Empty; + GetRelativePosition(out firstPoint, out size, out anchorPoint); + PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height); + RectangleF textPosition = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y)); + if(textPosition.Width < 0) + { + textPosition.X = textPosition.Right; + textPosition.Width = -textPosition.Width; + } + if(textPosition.Height < 0) + { + textPosition.Y = textPosition.Bottom; + textPosition.Height = -textPosition.Height; + } + + // Set text control position in pixels + if(GetGraphics() != null) + { + // Convert point to relative coordinates + textPosition = GetGraphics().GetAbsoluteRectangle(textPosition); + } + + // Adjust Location and Size + if(this.IsMultiline) + { + textPosition.X -= 1; + textPosition.Y -= 1; + textPosition.Width += 2; + textPosition.Height += 2; + } + else + { + textPosition.Y += textPosition.Height / 2f - _editTextBox.Size.Height / 2f; + } + _editTextBox.Location = Point.Round(textPosition.Location); + _editTextBox.Size = Size.Round(textPosition.Size); + + // Add control to the chart + this.Chart.Controls.Add(_editTextBox); + try + { + _editTextBox.SelectAll(); + _editTextBox.Focus(); + } + catch(SecurityException) + { + // Ignore security issues + } + + try + { + // Set text box event hanlers + _editTextBox.KeyDown += new KeyEventHandler(OnTextBoxKeyDown); + _editTextBox.LostFocus += new EventHandler(OnTextBoxLostFocus); + } + catch(SecurityException) + { + // Ignore security issues + } + } + } + +#endif // Microsoft_CONTROL + + #endregion // Text Editing + + #region Content Size + + /// + /// Gets text annotation content size based on the text and font. + /// + /// Annotation content position. + override internal RectangleF GetContentPosition() + { + // Return pre calculated value + if(!contentSize.IsEmpty) + { + return new RectangleF(float.NaN, float.NaN, contentSize.Width, contentSize.Height); + } + + // Create temporary bitmap based chart graphics if chart was not + // rendered yet and the graphics was not created. + // NOTE: Fix for issue #3978. + Graphics graphics = null; +System.Drawing.Image graphicsImage = null; + ChartGraphics tempChartGraph = null; + if(GetGraphics() == null && this.Common != null) + { + graphicsImage = new System.Drawing.Bitmap(Common.ChartPicture.Width, Common.ChartPicture.Height); + graphics = Graphics.FromImage( graphicsImage ); + tempChartGraph = new ChartGraphics( Common ); + tempChartGraph.Graphics = graphics; + tempChartGraph.SetPictureSize( Common.ChartPicture.Width, Common.ChartPicture.Height ); + this.Common.graph = tempChartGraph; + } + + // Calculate content size + RectangleF result = RectangleF.Empty; + if(GetGraphics() != null && this.Text.Trim().Length > 0) + { + // Measure text using current font and slightly increase it + contentSize = GetGraphics().MeasureString( + "W" + this.ReplaceKeywords(this.Text.Replace("\\n", "\n")), + this.Font, + new SizeF(2000, 2000), + StringFormat.GenericTypographic); + + contentSize.Height *= 1.04f; + + // Convert to relative coordinates + contentSize = GetGraphics().GetRelativeSize(contentSize); + + // Add spacing + bool annotationRelative = false; + RectangleF textSpacing = GetTextSpacing(out annotationRelative); + float spacingScaleX = 1f; + float spacingScaleY = 1f; + if(annotationRelative) + { + if(contentSize.Width > 25f) + { + spacingScaleX = contentSize.Width / 25f; + spacingScaleX = Math.Max(1f, spacingScaleX); + } + if(contentSize.Height > 25f) + { + spacingScaleY = contentSize.Height / 25f; + spacingScaleY = Math.Max(1f, spacingScaleY); + } + } + + contentSize.Width += (textSpacing.X + textSpacing.Width) * spacingScaleX; + contentSize.Height += (textSpacing.Y + textSpacing.Height) * spacingScaleY; + + result = new RectangleF(float.NaN, float.NaN, contentSize.Width, contentSize.Height); + } + + // Dispose temporary chart graphics + if(tempChartGraph != null) + { + tempChartGraph.Dispose(); + graphics.Dispose(); + graphicsImage.Dispose(); + this.Common.graph = null; + } + + return result; + } + + /// + /// Gets text spacing on four different sides in relative coordinates. + /// + /// Indicates that spacing is in annotation relative coordinates. + /// Rectangle with text spacing values. + internal virtual RectangleF GetTextSpacing(out bool annotationRelative) + { + annotationRelative = false; + RectangleF rect = new RectangleF(3f, 3f, 3f, 3f); + if(GetGraphics() != null) + { + rect = GetGraphics().GetRelativeRectangle(rect); + } + return rect; + } + + #endregion + + #region Placement Methods + +#if Microsoft_CONTROL + + /// + /// Ends user placement of an annotation. + /// + /// + /// Ends an annotation placement operation previously started by a + /// method call. + /// + /// Calling this method is not required, since placement will automatically + /// end when an end user enters all required points. However, it is useful when an annotation + /// placement operation needs to be aborted for some reason. + /// + /// + override public void EndPlacement() + { + // Check if text editing is allowed + // Maybe changed later in the EndPlacement method. + bool allowTextEditing = this.AllowTextEditing; + + // Call base class + base.EndPlacement(); + + // Begin text editing + if(this.Chart != null) + { + this.Chart.Annotations.lastClickedAnnotation = this; + if(allowTextEditing) + { + BeginTextEditing(); + } + } + } + +#endif // Microsoft_CONTROL + + #endregion // Placement Methods + + #endregion // Methods + } + + /// + /// The AnnotationSmartLabelStyle class is used to store an annotation's smart + /// labels properties. + /// + /// + /// + /// This class is derived from the SmartLabelStyle class + /// used for Series objects. + /// + [ + DefaultProperty("Enabled"), + SRDescription("DescriptionAttributeAnnotationSmartLabelsStyle_AnnotationSmartLabelsStyle"), + TypeConverter(typeof(NoNameExpandableObjectConverter)), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class AnnotationSmartLabelStyle : SmartLabelStyle + { + #region Constructors and initialization + + /// + /// Default public constructor. + /// + public AnnotationSmartLabelStyle() + { + this.chartElement = null; + } + + /// + /// Constructor. + /// + /// + /// Chart element this style belongs to. + /// + public AnnotationSmartLabelStyle(Object chartElement) : base(chartElement) + { + } + + #endregion + + #region Non Applicable Appearance Attributes (set as Non-Browsable) + + + /// + /// Callout style of the repositioned smart labels. + /// + /// + /// This method is for internal use and is hidden at design time and runtime. + /// + [ + SRCategory("CategoryAttributeMisc"), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DefaultValue(LabelCalloutStyle.Underlined), + SRDescription("DescriptionAttributeCalloutStyle3"), + ] + override public LabelCalloutStyle CalloutStyle + { + get + { + return base.CalloutStyle; + } + set + { + base.CalloutStyle = value; + } + } + + /// + /// Label callout line color. + /// + /// + /// This method is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeCalloutLineColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color CalloutLineColor + { + get + { + return base.CalloutLineColor; + } + set + { + base.CalloutLineColor = value; + } + } + + /// + /// Label callout line style. + /// + /// + /// This method is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeLineDashStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + override public ChartDashStyle CalloutLineDashStyle + { + get + { + return base.CalloutLineDashStyle; + } + set + { + base.CalloutLineDashStyle = value; + } + } + + /// + /// Label callout back color. Applies to the Box style only. + /// + /// + /// This method is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DefaultValue(typeof(Color), "Transparent"), + SRDescription("DescriptionAttributeCalloutBackColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + override public Color CalloutBackColor + { + get + { + return base.CalloutBackColor; + } + set + { + base.CalloutBackColor = value; + } + } + + /// + /// Label callout line width. + /// + /// + /// This method is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DefaultValue(1), + SRDescription("DescriptionAttributeLineWidth"), + ] + override public int CalloutLineWidth + { + get + { + return base.CalloutLineWidth; + } + set + { + base.CalloutLineWidth = value; + } + } + + /// + /// Label callout line anchor cap. + /// + /// + /// This method is for internal use and is hidden at design and run time. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DefaultValue(LineAnchorCapStyle.Arrow), + SRDescription("DescriptionAttributeCalloutLineAnchorCapStyle"), + ] + override public LineAnchorCapStyle CalloutLineAnchorCapStyle + { + get + { + return base.CalloutLineAnchorCapStyle; + } + set + { + base.CalloutLineAnchorCapStyle = value; + } + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Borders3D/Borders3D.cs b/System.Web.DataVisualization/Common/Borders3D/Borders3D.cs new file mode 100644 index 000000000..64c6d5575 --- /dev/null +++ b/System.Web.DataVisualization/Common/Borders3D/Borders3D.cs @@ -0,0 +1,784 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: Borders3D.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// System.Web.UI.WebControls[Windows.Forms].Charting.Borders3D +// +// Classes: BorderTypeRegistry, IBorderType, BorderSkin +// +// Purpose: 3D borders related classes: +// BorderTypeRegistry - known borders registry. +// IBorderType - border class interface. +// BorderSkin - border visual properties. +// +// Reviewed: AG - August 7, 2002 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Design; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Resources; +using System.Reflection; +using System.IO; +using System.Drawing.Imaging; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +using System.Windows.Forms.Design; +#else + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Border style enumeration + + /// + /// Styles of the border skin. + /// + public enum BorderSkinStyle + { + /// + /// Border not used. + /// + None, + /// + /// Emboss border. + /// + Emboss, + /// + /// Raised border. + /// + Raised, + /// + /// Sunken border. + /// + Sunken, + /// + /// Thin border with rounded corners. + /// + FrameThin1, + /// + /// Thin border with rounded top corners. + /// + FrameThin2, + /// + /// Thin border with square corners. + /// + FrameThin3, + /// + /// Thin border with square outside corners and rounded inside corners. + /// + FrameThin4, + /// + /// Thin border with rounded corners and ----s. + /// + FrameThin5, + /// + /// Thin border with square inside corners and rounded outside corners. + /// + FrameThin6, + /// + /// Border with rounded corners. Supports title text. + /// + FrameTitle1, + /// + /// Border with rounded top corners. Supports title text. + /// + FrameTitle2, + /// + /// Border with square corners. Supports title text. + /// + FrameTitle3, + /// + /// Border with rounded inside corners and square outside corners. Supports title text. + /// + FrameTitle4, + /// + /// Border with rounded corners and ----s. Supports title text. + /// + FrameTitle5, + /// + /// Border with rounded outside corners and square inside corners. Supports title text. + /// + FrameTitle6, + /// + /// Border with rounded corners. No border on the right side. Supports title text. + /// + FrameTitle7, + /// + /// Border with rounded corners on top and bottom sides only. Supports title text. + /// + FrameTitle8 + } + + #endregion + + /// + /// Drawing properties of the 3D border skin. + /// + [ + DefaultProperty("SkinStyle"), + SRDescription("DescriptionAttributeBorderSkin_BorderSkin"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class BorderSkin : ChartElement + { + #region Fields + + // Private data members, which store properties values + private Color _pageColor = Color.White; + private BorderSkinStyle _skinStyle = BorderSkinStyle.None; + private GradientStyle _backGradientStyle = GradientStyle.None; + private Color _backSecondaryColor = Color.Empty; + private Color _backColor = Color.Gray; + private string _backImage = ""; + private ChartImageWrapMode _backImageWrapMode = ChartImageWrapMode.Tile; + private Color _backImageTransparentColor = Color.Empty; + private ChartImageAlignmentStyle _backImageAlignment = ChartImageAlignmentStyle.TopLeft; + private Color _borderColor = Color.Black; + private int _borderWidth = 1; + private ChartDashStyle _borderDashStyle = ChartDashStyle.NotSet; + private ChartHatchStyle _backHatchStyle = ChartHatchStyle.None; + + #endregion + + #region Constructors + + /// + /// Default public constructor. + /// + public BorderSkin() : base() + { + } + + /// + /// Constructor. + /// + /// The parent chart element. + internal BorderSkin(IChartElement parent) : base (parent) + { + } + + #endregion + + #region Border skin properties + + /// + /// Gets or sets the page color of a border skin. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(typeof(Color), "White"), + SRDescription("DescriptionAttributeBorderSkin_PageColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color PageColor + { + get + { + return _pageColor; + } + set + { + _pageColor = value; + this.Invalidate(); + } + } + + + /// + /// Gets or sets the style of a border skin. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(BorderSkinStyle.None), + SRDescription("DescriptionAttributeBorderSkin_SkinStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ParenthesizePropertyNameAttribute(true) + ] + public BorderSkinStyle SkinStyle + { + get + { + return _skinStyle; + } + set + { + _skinStyle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background color of a skin frame. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(typeof(Color), "Gray"), + SRDescription("DescriptionAttributeFrameBackColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackColor + { + get + { + return _backColor; + } + set + { + _backColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the border color of a skin frame. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeBorderColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BorderColor + { + get + { + return _borderColor; + } + set + { + _borderColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background hatch style of a skin frame. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(ChartHatchStyle.None), + SRDescription("DescriptionAttributeFrameBackHatchStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + public ChartHatchStyle BackHatchStyle + { + get + { + return _backHatchStyle; + } + set + { + _backHatchStyle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background image of a skin frame. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(""), + SRDescription("DescriptionAttributeBackImage"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public string BackImage + { + get + { + return _backImage; + } + set + { + _backImage = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the drawing mode for the background image of a skin frame. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(ChartImageWrapMode.Tile), + SRDescription("DescriptionAttributeImageWrapMode"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageWrapMode BackImageWrapMode + { + get + { + return _backImageWrapMode; + } + set + { + _backImageWrapMode = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a color which will be replaced with a transparent color + /// while drawing the background image of a skin frame. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackImageTransparentColor + { + get + { + return _backImageTransparentColor; + } + set + { + _backImageTransparentColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background image alignment of a skin frame. + /// + /// + /// Used by ClampUnscale drawing mode. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(ChartImageAlignmentStyle.TopLeft), + SRDescription("DescriptionAttributeBackImageAlign"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageAlignmentStyle BackImageAlignment + { + get + { + return _backImageAlignment; + } + set + { + _backImageAlignment = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background gradient style of a skin frame. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(GradientStyle.None), + SRDescription("DescriptionAttributeBackGradientStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + public GradientStyle BackGradientStyle + { + get + { + return _backGradientStyle; + } + set + { + _backGradientStyle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the secondary background color of a skin frame. + /// + /// + /// This color is used with when or + /// are used. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBorderSkin_FrameBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackSecondaryColor + { + get + { + return _backSecondaryColor; + } + set + { + _backSecondaryColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the width of the border line of a skin frame. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(1), + SRDescription("DescriptionAttributeBorderSkin_FrameBorderWidth"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int BorderWidth + { + get + { + return _borderWidth; + } + set + { + if(value < 0) + { + throw(new ArgumentOutOfRangeException("value", SR.ExceptionBorderWidthIsNotPositive)); + } + _borderWidth = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the style of the border line of a skin frame. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + DefaultValue(ChartDashStyle.NotSet), + SRDescription("DescriptionAttributeBorderSkin_FrameBorderDashStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartDashStyle BorderDashStyle + { + get + { + return _borderDashStyle; + } + set + { + _borderDashStyle = value; + this.Invalidate(); + } + } + + #endregion + } +} + + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Borders3D +#else + namespace System.Web.UI.DataVisualization.Charting.Borders3D +#endif +{ + /// + /// Keep track of all registered 3D borders. + /// + internal class BorderTypeRegistry : IServiceProvider + { + #region Fields + + // Border types image resource manager + private ResourceManager _resourceManager = null; + + // Storage for all registered border types + internal Hashtable registeredBorderTypes = new Hashtable(StringComparer.OrdinalIgnoreCase); + private Hashtable _createdBorderTypes = new Hashtable(StringComparer.OrdinalIgnoreCase); + + #endregion + + #region Constructors and services + + /// + /// Border types registry public constructor + /// + public BorderTypeRegistry() + { + } + + /// + /// Returns border type registry service object + /// + /// Service type to get. + /// Border registry service. + [EditorBrowsableAttribute(EditorBrowsableState.Never)] + object IServiceProvider.GetService(Type serviceType) + { + if(serviceType == typeof(BorderTypeRegistry)) + { + return this; + } + throw (new ArgumentException( SR.ExceptionBorderTypeRegistryUnsupportedType( serviceType.ToString()) )); + } + + #endregion + + #region Methods + + /// + /// Adds 3D border type into the registry. + /// + /// Border type name. + /// Border class type. + public void Register(string name, Type borderType) + { + // First check if border type with specified name already registered + if(registeredBorderTypes.Contains(name)) + { + // If same type provided - ignore + if(registeredBorderTypes[name].GetType() == borderType) + { + return; + } + + // Error - throw exception + throw (new ArgumentException(SR.ExceptionBorderTypeNameIsNotUnique( name ) ) ); + } + + // Make sure that specified class support IBorderType interface + bool found = false; + Type[] interfaces = borderType.GetInterfaces(); + foreach(Type type in interfaces) + { + if(type == typeof(IBorderType)) + { + found = true; + break; + } + } + if(!found) + { + throw (new ArgumentException(SR.ExceptionBorderTypeHasNoInterface )); + } + + // Add border type to the hash table + registeredBorderTypes[name] = borderType; + } + + /// + /// Returns border type object by name. + /// + /// Border type name. + /// Border type object derived from IBorderType. + public IBorderType GetBorderType(string name) + { + // First check if border type with specified name registered + if(!registeredBorderTypes.Contains(name)) + { + throw( new ArgumentException( SR.ExceptionBorderTypeUnknown( name ) ) ); + } + + // Check if the border type object is already created + if(!_createdBorderTypes.Contains(name)) + { + // Create border type object + _createdBorderTypes[name] = + ((Type)registeredBorderTypes[name]).Assembly. + CreateInstance(((Type)registeredBorderTypes[name]).ToString()); + } + + return (IBorderType)_createdBorderTypes[name]; + } + + /// + /// Border images resource manager. + /// + public ResourceManager ResourceManager + { + get + { + // Create border images resource manager + if(_resourceManager == null) + { + _resourceManager = new ResourceManager("System.Web.UI.DataVisualization.Charting", Assembly.GetExecutingAssembly()); + } + return _resourceManager; + } + } + + #endregion + } + + /// + /// Interface which defines the set of standard methods and + /// properties for each border type. + /// + internal interface IBorderType + { + #region Properties and Method + + /// + /// Border type name. + /// + string Name { get; } + + /// + /// Sets/Gets the resolution to draw with; + /// + float Resolution + { + set; + } + /// + /// Draws 3D border. + /// + /// Graphics to draw the border on. + /// Border skin object. + /// Rectangle of the border. + /// Color of rectangle. + /// Hatch style. + /// Back Image. + /// Image mode. + /// Image transparent color. + /// Image alignment. + /// Gradient type. + /// Gradient End Color. + /// Border Color. + /// Border Width. + /// Border Style. + void DrawBorder( + ChartGraphics graph, + BorderSkin borderSkin, + RectangleF rect, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle); + + /// + /// Adjust areas rectangle coordinate to fit the 3D border. + /// + /// Graphics to draw the border on. + /// Position to adjust. + void AdjustAreasPosition(ChartGraphics graph, ref RectangleF areasRect); + + /// + /// Returns the position of the rectangular area in the border where + /// title should be displayed. Returns empty rect if title can't be shown in the border. + /// + /// Title position in border. + RectangleF GetTitlePositionInBorder(); + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Borders3D/EmbedBorder.cs b/System.Web.DataVisualization/Common/Borders3D/EmbedBorder.cs new file mode 100644 index 000000000..6ce591729 --- /dev/null +++ b/System.Web.DataVisualization/Common/Borders3D/EmbedBorder.cs @@ -0,0 +1,1102 @@ +//------------------------------------------------------------- +// +// Copyright � Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: EmbedBorder.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Borders3D +// +// Classes: EmbedBorder, FrameTitle1Border, FrameTitle2Border, +// FrameTitle3Border, FrameTitle4Border, FrameTitle5Border, +// FrameTitle6Border, FrameTitle7Border, FrameTitle8Border, +// FrameThin2Border, FrameThin3Border, FrameThin4Border, +// FrameThin5Border, FrameThin6Border, FrameThin1Border, +// RaisedBorder, SunkenBorder +// +// Purpose: Classes that implement different 3D border styles. +// +// Reviewed: AG - August 7, 2002 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel.Design; + +#if WINFORMS_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else + using System.Web.UI.DataVisualization.Charting; using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if WINFORMS_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Borders3D +#else + namespace System.Web.UI.DataVisualization.Charting.Borders3D +#endif +{ + /// + /// Implements frame border. + /// + internal class FrameTitle1Border : FrameThin1Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameTitle1Border() + { + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameTitle1";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); + } + } + /// + /// Returns the position of the rectangular area in the border where + /// title should be displayed. Returns empty rect if title can't be shown in the border. + /// + /// Title position in border. + public override RectangleF GetTitlePositionInBorder() + { + return new RectangleF( + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 1.6f); + } + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameTitle2Border : FrameThin2Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameTitle2Border() + { + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameTitle2";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); + } + } + + /// + /// Returns the position of the rectangular area in the border where + /// title should be displayed. Returns empty rect if title can't be shown in the border. + /// + /// Title position in border. + public override RectangleF GetTitlePositionInBorder() + { + return new RectangleF( + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 1.6f); + } + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameTitle3Border : FrameThin3Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameTitle3Border() + { + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameTitle3";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); + } + } + + /// + /// Returns the position of the rectangular area in the border where + /// title should be displayed. Returns empty rect if title can't be shown in the border. + /// + /// Title position in border. + public override RectangleF GetTitlePositionInBorder() + { + return new RectangleF( + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 1.6f); + } + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameTitle4Border : FrameThin4Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameTitle4Border() + { + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameTitle4";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); + } + } + + /// + /// Returns the position of the rectangular area in the border where + /// title should be displayed. Returns empty rect if title can't be shown in the border. + /// + /// Title position in border. + public override RectangleF GetTitlePositionInBorder() + { + return new RectangleF( + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 1.6f); + } + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameTitle5Border : FrameThin5Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameTitle5Border() + { + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); + this.drawScrews = true; + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameTitle5";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); + } + } + + /// + /// Returns the position of the rectangular area in the border where + /// title should be displayed. Returns empty rect if title can't be shown in the border. + /// + /// Title position in border. + public override RectangleF GetTitlePositionInBorder() + { + return new RectangleF( + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 1.6f); + } + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameTitle6Border : FrameThin6Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameTitle6Border() + { + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameTitle6";}} + + public override float Resolution + { + set + { + base.Resolution = value; + sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); + } + } + + /// + /// Returns the position of the rectangular area in the border where + /// title should be displayed. Returns empty rect if title can't be shown in the border. + /// + /// Title position in border. + public override RectangleF GetTitlePositionInBorder() + { + return new RectangleF( + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 0.25f, + defaultRadiusSize * 1.6f); + } + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameTitle7Border : FrameTitle1Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameTitle7Border() + { + this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height); + float[] corners = {15f, 1f, 1f, 1f, 1f, 15f, 15f, 15f}; + innerCorners = corners; + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameTitle7";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height); + float largeRadius = 15f * resolution / 96.0f; + float smallRadius = 1 * resolution / 96.0f; + float[] corners = { largeRadius, smallRadius, smallRadius, smallRadius, smallRadius, largeRadius, largeRadius, largeRadius }; + innerCorners = corners; + } + } + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameTitle8Border : FrameTitle1Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameTitle8Border() + { + this.sizeLeftTop = new SizeF(0, sizeLeftTop.Height); + this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height); + float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}; + innerCorners = corners; + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameTitle8";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + + this.sizeLeftTop = new SizeF(0, sizeLeftTop.Height); + this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height); + float radius = 1 * resolution / 96.0f; + float[] corners = { radius, radius, radius, radius, radius, radius, radius, radius }; + innerCorners = corners; + } + } + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameThin2Border : FrameThin1Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameThin2Border() + { + float[] corners = {15f, 15f, 15f, 1f, 1f, 1f, 1f, 15f}; + cornerRadius = corners; + innerCorners = corners; + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameThin2";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + + float largeRadius = 15f * resolution / 96.0f; + float smallRadius = 1 * resolution / 96.0f; + float[] corners = { largeRadius, largeRadius, largeRadius, smallRadius, smallRadius, smallRadius, smallRadius, largeRadius }; + cornerRadius = corners; + innerCorners = corners; + } + } + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameThin3Border : FrameThin1Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameThin3Border() + { + float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}; + cornerRadius = corners; + innerCorners = corners; + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameThin3";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + float radius = resolution / 96.0f; + float[] corners = { radius, radius, radius, radius, radius, radius, radius, radius }; + cornerRadius = corners; + innerCorners = corners; + } + } + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameThin4Border : FrameThin1Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameThin4Border() + { + float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}; + cornerRadius = corners; + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameThin4";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + float radius = 1f * resolution / 96.0f; + cornerRadius = new float[] { radius, radius, radius, radius, radius, radius, radius, radius }; + } + } + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameThin5Border : FrameThin1Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameThin5Border() + { + drawScrews = true; + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameThin5";}} + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameThin6Border : FrameThin1Border + { + #region Border properties and methods + + /// + /// Default constructor + /// + public FrameThin6Border() + { + float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}; + innerCorners = corners; + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameThin6";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + float radius = resolution / 96.0f; + float[] corners = { radius, radius, radius, radius, radius, radius, radius, radius }; + innerCorners = corners; + } + } + + #endregion + } + + /// + /// Implements frame border. + /// + internal class FrameThin1Border : RaisedBorder + { + #region Border properties and methods + + /// + /// Inner corners radius array + /// + internal float[] innerCorners = { 15f, 15f, 15f, 15f, 15f, 15f, 15f, 15f }; + + /// + /// Default constructor + /// + public FrameThin1Border() + { + sizeLeftTop = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f); + sizeRightBottom = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f); + } + + /// + /// Chart type name + /// + public override string Name { get{ return "FrameThin1";}} + + + public override float Resolution + { + set + { + base.Resolution = value; + float radius = 15.0f * resolution / 96.0f; + innerCorners = new float[] { radius, radius, radius, radius, radius, radius, radius, radius }; + sizeLeftTop = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f); + sizeRightBottom = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f); + + } + } + + /// + /// Draws 3D border. + /// + /// Graphics to draw the border on. + /// Border skin object. + /// Rectangle of the border. + /// Color of rectangle + /// Hatch style + /// Back Image + /// Image mode + /// Image transparent color. + /// Image alignment + /// Gradient type + /// Gradient End Color + /// Border Color + /// Border Width + /// Border Style + public override void DrawBorder( + ChartGraphics graph, + BorderSkin borderSkin, + RectangleF rect, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle) + { + drawBottomShadow = true; + sunken = false; + outsideShadowRate = .9f; + drawOutsideTopLeftShadow = false; + bool oldScrewsFlag = this.drawScrews; + this.drawScrews = false; + base.DrawBorder( + graph, + borderSkin, + rect, + borderSkin.BackColor, + borderSkin.BackHatchStyle, + borderSkin.BackImage, + borderSkin.BackImageWrapMode, + borderSkin.BackImageTransparentColor, + borderSkin.BackImageAlignment, + borderSkin.BackGradientStyle, + borderSkin.BackSecondaryColor, + borderSkin.BorderColor, + borderSkin.BorderWidth, + borderSkin.BorderDashStyle); + + this.drawScrews = oldScrewsFlag; + rect.X += sizeLeftTop.Width; + rect.Y += sizeLeftTop.Height; + rect.Width -= sizeRightBottom.Width + sizeLeftTop.Width; + rect.Height -= sizeRightBottom.Height + sizeLeftTop.Height; + if(rect.Width > 0 && rect.Height > 0 ) + { + float[] oldCorners = new float[8]; + oldCorners = (float[])cornerRadius.Clone(); + cornerRadius = innerCorners; + drawBottomShadow = false; + sunken = true; + drawOutsideTopLeftShadow = true; + outsideShadowRate = 1.4f; + Color oldPageColor = borderSkin.PageColor; + borderSkin.PageColor = Color.Transparent; + base.DrawBorder( + graph, + borderSkin, + rect, + backColor, + backHatchStyle, + backImage, + backImageWrapMode, + backImageTransparentColor, + backImageAlign, + backGradientStyle, + backSecondaryColor, + borderColor, + borderWidth, + borderDashStyle ); + borderSkin.PageColor = oldPageColor; + cornerRadius = oldCorners; + } + } + + #endregion + } + + + /// + /// Implements raised border. + /// + internal class RaisedBorder : SunkenBorder + { + #region Border properties and methods + + /// + /// Public constructor + /// + public RaisedBorder() + { + sunken = false; + } + + /// + /// Chart type name + /// + public override string Name { get{ return "Raised";}} + + #endregion + } + + /// + /// Implements embed 3D border. + /// + internal class SunkenBorder : IBorderType + { + #region Border properties and methods + + /// + /// Radius for rounded rectangle + /// + internal float defaultRadiusSize = 15f; + + /// + /// Outside shadow rate + /// + internal float outsideShadowRate = .9f; + + /// + /// Indicates that sunken shadows should be drawn + /// + internal bool sunken = true; + + /// + /// Indicates that bottom shadow should be drawn + /// + internal bool drawBottomShadow = true; + + /// + /// Indicates that top left outside dark shadow must be drawn + /// + internal bool drawOutsideTopLeftShadow = false; + + /// + /// Array of corner radius + /// + internal float[] cornerRadius = { 15f, 15f, 15f, 15f, 15f, 15f, 15f, 15f }; + + /// + /// Border top/left size + /// + internal SizeF sizeLeftTop = SizeF.Empty; + + /// + /// Border right/bottom size + /// + internal SizeF sizeRightBottom = SizeF.Empty; + + /// + /// Indicates that ----s should be drawn in the corners of the frame + /// + internal bool drawScrews = false; + + + internal float resolution = 96f; + + + /// + /// Public constructor + /// + public SunkenBorder() + { + } + + /// + /// Chart type name + /// + public virtual string Name { get{ return "Sunken";}} + + + public virtual float Resolution + { + set + { + resolution = value; + defaultRadiusSize = 15 * resolution / 96; + //X = defaultRadiusSize; + //Y = defaultRadiusSize; + cornerRadius = new float[] { defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize }; + } + } + + /// + /// Returns the position of the rectangular area in the border where + /// title should be displayed. Returns empty rect if title can't be shown in the border. + /// + /// Title position in border. + public virtual RectangleF GetTitlePositionInBorder() + { + return RectangleF.Empty; + } + + /// + /// Adjust areas rectangle coordinate to fit the 3D border + /// + /// Graphics to draw the border on. + /// Position to adjust. + public virtual void AdjustAreasPosition(ChartGraphics graph, ref RectangleF areasRect) + { + SizeF relSizeLeftTop = new SizeF(sizeLeftTop); + SizeF relSizeRightBottom = new SizeF(sizeRightBottom); + relSizeLeftTop.Width += defaultRadiusSize * 0.7f; + relSizeLeftTop.Height += defaultRadiusSize * 0.85f; + relSizeRightBottom.Width += defaultRadiusSize * 0.7f; + relSizeRightBottom.Height += defaultRadiusSize * 0.7f; + relSizeLeftTop = graph.GetRelativeSize(relSizeLeftTop); + relSizeRightBottom = graph.GetRelativeSize(relSizeRightBottom); + + if(relSizeLeftTop.Width > 30f) + relSizeLeftTop.Width = 0; + if(relSizeLeftTop.Height > 30f) + relSizeLeftTop.Height = 0; + if(relSizeRightBottom.Width > 30f) + relSizeRightBottom.Width = 0; + if(relSizeRightBottom.Height > 30f) + relSizeRightBottom.Height = 0; + + + areasRect.X += relSizeLeftTop.Width; + areasRect.Width -= (float)Math.Min(areasRect.Width, relSizeLeftTop.Width + relSizeRightBottom.Width); + areasRect.Y += relSizeLeftTop.Height; + areasRect.Height -= (float)Math.Min(areasRect.Height, relSizeLeftTop.Height + relSizeRightBottom.Height); + + if(areasRect.Right > 100f) + { + if(areasRect.Width > 100f - areasRect.Right) + areasRect.Width -= 100f - areasRect.Right; + else + areasRect.X -= 100f - areasRect.Right; + } + if(areasRect.Bottom > 100f) + { + if(areasRect.Height > 100f - areasRect.Bottom) + areasRect.Height -= 100f - areasRect.Bottom; + else + areasRect.Y -= 100f - areasRect.Bottom; + + } + } + + /// + /// Draws 3D border + /// + /// Graphics to draw the border on. + /// Border skin object. + /// Rectangle of the border. + /// Color of rectangle + /// Hatch style + /// Back Image + /// Image mode + /// Image transparent color. + /// Image alignment + /// Gradient type + /// Gradient End Color + /// Border Color + /// Border Width + /// Border Style + public virtual void DrawBorder( + ChartGraphics graph, + BorderSkin borderSkin, + RectangleF rect, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle) + { + RectangleF absolute = graph.Round( rect ); + RectangleF shadowRect = absolute; + + // Calculate shadow colors (0.2 - 0.6) + float colorDarkeningIndex = 0.3f + (0.4f * (borderSkin.PageColor.R + borderSkin.PageColor.G + borderSkin.PageColor.B) / 765f); + Color shadowColor = Color.FromArgb( + (int)(backColor.R*colorDarkeningIndex), + (int)(backColor.G*colorDarkeningIndex), + (int)(backColor.B*colorDarkeningIndex)); + + colorDarkeningIndex += 0.2f; + Color shadowLightColor = Color.FromArgb( + (int)(borderSkin.PageColor.R*colorDarkeningIndex), + (int)(borderSkin.PageColor.G*colorDarkeningIndex), + (int)(borderSkin.PageColor.B*colorDarkeningIndex)); + if(borderSkin.PageColor == Color.Transparent) + { + shadowLightColor = Color.FromArgb(60, 0, 0, 0); + } + + // Calculate rounded rect radius + float radius = defaultRadiusSize; + radius = (float)Math.Max(radius, 2f * resolution / 96.0f); + radius = (float)Math.Min(radius, rect.Width/2f); + radius = (float)Math.Min(radius, rect.Height/2f); + radius = (float)Math.Ceiling(radius); + + // Fill page background color + using (Brush brush = new SolidBrush(borderSkin.PageColor)) + { + graph.FillRectangle(brush, rect); + } + + if(drawOutsideTopLeftShadow) + { + // Top/Left outside shadow + shadowRect = absolute; + shadowRect.X -= radius * 0.3f; + shadowRect.Y -= radius * 0.3f; + shadowRect.Width -= radius * .3f; + shadowRect.Height -= radius * .3f; + graph.DrawRoundedRectShadowAbs(shadowRect, cornerRadius, radius, Color.FromArgb(128, Color.Black), borderSkin.PageColor, outsideShadowRate); + } + + // Bottom/Right outside shadow + shadowRect = absolute; + shadowRect.X += radius * 0.3f; + shadowRect.Y += radius * 0.3f; + shadowRect.Width -= radius * .3f; + shadowRect.Height -= radius * .3f; + graph.DrawRoundedRectShadowAbs(shadowRect, cornerRadius, radius, shadowLightColor, borderSkin.PageColor, outsideShadowRate); + + // Background + shadowRect = absolute; + shadowRect.Width -= radius * .3f; + shadowRect.Height -= radius * .3f; + GraphicsPath path = graph.CreateRoundedRectPath(shadowRect, cornerRadius); + graph.DrawPathAbs( + path, + backColor, + backHatchStyle, + backImage, + backImageWrapMode, + backImageTransparentColor, + backImageAlign, + backGradientStyle, + backSecondaryColor, + borderColor, + borderWidth, + borderDashStyle, + PenAlignment.Inset ); + + // Dispose Graphic path + if( path != null ) + path.Dispose(); + + // Draw ----s imitation in the corners of the farame + if(drawScrews) + { + // Left/Top ---- + RectangleF screwRect = RectangleF.Empty; + float offset = radius * 0.4f; + screwRect.X = shadowRect.X + offset; + screwRect.Y = shadowRect.Y + offset; + screwRect.Width = radius * 0.55f; + screwRect.Height = screwRect.Width; + DrawScrew(graph, screwRect); + + // Right/Top ---- + screwRect.X = shadowRect.Right - offset - screwRect.Width; + DrawScrew(graph, screwRect); + + // Right/Bottom ---- + screwRect.X = shadowRect.Right - offset - screwRect.Width; + screwRect.Y = shadowRect.Bottom - offset - screwRect.Height; + DrawScrew(graph, screwRect); + + // Left/Bottom ---- + screwRect.X = shadowRect.X + offset; + screwRect.Y = shadowRect.Bottom - offset - screwRect.Height; + DrawScrew(graph, screwRect); + } + + // Bottom/Right inner shadow + Region innerShadowRegion = null; + if(drawBottomShadow) + { + shadowRect = absolute; + shadowRect.Width -= radius * .3f; + shadowRect.Height -= radius * .3f; + innerShadowRegion = new Region( + graph.CreateRoundedRectPath( + new RectangleF( + shadowRect.X - radius, + shadowRect.Y - radius, + shadowRect.Width + 0.5f*radius, + shadowRect.Height + 0.5f*radius), + cornerRadius)); + innerShadowRegion.Complement(graph.CreateRoundedRectPath(shadowRect, cornerRadius)); + graph.Clip = innerShadowRegion; + + shadowRect.X -= 0.5f*radius; + shadowRect.Width += 0.5f*radius; + shadowRect.Y -= 0.5f*radius; + shadowRect.Height += 0.5f*radius; + + graph.DrawRoundedRectShadowAbs( + shadowRect, + cornerRadius, + radius, + Color.Transparent, + Color.FromArgb(175, (sunken) ? Color.White : shadowColor), + 1.0f); + graph.Clip = new Region(); + } + + // Top/Left inner shadow + shadowRect = absolute; + shadowRect.Width -= radius * .3f; + shadowRect.Height -= radius * .3f; + innerShadowRegion = new Region( + graph.CreateRoundedRectPath( + new RectangleF( + shadowRect.X + radius*.5f, + shadowRect.Y + radius*.5f, + shadowRect.Width - .2f*radius, + shadowRect.Height - .2f*radius), + cornerRadius)); + + RectangleF shadowWithOffset = shadowRect; + shadowWithOffset.Width += radius; + shadowWithOffset.Height += radius; + innerShadowRegion.Complement(graph.CreateRoundedRectPath(shadowWithOffset, cornerRadius)); + + innerShadowRegion.Intersect(graph.CreateRoundedRectPath(shadowRect, cornerRadius)); + graph.Clip = innerShadowRegion; + graph.DrawRoundedRectShadowAbs( + shadowWithOffset, + cornerRadius, + radius, + Color.Transparent, + Color.FromArgb(175, (sunken) ? shadowColor : Color.White), + 1.0f); + graph.Clip = new Region(); + + } + + /// + /// Helper function, which draws a ---- on the frame + /// + /// Chart graphics to use. + /// ---- position. + private void DrawScrew(ChartGraphics graph, RectangleF rect) + { + // Draw ---- + Pen screwPen = new Pen(Color.FromArgb(128,255,255,255), 1); + graph.DrawEllipse(screwPen, rect.X, rect.Y, rect.Width, rect.Height); + graph.DrawLine(screwPen, rect.X + 2 * resolution / 96.0f, rect.Y + rect.Height - 2 * resolution / 96.0f, rect.Right - 2 * resolution / 96.0f, rect.Y + 2 * resolution / 96.0f); + screwPen = new Pen(Color.FromArgb(128, Color.Black), 1); + graph.DrawEllipse(screwPen, rect.X + 1 * resolution / 96.0f, rect.Y + 1 * resolution / 96.0f, rect.Width, rect.Height); + graph.DrawLine(screwPen, rect.X + 3 * resolution / 96.0f, rect.Y + rect.Height - 1 * resolution / 96.0f, rect.Right - 1 * resolution / 96.0f, rect.Y + 3 * resolution / 96.0f); + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Borders3D/EmbossBorder.cs b/System.Web.DataVisualization/Common/Borders3D/EmbossBorder.cs new file mode 100644 index 000000000..24f289589 --- /dev/null +++ b/System.Web.DataVisualization/Common/Borders3D/EmbossBorder.cs @@ -0,0 +1,268 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: EmbossBorder.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Borders3D +// +// Classes: EmbossBorder +// +// Purpose: Class that implements Emboss 3D border style. +// +// Reviewed: AG - August 7, 2002 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel.Design; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else + using System.Web.UI.DataVisualization.Charting; using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Borders3D +#else + namespace System.Web.UI.DataVisualization.Charting.Borders3D +#endif + { + + /// + /// Implements emboss 3D border. + /// + internal class EmbossBorder : IBorderType + { + #region Border properties and methods + + /// + /// Default border radius size (relative) + /// + public float defaultRadiusSize = 15f; + + public float resolution = 96f; + + /// + /// Array of corner radius + /// + internal float[] cornerRadius = { 15f, 15f, 15f, 15f, 15f, 15f, 15f, 15f }; + + + /// + /// Public constructor + /// + public EmbossBorder() + { + } + + /// + /// Chart type name + /// + public virtual string Name { get{ return "Emboss";}} + + + public virtual float Resolution + { + set + { + resolution = value; + float radius = 15f * value / 96.0f; + defaultRadiusSize = radius; + cornerRadius = new float[] { radius, radius, radius, radius, radius, radius, radius, radius }; + } + + } + + /// + /// Returns the position of the rectangular area in the border where + /// title should be displayed. Returns empty rect if title can't be shown in the border. + /// + /// Title position in border. + public virtual RectangleF GetTitlePositionInBorder() + { + return RectangleF.Empty; + } + + /// + /// Adjust areas rectangle coordinate to fit the 3D border. + /// + /// Graphics to draw the border on. + /// Position to adjust. + public virtual void AdjustAreasPosition(ChartGraphics graph, ref RectangleF areasRect) + { + SizeF borderSize = new SizeF(defaultRadiusSize/2f, defaultRadiusSize/2f); + borderSize = graph.GetRelativeSize(borderSize); + + // Do not do anything if rectangle is too small + if(borderSize.Width < 30f) + { + areasRect.X += borderSize.Width; + areasRect.Width -= (float)Math.Min(areasRect.Width, borderSize.Width * 2.5f); + } + + if(borderSize.Height < 30f) + { + areasRect.Y += borderSize.Height; + areasRect.Height -= (float)Math.Min(areasRect.Height, borderSize.Height * 2.5f); + } + + if(areasRect.X + areasRect.Width > 100f) + { + areasRect.X -= 100f - areasRect.Width; + } + if(areasRect.Y + areasRect.Height > 100f) + { + areasRect.Y -= 100f - areasRect.Height; + } + } + + /// + /// Draws 3D border. + /// + /// Graphics to draw the border on. + /// Border skin object. + /// Rectangle of the border. + /// Color of rectangle + /// Hatch style + /// Back Image + /// Image mode + /// Image transparent color. + /// Image alignment + /// Gradient type + /// Gradient End Color + /// Border Color + /// Border Width + /// Border Style + public virtual void DrawBorder( + ChartGraphics graph, + BorderSkin borderSkin, + RectangleF rect, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle) + { + RectangleF absolute = graph.Round( rect ); + RectangleF shadowRect = absolute; + + // Calculate shadow colors (0.2 - 0.6) + float colorDarkeningIndex = 0.2f + (0.4f * (borderSkin.PageColor.R + borderSkin.PageColor.G + borderSkin.PageColor.B) / 765f); + Color shadowColor = Color.FromArgb( + (int)(borderSkin.PageColor.R*colorDarkeningIndex), + (int)(borderSkin.PageColor.G*colorDarkeningIndex), + (int)(borderSkin.PageColor.B*colorDarkeningIndex)); + if(borderSkin.PageColor == Color.Transparent) + { + shadowColor = Color.FromArgb(60, 0, 0, 0); + } + + colorDarkeningIndex += 0.2f; + Color shadowLightColor = Color.FromArgb( + (int)(borderSkin.PageColor.R*colorDarkeningIndex), + (int)(borderSkin.PageColor.G*colorDarkeningIndex), + (int)(borderSkin.PageColor.B*colorDarkeningIndex)); + + // Calculate rounded rect radius + float radius = defaultRadiusSize; + radius = (float)Math.Max(radius, 2f * resolution / 96.0f); + radius = (float)Math.Min(radius, rect.Width/2f); + radius = (float)Math.Min(radius, rect.Height/2f); + radius = (float)Math.Ceiling(radius); + + // Fill page background color + using (Brush brush = new SolidBrush(borderSkin.PageColor)) + { + graph.FillRectangle(brush, rect); + } + + // Top/Left shadow + shadowRect = absolute; + shadowRect.Width -= radius * .3f; + shadowRect.Height -= radius * .3f; + graph.DrawRoundedRectShadowAbs(shadowRect, cornerRadius, radius + 1 * resolution / 96.0f, shadowLightColor, borderSkin.PageColor, 1.4f); + + // Bottom/Right shadow + shadowRect = absolute; + shadowRect.X = absolute.X + radius / 3f; + shadowRect.Y = absolute.Y + radius / 3f; + shadowRect.Width -= radius / 3.5f; + shadowRect.Height -= radius / 3.5f; + graph.DrawRoundedRectShadowAbs(shadowRect, cornerRadius, radius, shadowColor, borderSkin.PageColor, 1.3f); + + // Draw Background + shadowRect = absolute; + shadowRect.X = absolute.X + 3f * resolution / 96.0f; + shadowRect.Y = absolute.Y + 3f * resolution / 96.0f; + shadowRect.Width -= radius * .75f; + shadowRect.Height -= radius * .75f; + GraphicsPath path = graph.CreateRoundedRectPath(shadowRect, cornerRadius); + graph.DrawPathAbs( + path, + backColor, + backHatchStyle, + backImage, + backImageWrapMode, + backImageTransparentColor, + backImageAlign, + backGradientStyle, + backSecondaryColor, + borderColor, + borderWidth, + borderDashStyle, + PenAlignment.Inset ); + + // Dispose Graphic path + if( path != null ) + path.Dispose(); + + // Bottom/Right inner shadow + Region innerShadowRegion = new Region( + graph.CreateRoundedRectPath( + new RectangleF( + shadowRect.X - radius, + shadowRect.Y - radius, + shadowRect.Width + radius - radius*0.25f, + shadowRect.Height + radius - radius*0.25f), + cornerRadius)); + innerShadowRegion.Complement(graph.CreateRoundedRectPath(shadowRect, cornerRadius)); + graph.Clip = innerShadowRegion; + graph.DrawRoundedRectShadowAbs( + shadowRect, + cornerRadius, + radius, + Color.Transparent, + Color.FromArgb(128, Color.Gray), + .5f); + graph.Clip = new Region(); + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/AreaChart.cs b/System.Web.DataVisualization/Common/ChartTypes/AreaChart.cs new file mode 100644 index 000000000..e4a351ace --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/AreaChart.cs @@ -0,0 +1,1647 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: AreaChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: AreaChart, SplineAreaChart +// +// Purpose: Provide 2D/3D drawing and hit testing functionality +// for the Area and SplineArea charts. Spline chart +// type is used as a base for the Area and SplineArea +// charts. +// +// Reviewed: AG - August 6, 2002; +// GS - August 8, 2002 +// AG - Microsoft 6, 2007 +// +//=================================================================== + + +#region Used namespaces +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// SplineAreaChart class extends the AreaChart class by + /// providing a different initial tension for the line. + /// + internal class SplineAreaChart : AreaChart + { + #region Constructor + + /// + /// Default constructor. + /// + public SplineAreaChart() + { + // Set default line tension + base.lineTension = 0.5f; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + public override string Name { get{ return ChartTypeNames.SplineArea;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + #endregion + + #region Default tension method + + /// + /// Gets default line tension. For spline charts it's always 0.5. + /// + /// Line tension. + override protected float GetDefaultTension() + { + return 0.5f; + } + + /// + /// Checks if line tension is supported by the chart type. + /// + /// True if line tension is supported. + protected override bool IsLineTensionSupported() + { + return true; + } + + #endregion + } + + /// + /// AreaChart class provides 2D/3D drawing and hit testing + /// functionality for the Area and SplineArea charts. The + /// only difference of the SplineArea chart is the default + /// tension of the line. + /// + /// SplineChart base class provides most of the functionality + /// like drawing lines, labels and markers. + /// + internal class AreaChart : SplineChart + { + #region Fields + + /// + /// Fields used to fill area with gradient + /// + + protected bool gradientFill = false; + + /// + /// Coordinates of the area path + /// + protected GraphicsPath areaPath = null; + + /// + /// Reference to the current series object + /// + protected Series Series { get; set; } + + /// + /// Horizontal axis position + /// + protected PointF axisPos = PointF.Empty; + + #endregion + + #region Constructor + + /// + /// Area chart constructor + /// + public AreaChart() + { + this.drawOutsideLines = true; + + // Set default line tension + base.lineTension = 0f; + + // Reset axis position + axisPos = PointF.Empty; + } + + #endregion + + #region Default tension method + + /// + /// Gets default line tension. + /// + /// Line tension. + override protected float GetDefaultTension() + { + return 0f; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + public override string Name { get { return ChartTypeNames.Area; } } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + public override bool ZeroCrossing { get{ return true;} } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + override public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Painting and Selection methods + + /// + /// This method recalculates position of the end points of lines. This method + /// is used from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + protected override void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + // Reset background gradient fill flag + gradientFill = false; + + // Reset axis position + axisPos = PointF.Empty; + + // Call base SplineChart class + base.ProcessChartType(selection, graph, common, area, seriesToDraw); + + // Fill background gradient for the 2D chart. Feature is not supported in 3D. + if(!area.Area3DStyle.Enable3D) + { + FillLastSeriesGradient(graph); + } + + } + + /// + /// This method is overriden to fill the area and draw border line. + /// + /// Graphics object. + /// The Common elements object + /// Point to draw the line for. + /// Point series. + /// Array of oints coordinates. + /// Index of point to draw. + /// Line tension + override protected void DrawLine( + ChartGraphics graph, + CommonElements common, + DataPoint point, + Series series, + PointF[] points, + int pointIndex, + float tension) + { + // Start drawing from the second point + if (pointIndex <= 0) + { + return; + } + + // Check if its a beginning of a new series + if (this.Series != null) + { + if (this.Series.Name != series.Name) + { + // Fill gradient from the previous series + FillLastSeriesGradient(graph); + this.Series = series; + } + } + else + { + this.Series = series; + } + + // Calculate points position + PointF point1 = points[pointIndex - 1]; + PointF point2 = points[pointIndex]; + point1.X = (float)Math.Round(point1.X); + point1.Y = (float)Math.Round(point1.Y); + point2.X = (float)Math.Round(point2.X); + point2.Y = (float)Math.Round(point2.Y); + if (axisPos == PointF.Empty) + { + axisPos.X = (float)VAxis.GetPosition(this.VAxis.Crossing); + axisPos.Y = (float)VAxis.GetPosition(this.VAxis.Crossing); + axisPos = graph.GetAbsolutePoint(axisPos); + axisPos.X = (float)Math.Round(axisPos.X); + axisPos.Y = (float)Math.Round(axisPos.Y); + } + + // Point properties + Color pointColor = point.Color; + Color pointBorderColor = point.BorderColor; + int pointBorderWidth = point.BorderWidth; + ChartDashStyle pointBorderDashStyle = point.BorderDashStyle; + + // Create area brush + Brush areaBrush = null; + if (point.BackHatchStyle != ChartHatchStyle.None) + { + areaBrush = graph.GetHatchBrush(point.BackHatchStyle, pointColor, point.BackSecondaryColor); + } + else if (point.BackGradientStyle != GradientStyle.None) + { + this.gradientFill = true; + this.Series = point.series; + } + else if (point.BackImage.Length > 0 && point.BackImageWrapMode != ChartImageWrapMode.Unscaled && point.BackImageWrapMode != ChartImageWrapMode.Scaled) + { + areaBrush = graph.GetTextureBrush(point.BackImage, point.BackImageTransparentColor, point.BackImageWrapMode, point.Color); + } + else + { + areaBrush = new SolidBrush(pointColor); + } + + // Calculate data point area segment path + GraphicsPath path = new GraphicsPath(); + + path.AddLine(point1.X, axisPos.Y, point1.X, point1.Y); + if (this.lineTension == 0) + { + path.AddLine(points[pointIndex - 1], points[pointIndex]); + } + else + { + path.AddCurve(points, pointIndex - 1, 1, this.lineTension); + } + path.AddLine(point2.X, point2.Y, point2.X, axisPos.Y); + + // Draw shadow + if (series.ShadowColor != Color.Empty && series.ShadowOffset != 0) + { + if (pointColor != Color.Empty && pointColor != Color.Transparent) + { + Region shadowRegion = new Region(path); + using (Brush shadowBrush = new SolidBrush((series.ShadowColor.A != 255) ? series.ShadowColor : Color.FromArgb(pointColor.A / 2, series.ShadowColor))) + { + // Set offset transformation + GraphicsState graphicsState = graph.Save(); + Region clipRegion = null; + Region clipRegionOld = null; + if (!graph.IsClipEmpty && !graph.Clip.IsInfinite(graph.Graphics)) + { + clipRegionOld = graph.Clip.Clone(); + clipRegion = graph.Clip; + clipRegion.Translate(series.ShadowOffset, series.ShadowOffset); + graph.Clip = clipRegion; + } + graph.TranslateTransform(series.ShadowOffset, series.ShadowOffset); + + // Draw top and bottom lines + if (graph.SmoothingMode != SmoothingMode.None) + { + using (Pen areaLinePen = new Pen(shadowBrush, 1)) + { + if (this.lineTension == 0) + { + graph.DrawLine(areaLinePen, points[pointIndex - 1], points[pointIndex]); + } + else + { + graph.DrawCurve(areaLinePen, points, pointIndex - 1, 1, this.lineTension); + } + } + } + + // Fill shadow region + graph.FillRegion(shadowBrush, shadowRegion); + + // Restore transformation matrix + graph.Restore(graphicsState); + if (clipRegion != null && clipRegionOld != null) + { + graph.Clip = clipRegionOld; + } + } + } + } + + // Draw area + if (!gradientFill) + { + // Turn off anti aliasing and fill area + SmoothingMode oldMode = graph.SmoothingMode; + graph.SmoothingMode = SmoothingMode.None; + + // Fill area + graph.FillPath(areaBrush, path); + + // Draw right side of the area (not filled by FillPath) + + // Restore smoothing mode + graph.SmoothingMode = oldMode; + + // Draw top and bottom lines + if (graph.SmoothingMode != SmoothingMode.None) + { + // Start Svg Selection mode + graph.StartHotRegion(point); + + using (Pen areaLinePen = new Pen(areaBrush, 1)) + { + if (this.lineTension == 0) + { + // Draw horizontal and vertical lines without anti-aliasing + if (!(points[pointIndex - 1].X == points[pointIndex].X || + points[pointIndex - 1].Y == points[pointIndex].Y)) + { + graph.DrawLine(areaLinePen, points[pointIndex - 1], points[pointIndex]); + } + } + else + { + graph.DrawCurve(areaLinePen, points, pointIndex - 1, 1, this.lineTension); + } + } + + // End Svg Selection mode + graph.EndHotRegion(); + } + + } + + if (areaBrush != null) + areaBrush.Dispose(); + + // Add first line + if (areaPath == null) + { + areaPath = new GraphicsPath(); + areaPath.AddLine(point1.X, axisPos.Y, point1.X, point1.Y); + } + + // Add line to the gradient path + if (this.lineTension == 0) + { + areaPath.AddLine(points[pointIndex - 1], points[pointIndex]); + } + else + { + areaPath.AddCurve(points, pointIndex - 1, 1, this.lineTension); + } + + // Draw area border line + if (pointBorderWidth > 0 && pointBorderColor != Color.Empty) + { + Pen pen = new Pen((pointBorderColor != Color.Empty) ? pointBorderColor : pointColor, pointBorderWidth); + pen.DashStyle = graph.GetPenStyle(pointBorderDashStyle); + + // Set Rounded Cap + pen.StartCap = LineCap.Round; + pen.EndCap = LineCap.Round; + + if (this.lineTension == 0) + { + graph.DrawLine(pen, points[pointIndex - 1], points[pointIndex]); + } + else + { + graph.DrawCurve(pen, points, pointIndex - 1, 1, this.lineTension); + } + } + + //************************************************************ + // Hot Regions mode used for image maps, tool tips and + // hit test function + //************************************************************ + if (common.ProcessModeRegions) + { + //************************************************************** + //** Add area for the inside of the area + //************************************************************** + + // Create grapics path object dor the curve + GraphicsPath mapAreaPath = new GraphicsPath(); + mapAreaPath.AddLine(point1.X, axisPos.Y, point1.X, point1.Y); + if (this.lineTension == 0) + { + mapAreaPath.AddLine(points[pointIndex - 1], points[pointIndex]); + } + else + { + mapAreaPath.AddCurve(points, pointIndex - 1, 1, this.lineTension); + mapAreaPath.Flatten(); + } + mapAreaPath.AddLine(point2.X, point2.Y, point2.X, axisPos.Y); + mapAreaPath.AddLine(point2.X, axisPos.Y, point1.X, axisPos.Y); + + // Allocate array of floats + PointF pointNew = PointF.Empty; + float[] coord = new float[mapAreaPath.PointCount * 2]; + PointF[] areaPoints = mapAreaPath.PathPoints; + for (int i = 0; i < mapAreaPath.PointCount; i++) + { + pointNew = graph.GetRelativePoint(areaPoints[i]); + coord[2 * i] = pointNew.X; + coord[2 * i + 1] = pointNew.Y; + } + + //************************************************************ + // Hot Regions mode used for image maps, tool tips and + // hit test function + //************************************************************ + common.HotRegionsList.AddHotRegion( + mapAreaPath, + false, + coord, + point, + series.Name, + pointIndex); + + //************************************************************** + //** Add area for the top line (with thickness) + //************************************************************** + if (pointBorderWidth > 1 && pointBorderDashStyle != ChartDashStyle.NotSet && pointBorderColor != Color.Empty) + { + try + { + + mapAreaPath.Dispose(); + // Reset path + mapAreaPath = new GraphicsPath(); + if (this.lineTension == 0) + { + mapAreaPath.AddLine(points[pointIndex - 1], points[pointIndex]); + } + else + { + mapAreaPath.AddCurve(points, pointIndex - 1, 1, this.lineTension); + mapAreaPath.Flatten(); + } + + // Widen the lines to the size of pen plus 2 + mapAreaPath.Widen(new Pen(pointColor, pointBorderWidth + 2)); + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + + // Allocate array of floats + pointNew = PointF.Empty; + coord = new float[mapAreaPath.PointCount * 2]; + PointF[] mapAreaPathPoints = mapAreaPath.PathPoints; + for (int i = 0; i < mapAreaPathPoints.Length; i++) + { + pointNew = graph.GetRelativePoint(mapAreaPathPoints[i]); + coord[2 * i] = pointNew.X; + coord[2 * i + 1] = pointNew.Y; + } + + //************************************************************ + // Hot Regions mode used for image maps, tool tips and + // hit test function + //************************************************************ + common.HotRegionsList.AddHotRegion( + mapAreaPath, + false, + coord, + point, + series.Name, + pointIndex); + + } + mapAreaPath.Dispose(); + } + } + + /// + /// Fills last series area with gradient. + /// + /// The Chart Graphics object + private void FillLastSeriesGradient(ChartGraphics graph) + { + // Add last line in the path + if(areaPath != null) + { + areaPath.AddLine(areaPath.GetLastPoint().X, areaPath.GetLastPoint().Y, areaPath.GetLastPoint().X, axisPos.Y); + } + + // Fill whole area with gradient + if(gradientFill && areaPath != null) + { + // Set clip region + graph.SetClip( Area.PlotAreaPosition.ToRectangleF() ); + + // Create brush + using (Brush areaGradientBrush = graph.GetGradientBrush(areaPath.GetBounds(), this.Series.Color, this.Series.BackSecondaryColor, this.Series.BackGradientStyle)) + { + // Fill area with gradient + graph.FillPath(areaGradientBrush, areaPath); + gradientFill = false; + } + + // Reset clip region + graph.ResetClip(); + } + if(areaPath != null) + { + areaPath.Dispose(); + areaPath = null; + } + } + + /// + /// Checks if line tension is supported by the chart type. + /// + /// True if line tension is supported. + protected override bool IsLineTensionSupported() + { + return false; + } + + #endregion + + #region 3D painting and selection methods + + /// + /// Draws a 3D surface connecting the two specified points in 2D space. + /// Used to draw Line based charts. + /// + /// Chart area reference. + /// Chart graphics. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Previous data point object. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Array of points. + /// Index of point to draw. + /// Index of points loop. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Darkenning scale for top surface. 0 - None. + /// Darkenning scale for bottom surface. 0 - None. + /// Position where the third point is actually located or float.NaN if same as in "firstPoint". + /// Position where the fourth point is actually located or float.NaN if same as in "secondPoint". + /// Indicates that drawn segment is 3D clipped. Only top/bottom should be drawn. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + protected override GraphicsPath Draw3DSurface( + ChartArea area, + ChartGraphics graph, + Matrix3D matrix, + LightStyle lightStyle, + DataPoint3D prevDataPointEx, + float positionZ, + float depth, + ArrayList points, + int pointIndex, + int pointLoopIndex, + float tension, + DrawingOperationTypes operationType, + float topDarkening, + float bottomDarkening, + PointF thirdPointPosition, + PointF fourthPointPosition, + bool clippedSegment) + { + // Create graphics path for selection + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + //**************************************************************** + //** Find line first and second points. + //**************************************************************** + + // Check if points are drawn from sides to center (do only once) + if(centerPointIndex == int.MaxValue) + { + centerPointIndex = GetCenterPointIndex(points); + } + + //************************************************************ + //** Find line first & second points + //************************************************************ + DataPoint3D secondPoint = (DataPoint3D)points[pointIndex]; + int pointArrayIndex = pointIndex; + DataPoint3D firstPoint = ChartGraphics.FindPointByIndex( + points, + secondPoint.index - 1, + (this.multiSeries) ? secondPoint : null, + ref pointArrayIndex); + + + //**************************************************************** + //** Switch first and second points. + //**************************************************************** + bool reversed = false; + if(firstPoint.index > secondPoint.index) + { + DataPoint3D tempPoint = firstPoint; + firstPoint = secondPoint; + secondPoint = tempPoint; + reversed = true; + } + + + // Points can be drawn from sides to the center. + // In this case can't use index in the list to find first point. + // Use point series and real point index to find the first point. + // Get required point index + if(matrix.Perspective != 0 && centerPointIndex != int.MaxValue) + { + pointArrayIndex = pointIndex; + if( pointIndex != (centerPointIndex + 1)) + { + firstPoint = ChartGraphics.FindPointByIndex(points, secondPoint.index - 1, (this.multiSeries) ? secondPoint : null, ref pointArrayIndex); + } + else + { + if (!area.ReverseSeriesOrder) + { + secondPoint = ChartGraphics.FindPointByIndex(points, firstPoint.index + 1, (this.multiSeries) ? secondPoint : null, ref pointArrayIndex); + } + else + { + firstPoint = secondPoint; + secondPoint = ChartGraphics.FindPointByIndex(points, secondPoint.index - 1, (this.multiSeries) ? secondPoint : null, ref pointArrayIndex); + } + } + } + + // Check if points are not null + if(firstPoint == null || secondPoint == null) + { + return resultPath; + } + + + //**************************************************************** + //** Check if reversed drawing order required + //**************************************************************** + reversed = false; + int indexOffset = 1; + while((pointIndex + indexOffset) < points.Count) + { + DataPoint3D p = (DataPoint3D)points[pointIndex + indexOffset]; + if(p.dataPoint.series.Name == firstPoint.dataPoint.series.Name) + { + if(p.index == firstPoint.index) + { + reversed = true; + } + break; + } + + ++indexOffset; + } + + //**************************************************************** + //** Check line tension and draw spline area if non zero. + //**************************************************************** + // Check tension + if(tension != 0f) + { + // Get spline flatten path + GraphicsPath splineSurfacePath = graph.GetSplineFlattenPath( + area, positionZ, + firstPoint, secondPoint, points, tension, true, false, 0); + + // Reversed array of points if needed + PointF[] splinePoints = null; + reversed = (pointIndex < pointArrayIndex); + if(reversed) + { + splineSurfacePath.Reverse(); + } + splinePoints = splineSurfacePath.PathPoints; + + // Loop through all segment lines the spline consist off + DataPoint3D dp1 = new DataPoint3D(); + DataPoint3D dp2 = new DataPoint3D(); + //LineSegmentType surfaceSegmentType = (!reversed) ? LineSegmentType.First : LineSegmentType.Last; + LineSegmentType surfaceSegmentType = LineSegmentType.Middle; + for(int pIndex = 1; pIndex < splinePoints.Length; pIndex++) + { + // Calculate surface coordinates + if(!reversed) + { + dp1.dataPoint = firstPoint.dataPoint; + dp1.index = firstPoint.index; + dp1.xPosition = splinePoints[pIndex - 1].X; + dp1.yPosition = splinePoints[pIndex - 1].Y; + + dp2.dataPoint = secondPoint.dataPoint; + dp2.index = secondPoint.index; + dp2.xPosition = splinePoints[pIndex].X; + dp2.yPosition = splinePoints[pIndex].Y; + } + else + { + dp2.dataPoint = firstPoint.dataPoint; + dp2.index = firstPoint.index; + dp2.xPosition = splinePoints[pIndex - 1].X; + dp2.yPosition = splinePoints[pIndex - 1].Y; + + dp1.dataPoint = secondPoint.dataPoint; + dp1.index = secondPoint.index; + dp1.xPosition = splinePoints[pIndex].X; + dp1.yPosition = splinePoints[pIndex].Y; + } + + // Get sefment type + surfaceSegmentType = LineSegmentType.Middle; + if(pIndex == 1) + { + if(!reversed) + surfaceSegmentType = LineSegmentType.First; + else + surfaceSegmentType = LineSegmentType.Last; + } + else if(pIndex == splinePoints.Length - 1) + { + if(!reversed) + surfaceSegmentType = LineSegmentType.Last; + else + surfaceSegmentType = LineSegmentType.First; + } + + // Draw each segment of the spline area + area.IterationCounter = 0; + GraphicsPath segmentResultPath = Draw3DSurface( dp1, dp2, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + 0f, operationType, surfaceSegmentType, + topDarkening, bottomDarkening, + new PointF(float.NaN, float.NaN), + new PointF(float.NaN, float.NaN), + clippedSegment, + true, true); + + // Add selection path + if(resultPath != null && segmentResultPath != null && segmentResultPath.PointCount > 0) + { + resultPath.AddPath(segmentResultPath, true); + } + } + + return resultPath; + } + + // Area point is drawn as one segment + return Draw3DSurface( firstPoint, secondPoint, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, LineSegmentType.Single, + topDarkening, bottomDarkening, + thirdPointPosition, fourthPointPosition, + clippedSegment, + true, true); + } + + /// + /// Draws a 3D surface connecting the two specified points in 2D space. + /// Used to draw Line based charts. + /// + /// First data point. + /// Second data point. + /// Points are in reversed order. + /// Chart area reference. + /// Chart graphics. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Previous data point object. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Array of points. + /// Index of point to draw. + /// Index of points loop. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Define surface segment type if it consists of several segments. + /// Darkenning scale for top surface. 0 - None. + /// Darkenning scale for bottom surface. 0 - None. + /// Position where the third point is actually located or float.NaN if same as in "firstPoint". + /// Position where the fourth point is actually located or float.NaN if same as in "secondPoint". + /// Indicates that drawn segment is 3D clipped. Only top/bottom should be drawn. + /// Indicates that top segment line should be clipped to the pkot area. + /// Indicates that bottom segment line should be clipped to the pkot area. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + protected override GraphicsPath Draw3DSurface( + DataPoint3D firstPoint, + DataPoint3D secondPoint, + bool reversed, + ChartArea area, + ChartGraphics graph, + Matrix3D matrix, + LightStyle lightStyle, + DataPoint3D prevDataPointEx, + float positionZ, + float depth, + ArrayList points, + int pointIndex, + int pointLoopIndex, + float tension, + DrawingOperationTypes operationType, + LineSegmentType surfaceSegmentType, + float topDarkening, + float bottomDarkening, + PointF thirdPointPosition, + PointF fourthPointPosition, + bool clippedSegment, + bool clipOnTop, + bool clipOnBottom) + { + // Create graphics path for selection + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + //********************************************************************** + //** Check surface coordinates + //********************************************************************** + if(Math.Round(firstPoint.xPosition, 3) == Math.Round(secondPoint.xPosition, 3) && + Math.Round(firstPoint.yPosition, 3) == Math.Round(secondPoint.yPosition, 3)) + { + return resultPath; + } + + //**************************************************************** + //** Fint point with line properties + //**************************************************************** + DataPoint3D pointAttr = secondPoint; + if(prevDataPointEx.dataPoint.IsEmpty) + { + pointAttr = prevDataPointEx; + } + else if(firstPoint.index > secondPoint.index) + { + pointAttr = firstPoint; + } + + //**************************************************************** + //** Adjust point visual properties. + //**************************************************************** + Color color = (useBorderColor) ? pointAttr.dataPoint.BorderColor : pointAttr.dataPoint.Color; + ChartDashStyle dashStyle = pointAttr.dataPoint.BorderDashStyle; + if( pointAttr.dataPoint.IsEmpty && pointAttr.dataPoint.Color == Color.Empty) + { + color = Color.Gray; + } + if( pointAttr.dataPoint.IsEmpty && pointAttr.dataPoint.BorderDashStyle == ChartDashStyle.NotSet ) + { + dashStyle = ChartDashStyle.Solid; + } + + //**************************************************************** + //** Get axis position + //**************************************************************** + float axisPosition = (float)Math.Round(VAxis.GetPosition(this.VAxis.Crossing), 3); + + + //**************************************************************** + //** Detect visibility of the bounding rectangle. + //**************************************************************** + float minX = (float)Math.Min(firstPoint.xPosition, secondPoint.xPosition); + float minY = (float)Math.Min(firstPoint.yPosition, secondPoint.yPosition); + minY = (float)Math.Min(minY, axisPosition); + float maxX = (float)Math.Max(firstPoint.xPosition, secondPoint.xPosition); + float maxY = (float)Math.Max(firstPoint.yPosition, secondPoint.yPosition); + maxY = (float)Math.Max(maxY, axisPosition); + RectangleF position = new RectangleF(minX, minY, maxX - minX, maxY - minY); + SurfaceNames visibleSurfaces = graph.GetVisibleSurfaces(position,positionZ,depth,matrix); + + // Check if area point is drawn upside down. + bool upSideDown = false; + if( ((decimal)firstPoint.yPosition) >= ((decimal)axisPosition) && + ((decimal)secondPoint.yPosition) >= ((decimal)axisPosition) ) + { + upSideDown = true; + + // Switch visibility between Top & Bottom surfaces + bool topVisible = ( (visibleSurfaces & SurfaceNames.Top) == SurfaceNames.Top ); + bool bottomVisible = ( (visibleSurfaces & SurfaceNames.Bottom) == SurfaceNames.Bottom ); + visibleSurfaces ^= SurfaceNames.Bottom; + visibleSurfaces ^= SurfaceNames.Top; + if(topVisible) + { + visibleSurfaces |= SurfaceNames.Bottom; + } + if(bottomVisible) + { + visibleSurfaces |= SurfaceNames.Top; + } + } + + // Get visibility of the top surface (different from bounding rectangle) + GetTopSurfaceVisibility( + area, + firstPoint, + secondPoint, + upSideDown, + positionZ, + depth, + matrix, + ref visibleSurfaces); + + //**************************************************************** + //** Calculate position of top/bootom points. + //**************************************************************** + PointF thirdPoint, fourthPoint; + GetBottomPointsPosition( + Common, + area, + axisPosition, + ref firstPoint, + ref secondPoint, + thirdPointPosition, + fourthPointPosition, + out thirdPoint, + out fourthPoint); + + // Check if point's position provided as parameter + if(!float.IsNaN(thirdPointPosition.Y)) + { + thirdPoint.Y = thirdPointPosition.Y; + } + if(!float.IsNaN(fourthPointPosition.Y)) + { + fourthPoint.Y = fourthPointPosition.Y; + } + + if(float.IsNaN(thirdPoint.X) || + float.IsNaN(thirdPoint.Y) || + float.IsNaN(fourthPoint.X) || + float.IsNaN(fourthPoint.Y) ) + { + return resultPath; + } + + //**************************************************************** + //** Clip area first and second data points inside + //** the plotting area. + //**************************************************************** + if(clipOnTop && ClipTopPoints( + resultPath, + ref firstPoint, + ref secondPoint, + reversed, + area, + graph, + matrix, + lightStyle, + prevDataPointEx, + positionZ, + depth, + points, + pointIndex, + pointLoopIndex, + tension, + operationType, + surfaceSegmentType, + topDarkening, + bottomDarkening + ) == true) + { + return resultPath; + } + + //**************************************************************** + //** Clip area third and fourth data points inside + //** the plotting area. + //**************************************************************** + if(clipOnBottom && ClipBottomPoints( + resultPath, + ref firstPoint, + ref secondPoint, + ref thirdPoint, + ref fourthPoint, + reversed, + area, + graph, + matrix, + lightStyle, + prevDataPointEx, + positionZ, + depth, + points, + pointIndex, + pointLoopIndex, + tension, + operationType, + surfaceSegmentType, + topDarkening, + bottomDarkening + ) == true) + { + return resultPath; + } + + + //**************************************************************** + //** Check if area points are on the different sides of the axis. + //** In this case split area point into two points where the line + //** intersects the axis line + //**************************************************************** + if( (Math.Round((decimal)firstPoint.yPosition, 3) > (decimal)axisPosition + 0.001M && Math.Round((decimal)secondPoint.yPosition, 3) < (decimal)axisPosition - 0.001M) || + (Math.Round((decimal)firstPoint.yPosition, 3) < (decimal)axisPosition - 0.001M && Math.Round((decimal)secondPoint.yPosition, 3) > (decimal)axisPosition + 0.001M) ) + { + // Find intersection point + DataPoint3D intersectionPoint = GetAxisIntersection(firstPoint, secondPoint, axisPosition); + + for(int segmentIndex = 0; segmentIndex <= 1; segmentIndex++) + { + GraphicsPath segmentPath = null; + if(segmentIndex == 0 && !reversed || + segmentIndex == 1 && reversed) + { + // Draw first segment + intersectionPoint.dataPoint = secondPoint.dataPoint; + intersectionPoint.index = secondPoint.index; + segmentPath = Draw3DSurface( firstPoint, intersectionPoint, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, surfaceSegmentType, + topDarkening, bottomDarkening, + new PointF(float.NaN, float.NaN), + new PointF(float.NaN, float.NaN), + clippedSegment, + clipOnTop, clipOnBottom); + } + + if(segmentIndex == 1 && !reversed || + segmentIndex == 0 && reversed) + { + // Draw second segment + intersectionPoint.dataPoint = firstPoint.dataPoint; + intersectionPoint.index = firstPoint.index; + segmentPath = Draw3DSurface( intersectionPoint, secondPoint, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, surfaceSegmentType, + topDarkening, bottomDarkening, + new PointF(float.NaN, float.NaN), + new PointF(float.NaN, float.NaN), + clippedSegment, + clipOnTop, clipOnBottom); + } + + // Add segment path + if(resultPath != null && segmentPath != null && segmentPath.PointCount > 0) + { + resultPath.AddPath(segmentPath, true); + } + } + + return resultPath; + } + + //********************************************************************** + //** Check surface coordinates + //********************************************************************** + if(Math.Round(firstPoint.xPosition, 3) == Math.Round(secondPoint.xPosition, 3) && + Math.Round(firstPoint.yPosition, 3) == Math.Round(secondPoint.yPosition, 3)) + { + return resultPath; + } + + //**************************************************************** + //** Draw elements of area chart in 2 layers (back & front) + //**************************************************************** + for(int elemLayer = 1; elemLayer <= 2; elemLayer++) + { + // Loop through all surfaces + SurfaceNames[] surfacesOrder = new SurfaceNames[] {SurfaceNames.Back, SurfaceNames.Bottom, SurfaceNames.Top, SurfaceNames.Left, SurfaceNames.Right, SurfaceNames.Front}; + LineSegmentType lineSegmentType = LineSegmentType.Middle; + foreach(SurfaceNames currentSurface in surfacesOrder) + { + // Check if surface should be drawn + if (ChartGraphics.ShouldDrawLineChartSurface(area, area.ReverseSeriesOrder, currentSurface, visibleSurfaces, color, + points, firstPoint, secondPoint, this.multiSeries, ref lineSegmentType) != elemLayer) + { + continue; + } + + // To solvce segments overlapping issues with semi-transparent colors -> + // Draw invisible surfaces in the first loop, visible in second + if(this.allPointsLoopsNumber == 2 && (operationType & DrawingOperationTypes.DrawElement) == DrawingOperationTypes.DrawElement) + { + if(pointLoopIndex == 0) + { + if(currentSurface == SurfaceNames.Front || + elemLayer == 2 && (currentSurface == SurfaceNames.Left || currentSurface == SurfaceNames.Right)) + { + continue; + } + } + if(pointLoopIndex == 1) + { + if(currentSurface == SurfaceNames.Back || + currentSurface != SurfaceNames.Front) + { + if(elemLayer == 1) + { + continue; + } + else if(currentSurface != SurfaceNames.Left && currentSurface != SurfaceNames.Right) + { + continue; + } + } + } + } + + // Draw only borders of the invisible elements on the back layer + Color surfaceColor = color; + Color surfaceBorderColor = pointAttr.dataPoint.BorderColor; + if(elemLayer == 1) + { + // Draw only if point color is semi-transparent + if(surfaceColor.A == 255) + { + continue; + } + + // Define drawing colors + surfaceColor = Color.Transparent; + if(surfaceBorderColor == Color.Empty) + { + // If border color is emty use color slightly darker than main back color + surfaceBorderColor = ChartGraphics.GetGradientColor( color, Color.Black, 0.2 ); + } + } + + // Check if marker lines should be drawn + bool forceThinLines = this.showPointLines; + if(surfaceSegmentType == LineSegmentType.Middle) + { + forceThinLines = false; + } + + // 3D clipped segment is drawn - draw only top & bottom + if(clippedSegment && + currentSurface != SurfaceNames.Top && + currentSurface != SurfaceNames.Bottom) + { + continue; + } + + // Draw surfaces + GraphicsPath surfacePath = null; + switch(currentSurface) + { + case(SurfaceNames.Top): + { + // Darken colors + Color topColor = (topDarkening == 0f) ? surfaceColor : ChartGraphics.GetGradientColor(surfaceColor, Color.Black, topDarkening); + Color topBorderColor = (topDarkening == 0f) ? surfaceBorderColor : ChartGraphics.GetGradientColor(surfaceBorderColor, Color.Black, topDarkening); + + surfacePath = graph.Draw3DSurface( area, matrix, lightStyle, currentSurface, positionZ, depth, + topColor, topBorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + firstPoint, secondPoint, points, pointIndex, + 0f, operationType, surfaceSegmentType, + forceThinLines, false, area.ReverseSeriesOrder, this.multiSeries, 0, true); + + break; + } + case(SurfaceNames.Bottom): + { + // Calculate coordinates + DataPoint3D dp1 = new DataPoint3D(); + dp1.index = firstPoint.index; + dp1.dataPoint = firstPoint.dataPoint; + dp1.xPosition = firstPoint.xPosition; + dp1.yPosition = thirdPoint.Y; + DataPoint3D dp2 = new DataPoint3D(); + dp2.index = secondPoint.index; + dp2.dataPoint = secondPoint.dataPoint; + dp2.xPosition = secondPoint.xPosition; + dp2.yPosition = fourthPoint.Y; + + // Darken colors + Color bottomColor = (bottomDarkening == 0f) ? surfaceColor : ChartGraphics.GetGradientColor(surfaceColor, Color.Black, topDarkening); + Color bottomBorderColor = (bottomDarkening == 0f) ? surfaceBorderColor : ChartGraphics.GetGradientColor(surfaceBorderColor, Color.Black, topDarkening); + + // Draw surface + surfacePath = graph.Draw3DSurface( area, matrix, lightStyle, currentSurface, positionZ, depth, + bottomColor, bottomBorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + dp1, dp2, points, pointIndex, + 0f, operationType, surfaceSegmentType, + forceThinLines, false, area.ReverseSeriesOrder, this.multiSeries, 0, true); + + break; + } + + case(SurfaceNames.Left): + { + if(surfaceSegmentType == LineSegmentType.Single || + (!area.ReverseSeriesOrder && surfaceSegmentType == LineSegmentType.First) || + (area.ReverseSeriesOrder && surfaceSegmentType == LineSegmentType.Last)) + { + + // Calculate coordinates + DataPoint3D leftMostPoint = (firstPoint.xPosition <= secondPoint.xPosition) ? firstPoint : secondPoint; + DataPoint3D dp1 = new DataPoint3D(); + dp1.index = leftMostPoint.index; + dp1.dataPoint = leftMostPoint.dataPoint; + dp1.xPosition = leftMostPoint.xPosition; + dp1.yPosition = (firstPoint.xPosition <= secondPoint.xPosition) ? thirdPoint.Y : fourthPoint.Y; + DataPoint3D dp2 = new DataPoint3D(); + dp2.index = leftMostPoint.index; + dp2.dataPoint = leftMostPoint.dataPoint; + dp2.xPosition = leftMostPoint.xPosition;; + dp2.yPosition = leftMostPoint.yPosition; + + // Draw surface + surfacePath = graph.Draw3DSurface( area, matrix, lightStyle, currentSurface, positionZ, depth, + surfaceColor, surfaceBorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + dp1, dp2, points, pointIndex, + 0f, operationType, LineSegmentType.Single, true, true, area.ReverseSeriesOrder, this.multiSeries, 0, true); + + } + break; + } + case(SurfaceNames.Right): + { + if(surfaceSegmentType == LineSegmentType.Single || + (!area.ReverseSeriesOrder && surfaceSegmentType == LineSegmentType.Last) || + (area.ReverseSeriesOrder && surfaceSegmentType == LineSegmentType.First)) + + { + // Calculate coordinates + DataPoint3D rightMostPoint = (secondPoint.xPosition >= firstPoint.xPosition) ? secondPoint : firstPoint; + DataPoint3D dp1 = new DataPoint3D(); + dp1.index = rightMostPoint.index; + dp1.dataPoint = rightMostPoint.dataPoint; + dp1.xPosition = rightMostPoint.xPosition; + dp1.yPosition = (secondPoint.xPosition >= firstPoint.xPosition) ? fourthPoint.Y : thirdPoint.Y; + DataPoint3D dp2 = new DataPoint3D(); + dp2.index = rightMostPoint.index; + dp2.dataPoint = rightMostPoint.dataPoint; + dp2.xPosition = rightMostPoint.xPosition; + dp2.yPosition = rightMostPoint.yPosition; + + // Draw surface + surfacePath = graph.Draw3DSurface( area, matrix, lightStyle, currentSurface, positionZ, depth, + surfaceColor, surfaceBorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + dp1, dp2, points, pointIndex, + 0f, operationType, LineSegmentType.Single, true, true, area.ReverseSeriesOrder, this.multiSeries, 0, true); + + } + + break; + } + case(SurfaceNames.Back): + { + // Calculate coordinates + DataPoint3D dp1 = new DataPoint3D(); + dp1.index = firstPoint.index; + dp1.dataPoint = firstPoint.dataPoint; + dp1.xPosition = firstPoint.xPosition; + dp1.yPosition = thirdPoint.Y; + DataPoint3D dp2 = new DataPoint3D(); + dp2.index = secondPoint.index; + dp2.dataPoint = secondPoint.dataPoint; + dp2.xPosition = secondPoint.xPosition; + dp2.yPosition = fourthPoint.Y; + + // Border line is required on the data point boundary + SurfaceNames thinBorderSides = 0; + if(forceThinLines) + { + if(surfaceSegmentType == LineSegmentType.Single) + thinBorderSides = SurfaceNames.Left | SurfaceNames.Right; + else if(surfaceSegmentType == LineSegmentType.First) + thinBorderSides = SurfaceNames.Left; + else if(surfaceSegmentType == LineSegmentType.Last) + thinBorderSides = SurfaceNames.Right; + } + + + // Draw surface + surfacePath = graph.Draw3DPolygon( area, matrix, currentSurface, positionZ, + surfaceColor, surfaceBorderColor, pointAttr.dataPoint.BorderWidth, + firstPoint, secondPoint, dp2, dp1, operationType, lineSegmentType, + thinBorderSides); + break; + } + case(SurfaceNames.Front): + { + // Calculate coordinates + DataPoint3D dp1 = new DataPoint3D(); + dp1.index = firstPoint.index; + dp1.dataPoint = firstPoint.dataPoint; + dp1.xPosition = firstPoint.xPosition; + dp1.yPosition = thirdPoint.Y; + + DataPoint3D dp2 = new DataPoint3D(); + dp2.index = secondPoint.index; + dp2.dataPoint = secondPoint.dataPoint; + dp2.xPosition = secondPoint.xPosition; + dp2.yPosition = fourthPoint.Y; + + // Change segment type for the reversed series order + if (area.ReverseSeriesOrder) + { + if(lineSegmentType == LineSegmentType.First) + { + lineSegmentType = LineSegmentType.Last; + } + else if(lineSegmentType == LineSegmentType.Last) + { + lineSegmentType = LineSegmentType.First; + } + } + + if(surfaceSegmentType != LineSegmentType.Single) + { + if( surfaceSegmentType == LineSegmentType.Middle || + ( surfaceSegmentType == LineSegmentType.First && lineSegmentType != LineSegmentType.First) || + ( surfaceSegmentType == LineSegmentType.Last && lineSegmentType != LineSegmentType.Last) ) + { + lineSegmentType = LineSegmentType.Middle; + } + } + + // Border line is required on the data point boundary + SurfaceNames thinBorderSides = 0; + if(forceThinLines) + { + if(surfaceSegmentType == LineSegmentType.Single) + thinBorderSides = SurfaceNames.Left | SurfaceNames.Right; + else if(surfaceSegmentType == LineSegmentType.First) + thinBorderSides = SurfaceNames.Left; + else if(surfaceSegmentType == LineSegmentType.Last) + thinBorderSides = SurfaceNames.Right; + } + + // Draw surface + surfacePath = graph.Draw3DPolygon( area, matrix, currentSurface, positionZ + depth, + surfaceColor, surfaceBorderColor, pointAttr.dataPoint.BorderWidth, + firstPoint, secondPoint, dp2, dp1, operationType, lineSegmentType, + thinBorderSides); + + break; + } + } + + // Add path of the fully visible surfaces to the result surface + if(elemLayer == 2 && resultPath != null && surfacePath != null && surfacePath.PointCount > 0) + { + resultPath.CloseFigure(); + resultPath.SetMarkers(); + resultPath.AddPath(surfacePath, true); + } + + } + } + + return resultPath; + } + + + /// + /// Gets visibility of the top surface. + /// + /// Chart area object. + /// First data point of the line. + /// Second data point of the line. + /// Indicates that Y values of the data points are below axis line. + /// Z coordinate of the back side of the cube. + /// Cube depth. + /// Coordinate transformation matrix. + /// Surface visibility reference. Initialized with bounary cube visibility. + protected virtual void GetTopSurfaceVisibility( + ChartArea area, + DataPoint3D firstPoint, + DataPoint3D secondPoint, + bool upSideDown, + float positionZ, + float depth, + Matrix3D matrix, + ref SurfaceNames visibleSurfaces) + { + // If Top surface visibility in bounding rectangle - do not gurantee angled linde visibility + if( (visibleSurfaces & SurfaceNames.Top) == SurfaceNames.Top) + { + visibleSurfaces ^= SurfaceNames.Top; + } + + // Create top surface coordinates in 3D space + Point3D[] cubePoints = new Point3D[3]; + if (!area.ReverseSeriesOrder) + { + if(!upSideDown && firstPoint.xPosition <= secondPoint.xPosition || + upSideDown && firstPoint.xPosition >= secondPoint.xPosition) + { + cubePoints[0] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ + depth ); + cubePoints[1] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ ); + cubePoints[2] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ ); + } + else + { + cubePoints[0] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ + depth ); + cubePoints[1] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ ); + cubePoints[2] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ ); + } + } + else + { + if(!upSideDown && secondPoint.xPosition <= firstPoint.xPosition || + upSideDown && secondPoint.xPosition >= firstPoint.xPosition) + { + cubePoints[0] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ + depth ); + cubePoints[1] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ ); + cubePoints[2] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ ); + } + else + { + cubePoints[0] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ + depth ); + cubePoints[1] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ ); + cubePoints[2] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ ); + } + } + + // Tranform coordinates + matrix.TransformPoints( cubePoints ); + + // Check the top side visibility + if(ChartGraphics.IsSurfaceVisible(cubePoints[0],cubePoints[1],cubePoints[2])) + { + visibleSurfaces |= SurfaceNames.Top; + } + } + + /// + /// Gets intersection point coordinates between point line and axis line. + /// + /// First data point. + /// Second data point. + /// Axis line position. + /// Intersection point coordinates. + internal DataPoint3D GetAxisIntersection(DataPoint3D firstPoint, DataPoint3D secondPoint, float axisPosition) + { + DataPoint3D intersectionPoint = new DataPoint3D(); + intersectionPoint.yPosition = axisPosition; + intersectionPoint.xPosition = (axisPosition - firstPoint.yPosition) * + (secondPoint.xPosition - firstPoint.xPosition) / + (secondPoint.yPosition - firstPoint.yPosition) + + firstPoint.xPosition ; + return intersectionPoint; + } + + /// + /// Gets position ob the bottom points in area chart. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Axis position. + /// First top point coordinates. + /// Second top point coordinates. + /// Position where the third point is actually located or float.NaN if same as in "firstPoint". + /// Position where the fourth point is actually located or float.NaN if same as in "secondPoint". + /// Returns third bottom point coordinates. + /// Returns fourth bottom point coordinates. + protected virtual void GetBottomPointsPosition( + CommonElements common, + ChartArea area, + float axisPosition, + ref DataPoint3D firstPoint, + ref DataPoint3D secondPoint, + PointF thirdPointPosition, + PointF fourthPointPosition, + out PointF thirdPoint, + out PointF fourthPoint) + { + thirdPoint = new PointF((float)firstPoint.xPosition, axisPosition); + fourthPoint = new PointF((float)secondPoint.xPosition, axisPosition); + } + + /// + /// Returns how many loops through all data points is required (1 or 2) + /// + /// Selection indicator. + /// Points array list. + /// Number of loops (1 or 2). + override protected int GetPointLoopNumber(bool selection, ArrayList pointsArray) + { + // Always one loop for selection + if(selection) + { + return 1; + } + + // Second loop will be required for semi-transparent colors + int loopNumber = 1; + foreach(object obj in pointsArray) + { + // Get point & series + DataPoint3D pointEx = (DataPoint3D) obj; + + // Check properties + if(pointEx.dataPoint.Color.A != 255) + { + loopNumber = 2; + } + } + + return loopNumber; + } + + #endregion + + #region IDisposable overrides + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { // Managed resources + if (this.areaPath != null) + { + this.areaPath.Dispose(); + this.areaPath = null; + } + } + base.Dispose(disposing); + } + #endregion + + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/BarChart.cs b/System.Web.DataVisualization/Common/ChartTypes/BarChart.cs new file mode 100644 index 000000000..f4be0d766 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/BarChart.cs @@ -0,0 +1,2351 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: BarChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: BarChart, RangeBarChart +// +// Purpose: Provides 2D/3D drawing and hit testing functionality +// for the Bar and RangeBar charts. +// +// Reviewed: AG - August 1, 2002 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + #region Bar label style enumeration + + /// + /// Bar chart value label drawing style. + /// + internal enum BarValueLabelDrawingStyle + { + /// + /// Outside of the bar. + /// + Outside, + + /// + /// Inside the bar aligned to the left. + /// + Left, + + /// + /// Inside the bar aligned to the center. + /// + Center, + + /// + /// Inside the bar aligned to the right. + /// + Right, + }; + + #endregion + + /// + /// BarChart class contains all the code necessary to draw + /// both Bar and RangeBar charts. The RangeBarChart class is used + /// to override few default settings, so that 2 Y values + /// will be used to define left and right position of each bar. + /// + internal class RangeBarChart : BarChart + { + #region Constructor + + /// + /// Public constructor + /// + public RangeBarChart() + { + // Set the flag to use two Y values, while drawing the bars + this.useTwoValues = true; + + // Change default style of the labels + this.defLabelDrawingStyle = BarValueLabelDrawingStyle.Center; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.RangeBar;}} + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + override public bool ZeroCrossing { get{ return true;} } + + /// + /// Number of supported Y value(s) per point + /// + override public int YValuesPerPoint{ get { return 2; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + override public bool ExtraYValuesConnectedToYAxis{ get { return true; } } + + #endregion + } + + /// + /// BarChart class provides 2D/3D drawing and hit testing + /// functionality for the Bar and RangeBar charts. The only + /// difference between the RangeBar and Bar chart is that + /// 2 Y values are used to position left and right side + /// of each RangeBar bar. + /// + internal class BarChart : IChartType + { + #region Fields + + /// + /// Indicates that two Y values are used to calculate bar position + /// + protected bool useTwoValues = false; + + /// + /// Indicates that bars from different series are drawn side by side + /// + protected bool drawSeriesSideBySide = true; + + /// + /// Defines the default drawing style of the labels. + /// + protected BarValueLabelDrawingStyle defLabelDrawingStyle = BarValueLabelDrawingStyle.Outside; + + /// + /// Indicates that second point loop is required to draw points labels or markers. + /// + protected bool pointLabelsMarkersPresent = false; + + #endregion + + #region Constructor + + /// + /// Default constructor + /// + public BarChart() + { + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.Bar;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + /// + /// True if chart type is stacked + /// + public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports Logarithmic axes + /// + public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + public bool SwitchValueAxes { get{ return true;} } + + /// + /// True if chart series can be placed side-by-side. + /// + virtual public bool SideBySideSeries { get{ return true;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return true;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + public bool DataPointsInLegend { get{ return false;} } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return false; } } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + public bool ApplyPaletteColorsToPoints { get { return false; } } + + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint{ get { return 1; } } + + #endregion + + #region Painting and selection methods + + /// + /// Paint Bar Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + // Draw data points + this.pointLabelsMarkersPresent = false; + ProcessChartType( false, false, graph, common, area, seriesToDraw ); + + // Draw markers and lables + if(this.pointLabelsMarkersPresent) + { + ProcessChartType( true, false, graph, common, area, seriesToDraw ); + } + } + + /// + /// Calculates position of each bar in all series and either draws it or checks the selection. + /// + /// Mode which draws only labels and markers. + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + private void ProcessChartType( + bool labels, + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + //************************************************************ + //** Local variables declaration + //************************************************************ + int seriesIndx = 0; // Data Series index + bool sameInterval = false; // Series points are equally spaced + + // Get pixel size + SizeF pixelRelSize = graph.GetRelativeSize(new SizeF(1.1f, 1.1f)); + + + //************************************************************ + //** Prosess 3D chart type + //************************************************************ + if(area.Area3DStyle.Enable3D) + { + ProcessChartType3D( selection, graph, common, area, seriesToDraw ); + return; + } + + + //************************************************************ + //** Collect initial series data + //************************************************************ + + // All data series from chart area which have Bar chart type + List typeSeries = area.GetSeriesFromChartType(Name); + + // Check if series should be drawn side by side + bool currentDrawSeriesSideBySide = this.drawSeriesSideBySide; + foreach(string seriesName in typeSeries) + { + if(common.DataManager.Series[seriesName].IsCustomPropertySet(CustomPropertyName.DrawSideBySide)) + { + string attribValue = common.DataManager.Series[seriesName][CustomPropertyName.DrawSideBySide]; + if(String.Compare(attribValue, "False", StringComparison.OrdinalIgnoreCase ) == 0) + { + currentDrawSeriesSideBySide = false; + } + else if (String.Compare(attribValue, "True", StringComparison.OrdinalIgnoreCase) == 0) + { + currentDrawSeriesSideBySide = true; + } + else if (String.Compare(attribValue, "Auto", StringComparison.OrdinalIgnoreCase) == 0) + { + // Do nothing + } + else + { + throw (new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid)); + } + } + } + + // Find the number of "Bar chart" data series + int numOfSeries = typeSeries.Count; + if(!currentDrawSeriesSideBySide) + { + numOfSeries = 1; + } + + // Check if bar chart series are indexed + bool indexedSeries = ChartHelper.IndexedSeries(area.Common, typeSeries.ToArray()); + + + //************************************************************ + //** Loop through all series + //************************************************************ + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with Bar chart type + if( String.Compare( ser.ChartTypeName, Name, true, System.Globalization.CultureInfo.CurrentCulture ) != 0 + || ser.ChartArea != area.Name || ser.Points.Count == 0 || !ser.IsVisible()) + { + continue; + } + + // Set active horizontal axis + Axis vAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + double vertViewMax = vAxis.ViewMaximum; + double vertViewMin = vAxis.ViewMinimum; + + // Set active vertical axis + Axis hAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + double horizViewMax = hAxis.ViewMaximum; + double horizViewMin = hAxis.ViewMinimum; + + // Get points interval: + // - set interval to 1 for indexed series + // - if points are not equaly spaced, the minimum interval between points is selected. + // - if points have same interval bars do not overlap each other. + double interval = 1; + if(!indexedSeries) + { + if(ser.Points.Count == 1 && + (ser.XValueType == ChartValueType.Date || + ser.XValueType == ChartValueType.DateTime || + ser.XValueType == ChartValueType.Time || + ser.XValueType == ChartValueType.DateTimeOffset)) + { + // Check if interval is the same + area.GetPointsInterval( typeSeries, vAxis.IsLogarithmic, vAxis.logarithmBase, true, out sameInterval ); + + // Special case when there is only one data point and date scale is used. + if(!double.IsNaN(vAxis.majorGrid.GetInterval()) && vAxis.majorGrid.GetIntervalType() != DateTimeIntervalType.NotSet) + { + interval = ChartHelper.GetIntervalSize(vAxis.minimum, vAxis.majorGrid.GetInterval(), vAxis.majorGrid.GetIntervalType()); + } + else + { + interval = ChartHelper.GetIntervalSize(vAxis.minimum, vAxis.Interval, vAxis.IntervalType); + } + } + else + { + interval = area.GetPointsInterval( typeSeries, vAxis.IsLogarithmic, vAxis.logarithmBase, true, out sameInterval ); + } + } + + // Calculates the width of bars. + double width = ser.GetPointWidth(graph, vAxis, interval, 0.8) / numOfSeries; + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + //************************************************************ + //** Loop through all points in series + //************************************************************ + int pointIndex = 0; + int markerIndex = 0; + foreach( DataPoint point in ser.Points ) + { + // Check required Y values number + if(point.YValues.Length < this.YValuesPerPoint) + { + throw(new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture) ))); + } + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Get Y value and make sure it fits the chart area. + // If chart type uses 2 Y values (RangeBar) use second Y value for size. + double yValue = hAxis.GetLogValue( GetYValue(common, area, ser, point, pointIndex, (useTwoValues) ? 1 : 0) ); + + bool yValueOutside = false; + bool yValueStartOutside = true; + if( (decimal)yValue > (decimal)horizViewMax ) + { + yValue = horizViewMax; + yValueOutside = true; + } + else if( (decimal)yValue < (decimal)horizViewMin ) + { + yValue = horizViewMin; + yValueOutside = true; + } + + // Calculate the bar size + double barSize = hAxis.GetLinearPosition( yValue ); + + // Set start position for a bar + double barStartPosition = 0; + if(useTwoValues) + { + // Point Y value (first) is used to determine the bar starting position + double yValueStart = hAxis.GetLogValue( GetYValue(common, area, ser, point, pointIndex, 0 ) ); + yValueStartOutside = false; + if( (decimal)yValueStart > (decimal)horizViewMax ) + { + yValueStart = horizViewMax; + yValueStartOutside = true; + } + else if( (decimal)yValueStart < (decimal)horizViewMin ) + { + yValueStart = horizViewMin; + yValueStartOutside = true; + } + + barStartPosition = hAxis.GetLinearPosition(yValueStart); + } + else + { + // Bar starts on the vertical axis + barStartPosition = hAxis.GetPosition(hAxis.Crossing); + } + + // Calculate X position of the Bar + double xPosition = 0; + if( indexedSeries ) + { + // The formula for position is based on a distance + // from the grid line or nPoints position. + xPosition = vAxis.GetPosition( (double)pointIndex + 1 ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width; + } + else if( sameInterval ) + { + xPosition = vAxis.GetPosition( point.XValue ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width; + } + else + { + xPosition = vAxis.GetPosition( point.XValue ); + } + + // Make sure that points with small values are still visible + if( barSize < barStartPosition && + (barStartPosition - barSize) < pixelRelSize.Width) + { + barSize = barStartPosition - pixelRelSize.Width; + } + if( barSize > barStartPosition && + (barSize - barStartPosition) < pixelRelSize.Width) + { + barSize = barStartPosition + pixelRelSize.Width; + } + + // Set rectangle coordinates of the bar + RectangleF rectSize = RectangleF.Empty; + try + { + // Set the bar rectangle + rectSize.Y = (float)(xPosition - width/2); + rectSize.Height = (float)(width); + + // The left side of rectangle has always + // smaller value than a right value + if( barStartPosition < barSize ) + { + rectSize.X = (float)barStartPosition; + rectSize.Width = (float)barSize - rectSize.X; + } + else + { + rectSize.X = (float)barSize; + rectSize.Width = (float)barStartPosition - rectSize.X; + } + } + catch(OverflowException) + { + pointIndex++; + continue; + } + + // Remeber pre-calculated point position + point.positionRel = new PointF(( barStartPosition < barSize ) ? rectSize.Right : rectSize.X, (float)xPosition); + + //************************************************************ + //** Painting mode + //************************************************************ + if( common.ProcessModePaint ) + { + // if data point is not empty and not labels drawing mode + if( !point.IsEmpty && !labels) + { + // Check if column is completly out of the data scaleView + double xValue = (indexedSeries) ? pointIndex + 1 : point.XValue; + xValue = vAxis.GetLogValue(xValue); + if(xValue < vertViewMin || xValue > vertViewMax ) + { + pointIndex++; + continue; + } + + // Check if column is partialy in the data scaleView + bool clipRegionSet = false; + if(rectSize.Y < area.PlotAreaPosition.Y || rectSize.Bottom > area.PlotAreaPosition.Bottom) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw the bar rectangle + graph.FillRectangleRel( rectSize, + point.Color, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + point.BackSecondaryColor, + point.BorderColor, + point.BorderWidth, + point.BorderDashStyle, + ser.ShadowColor, + ser.ShadowOffset, + PenAlignment.Inset, + ChartGraphics.GetBarDrawingStyle(point), + false); + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + + if (common.ProcessModeRegions) + { + common.HotRegionsList.AddHotRegion(rectSize, point, ser.Name, pointIndex); + } + } + + // Draw labels and markers (only if part of the bar is visible) + if( !(yValueOutside && yValueStartOutside && rectSize.Width == 0f) ) + { + if ((rectSize.Y + rectSize.Height / 2f) >= area.PlotAreaPosition.Y && + (rectSize.Y + rectSize.Height / 2f) <= area.PlotAreaPosition.Bottom) + { + if(labels) + { + DrawLabelsAndMarkers( area, graph, common, rectSize, point, ser, barStartPosition, barSize, width, pointIndex, ref markerIndex); + } + else + { + // Check if separate drawing loop required for labels and markers + if(point.MarkerStyle != MarkerStyle.None || point.MarkerImage.Length > 0) + { + this.pointLabelsMarkersPresent = true; + } + else if(ser.IsValueShownAsLabel || point.IsValueShownAsLabel || point.Label.Length > 0) + { + this.pointLabelsMarkersPresent = true; + } + } + } + } + } + + //************************************************************ + // Hot Regions mode used for image maps, tool tips and + // hit test function + //************************************************************ + if (common.ProcessModeRegions && !common.ProcessModePaint) + { + common.HotRegionsList.AddHotRegion( rectSize, point, ser.Name, pointIndex ); + + // Process labels and markers regions only if it was not done while painting + if(labels ) + { + DrawLabelsAndMarkers( area, graph, common, rectSize, point, ser, barStartPosition, barSize, width, pointIndex, ref markerIndex); + } + } + + // Increase the data index counter + pointIndex++; + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + // Increase data series index + if(currentDrawSeriesSideBySide) + { + seriesIndx++; + } + + } + } + + /// + /// Adjusts size in pixels to the DPIs different than 96. + /// + /// Size in pixels. + /// Chart graphics. + /// Adjusted pixel size. + private static int GetAdjustedPixelSize(int pixelSize, ChartGraphics graph) + { + if (graph != null && graph.Graphics != null) + { + // Marker size is in pixels and we do the mapping for higher DPIs + SizeF size = new SizeF(); + size.Width = pixelSize * graph.Graphics.DpiX / 96; + size.Height = pixelSize * graph.Graphics.DpiY / 96; + pixelSize = (int)Math.Max(size.Width, size.Height); + } + + return pixelSize; + } + + /// + /// Draws labels and markers. + /// + /// Chart area for this chart. + /// The Chart Graphics object. + /// The Common elements object. + /// Bar rectangle. + /// Data point. + /// Data series. + /// The zero position or the bottom of bars. + /// The Height of bars. + /// The width of bars. + /// Point index. + /// Marker index reference. + private void DrawLabelsAndMarkers( + ChartArea area, + ChartGraphics graph, + CommonElements common, + RectangleF rectSize, + DataPoint point, + Series ser, + double barStartPosition, + double barSize, + double width, + int pointIndex, + ref int markerIndex) + { + + //************************************************************ + // Draw data point value marker + //************************************************************ + SizeF markerSize = SizeF.Empty; + if(point.MarkerStyle != MarkerStyle.None || point.MarkerImage.Length > 0) + { + // Check if this marker should be drawn + if(markerIndex == 0) + { + // Find relative marker size + if(point.MarkerImage.Length == 0) + { + markerSize.Width = point.MarkerSize; + markerSize.Height = point.MarkerSize; + } + else + common.ImageLoader.GetAdjustedImageSize(point.MarkerImage, graph.Graphics, ref markerSize); + + markerSize = graph.GetRelativeSize( markerSize ); + + // Calculate marker position + PointF markerPosition = PointF.Empty; + if( barStartPosition < barSize ) + { + markerPosition.X = rectSize.Right; + } + else + { + markerPosition.X = rectSize.X; + } + markerPosition.Y = rectSize.Y + rectSize.Height/2F; + + if( common.ProcessModePaint ) + { + // Draw marker + graph.DrawMarkerRel( + markerPosition, + point.MarkerStyle, + BarChart.GetAdjustedPixelSize(point.MarkerSize, graph), + (point.MarkerColor == Color.Empty) ? point.Color : point.MarkerColor, + point.MarkerBorderColor, + point.MarkerBorderWidth, + point.MarkerImage, + point.MarkerImageTransparentColor, + (point.series != null) ? point.series.ShadowOffset : 0, + (point.series != null) ? point.series.ShadowColor : Color.Empty, + RectangleF.Empty); + } + if( common.ProcessModeRegions ) + { + SetHotRegions( + common, + graph, + point, + markerSize, + point.series.Name, + pointIndex, + point.MarkerStyle, + markerPosition ); + } + } + + // Increase the markers counter + ++markerIndex; + if(ser.MarkerStep == markerIndex) + { + markerIndex = 0; + } + + } + + //************************************************************ + // Draw data point value label + //************************************************************ + if (point.Label.Length > 0 || + (!point.IsEmpty && (ser.IsValueShownAsLabel || point.IsValueShownAsLabel))) + { + // Label rectangle + RectangleF rectLabel = RectangleF.Empty; + + // Label text format + using (StringFormat format = new StringFormat()) + { + + //************************************************************ + // Get label text + //************************************************************ + string text; + if( point.Label.Length == 0 ) + { + text = ValueConverter.FormatValue( + ser.Chart, + point, + point.Tag, + GetYValue(common, area, ser, point, pointIndex, 0 ), + point.LabelFormat, + ser.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + } + + //************************************************************ + // Check labels style custom properties + //************************************************************ + BarValueLabelDrawingStyle drawingStyle = defLabelDrawingStyle; + string valueLabelAttrib = ""; + if (point.IsCustomPropertySet(CustomPropertyName.BarLabelStyle)) + { + valueLabelAttrib = point[CustomPropertyName.BarLabelStyle]; + } + else if (ser.IsCustomPropertySet(CustomPropertyName.BarLabelStyle)) + { + valueLabelAttrib = ser[CustomPropertyName.BarLabelStyle]; + } + + if (valueLabelAttrib.Length > 0) + { + if (String.Compare(valueLabelAttrib, "Left", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Left; + if (String.Compare(valueLabelAttrib, "Right", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Right; + if (String.Compare(valueLabelAttrib, "Center", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Center; + else if (String.Compare(valueLabelAttrib, "Outside", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Outside; + } + + //************************************************************ + // Make sure label fits. Otherwise change it style + //************************************************************ + bool labelFit = false; + bool labelSwitched = false; + bool labelSwitchedBack = false; + float prevWidth = 0f; + while (!labelFit) + { + // LabelStyle text format + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + + // Label rectangle + if (barStartPosition <= barSize) + { + rectLabel.X = rectSize.Right; + rectLabel.Width = area.PlotAreaPosition.Right - rectSize.Right; + if (rectLabel.Width < 0.001f && + barStartPosition == barSize) + { + rectLabel.Width = rectSize.X - area.PlotAreaPosition.X; + rectLabel.X = area.PlotAreaPosition.X; + format.Alignment = StringAlignment.Far; + } + } + else + { + rectLabel.X = area.PlotAreaPosition.X; + rectLabel.Width = rectSize.X - area.PlotAreaPosition.X; + } + + // Adjust label rectangle + rectLabel.Y = rectSize.Y - (float)width / 2F; + rectLabel.Height = rectSize.Height + (float)width; + + // Adjust label position depending on the drawing style + if (drawingStyle == BarValueLabelDrawingStyle.Outside) + { + // Adjust position if point marker is drawn + if (!markerSize.IsEmpty) + { + rectLabel.Width -= (float)Math.Min(rectLabel.Width, markerSize.Width / 2F); + if (barStartPosition < barSize) + { + rectLabel.X += (float)Math.Min(rectLabel.Width, markerSize.Width / 2F); + } + } + } + else if (drawingStyle == BarValueLabelDrawingStyle.Left) + { + rectLabel = rectSize; + format.Alignment = StringAlignment.Near; + } + else if (drawingStyle == BarValueLabelDrawingStyle.Center) + { + rectLabel = rectSize; + format.Alignment = StringAlignment.Center; + } + else if (drawingStyle == BarValueLabelDrawingStyle.Right) + { + rectLabel = rectSize; + format.Alignment = StringAlignment.Far; + + // Adjust position if point marker is drawn + if (!markerSize.IsEmpty) + { + rectLabel.Width -= (float)Math.Min(rectLabel.Width, markerSize.Width / 2F); + if (barStartPosition >= barSize) + { + rectLabel.X += (float)Math.Min(rectLabel.Width, markerSize.Width / 2F); + } + } + } + + // Reversed string alignment + if (barStartPosition > barSize) + { + if (format.Alignment == StringAlignment.Far) + format.Alignment = StringAlignment.Near; + else if (format.Alignment == StringAlignment.Near) + format.Alignment = StringAlignment.Far; + } + + // Make sure value label fits rectangle. + SizeF valueTextSize = graph.MeasureStringRel(text, point.Font); + if (!labelSwitched && + !labelSwitchedBack && + valueTextSize.Width > rectLabel.Width - 1) + { + // Switch label style only once + labelSwitched = true; + prevWidth = rectLabel.Width; + + // If text do not fit - try to switch between Outside/Inside drawing styles + if (drawingStyle == BarValueLabelDrawingStyle.Outside) + { + drawingStyle = BarValueLabelDrawingStyle.Right; + } + else + { + drawingStyle = BarValueLabelDrawingStyle.Outside; + } + } + else + { + // If label do not fit either Outside or to the Right, + // select the style that has more space available. + if (labelSwitched && + !labelSwitchedBack && + valueTextSize.Width > rectLabel.Width - 1 && + prevWidth > rectLabel.Width) + { + labelSwitchedBack = true; + + // Change back to the previous labels style + if (drawingStyle == BarValueLabelDrawingStyle.Outside) + { + drawingStyle = BarValueLabelDrawingStyle.Right; + } + else + { + drawingStyle = BarValueLabelDrawingStyle.Outside; + } + } + else + { + // Do not try to fit labels any more + labelFit = true; + } + } + } + + //************************************************************ + // Draw label + //************************************************************ + + // Calculate label background position + RectangleF labelBackPosition = RectangleF.Empty; + if (common.ProcessModeRegions || + !point.LabelBackColor.IsEmpty || + !point.LabelBorderColor.IsEmpty) + { + if (rectLabel.Width > 0 && rectLabel.Height > 0) + { + // Get label background position + SizeF valueTextSize = graph.MeasureStringRel(text, point.Font); + valueTextSize.Height += valueTextSize.Height / 8; + float spacing = valueTextSize.Width / text.Length / 2; + valueTextSize.Width += spacing; + labelBackPosition = new RectangleF( + rectLabel.X, + rectLabel.Y + (rectLabel.Height - valueTextSize.Height) / 2, + valueTextSize.Width, + valueTextSize.Height); + + // Adjust position based on alignment + if (format.Alignment == StringAlignment.Near) + { + labelBackPosition.X += spacing / 2f; + rectLabel.X += spacing; + } + else if (format.Alignment == StringAlignment.Center) + { + labelBackPosition.X = rectLabel.X + (rectLabel.Width - valueTextSize.Width) / 2f; + } + else if (format.Alignment == StringAlignment.Far) + { + labelBackPosition.X = rectLabel.Right - valueTextSize.Width - spacing / 2f; + rectLabel.X -= spacing; + } + } + } + + // Make sure there is enough vertical space for the label + // NOTE: Fixes issue #4502 + SizeF textSize = graph.MeasureStringRel(text, point.Font); + if (textSize.Height > rectLabel.Height) + { + rectLabel.Y -= (textSize.Height - rectLabel.Height) / 2f; + rectLabel.Height = textSize.Height; + } + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + rectLabel, + format, + point.LabelAngle, + labelBackPosition, + + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + ser, + point, + pointIndex); + } + } + } + } + + /// + /// Inserts Hot Regions used for image maps, tool tips and + /// hit test function + /// + /// Common elements object + /// Chart Graphics object + /// Data point used for hot region + /// Size of the marker + /// Name of the series + /// Data point index + /// Marker Style + /// Marker Position + private void SetHotRegions( CommonElements common, ChartGraphics graph, DataPoint point, SizeF markerSize, string seriesName, int pointIndex, MarkerStyle pointMarkerStyle, PointF markerPosition ) + { + + // Get relative marker size + SizeF relativeMarkerSize = markerSize; + + int insertIndex = common.HotRegionsList.FindInsertIndex(); + + // Insert circle area + if( pointMarkerStyle == MarkerStyle.Circle ) + { + common.HotRegionsList.AddHotRegion( insertIndex, graph, markerPosition.X, markerPosition.Y, relativeMarkerSize.Width/2f, point, seriesName, pointIndex ); + } + // All other markers represented as rectangles + else + { + // Insert area + common.HotRegionsList.AddHotRegion( + new RectangleF(markerPosition.X - relativeMarkerSize.Width/2f, markerPosition.Y - relativeMarkerSize.Height/2f, relativeMarkerSize.Width, relativeMarkerSize.Height), + point, + seriesName, + pointIndex ); + } + + } + + #endregion + + #region Getting Y value methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + // Point chart do not have height + if(yValueIndex == -1) + { + return 0.0; + } + + // Check required Y values number + if (point.YValues.Length <= yValueIndex) + { + throw (new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)))); + } + + if (point.IsEmpty || double.IsNaN(point.YValues[yValueIndex])) + { + // Get empty point value + double result = GetEmptyPointValue(point, pointIndex, yValueIndex); + + // NOTE: Fixes issue #6921 + // If empty point Y value is zero then check if the scale of + // the Y axis and if it is not containing zero adjust the Y value + // of the empty point, so it will be visible + if (result == 0.0) + { + Axis yAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName); + double yViewMax = yAxis.maximum; + double yViewMin = yAxis.minimum; + if (result < yViewMin) + { + result = yViewMin; + } + else if (result > yViewMax) + { + result = yViewMax; + } + } + + return result; + } + + // Return Y value from the point + return point.YValues[yValueIndex]; + } + + /// + /// This method will find previous and next data point, which is not + /// empty and recalculate a new value for current empty data point. + /// New value depends on custom attribute “EmptyPointValue” and + /// it could be zero or average. + /// + /// IsEmpty data point. + /// IsEmpty data point index. + /// Index of the Y value to get. + /// A Value for empty data point. + internal double GetEmptyPointValue( DataPoint point, int pointIndex, int yValueIndex) + { + Series series = point.series; // Data series + double previousPoint = 0; // Previous data point value (not empty) + double nextPoint = 0; // Next data point value (not empty) + int prevIndx = 0; // Previous data point index + int nextIndx = series.Points.Count - 1; // Next data point index + + //************************************************************ + //** Check custom attribute "EmptyPointValue" + //************************************************************ + string emptyPointValue = ""; + if( series.EmptyPointStyle.IsCustomPropertySet(CustomPropertyName.EmptyPointValue) ) + { + emptyPointValue = series.EmptyPointStyle[CustomPropertyName.EmptyPointValue]; + } + else if( series.IsCustomPropertySet(CustomPropertyName.EmptyPointValue) ) + { + emptyPointValue = series[CustomPropertyName.EmptyPointValue]; + } + + // Take attribute value + if (String.Compare(emptyPointValue, "Zero", StringComparison.OrdinalIgnoreCase) == 0) + { + // IsEmpty points represented with zero values + return 0; + } + + //************************************************************ + //** IsEmpty point value is an average of neighbour points + //************************************************************ + + // Find previous non-empty point value + for( int indx = pointIndex; indx >= 0; indx-- ) + { + if( !series.Points[indx].IsEmpty ) + { + previousPoint = series.Points[indx].YValues[yValueIndex]; + prevIndx = indx; + break; + } + previousPoint = Double.NaN; + } + + // Find next non-empty point value + for( int indx = pointIndex; indx < series.Points.Count; indx++ ) + { + if( !series.Points[indx].IsEmpty ) + { + nextPoint = series.Points[indx].YValues[yValueIndex]; + nextIndx = indx; + break; + } + nextPoint = Double.NaN; + } + + // All Previous points are empty + if( Double.IsNaN( previousPoint ) ) + { + // All points are empty + if( Double.IsNaN( nextPoint ) ) + { + previousPoint = 0; + } + else // Next point is equal to previous point + { + previousPoint = nextPoint; + } + } + + // All next points are empty + if( Double.IsNaN( nextPoint ) ) + { + // Previous point is equal to next point + nextPoint = previousPoint; + } + + // If points value are the same use average + if( series.Points[nextIndx].XValue == series.Points[prevIndx].XValue ) + { + return ( previousPoint + nextPoint ) / 2; + } + + // Calculate and return average value + double aCoeff = (previousPoint - nextPoint) / (series.Points[nextIndx].XValue - series.Points[prevIndx].XValue); + return -aCoeff * (point.XValue - series.Points[prevIndx].XValue) + previousPoint; + } + + #endregion + + #region 3D Drawing and Selection + + /// + /// Calculates position of each bar in all series and either draws it or checks the selection in 3D space. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + private void ProcessChartType3D( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + //************************************************************ + //** Local variables declaration + //************************************************************ + + // Get pixel size + SizeF pixelRelSize = graph.GetRelativeSize(new SizeF(1.1f, 1.1f)); + + + //************************************************************ + //** Get list of series to draw + //************************************************************ + double xValue = 0; + List typeSeries = null; + bool currentDrawSeriesSideBySide = this.drawSeriesSideBySide; + if( (area.Area3DStyle.IsClustered && this.SideBySideSeries) || + this.Stacked) + { + // Draw all series of the same chart type + typeSeries = area.GetSeriesFromChartType(Name); + + // Check if series should be drawn side by side + foreach(string seriesName in typeSeries) + { + if(common.DataManager.Series[seriesName].IsCustomPropertySet(CustomPropertyName.DrawSideBySide)) + { + string attribValue = common.DataManager.Series[seriesName][CustomPropertyName.DrawSideBySide]; + if(String.Compare(attribValue, "False", StringComparison.OrdinalIgnoreCase) == 0) + { + currentDrawSeriesSideBySide = false; + } + else if(String.Compare(attribValue, "True", StringComparison.OrdinalIgnoreCase) == 0) + { + currentDrawSeriesSideBySide = true; + } + else if(String.Compare(attribValue, "Auto", StringComparison.OrdinalIgnoreCase) == 0) + { + // Do nothing + } + else + { + throw (new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid)); + } + } + } + } + else + { + // Draw just one chart series + typeSeries = new List(); + typeSeries.Add(seriesToDraw.Name); + } + + //************************************************************ + //** Get order of data points drawing + //************************************************************ + ArrayList dataPointDrawingOrder = area.GetDataPointDrawingOrder( + typeSeries, + this, + selection, + COPCoordinates.X | COPCoordinates.Y, + new BarPointsDrawingOrderComparer(area, selection, COPCoordinates.X | COPCoordinates.Y), + 0, + currentDrawSeriesSideBySide); + + //************************************************************ + //** Loop through all data poins + //************************************************************ + bool drawLabels = false; + foreach(object obj in dataPointDrawingOrder) + { + // Get point & series + DataPoint3D pointEx = (DataPoint3D) obj; + DataPoint point = pointEx.dataPoint; + Series ser = point.series; + + // Check required Y values number + if(point.YValues.Length < this.YValuesPerPoint) + { + throw(new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)))); + } + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Set active vertical/horizontal axis + Axis vAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + Axis hAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Get point bar drawing style + BarDrawingStyle barDrawingStyle = ChartGraphics.GetBarDrawingStyle(point); + + // Get Y value and make sure it fits the chart area. + // If chart type uses 2 Y values (RangeBar) use second Y value for size. + float rightDarkening = 0f; + float leftDarkening = 0f; + double yValue = hAxis.GetLogValue( GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, (useTwoValues) ? 1 : 0) ); + if( yValue > hAxis.ViewMaximum ) + { + rightDarkening = 0.5f; + yValue = hAxis.ViewMaximum; + } + else if( yValue < hAxis.ViewMinimum ) + { + rightDarkening = 0.5f; + yValue = hAxis.ViewMinimum; + } + + // Calculate the bar size + double barSize = hAxis.GetLinearPosition( yValue ); + + // Set start position for a bar + double barStartPosition = 0; + if(useTwoValues) + { + // Point Y value (first) is used to determine the bar starting position + double yValueStart = hAxis.GetLogValue( GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, 0 ) ); + if( yValueStart > hAxis.ViewMaximum ) + { + leftDarkening = 0.5f; + yValueStart = hAxis.ViewMaximum; + } + else if( yValueStart < hAxis.ViewMinimum ) + { + leftDarkening = 0.5f; + yValueStart = hAxis.ViewMinimum; + } + + barStartPosition = hAxis.GetLinearPosition(yValueStart); + } + else + { + // Bar starts on the vertical axis + barStartPosition = hAxis.GetPosition(hAxis.Crossing); + } + + // Calculate X position of the Bar + double xPosition = pointEx.xPosition; + + // Make sure that points with small values are still visible + if( barSize < barStartPosition && + (barStartPosition - barSize) < pixelRelSize.Width) + { + barSize = barStartPosition - pixelRelSize.Width; + } + if( barSize > barStartPosition && + (barSize - barStartPosition) < pixelRelSize.Width) + { + barSize = barStartPosition + pixelRelSize.Width; + } + + // Set rectangle coordinates of the bar + RectangleF rectSize = RectangleF.Empty; + try + { + // Set the bar rectangle + rectSize.Y = (float)(xPosition - pointEx.width/2); + rectSize.Height = (float)(pointEx.width); + + // The left side of rectangle has always + // smaller value than a right value + if( barStartPosition < barSize ) + { + rectSize.X = (float)barStartPosition; + rectSize.Width = (float)barSize - rectSize.X; + } + else + { + float temp = rightDarkening; + rightDarkening = leftDarkening; + leftDarkening = temp; + + rectSize.X = (float)barSize; + rectSize.Width = (float)barStartPosition - rectSize.X; + } + } + catch(OverflowException) + { + continue; + } + + // Remeber pre-calculated point position + point.positionRel = new PointF(rectSize.Right, (float)xPosition); + + + //************************************************************ + //** Painting mode + //************************************************************ + GraphicsPath rectPath = null; + + // if data point is not empty + if( !point.IsEmpty ) + { + // Check if column is completly out of the data scaleView + xValue = (pointEx.indexedSeries) ? pointEx.index : point.XValue; + xValue = vAxis.GetLogValue(xValue); + if(xValue < vAxis.ViewMinimum || xValue > vAxis.ViewMaximum ) + { + continue; + } + + // Check if column is partialy in the data scaleView + bool clipRegionSet = false; + if(rectSize.Bottom <= area.PlotAreaPosition.Y || rectSize.Y >= area.PlotAreaPosition.Bottom) + { + continue; + } + if(rectSize.Y < area.PlotAreaPosition.Y) + { + rectSize.Height -= area.PlotAreaPosition.Y - rectSize.Y; + rectSize.Y = area.PlotAreaPosition.Y; + } + if(rectSize.Bottom > area.PlotAreaPosition.Bottom) + { + rectSize.Height -= rectSize.Bottom - area.PlotAreaPosition.Bottom; + } + if(rectSize.Height < 0) + { + rectSize.Height = 0; + } + if(rectSize.Height == 0f || rectSize.Width == 0f) + { + continue; + } + + // Detect if we need to get graphical path of drawn object + DrawingOperationTypes drawingOperationType = DrawingOperationTypes.DrawElement; + + if( common.ProcessModeRegions ) + { + drawingOperationType |= DrawingOperationTypes.CalcElementPath; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw the bar rectangle + rectPath = graph.Fill3DRectangle( + rectSize, + pointEx.zPosition, + pointEx.depth, + area.matrix3D, + area.Area3DStyle.LightStyle, + point.Color, + rightDarkening, + leftDarkening, + point.BorderColor, + point.BorderWidth, + point.BorderDashStyle, + barDrawingStyle, + false, + drawingOperationType ); + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + } + + // Draw 3D markers + DrawMarkers3D( area, graph, common, rectSize, pointEx, ser, barStartPosition, barSize ); + + // Check if labels should be drawn (in additional points loop) + if( point.IsValueShownAsLabel || point.Label.Length > 0 ) + { + drawLabels = true; + } + + //************************************************************ + // Hot Regions mode used for image maps, tool tips and + // hit test function + //************************************************************ + if( common.ProcessModeRegions ) + { + common.HotRegionsList.AddHotRegion( + rectPath, + false, + graph, + point, + ser.Name, + pointEx.index - 1 ); + } + if (rectPath != null) + { + rectPath.Dispose(); + } + } + + + //************************************************************ + //** Loop through all data poins and draw labels + //************************************************************ + if(drawLabels) + { + foreach(object obj in dataPointDrawingOrder) + { + // Get point & series + DataPoint3D pointEx = (DataPoint3D) obj; + DataPoint point = pointEx.dataPoint; + Series ser = point.series; + + // Set active vertical/horizontal axis + Axis vAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + Axis hAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Get Y value and make sure it fits the chart area. + // If chart type uses 2 Y values (RangeBar) use second Y value for size. + double yValue = hAxis.GetLogValue( GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, (useTwoValues) ? 1 : 0) ); + if( yValue > hAxis.ViewMaximum ) + { + yValue = hAxis.ViewMaximum; + } + else if( yValue < hAxis.ViewMinimum ) + { + yValue = hAxis.ViewMinimum; + } + + // Calculate the bar size + double barSize = hAxis.GetLinearPosition( yValue ); + + // Set start position for a bar + double barStartPosition = 0; + if(useTwoValues) + { + // Point Y value (first) is used to determine the bar starting position + double yValueStart = hAxis.GetLogValue( GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, 0 ) ); + if( yValueStart > hAxis.ViewMaximum ) + { + yValueStart = hAxis.ViewMaximum; + } + else if( yValueStart < hAxis.ViewMinimum ) + { + yValueStart = hAxis.ViewMinimum; + } + + barStartPosition = hAxis.GetLinearPosition(yValueStart); + } + else + { + // Bar starts on the vertical axis + barStartPosition = hAxis.GetPosition(hAxis.Crossing); + } + + // Calculate X position of the Bar + double xPosition = pointEx.xPosition; + + // Set rectangle coordinates of the bar + RectangleF rectSize = RectangleF.Empty; + try + { + // Set the bar rectangle + rectSize.Y = (float)(xPosition - pointEx.width/2); + rectSize.Height = (float)(pointEx.width); + + // The left side of rectangle has always + // smaller value than a right value + if( barStartPosition < barSize ) + { + rectSize.X = (float)barStartPosition; + rectSize.Width = (float)barSize - rectSize.X; + } + else + { + rectSize.X = (float)barSize; + rectSize.Width = (float)barStartPosition - rectSize.X; + } + } + catch(OverflowException) + { + continue; + } + + + //************************************************************ + //** Painting mode + //************************************************************ + // if data point is not empty + if( !point.IsEmpty ) + { + // Check if column is completly out of the data scaleView + xValue = (pointEx.indexedSeries) ? pointEx.index : point.XValue; + xValue = vAxis.GetLogValue(xValue); + if(xValue < vAxis.ViewMinimum || xValue > vAxis.ViewMaximum ) + { + continue; + } + + // Check if column is partialy in the data scaleView + if ((decimal)rectSize.Y >= (decimal)area.PlotAreaPosition.Y && (decimal)rectSize.Bottom <= (decimal)area.PlotAreaPosition.Bottom) + { + // Draw 3D labels + DrawLabels3D(area, graph, common, rectSize, pointEx, ser, barStartPosition, barSize, pointEx.width, pointEx.index - 1); + } + } + } + } + + } + + /// + /// Draws markers in 3D. + /// + /// Chart area for this chart. + /// The Chart Graphics object. + /// The Common elements object. + /// Bar rectangle. + /// Data point. + /// Data series. + /// The zero position or the bottom of bars. + /// The Height of bars. + private void DrawMarkers3D( + ChartArea area, + ChartGraphics graph, + CommonElements common, + RectangleF rectSize, + DataPoint3D pointEx, + Series ser, + double barStartPosition, + double barSize) + { + DataPoint point = pointEx.dataPoint; + + //************************************************************ + // Draw data point value marker + //************************************************************ + SizeF markerSize = SizeF.Empty; + if(point.MarkerStyle != MarkerStyle.None || point.MarkerImage.Length > 0) + { + // Check if this marker should be drawn + if((pointEx.index % ser.MarkerStep) == 0) + { + // Find relative marker size + if(point.MarkerImage.Length == 0) + { + markerSize.Width = point.MarkerSize; + markerSize.Height = point.MarkerSize; + } + else + common.ImageLoader.GetAdjustedImageSize(point.MarkerImage, graph.Graphics, ref markerSize); + + markerSize = graph.GetRelativeSize( markerSize ); + + // Calculate marker position + PointF markerPosition = PointF.Empty; + if( barStartPosition < barSize ) + { + markerPosition.X = rectSize.Right; + } + else + { + markerPosition.X = rectSize.X; + } + markerPosition.Y = rectSize.Y + rectSize.Height/2F; + + //************************************************************ + //** Transform marker position in 3D space + //************************************************************ + // Get projection coordinates + Point3D[] marker3DPosition = new Point3D[1]; + marker3DPosition[0] = new Point3D(markerPosition.X, markerPosition.Y, (float)(pointEx.zPosition + pointEx.depth/2f)); + + // Transform coordinates of text size + area.matrix3D.TransformPoints(marker3DPosition); + + + //************************************************************ + //** Draw 3D marker + //************************************************************ + graph.DrawMarker3D( + area.matrix3D, + area.Area3DStyle.LightStyle, + pointEx.zPosition + pointEx.depth/2f, + markerPosition, + point.MarkerStyle, + BarChart.GetAdjustedPixelSize(point.MarkerSize, graph), + (point.MarkerColor.IsEmpty) ? point.series.Color : point.MarkerColor, + point.MarkerBorderColor, + point.MarkerBorderWidth, + point.MarkerImage, + point.MarkerImageTransparentColor, + (point.series != null) ? point.series.ShadowOffset : 0, + (point.series != null) ? point.series.ShadowColor : Color.Empty, + RectangleF.Empty, + DrawingOperationTypes.DrawElement); + } + } + } + + + /// + /// Draws labels in 3D. + /// + /// Chart area for this chart. + /// The Chart Graphics object. + /// The Common elements object. + /// Bar rectangle. + /// Data point. + /// Data series. + /// The zero position or the bottom of bars. + /// The Height of bars. + /// The width of bars. + /// Point index. + private void DrawLabels3D( + ChartArea area, + ChartGraphics graph, + CommonElements common, + RectangleF rectSize, + DataPoint3D pointEx, + Series ser, + double barStartPosition, + double barSize, + double width, + int pointIndex) + { + DataPoint point = pointEx.dataPoint; + + //************************************************************ + // Draw data point value label + //************************************************************ + if (ser.IsValueShownAsLabel || point.IsValueShownAsLabel || point.Label.Length > 0) + { + // Label rectangle + RectangleF rectLabel = RectangleF.Empty; + // Label text format + using (StringFormat format = new StringFormat()) + { + + //************************************************************ + // Get label text + //************************************************************ + string text; + if( point.Label.Length == 0 ) + { + text = ValueConverter.FormatValue( + ser.Chart, + point, + point.Tag, + GetYValue(common, area, ser, point, pointIndex, 0 ), + point.LabelFormat, + ser.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + } + + //************************************************************ + // Calculate marker size + //************************************************************ + SizeF markerSize = SizeF.Empty; + if(point.MarkerStyle != MarkerStyle.None || point.MarkerImage.Length > 0) + { + // Check if this marker should be drawn + if((pointEx.index % ser.MarkerStep) == 0) + { + // Find relative marker size + if (point.MarkerImage.Length == 0) + { + markerSize.Width = point.MarkerSize; + markerSize.Height = point.MarkerSize; + } + else + common.ImageLoader.GetAdjustedImageSize(point.MarkerImage, graph.Graphics, ref markerSize); + + markerSize = graph.GetRelativeSize( markerSize ); + } + } + + //************************************************************ + // Check labels style custom properties + //************************************************************ + BarValueLabelDrawingStyle drawingStyle = defLabelDrawingStyle; + string valueLabelAttrib = ""; + if (point.IsCustomPropertySet(CustomPropertyName.BarLabelStyle)) + { + valueLabelAttrib = point[CustomPropertyName.BarLabelStyle]; + } + else if (ser.IsCustomPropertySet(CustomPropertyName.BarLabelStyle)) + { + valueLabelAttrib = ser[CustomPropertyName.BarLabelStyle]; + } + + if (valueLabelAttrib != null && valueLabelAttrib.Length > 0) + { + if (String.Compare(valueLabelAttrib, "Left", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Left; + else if (String.Compare(valueLabelAttrib, "Right", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Right; + else if (String.Compare(valueLabelAttrib, "Center", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Center; + else if (String.Compare(valueLabelAttrib, "Outside", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Outside; + } + + //************************************************************ + // Make sure label fits. Otherwise change it style + //************************************************************ + bool labelFit = false; + bool labelSwitched = false; + bool labelSwitchedBack = false; + float prevWidth = 0f; + while (!labelFit) + { + // Label text format + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + + // LabelStyle rectangle + if (barStartPosition < barSize) + { + rectLabel.X = rectSize.Right; + rectLabel.Width = area.PlotAreaPosition.Right - rectSize.Right; + } + else + { + rectLabel.X = area.PlotAreaPosition.X; + rectLabel.Width = rectSize.X - area.PlotAreaPosition.X; + } + + // Adjust label rectangle + rectLabel.Y = rectSize.Y - (float)width / 2F; + rectLabel.Height = rectSize.Height + (float)width; + + // Adjust label position depending on the drawing style + if (drawingStyle == BarValueLabelDrawingStyle.Outside) + { + // Adjust position if point marker is drawn + if (!markerSize.IsEmpty) + { + rectLabel.Width -= (float)Math.Min(rectLabel.Width, markerSize.Width / 2F); + if (barStartPosition < barSize) + { + rectLabel.X += (float)Math.Min(rectLabel.Width, markerSize.Width / 2F); + } + } + } + else if (drawingStyle == BarValueLabelDrawingStyle.Left) + { + rectLabel = rectSize; + format.Alignment = StringAlignment.Near; + } + else if (drawingStyle == BarValueLabelDrawingStyle.Center) + { + rectLabel = rectSize; + format.Alignment = StringAlignment.Center; + } + else if (drawingStyle == BarValueLabelDrawingStyle.Right) + { + rectLabel = rectSize; + format.Alignment = StringAlignment.Far; + + // Adjust position if point marker is drawn + if (!markerSize.IsEmpty) + { + rectLabel.Width -= (float)Math.Min(rectLabel.Width, markerSize.Width / 2F); + if (barStartPosition >= barSize) + { + rectLabel.X += (float)Math.Min(rectLabel.Width, markerSize.Width / 2F); + } + } + } + + // Reversed string alignment + if (barStartPosition >= barSize) + { + if (format.Alignment == StringAlignment.Far) + format.Alignment = StringAlignment.Near; + else if (format.Alignment == StringAlignment.Near) + format.Alignment = StringAlignment.Far; + } + + // Make sure value label fits rectangle. + SizeF valueTextSize = graph.MeasureStringRel(text, point.Font); + if (!labelSwitched && + !labelSwitchedBack && + valueTextSize.Width > rectLabel.Width) + { + // Switch label style only once + labelSwitched = true; + prevWidth = rectLabel.Width; + + // If text do not fit - try to switch between Outside/Inside drawing styles + if (drawingStyle == BarValueLabelDrawingStyle.Outside) + { + drawingStyle = BarValueLabelDrawingStyle.Right; + } + else + { + drawingStyle = BarValueLabelDrawingStyle.Outside; + } + } + else + { + // If label do not fit either Outside or to the Right, + // select the style that has more space available. + if (labelSwitched && + !labelSwitchedBack && + valueTextSize.Width > rectLabel.Width - 1 && + prevWidth > rectLabel.Width) + { + labelSwitchedBack = true; + + // Change back to the previous labels style + if (drawingStyle == BarValueLabelDrawingStyle.Outside) + { + drawingStyle = BarValueLabelDrawingStyle.Right; + } + else + { + drawingStyle = BarValueLabelDrawingStyle.Outside; + } + } + else + { + // Do not try to fit labels any more + labelFit = true; + } + } + } + + //************************************************************ + // Find text rotation center point + //************************************************************ + + // Measure string size + SizeF size = graph.MeasureStringRel(text, point.Font, new SizeF(rectLabel.Width, rectLabel.Height), format); + + PointF rotationCenter = PointF.Empty; + if (format.Alignment == StringAlignment.Near) + { // Near + rotationCenter.X = rectLabel.X + size.Width / 2; + } + else if (format.Alignment == StringAlignment.Far) + { // Far + rotationCenter.X = rectLabel.Right - size.Width / 2; + } + else + { // Center + rotationCenter.X = (rectLabel.Left + rectLabel.Right) / 2; + } + + if (format.LineAlignment == StringAlignment.Near) + { // Near + rotationCenter.Y = rectLabel.Top + size.Height / 2; + } + else if (format.LineAlignment == StringAlignment.Far) + { // Far + rotationCenter.Y = rectLabel.Bottom - size.Height / 2; + } + else + { // Center + rotationCenter.Y = (rectLabel.Bottom + rectLabel.Top) / 2; + } + + // Reset string alignment to center point + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + + //************************************************************ + // Adjust label rotation angle + //************************************************************ + int angle = point.LabelAngle; + + // Get projection coordinates + Point3D[] rotationCenterProjection = new Point3D[] { + new Point3D(rotationCenter.X, rotationCenter.Y, pointEx.zPosition + pointEx.depth), + new Point3D(rotationCenter.X - 20f, rotationCenter.Y, pointEx.zPosition + pointEx.depth) }; + + // Transform coordinates of text rotation point + area.matrix3D.TransformPoints(rotationCenterProjection); + + // Adjust rotation point + rotationCenter = rotationCenterProjection[0].PointF; + + // Adjust angle of the horisontal text + if (angle == 0 || angle == 180) + { + // Convert coordinates to absolute + rotationCenterProjection[0].PointF = graph.GetAbsolutePoint(rotationCenterProjection[0].PointF); + rotationCenterProjection[1].PointF = graph.GetAbsolutePoint(rotationCenterProjection[1].PointF); + + // Calcuate axis angle + float angleXAxis = (float)Math.Atan( + (rotationCenterProjection[1].Y - rotationCenterProjection[0].Y) / + (rotationCenterProjection[1].X - rotationCenterProjection[0].X)); + angleXAxis = (float)Math.Round(angleXAxis * 180f / (float)Math.PI); + angle += (int)angleXAxis; + } + + + // Calculate label background position + RectangleF labelBackPosition = RectangleF.Empty; + if (common.ProcessModeRegions || + !point.LabelBackColor.IsEmpty || + !point.LabelBorderColor.IsEmpty) + { + SizeF sizeLabel = new SizeF(size.Width, size.Height); + sizeLabel.Height += sizeLabel.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = new RectangleF( + rotationCenter.X - sizeLabel.Width / 2, + rotationCenter.Y - sizeLabel.Height / 2, + sizeLabel.Width, + sizeLabel.Height); + } + + //************************************************************ + // Draw label + //************************************************************ + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + rotationCenter, + format, + angle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + ser, + point, + pointIndex); + } + } + + } + } + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + // NOTE: Bar chart do not support SmartLabelStyle feature. + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } + + #region Points drawing order comparer class + + /// + /// Chart 3D engine relies on the data point drawing order + /// to achieve correct visual appearance. All data points + /// have to be drawn in the correct order depending on the + /// 3D angles, perspective and the depth of the series. + /// + /// BarPointsDrawingOrderComparer class is used sort data + /// points of the Bar chart type. + /// + internal class BarPointsDrawingOrderComparer : IComparer + { + #region Fields + + /// + /// Chart area object reference. + /// + private ChartArea _area = null; + + /// + /// Area X position where visible sides are switched. + /// + private Point3D _areaProjectionCenter = new Point3D(float.NaN, float.NaN, float.NaN); + + /// + /// Selection mode. Points order should be reversed. + /// + private bool _selection = false; + + #endregion // Fields + + #region Methods + + /// + /// Public constructor. + /// + /// Chart area. + /// Selection indicator. + /// Which coordinate of COP (X, Y or Z) to test for surface everlapping. + public BarPointsDrawingOrderComparer(ChartArea area, bool selection, COPCoordinates coord) + { + this._area = area; + this._selection = selection; + + // Get center of projection + if(area.DrawPointsToCenter(ref coord)) + { + // Get COP + _areaProjectionCenter = area.GetCenterOfProjection(coord); + + // Switch X & Y coordinates + float val = _areaProjectionCenter.X; + _areaProjectionCenter.X = _areaProjectionCenter.Y; + _areaProjectionCenter.Y = val; + } + } + + /// + /// Comarer method. + /// + /// First object. + /// Second object. + /// Comparison result. + public int Compare(object o1, object o2) + { + DataPoint3D point1 = (DataPoint3D) o1; + DataPoint3D point2 = (DataPoint3D) o2; + + int result = 0; + if(point1.xPosition < point2.xPosition) + { + result = -1; + } + else if(point1.xPosition > point2.xPosition) + { + result = 1; + } + else + { + // If X coordinate is the same - filter by Y coordinate + if(point1.yPosition < point2.yPosition) + { + result = 1; + } + else if(point1.yPosition > point2.yPosition) + { + result = -1; + } + + // Order points from sides to center + if(!float.IsNaN(_areaProjectionCenter.Y)) + { + double yMin1 = Math.Min(point1.yPosition, point1.height); + double yMax1 = Math.Max(point1.yPosition, point1.height); + double yMin2 = Math.Min(point2.yPosition, point2.height); + double yMax2 = Math.Max(point2.yPosition, point2.height); + + if(_area.IsBottomSceneWallVisible()) + { + if( yMin1 <= _areaProjectionCenter.Y && yMin2 <= _areaProjectionCenter.Y ) + { + result *= -1; + } + else if( yMin1 <= _areaProjectionCenter.Y) + { + result = 1; + } + + } + else + { + + if( yMax1 >= _areaProjectionCenter.Y && yMax2 >= _areaProjectionCenter.Y ) + { + result *= 1; + } + else if( yMax1 >= _areaProjectionCenter.Y) + { + result = 1; + } + else + { + result *= -1; + } + } + } + + // Reversed order if looking from left or right + else if(!_area.DrawPointsInReverseOrder()) + { + result *= -1; + } + } + + if(point1.xPosition != point2.xPosition) + { + // Order points from sides to center + if(!float.IsNaN(_areaProjectionCenter.X)) + { + if((point1.xPosition + point1.width / 2f) >= _areaProjectionCenter.X && + (point2.xPosition + point2.width / 2f) >= _areaProjectionCenter.X) + { + result *= -1; + } + } + + // Reversed order of points by X value + else if(_area.IsBottomSceneWallVisible()) + { + result *= -1; + } + } + + return (_selection) ? - result : result; + } + + #endregion // Methods + } + +#endregion +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/BoxPlotChart.cs b/System.Web.DataVisualization/Common/ChartTypes/BoxPlotChart.cs new file mode 100644 index 000000000..e1b650d3c --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/BoxPlotChart.cs @@ -0,0 +1,1856 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: BoxPlotChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: BoxPlotChart +// +// Purpose: Provides 2D and 3D drawing and hit testing of the +// Box Plot chart. +// +// Box Plot Overview: +// ------------------ +// +// The Box Plot chart type consists of one or more box symbols that +// summarize the distribution of the data within one or more data +// sets. A Box Chart displays a rectangle with whisker lines +// extending from both ends. What makes a Box Plot unique, in +// comparison to standard chart types, is that the values for a box +// plot most often are calculated values from data that is present +// in another series. One box symbol, or data point, is associated +// with one data series. The data for a Box Plot series may still +// be populated using Data Binding or the Points Collection. +// +// Reviewed: GS - Jul 15, 2003 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel.Design; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Utilities; +#else + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else +namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// BoxPlotChart class provides 2D and 3D drawing and hit testing of + /// the Box Plot chart. + /// + internal class BoxPlotChart : IChartType + { + #region Fields + + /// + /// Vertical axis + /// + protected Axis vAxis = null; + + /// + /// Horizontal axis + /// + protected Axis hAxis = null; + + /// + /// Side by side drawing flag. + /// + protected bool showSideBySide = true; + + #endregion + + #region Constructor + + /// + /// Box Plot chart constructor. + /// + public BoxPlotChart() + { + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.BoxPlot;}} + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axes + /// + virtual public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + public bool SideBySideSeries { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value ZeroCrossing should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return true; } } + + /// + /// Indicates that this is a one hundred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that negative 100% stacked values are shown on + /// the other side of the X axis + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint { get { return 6; } } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Painting and Selection methods + + /// + /// Paint box plot chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + ProcessChartType( false, graph, common, area, seriesToDraw ); + } + + /// + /// This method recalculates size of the bars. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual protected void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + + // Prosess 3D chart type + if(area.Area3DStyle.Enable3D) + { + ProcessChartType3D( selection, graph, common, area, seriesToDraw ); + return; + } + + // All data series from chart area which have Box Plot chart type + List typeSeries = area.GetSeriesFromChartType(this.Name); + + // Zero X values mode. + bool indexedSeries = ChartHelper.IndexedSeries(area.Common, typeSeries.ToArray() ); + + //************************************************************ + //** Loop through all series + //************************************************************ + int seriesIndx = 0; + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with box plot chart type + if( String.Compare( ser.ChartTypeName, this.Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Set active horizontal/vertical axis + hAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + vAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Get interval between points + double interval = (indexedSeries) ? 1 : area.GetPointsInterval( hAxis.IsLogarithmic, hAxis.logarithmBase ); + + // Check if side-by-side attribute is set + bool currentShowSideBySide = showSideBySide; + if(ser.IsCustomPropertySet(CustomPropertyName.DrawSideBySide)) + { + string attribValue = ser[CustomPropertyName.DrawSideBySide]; + if(String.Compare(attribValue, "False", StringComparison.OrdinalIgnoreCase) == 0 ) + { + currentShowSideBySide = false; + } + else if (String.Compare(attribValue, "True", StringComparison.OrdinalIgnoreCase) == 0) + { + currentShowSideBySide = true; + } + else if (String.Compare(attribValue, "Auto", StringComparison.OrdinalIgnoreCase) == 0) + { + } + else + { + throw (new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid)); + } + } + + // Find the number of "Column chart" data series + double numOfSeries = typeSeries.Count; + if(!currentShowSideBySide) + { + numOfSeries = 1; + } + + // Calculates the width of the points. + float width = (float)(ser.GetPointWidth(graph, hAxis, interval, 0.8) / numOfSeries); + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + + //************************************************************ + //** Series data points loop + //************************************************************ + int index = 1; + foreach( DataPoint point in ser.Points ) + { + // Check required Y values number + if(point.YValues.Length < this.YValuesPerPoint) + { + throw(new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)))); + } + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Get point X position + float xPosition = 0f; + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + xPosition = (float)(hAxis.GetPosition( (double)index ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width); + } + else if( currentShowSideBySide ) + { + xPosition = (float)(hAxis.GetPosition( xValue ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width); + } + else + { + xPosition = (float)hAxis.GetPosition( xValue ); + } + + + double yValue0 = vAxis.GetLogValue( point.YValues[0] ); + double yValue1 = vAxis.GetLogValue( point.YValues[1] ); + xValue = hAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < hAxis.ViewMinimum || + xValue > hAxis.ViewMaximum || + (yValue0 < vAxis.ViewMinimum && yValue1 < vAxis.ViewMinimum) || + (yValue0 > vAxis.ViewMaximum && yValue1 > vAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Make sure High/Low values are in data scaleView range + double low = vAxis.GetLogValue( point.YValues[0] ); + double high = vAxis.GetLogValue( point.YValues[1] ); + + // Check if values are in range + if( high > vAxis.ViewMaximum ) + { + high = vAxis.ViewMaximum; + } + if( high < vAxis.ViewMinimum ) + { + high = vAxis.ViewMinimum; + } + high = (float)vAxis.GetLinearPosition(high); + + if( low > vAxis.ViewMaximum ) + { + low = vAxis.ViewMaximum; + } + if( low < vAxis.ViewMinimum ) + { + low = vAxis.ViewMinimum; + } + low = vAxis.GetLinearPosition(low); + + // Remeber pre-calculated point position + point.positionRel = new PointF((float)xPosition, (float)Math.Min(high, low)); + + if( common.ProcessModePaint ) + { + + // Check if chart is partialy in the data scaleView + bool clipRegionSet = false; + if(xValue == hAxis.ViewMinimum || xValue == hAxis.ViewMaximum ) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + // Define line color + Color lineColor = point.BorderColor; + if(lineColor == Color.Empty) + { + lineColor = point.Color; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw lower whisker line + graph.DrawLineRel( + lineColor, + point.BorderWidth, + point.BorderDashStyle, + new PointF(xPosition, (float)low), + new PointF(xPosition, (float)vAxis.GetPosition( point.YValues[2] )), + ser.ShadowColor, + ser.ShadowOffset ); + + // Draw upper whisker line + graph.DrawLineRel( + lineColor, + point.BorderWidth, + point.BorderDashStyle, + new PointF(xPosition, (float)high), + new PointF(xPosition, (float)vAxis.GetPosition( point.YValues[3] )), + ser.ShadowColor, + ser.ShadowOffset ); + + // Draw Box + RectangleF rectSize = RectangleF.Empty; + rectSize.X = (float)(xPosition - width/2); + rectSize.Width = (float)(width); + rectSize.Y = (float)vAxis.GetPosition( point.YValues[3] ); + rectSize.Height = (float)Math.Abs(rectSize.Y - vAxis.GetPosition( point.YValues[2] )); + graph.FillRectangleRel( rectSize, + point.Color, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + point.BackSecondaryColor, + point.BorderColor, + point.BorderWidth, + point.BorderDashStyle, + ser.ShadowColor, + ser.ShadowOffset, + PenAlignment.Inset ); + + + // Check if average line should be drawn + bool showAverage = true; + if(point.IsCustomPropertySet(CustomPropertyName.BoxPlotShowAverage) || ser.IsCustomPropertySet(CustomPropertyName.BoxPlotShowAverage)) + { + string showAverageValue = ser[CustomPropertyName.BoxPlotShowAverage]; + if(point.IsCustomPropertySet(CustomPropertyName.BoxPlotShowAverage)) + { + showAverageValue = point[CustomPropertyName.BoxPlotShowAverage]; + } + if(String.Compare( showAverageValue, "True", StringComparison.OrdinalIgnoreCase ) == 0 ) + { + // default - do nothing + } + else if(String.Compare( showAverageValue, "False", StringComparison.OrdinalIgnoreCase) == 0) + { + showAverage = false; + } + else + { + throw(new InvalidOperationException( SR.ExceptionCustomAttributeValueInvalid( point[CustomPropertyName.BoxPlotShowAverage], "BoxPlotShowAverage"))); + } + } + + + // Draw average line + SizeF relBorderWidth = graph.GetRelativeSize(new SizeF(point.BorderWidth, point.BorderWidth)); + if(point.BorderColor == Color.Empty) + { + relBorderWidth.Height = 0; + relBorderWidth.Width = 0; + } + Color markerLinesColor = lineColor; + if(markerLinesColor == point.Color) + { + double brightness = Math.Sqrt(point.Color.R * point.Color.R + point.Color.G * point.Color.G + point.Color.B * point.Color.B); + if(brightness > 220) + { + markerLinesColor = ChartGraphics.GetGradientColor(point.Color, Color.Black, 0.4); + } + else + { + markerLinesColor = ChartGraphics.GetGradientColor(point.Color, Color.White, 0.4); + } + } + if(!double.IsNaN(point.YValues[4]) && showAverage) + { + graph.DrawLineRel( + markerLinesColor, + 1, + ChartDashStyle.Solid, + new PointF(rectSize.Left + relBorderWidth.Width, (float)vAxis.GetPosition( point.YValues[4])), + new PointF(rectSize.Right - relBorderWidth.Width, (float)vAxis.GetPosition( point.YValues[4])), + Color.Empty, + 0 ); + } + + // Check if median line should be drawn + bool showMedian = true; + if(point.IsCustomPropertySet(CustomPropertyName.BoxPlotShowMedian) || ser.IsCustomPropertySet(CustomPropertyName.BoxPlotShowMedian)) + { + string showMedianValue = ser[CustomPropertyName.BoxPlotShowMedian]; + if(point.IsCustomPropertySet(CustomPropertyName.BoxPlotShowMedian)) + { + showMedianValue = point[CustomPropertyName.BoxPlotShowMedian]; + } + if(String.Compare(showMedianValue, "True", StringComparison.OrdinalIgnoreCase) == 0) + { + // default - do nothing + } + else if(String.Compare(showMedianValue, "False", StringComparison.OrdinalIgnoreCase) == 0) + { + showMedian = false; + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid( point[CustomPropertyName.BoxPlotShowMedian],"BoxPlotShowMedian"))); + } + } + + // Draw median line + if(!double.IsNaN(point.YValues[5]) && showMedian) + { + float medianValue = (float)vAxis.GetPosition( point.YValues[5]); + float dashWidth = (rectSize.Width - relBorderWidth.Width * 2) / 9f; + + // Dash width should not be less than 2 pixels + SizeF minSize = graph.GetRelativeSize(new SizeF(2, 2)); + dashWidth = Math.Max(dashWidth, minSize.Width); + + for(float curPosition = rectSize.Left + relBorderWidth.Width; curPosition < (rectSize.Right - relBorderWidth.Width); curPosition += dashWidth * 2f) + { + graph.DrawLineRel( + markerLinesColor, + 1, + ChartDashStyle.Solid, + new PointF(curPosition, medianValue), + new PointF((float) Math.Min(rectSize.Right, curPosition + dashWidth), medianValue), + Color.Empty, + 0 ); + } + } + + // Draw Box Plot marks + DrawBoxPlotMarks(graph, area, ser, point, xPosition, width); + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + } + + if( common.ProcessModeRegions ) + { + // Calculate rect around the box plot marks + RectangleF areaRect = RectangleF.Empty; + areaRect.X = xPosition - width / 2f; + areaRect.Y = (float)Math.Min(high, low); + areaRect.Width = width; + areaRect.Height = (float)Math.Max(high, low) - areaRect.Y; + + // Add area + common.HotRegionsList.AddHotRegion( areaRect, point, ser.Name, index - 1 ); + } + ++index; + } + + //************************************************************ + //** Second series data points loop, when labels are drawn. + //************************************************************ + if( !selection ) + { + index = 1; + foreach( DataPoint point in ser.Points ) + { + // Get point X position + float xPosition = 0f; + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + xPosition = (float)(hAxis.GetPosition( (double)index ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width); + } + else if( currentShowSideBySide ) + { + xPosition = (float)(hAxis.GetPosition( xValue ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width); + } + else + { + xPosition = (float)hAxis.GetPosition( xValue ); + } + + double yValue0 = vAxis.GetLogValue( point.YValues[0] ); + double yValue1 = vAxis.GetLogValue( point.YValues[1] ); + xValue = hAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < hAxis.ViewMinimum || + xValue > hAxis.ViewMaximum || + (yValue0 < vAxis.ViewMinimum && yValue1 < vAxis.ViewMinimum) || + (yValue0 > vAxis.ViewMaximum && yValue1 > vAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Make sure High/Low values are in data scaleView range + double high = double.MaxValue; + for(int valueIndex = 0; valueIndex < point.YValues.Length; valueIndex++) + { + if(!double.IsNaN(point.YValues[valueIndex])) + { + double currentValue = vAxis.GetLogValue( point.YValues[valueIndex] ); + if( currentValue > vAxis.ViewMaximum ) + { + currentValue = vAxis.ViewMaximum; + } + if( currentValue < vAxis.ViewMinimum ) + { + currentValue = vAxis.ViewMinimum; + } + currentValue = (float)vAxis.GetLinearPosition(currentValue); + + high = Math.Min(high, currentValue); + } + } + + // Adjust label position by marker size + SizeF relMarkerSize = graph.GetRelativeSize(new SizeF(point.MarkerSize, point.MarkerSize)); + high -= relMarkerSize.Height / 2f; + + // Start Svg Selection mode + graph.StartHotRegion( point, true ); + + // Draw label + DrawLabel(common, area, graph, ser, point, new PointF(xPosition, (float)high), index); + + // End Svg Selection mode + graph.EndHotRegion( ); + + + ++index; + } + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + // Data series index + if(currentShowSideBySide) + { + seriesIndx++; + } + } + } + + /// + /// Draws box plot markers. + /// + /// Chart graphics object. + /// Chart area. + /// Data point series. + /// Data point to draw. + /// X position. + /// Point width. + virtual protected void DrawBoxPlotMarks( + ChartGraphics graph, + ChartArea area, + Series ser, + DataPoint point, + float xPosition, + float width) + { + // Get markers style + string markerStyle = "LINE"; + if(point.MarkerStyle != MarkerStyle.None) + { + markerStyle = point.MarkerStyle.ToString(); + } + + // Draw lower marker + double yPosition = vAxis.GetLogValue( point.YValues[0] ); + DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)yPosition, 0f, width, false); + + // Draw upper marker + yPosition = vAxis.GetLogValue( point.YValues[1] ); + DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)yPosition, 0f, width, false); + + // Draw unusual points if any + markerStyle = "CIRCLE"; + if(point.MarkerStyle != MarkerStyle.None) + { + markerStyle = point.MarkerStyle.ToString(); + } + for(int valueIndex = 6; valueIndex < point.YValues.Length; valueIndex++) + { + if(!double.IsNaN(point.YValues[valueIndex])) + { + yPosition = vAxis.GetLogValue( point.YValues[valueIndex] ); + DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)yPosition, 0f, width, false); + } + } + } + + /// + /// Draws single marker on the box plot. + /// + /// Chart graphics. + /// Chart area. + /// Series point. + /// Marker style name. + /// X position. + /// Y position. + /// Z position. + /// Point width. + /// Used for 3d drawing. + private void DrawBoxPlotSingleMarker( + ChartGraphics graph, + ChartArea area, + DataPoint point, + string markerStyle, + float xPosition, + float yPosition, + float zPosition, + float width, + bool draw3D) + { + markerStyle = markerStyle.ToUpper(CultureInfo.InvariantCulture); + if(markerStyle.Length > 0 && String.Compare(markerStyle, "None", StringComparison.OrdinalIgnoreCase ) != 0) + { + // Make sure Y value is in range + if( yPosition > vAxis.ViewMaximum || yPosition < vAxis.ViewMinimum) + { + return; + } + yPosition = (float)vAxis.GetLinearPosition(yPosition); + + // 3D Transform coordinates + if(draw3D) + { + Point3D[] points = new Point3D[1]; + points[0] = new Point3D(xPosition, yPosition, zPosition); + area.matrix3D.TransformPoints(points); + xPosition = points[0].X; + yPosition = points[0].Y; + } + + // Define line color + Color lineColor = point.BorderColor; + if(lineColor == Color.Empty) + { + lineColor = point.Color; + } + + // Draw horizontal line marker + if (String.Compare(markerStyle, "Line", StringComparison.OrdinalIgnoreCase) == 0) + { + graph.DrawLineRel( + lineColor, + point.BorderWidth, + point.BorderDashStyle, + new PointF(xPosition - width/4f, yPosition), + new PointF(xPosition + width/4f, yPosition), + (point.series != null) ? point.series.ShadowColor : Color.Empty, + (point.series != null) ? point.series.ShadowOffset : 0 ); + } + + // Draw standard marker + else + { + MarkerStyle marker = (MarkerStyle)Enum.Parse(typeof(MarkerStyle), markerStyle, true); + + // Get marker size + SizeF markerSize = GetMarkerSize( + graph, + area.Common, + area, + point, + point.MarkerSize, + point.MarkerImage); + + // Get marker color + Color markerColor = (point.MarkerColor == Color.Empty) ? point.BorderColor : point.MarkerColor; + if(markerColor == Color.Empty) + { + markerColor = point.Color; + } + + // Draw the marker + graph.DrawMarkerRel( + new PointF(xPosition, yPosition), + marker, + point.MarkerSize, + markerColor, + point.MarkerBorderColor, + point.MarkerBorderWidth, + point.MarkerImage, + point.MarkerImageTransparentColor, + (point.series != null) ? point.series.ShadowOffset : 0, + (point.series != null) ? point.series.ShadowColor : Color.Empty, + new RectangleF(xPosition, yPosition, markerSize.Width, markerSize.Height)); + } + } + } + + /// + /// Returns marker size. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Data point. + /// Marker size. + /// Marker image. + /// Marker width and height. + virtual protected SizeF GetMarkerSize( + ChartGraphics graph, + CommonElements common, + ChartArea area, + DataPoint point, + int markerSize, + string markerImage) + { + SizeF size = new SizeF(markerSize, markerSize); + if (graph != null && graph.Graphics != null) + { + // Marker size is in pixels and we do the mapping for higher DPIs + size.Width = markerSize * graph.Graphics.DpiX / 96; + size.Height = markerSize * graph.Graphics.DpiY / 96; + } + + if(markerImage.Length > 0) + common.ImageLoader.GetAdjustedImageSize(markerImage, graph.Graphics, ref size); + + return size; + } + + + /// + /// Draws box plot chart data point label. + /// + /// The Common elements object + /// Chart area for this chart + /// Chart graphics object. + /// Data point series. + /// Data point to draw. + /// Label position. + /// Data point index. + virtual protected void DrawLabel( + CommonElements common, + ChartArea area, + ChartGraphics graph, + Series ser, + DataPoint point, + PointF position, + int pointIndex) + { + if (ser.IsValueShownAsLabel || point.IsValueShownAsLabel || point.Label.Length > 0) + { + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + if (point.LabelAngle == 0) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Far; + } + + // Get label text + string text; + if( point.Label.Length == 0 ) + { + text = ValueConverter.FormatValue( + ser.Chart, + point, + point.Tag, + point.YValues[0], + point.LabelFormat, + ser.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + } + + // Adjust label positio to the marker size + SizeF markerSizes = new SizeF(0f, 0f); + if (point.MarkerStyle != MarkerStyle.None) + { + markerSizes = graph.GetRelativeSize(new SizeF(point.MarkerSize, point.MarkerSize)); + position.Y -= markerSizes.Height / 2f; + } + + // Get text angle + int textAngle = point.LabelAngle; + + // Check if text contains white space only + if (text.Trim().Length != 0) + { + SizeF sizeFont = SizeF.Empty; + + + // Check if Smart Labels are enabled + if (ser.SmartLabelStyle.Enabled) + { + // Get text size + sizeFont = graph.GetRelativeSize( + graph.MeasureString(text, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic)); + + // Adjust label position using SmartLabelStyle algorithm + position = area.smartLabels.AdjustSmartLabelPosition( + common, + graph, + area, + ser.SmartLabelStyle, + position, + sizeFont, + format, + position, + markerSizes, + LabelAlignmentStyles.Top); + + // Smart labels always use 0 degrees text angle + textAngle = 0; + } + + + + // Draw label + if (!position.IsEmpty) + { + // Get text size + if (sizeFont.IsEmpty) + { + sizeFont = graph.GetRelativeSize( + graph.MeasureString(text, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic)); + } + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeFont.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = PointChart.GetLabelPosition( + graph, + position, + sizeLabel, + format, + true); + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + position, + format, + textAngle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + ser, + point, + pointIndex - 1); + } + } + } + } + } + } + + #endregion + + #region 3D Drawing and Selection methods + + /// + /// This method recalculates size of the bars. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual protected void ProcessChartType3D( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + // All data series from chart area which have Error Bar chart type + List typeSeries = area.GetSeriesFromChartType(this.Name); + + // Zero X values mode. + bool indexedSeries = ChartHelper.IndexedSeries(common, typeSeries.ToArray() ); + + //************************************************************ + //** Loop through all series + //************************************************************ + int seriesIndx = 0; + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with stock chart type + if( String.Compare( ser.ChartTypeName, this.Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Check that we have at least 6 Y values + if(ser.YValuesPerPoint < 6) + { + throw(new ArgumentException(SR.ExceptionChartTypeRequiresYValues( ChartTypeNames.BoxPlot, "6"))); + } + + // Check if side-by-side attribute is set + bool currentShowSideBySide = showSideBySide; + if(ser.IsCustomPropertySet(CustomPropertyName.DrawSideBySide)) + { + string attribValue = ser[CustomPropertyName.DrawSideBySide]; + if(String.Compare( attribValue, "False", StringComparison.OrdinalIgnoreCase) == 0) + { + currentShowSideBySide = false; + } + else if (String.Compare(attribValue, "True", StringComparison.OrdinalIgnoreCase) == 0) + { + currentShowSideBySide = true; + } + else if (String.Compare(attribValue, "Auto", StringComparison.OrdinalIgnoreCase) == 0) + { + } + else + { + throw (new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid)); + } + } + + // Find the number of "Column chart" data series + double numOfSeries = typeSeries.Count; + if(!currentShowSideBySide) + { + numOfSeries = 1; + } + + // Set active horizontal/vertical axis + hAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + vAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Get interval between points + double interval = (indexedSeries) ? 1 : area.GetPointsInterval( hAxis.IsLogarithmic, hAxis.logarithmBase ); + + // Calculates the width of the candles. + float width = (float)(ser.GetPointWidth(graph, hAxis, interval, 0.8) / numOfSeries); + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + //************************************************************ + //** Get series depth and Z position + //************************************************************ + float seriesDepth, seriesZPosition; + area.GetSeriesZPositionAndDepth(ser, out seriesDepth, out seriesZPosition); + + //************************************************************ + //** Series data points loop + //************************************************************ + int index = 1; + foreach( DataPoint point in ser.Points ) + { + // Check required Y values number + if(point.YValues.Length < this.YValuesPerPoint) + { + throw(new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)))); + } + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Get point X position + float xPosition = 0f; + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + xPosition = (float)(hAxis.GetPosition( (double)index ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width); + } + else if( currentShowSideBySide ) + { + xPosition = (float)(hAxis.GetPosition( xValue ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width); + } + else + { + xPosition = (float)hAxis.GetPosition( xValue ); + } + + double yValue0 = vAxis.GetLogValue( point.YValues[0] ); + double yValue1 = vAxis.GetLogValue( point.YValues[1] ); + xValue = hAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < hAxis.ViewMinimum || + xValue > hAxis.ViewMaximum || + (yValue0 < vAxis.ViewMinimum && yValue1 < vAxis.ViewMinimum) || + (yValue0 > vAxis.ViewMaximum && yValue1 > vAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Make sure High/Low values are in data scaleView range + double high = vAxis.GetLogValue( point.YValues[1] ); + double low = vAxis.GetLogValue( point.YValues[0] ); + + if( high > vAxis.ViewMaximum ) + { + high = vAxis.ViewMaximum; + } + if( high < vAxis.ViewMinimum ) + { + high = vAxis.ViewMinimum; + } + high = (float)vAxis.GetLinearPosition(high); + + if( low > vAxis.ViewMaximum ) + { + low = vAxis.ViewMaximum; + } + if( low < vAxis.ViewMinimum ) + { + low = vAxis.ViewMinimum; + } + low = vAxis.GetLinearPosition(low); + + // Remeber pre-calculated point position + point.positionRel = new PointF((float)xPosition, (float)Math.Min(high, low)); + + // 3D Transform coordinates + Point3D[] points = new Point3D[6]; + points[0] = new Point3D(xPosition, (float)low, seriesZPosition+seriesDepth/2f); + points[1] = new Point3D(xPosition, (float)high, seriesZPosition+seriesDepth/2f); + points[2] = new Point3D(xPosition, (float)vAxis.GetPosition(point.YValues[2]), seriesZPosition+seriesDepth/2f); + points[3] = new Point3D(xPosition, (float)vAxis.GetPosition(point.YValues[3]), seriesZPosition+seriesDepth/2f); + points[4] = new Point3D(xPosition, (float)vAxis.GetPosition(point.YValues[4]), seriesZPosition+seriesDepth/2f); + points[5] = new Point3D(xPosition, (float)vAxis.GetPosition(point.YValues[5]), seriesZPosition+seriesDepth/2f); + area.matrix3D.TransformPoints(points); + + if( common.ProcessModePaint ) + { + // Check if chart is partialy in the data scaleView + bool clipRegionSet = false; + if(xValue == hAxis.ViewMinimum || xValue == hAxis.ViewMaximum ) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + // Define line color + Color lineColor = point.BorderColor; + if(lineColor == Color.Empty) + { + lineColor = point.Color; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw lower whisker line + graph.DrawLineRel( + lineColor, + point.BorderWidth, + point.BorderDashStyle, + points[0].PointF, + points[2].PointF, + ser.ShadowColor, + ser.ShadowOffset ); + + // Draw upper whisker line + graph.DrawLineRel( + lineColor, + point.BorderWidth, + point.BorderDashStyle, + points[1].PointF, + points[3].PointF, + ser.ShadowColor, + ser.ShadowOffset ); + + // Draw Box + RectangleF rectSize = RectangleF.Empty; + rectSize.X = (float)(points[0].X - width/2); + rectSize.Width = (float)(width); + rectSize.Y = (float)points[3].Y; + rectSize.Height = (float)Math.Abs(rectSize.Y - points[2].Y); + graph.FillRectangleRel( rectSize, + point.Color, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + point.BackSecondaryColor, + point.BorderColor, + point.BorderWidth, + point.BorderDashStyle, + ser.ShadowColor, + ser.ShadowOffset, + PenAlignment.Inset ); + + // Check if average line should be drawn + bool showAverage = true; + if(point.IsCustomPropertySet(CustomPropertyName.BoxPlotShowAverage) || ser.IsCustomPropertySet(CustomPropertyName.BoxPlotShowAverage)) + { + string showAverageValue = ser[CustomPropertyName.BoxPlotShowAverage]; + if(point.IsCustomPropertySet(CustomPropertyName.BoxPlotShowAverage)) + { + showAverageValue = point[CustomPropertyName.BoxPlotShowAverage]; + } + if(String.Compare(showAverageValue, "True", StringComparison.OrdinalIgnoreCase) == 0) + { + // default - do nothing + } + else if(String.Compare(showAverageValue, "False", StringComparison.OrdinalIgnoreCase) == 0) + { + showAverage = false; + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(point[CustomPropertyName.BoxPlotShowAverage], "BoxPlotShowAverage"))); + } + } + + // Draw average line + Color markerLinesColor = lineColor; + if(markerLinesColor == point.Color) + { + double brightness = Math.Sqrt(point.Color.R * point.Color.R + point.Color.G * point.Color.G + point.Color.B * point.Color.B); + if(brightness > 220) + { + markerLinesColor = ChartGraphics.GetGradientColor(point.Color, Color.Black, 0.4); + } + else + { + markerLinesColor = ChartGraphics.GetGradientColor(point.Color, Color.White, 0.4); + } + } + if(!double.IsNaN(point.YValues[4]) && showAverage) + { + graph.DrawLineRel( + markerLinesColor, + 1, + ChartDashStyle.Solid, + new PointF(rectSize.Left, (float)points[4].Y), + new PointF(rectSize.Right, (float)points[4].Y), + Color.Empty, + 0 ); + } + + // Check if median line should be drawn + bool showMedian = true; + if(point.IsCustomPropertySet(CustomPropertyName.BoxPlotShowMedian) || ser.IsCustomPropertySet(CustomPropertyName.BoxPlotShowMedian)) + { + string showMedianValue = ser[CustomPropertyName.BoxPlotShowMedian]; + if(point.IsCustomPropertySet(CustomPropertyName.BoxPlotShowMedian)) + { + showMedianValue = point[CustomPropertyName.BoxPlotShowMedian]; + } + if(String.Compare( showMedianValue, "True", StringComparison.OrdinalIgnoreCase ) == 0) + { + // default - do nothing + } + else if(String.Compare(showMedianValue, "False", StringComparison.OrdinalIgnoreCase ) == 0) + { + showMedian = false; + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(point[CustomPropertyName.BoxPlotShowMedian], "BoxPlotShowMedian"))); + } + } + + // Draw median line + if(!double.IsNaN(point.YValues[5]) && showMedian) + { + float medianValue = (float)points[5].Y; + float dashWidth = rectSize.Width / 9f; + + // Dash width should not be less than 2 pixels + SizeF minSize = graph.GetRelativeSize(new SizeF(2, 2)); + dashWidth = Math.Max(dashWidth, minSize.Width); + + for(float curPosition = rectSize.Left; curPosition < rectSize.Right; curPosition += dashWidth * 2f) + { + graph.DrawLineRel( + markerLinesColor, + 1, + ChartDashStyle.Solid, + new PointF(curPosition, medianValue), + new PointF((float) Math.Min(rectSize.Right, curPosition + dashWidth), medianValue), + Color.Empty, + 0 ); + } + } + + // Draw Box Plot marks + DrawBoxPlotMarks3D(graph, area, ser, point, xPosition, width, seriesZPosition, seriesDepth); + xPosition = points[0].X; + high = points[0].Y; + low = points[1].Y; + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + } + + if( common.ProcessModeRegions ) + { + xPosition = points[0].X; + high = points[0].Y; + low = points[1].Y; + + // Calculate rect around the error bar marks + RectangleF areaRect = RectangleF.Empty; + areaRect.X = xPosition - width / 2f; + areaRect.Y = (float)Math.Min(high, low); + areaRect.Width = width; + areaRect.Height = (float)Math.Max(high, low) - areaRect.Y; + + // Add area + common.HotRegionsList.AddHotRegion( areaRect, point, ser.Name, index - 1 ); + } + + ++index; + } + + //************************************************************ + //** Second series data points loop, when labels are drawn. + //************************************************************ + if( !selection ) + { + index = 1; + foreach( DataPoint point in ser.Points ) + { + // Get point X position + float xPosition = 0f; + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + xPosition = (float)(hAxis.GetPosition( (double)index ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width); + } + else if( currentShowSideBySide ) + { + xPosition = (float)(hAxis.GetPosition( xValue ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width); + } + else + { + xPosition = (float)hAxis.GetPosition( xValue ); + } + + + double yValue0 = vAxis.GetLogValue( point.YValues[0] ); + double yValue1 = vAxis.GetLogValue( point.YValues[1] ); + xValue = hAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < hAxis.ViewMinimum || + xValue > hAxis.ViewMaximum || + (yValue0 < vAxis.ViewMinimum && yValue1 < vAxis.ViewMinimum) || + (yValue0 > vAxis.ViewMaximum && yValue1 > vAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Make sure High/Low values are in data scaleView range + double high = vAxis.GetLogValue( point.YValues[1] ); + double low = vAxis.GetLogValue( point.YValues[0] ); + if( high > vAxis.ViewMaximum ) + { + high = vAxis.ViewMaximum; + } + if( high < vAxis.ViewMinimum ) + { + high = vAxis.ViewMinimum; + } + high = (float)vAxis.GetLinearPosition(high); + + if( low > vAxis.ViewMaximum ) + { + low = vAxis.ViewMaximum; + } + if( low < vAxis.ViewMinimum ) + { + low = vAxis.ViewMinimum; + } + low = vAxis.GetLinearPosition(low); + + + // 3D Transform coordinates + Point3D[] points = new Point3D[2]; + points[0] = new Point3D(xPosition, (float)high, seriesZPosition+seriesDepth/2f); + points[1] = new Point3D(xPosition, (float)low, seriesZPosition+seriesDepth/2f); + area.matrix3D.TransformPoints(points); + xPosition = points[0].X; + high = points[0].Y; + low = points[1].Y; + + // Draw label + DrawLabel(common, area, graph, ser, point, new PointF(xPosition, (float)Math.Min(high, low)), index); + + ++index; + } + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + } + } + + /// + /// Draws 3D box plot markers. + /// + /// Chart graphics object. + /// Chart area. + /// Data point series. + /// Data point to draw. + /// X position. + /// Point width. + /// Series Z position. + /// Series depth. + virtual protected void DrawBoxPlotMarks3D( + ChartGraphics graph, + ChartArea area, + Series ser, + DataPoint point, + float xPosition, + float width, + float zPosition, + float depth) + { + // Get markers style + string markerStyle = "LINE"; + if(point.MarkerStyle != MarkerStyle.None) + { + markerStyle = point.MarkerStyle.ToString(); + } + + // Draw lower marker + double yPosition = vAxis.GetLogValue( point.YValues[0] ); + DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)yPosition, zPosition+depth/2f, width, true); + + // Draw upper marker + yPosition = vAxis.GetLogValue( point.YValues[1] ); + DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)yPosition, zPosition+depth/2f, width, true); + + // Draw unusual points if any + markerStyle = "CIRCLE"; + if(point.MarkerStyle != MarkerStyle.None) + { + markerStyle = point.MarkerStyle.ToString(); + } + for(int valueIndex = 6; valueIndex < point.YValues.Length; valueIndex++) + { + if(!double.IsNaN(point.YValues[valueIndex])) + { + yPosition = vAxis.GetLogValue( point.YValues[valueIndex] ); + DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)yPosition, zPosition+depth/2f, width, true); + } + } + } + + #endregion + + #region Y values related methods + + /// + /// Helper function that returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + return point.YValues[yValueIndex]; + } + + #endregion + + #region Automatic Values Calculation methods + + /// + /// Populates box plot chart type using series data specified in "BoxPlotSeries" custom attribute. + /// + /// Box Plot chart type series. + internal static void CalculateBoxPlotFromLinkedSeries(Series boxPlotSeries) + { + // Check input parameters + if(String.Compare( boxPlotSeries.ChartTypeName, ChartTypeNames.BoxPlot, StringComparison.OrdinalIgnoreCase) != 0) + { + return; + } + + // Check if "BoxPlotSeries" custom attribute is set for the series + if(boxPlotSeries.IsCustomPropertySet(CustomPropertyName.BoxPlotSeries)) + { + // Create as many data points as series in attribute + string[] attrValues = boxPlotSeries[CustomPropertyName.BoxPlotSeries].Split(';'); + + // Clear and and new points + boxPlotSeries.Points.Clear(); + int pointIndex = 0; + foreach(string val in attrValues) + { + boxPlotSeries.Points.AddY(0.0); + boxPlotSeries.Points[pointIndex++][CustomPropertyName.BoxPlotSeries] = val.Trim(); + } + } + + // Calculate box plot for every data point + for(int pointIndex = 0; pointIndex < boxPlotSeries.Points.Count; pointIndex++) + { + DataPoint point = boxPlotSeries.Points[pointIndex]; + if(point.IsCustomPropertySet(CustomPropertyName.BoxPlotSeries)) + { + // Get series and value name + string linkedSeriesName = point[CustomPropertyName.BoxPlotSeries]; + String valueName = "Y"; + int valueTypeIndex = linkedSeriesName.IndexOf(":", StringComparison.OrdinalIgnoreCase); + if(valueTypeIndex >= 0) + { + valueName = linkedSeriesName.Substring(valueTypeIndex + 1); + linkedSeriesName = linkedSeriesName.Substring(0, valueTypeIndex); + } + + // Get reference to the chart control + Chart control = boxPlotSeries.Chart; + if(control != null) + { + // Get linked series and check existance + if(control.Series.IndexOf(linkedSeriesName) == -1) + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeSeriesNameNotFound("BoxPlotSeries", linkedSeriesName) )); + } + Series linkedSeries = control.Series[linkedSeriesName]; + + // Calculate box point values + CalculateBoxPlotValues(ref point, linkedSeries, valueName); + } + + } + } + + } + + /// + /// Calculates values for single Box Plot point using specified data series. + /// + /// Data Point. + /// Linked data series. + /// Name of the point value to link to. + private static void CalculateBoxPlotValues(ref DataPoint boxPoint, Series linkedSeries, string valueName) + { + // Linked series must be non-empty + if (linkedSeries.Points.Count == 0) + { + return; + } + + // Calculate an average value for all the data points + double averageValue = 0.0; + int valueCount = 0; + foreach(DataPoint point in linkedSeries.Points) + { + if(!point.IsEmpty) + { + averageValue += point.GetValueByName(valueName); + ++valueCount; + } + } + averageValue /= valueCount; + + // Fill array of Y values + List yValues = new List(valueCount); + foreach(DataPoint point in linkedSeries.Points) + { + if(!point.IsEmpty) + { + yValues.Add((point.IsEmpty) ? double.NaN : point.GetValueByName(valueName)); + } + } + + // Get required percentiles + double[] requiredPercentile = new Double[] { 10.0, 90.0, 25.0, 75.0, 50.0 }; + string boxPercentile = (boxPoint.IsCustomPropertySet(CustomPropertyName.BoxPlotPercentile)) ? boxPoint[CustomPropertyName.BoxPlotPercentile] : String.Empty; + if(boxPercentile.Length == 0 && boxPoint.series != null && boxPoint.series.IsCustomPropertySet(CustomPropertyName.BoxPlotPercentile)) + { + boxPercentile = boxPoint.series[CustomPropertyName.BoxPlotPercentile]; + } + string boxWhiskerPercentile = (boxPoint.IsCustomPropertySet(CustomPropertyName.BoxPlotWhiskerPercentile)) ? boxPoint[CustomPropertyName.BoxPlotWhiskerPercentile] : String.Empty; + if(boxWhiskerPercentile.Length == 0 && boxPoint.series != null && boxPoint.series.IsCustomPropertySet(CustomPropertyName.BoxPlotWhiskerPercentile)) + { + boxWhiskerPercentile = boxPoint.series[CustomPropertyName.BoxPlotWhiskerPercentile]; + } + + // Check specified + if (boxPercentile.Length > 0) + { + double percentile; + bool parseSucceed = double.TryParse(boxPercentile, NumberStyles.Any, CultureInfo.InvariantCulture, out percentile); + if (parseSucceed) + { + requiredPercentile[2] = percentile; + } + + if (!parseSucceed || requiredPercentile[2] < 0 || requiredPercentile[2] > 50) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeIsNotInRange0to50("BoxPlotPercentile"))); + } + + requiredPercentile[3] = 100.0 - requiredPercentile[2]; + } + + if (boxWhiskerPercentile.Length > 0) + { + + double percentile; + bool parseSucceed = double.TryParse(boxWhiskerPercentile, NumberStyles.Any, CultureInfo.InvariantCulture, out percentile); + if (parseSucceed) + { + requiredPercentile[0] = percentile; + } + + + if (!parseSucceed || requiredPercentile[0] < 0 || requiredPercentile[0] > 50) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeIsNotInRange0to50("BoxPlotPercentile"))); + } + + requiredPercentile[1] = 100.0 - requiredPercentile[0]; + } + + // Calculate 5 recured percentile values + double[] percentileValues = CalculatePercentileValues(yValues, requiredPercentile); + + // Set data points values + boxPoint.YValues[0] = percentileValues[0]; + boxPoint.YValues[1] = percentileValues[1]; + boxPoint.YValues[2] = percentileValues[2]; + boxPoint.YValues[3] = percentileValues[3]; + boxPoint.YValues[4] = averageValue; + boxPoint.YValues[5] = percentileValues[4]; + + // Check if unusual values should be added + bool addUnusualValues = false; + string showUnusualValues = (boxPoint.IsCustomPropertySet(CustomPropertyName.BoxPlotShowUnusualValues)) ? boxPoint[CustomPropertyName.BoxPlotShowUnusualValues] : String.Empty; + if(showUnusualValues.Length == 0 && boxPoint.series != null && boxPoint.series.IsCustomPropertySet(CustomPropertyName.BoxPlotShowUnusualValues)) + { + showUnusualValues = boxPoint.series[CustomPropertyName.BoxPlotShowUnusualValues]; + } + if(showUnusualValues.Length > 0) + { + if(String.Compare(showUnusualValues, "True", StringComparison.OrdinalIgnoreCase ) == 0) + { + addUnusualValues = true; + } + else if(String.Compare(showUnusualValues, "False", StringComparison.OrdinalIgnoreCase ) == 0) + { + addUnusualValues = false; + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid2("BoxPlotShowUnusualValues"))); + } + } + + // Add unusual point + if(addUnusualValues) + { + BoxPlotAddUnusual(ref boxPoint, yValues); + } + } + + /// + /// Add unusual data point + /// + /// Data Point. + /// Y values array. + static private void BoxPlotAddUnusual(ref DataPoint boxPoint, List yValues) + { + // Get unusual values + ArrayList unusualValuesList = new ArrayList(); + foreach(double yValue in yValues) + { + if(yValue < boxPoint.YValues[0] || yValue > boxPoint.YValues[1]) + { + unusualValuesList.Add(yValue); + } + } + + // Update point's values + if(unusualValuesList.Count > 0) + { + // Create new arry of values for the data pont + double[] newYValues = new double[6 + unusualValuesList.Count]; + + // Copy original data + for(int index = 0; index < 6; index++) + { + newYValues[index] = boxPoint.YValues[index]; + } + + // Add unusual values + for(int index = 0; index < unusualValuesList.Count; index++) + { + newYValues[6 + index] = (double)unusualValuesList[index]; + } + + // Set new values array + boxPoint.YValues = newYValues; + } + } + + /// + /// Calculates required percentile values from the data + /// + /// Array of 5 values + /// Y values array. + /// Required percentile + /// Array of 5 values + static private double[] CalculatePercentileValues(List yValues, double[] requiredPercentile) + { + // Create results array + double[] result = new double[5]; + + // Sort Y values array + yValues.Sort(); + + // Calculate required percentile + int index = 0; + foreach(double percentile in requiredPercentile) + { + // Get percentile point index + double percentPointIndex = (yValues.Count - 1.0)/ 100.0 * percentile; + double percentPointIndexInteger = Math.Floor(percentPointIndex); + double percentPointIndexReminder = percentPointIndex - percentPointIndexInteger; + + result[index] = 0.0; + if ((int)percentPointIndexInteger < yValues.Count) + { + result[index] += (1.0 - percentPointIndexReminder) * yValues[(int)percentPointIndexInteger]; + } + if ((int)(percentPointIndexInteger + 1) < yValues.Count) + { + result[index] += percentPointIndexReminder * yValues[(int)percentPointIndexInteger + 1]; + } + + ++index; + } + + + return result; + } + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + // No data point markers supported for SmartLabelStyle + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} + diff --git a/System.Web.DataVisualization/Common/ChartTypes/BubbleChart.cs b/System.Web.DataVisualization/Common/ChartTypes/BubbleChart.cs new file mode 100644 index 000000000..bab203a81 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/BubbleChart.cs @@ -0,0 +1,497 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: BubbleChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: BubbleChart +// +// Purpose: Bubble chart type is similar to the Point chart +// where each data point is presented with a marker +// positioned using X and Y values. The difference +// of the Bubble chart is that an additional Y value +// is used to control the size of the marker. +// +// Reviewed: AG - August 6, 2002 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Resources; +using System.Reflection; +using System.Drawing; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// BubbleChart class extends PointChart class to add support for + /// additional Y value which controls the size of the markers used. + /// + internal class BubbleChart : PointChart + { + #region Fields and Constructor + + // Indicates that bubble size scale is calculated + private bool _scaleDetected = false; + + // Minimum/Maximum bubble size + private double _maxPossibleBubbleSize = 15F; + private double _minPossibleBubbleSize = 3F; + private float _maxBubleSize = 0f; + private float _minBubleSize = 0f; + + // Current min/max size of the bubble size + private double _minAll = double.MaxValue; + private double _maxAll = double.MinValue; + + + // Bubble size difference value + private double _valueDiff = 0; + private double _valueScale = 1; + + /// + /// Class public constructor + /// + public BubbleChart() : base(true) + { + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.Bubble;}} + + /// + /// Number of supported Y value(s) per point + /// + override public int YValuesPerPoint { get { return 2; } } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + override public bool SecondYScale{ get{ return true;} } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Bubble chart methods + + /// + /// This method recalculates size of the bars. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Chart series to draw. + override protected void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + _scaleDetected = false; + base.ProcessChartType(selection, graph, common, area, seriesToDraw ); + } + + /// + /// Gets marker border size. + /// + /// Data point. + /// Marker border size. + override protected int GetMarkerBorderSize(DataPointCustomProperties point) + { + if(point.series != null) + { + return point.series.BorderWidth; + } + + return 1; + } + + /// + /// Returns marker size. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Data point. + /// Marker size. + /// Marker image. + /// Marker width and height. + override protected SizeF GetMarkerSize( + ChartGraphics graph, + CommonElements common, + ChartArea area, + DataPoint point, + int markerSize, + string markerImage) + { + // Check required Y values number + if(point.YValues.Length < this.YValuesPerPoint) + { + throw(new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)))); + } + + // Marker size + SizeF size = new SizeF(markerSize, markerSize); + if (graph != null && graph.Graphics != null) + { + // Marker size is in pixels and we do the mapping for higher DPIs + size.Width = markerSize * graph.Graphics.DpiX / 96; + size.Height = markerSize * graph.Graphics.DpiY / 96; + } + + // Check number of Y values for non empty points + if(point.series.YValuesPerPoint > 1 && !point.IsEmpty) + { + // Scale Y values + size.Width = ScaleBubbleSize(graph, common, area, point.YValues[1]); + size.Height = ScaleBubbleSize(graph, common, area, point.YValues[1]); + } + + return size; + } + + /// + /// Scales the value used to determine the size of the Bubble. + /// + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Value to scale. + /// Scaled values. + private float ScaleBubbleSize(ChartGraphics graph, CommonElements common, ChartArea area, double value) + { + // Check if scaling numbers are detected + if(!_scaleDetected) + { + // Try to find bubble size scale in the custom series properties + _minAll = double.MaxValue; + _maxAll = double.MinValue; + foreach( Series ser in common.DataManager.Series ) + { + if( String.Compare( ser.ChartTypeName, this.Name, true, System.Globalization.CultureInfo.CurrentCulture) == 0 && + ser.ChartArea == area.Name && + ser.IsVisible()) + { + // Check if custom properties are set to specify scale + if(ser.IsCustomPropertySet(CustomPropertyName.BubbleScaleMin)) + { + _minAll = Math.Min(_minAll, CommonElements.ParseDouble(ser[CustomPropertyName.BubbleScaleMin])); + } + if(ser.IsCustomPropertySet(CustomPropertyName.BubbleScaleMax)) + { + _maxAll = Math.Max(_maxAll, CommonElements.ParseDouble(ser[CustomPropertyName.BubbleScaleMax])); + } + + // Check if attribute for max. size is set + if(ser.IsCustomPropertySet(CustomPropertyName.BubbleMaxSize)) + { + _maxPossibleBubbleSize = CommonElements.ParseDouble(ser[CustomPropertyName.BubbleMaxSize]); + if(_maxPossibleBubbleSize < 0 || _maxPossibleBubbleSize > 100) + { + throw(new ArgumentException(SR.ExceptionCustomAttributeIsNotInRange0to100("BubbleMaxSize"))); + } + } + + // Check if attribute for min. size is set + if(ser.IsCustomPropertySet(CustomPropertyName.BubbleMinSize)) + { + _minPossibleBubbleSize = CommonElements.ParseDouble(ser[CustomPropertyName.BubbleMinSize]); + if(_minPossibleBubbleSize < 0 || _minPossibleBubbleSize > 100) + { + throw(new ArgumentException(SR.ExceptionCustomAttributeIsNotInRange0to100("BubbleMinSize"))); + } + } + + + // Check if custom properties set to use second Y value (bubble size) as label text + labelYValueIndex = 0; + if(ser.IsCustomPropertySet(CustomPropertyName.BubbleUseSizeForLabel)) + { + if(String.Compare(ser[CustomPropertyName.BubbleUseSizeForLabel], "true", StringComparison.OrdinalIgnoreCase) == 0) + { + labelYValueIndex = 1; + break; + } + } + } + } + + // Scale values are not specified - auto detect + if(_minAll == double.MaxValue || _maxAll == double.MinValue) + { + double minSer = double.MaxValue; + double maxSer = double.MinValue; + foreach( Series ser in common.DataManager.Series ) + { + if( ser.ChartTypeName == this.Name && ser.ChartArea == area.Name && ser.IsVisible() ) + { + foreach(DataPoint point in ser.Points) + { + if (!point.IsEmpty) + { + // Check required Y values number + if (point.YValues.Length < this.YValuesPerPoint) + { + throw (new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)))); + } + + minSer = Math.Min(minSer, point.YValues[1]); + maxSer = Math.Max(maxSer, point.YValues[1]); + } + } + } + } + if(_minAll == double.MaxValue) + { + _minAll = minSer; + } + if(_maxAll == double.MinValue) + { + _maxAll = maxSer; + } + } + + // Calculate maximum bubble size + SizeF areaSize = graph.GetAbsoluteSize(area.PlotAreaPosition.Size); + _maxBubleSize = (float)(Math.Min(areaSize.Width, areaSize.Height) / (100.0/_maxPossibleBubbleSize)); + _minBubleSize = (float)(Math.Min(areaSize.Width, areaSize.Height) / (100.0/_minPossibleBubbleSize)); + + // Calculate scaling variables depending on the Min/Max values + if(_maxAll == _minAll) + { + this._valueScale = 1; + this._valueDiff = _minAll - (_maxBubleSize - _minBubleSize)/2f; + } + else + { + this._valueScale = (_maxBubleSize - _minBubleSize) / (_maxAll - _minAll); + this._valueDiff = _minAll; + } + + _scaleDetected = true; + } + + // Check if value do not exceed Min&Max + if(value > _maxAll) + { + return 0F; + } + if(value < _minAll) + { + return 0F; + } + + // Return scaled value + return (float)((value - this._valueDiff) * this._valueScale) + _minBubleSize; + } + + /// + /// Scales the value used to determine the size of the Bubble. + /// + /// The Common elements object + /// Chart area for this chart + /// Value to scale. + /// True if Y value is calculated, false if X. + /// Scaled values. + static internal double AxisScaleBubbleSize(CommonElements common, ChartArea area, double value, bool yValue ) + { + + // Try to find bubble size scale in the custom series properties + double minAll = double.MaxValue; + double maxAll = double.MinValue; + double maxPossibleBubbleSize = 15F; + double minPossibleBubbleSize = 3F; + float maxBubleSize; + float minBubleSize; + double valueScale; + double valueDiff; + foreach( Series ser in common.DataManager.Series ) + { + if( String.Compare( ser.ChartTypeName, ChartTypeNames.Bubble, StringComparison.OrdinalIgnoreCase) == 0 && + ser.ChartArea == area.Name && + ser.IsVisible()) + { + // Check if custom properties are set to specify scale + if(ser.IsCustomPropertySet(CustomPropertyName.BubbleScaleMin)) + { + minAll = Math.Min(minAll, CommonElements.ParseDouble(ser[CustomPropertyName.BubbleScaleMin])); + } + if(ser.IsCustomPropertySet(CustomPropertyName.BubbleScaleMax)) + { + maxAll = Math.Max(maxAll, CommonElements.ParseDouble(ser[CustomPropertyName.BubbleScaleMax])); + } + + // Check if attribute for max. size is set + if(ser.IsCustomPropertySet(CustomPropertyName.BubbleMaxSize)) + { + maxPossibleBubbleSize = CommonElements.ParseDouble(ser[CustomPropertyName.BubbleMaxSize]); + if(maxPossibleBubbleSize < 0 || maxPossibleBubbleSize > 100) + { + throw(new ArgumentException(SR.ExceptionCustomAttributeIsNotInRange0to100("BubbleMaxSize"))); + } + } + + // Check if custom properties set to use second Y value (bubble size) as label text + if(ser.IsCustomPropertySet(CustomPropertyName.BubbleUseSizeForLabel)) + { + if(String.Compare(ser[CustomPropertyName.BubbleUseSizeForLabel], "true", StringComparison.OrdinalIgnoreCase) == 0) + { + break; + } + } + } + } + + // Scale values are not specified - auto detect + double minimum = double.MaxValue; + double maximum = double.MinValue; + double minSer = double.MaxValue; + double maxSer = double.MinValue; + foreach( Series ser in common.DataManager.Series ) + { + if( String.Compare(ser.ChartTypeName, ChartTypeNames.Bubble, StringComparison.OrdinalIgnoreCase) == 0 + && ser.ChartArea == area.Name + && ser.IsVisible() ) + { + foreach(DataPoint point in ser.Points) + { + if (!point.IsEmpty) + { + minSer = Math.Min(minSer, point.YValues[1]); + maxSer = Math.Max(maxSer, point.YValues[1]); + + if (yValue) + { + minimum = Math.Min(minimum, point.YValues[0]); + maximum = Math.Max(maximum, point.YValues[0]); + } + else + { + minimum = Math.Min(minimum, point.XValue); + maximum = Math.Max(maximum, point.XValue); + } + } + } + } + } + if(minAll == double.MaxValue) + { + minAll = minSer; + } + if(maxAll == double.MinValue) + { + maxAll = maxSer; + } + + // Calculate maximum bubble size + maxBubleSize = (float)( (maximum - minimum) / (100.0/maxPossibleBubbleSize)); + minBubleSize = (float)( (maximum - minimum) / (100.0/minPossibleBubbleSize)); + + // Calculate scaling variables depending on the Min/Max values + if(maxAll == minAll) + { + valueScale = 1; + valueDiff = minAll - (maxBubleSize - minBubleSize)/2f; + } + else + { + valueScale = (maxBubleSize - minBubleSize) / (maxAll - minAll); + valueDiff = minAll; + } + + + // Check if value do not exceed Min&Max + if(value > maxAll) + { + return 0F; + } + if(value < minAll) + { + return 0F; + } + + // Return scaled value + return (float)((value - valueDiff) * valueScale) + minBubleSize; + } + + /// + /// Get value from custom attribute BubbleMaxSize + /// + /// Chart Area + /// Bubble Max size + static internal double GetBubbleMaxSize( ChartArea area ) + { + double maxPossibleBubbleSize = 15; + // Try to find bubble size scale in the custom series properties + foreach( Series ser in area.Common.DataManager.Series ) + { + if( String.Compare( ser.ChartTypeName, ChartTypeNames.Bubble, StringComparison.OrdinalIgnoreCase) == 0 && + ser.ChartArea == area.Name && + ser.IsVisible()) + { + // Check if attribute for max. size is set + if(ser.IsCustomPropertySet(CustomPropertyName.BubbleMaxSize)) + { + maxPossibleBubbleSize = CommonElements.ParseDouble(ser[CustomPropertyName.BubbleMaxSize]); + if(maxPossibleBubbleSize < 0 || maxPossibleBubbleSize > 100) + { + throw(new ArgumentException(SR.ExceptionCustomAttributeIsNotInRange0to100("BubbleMaxSize"))); + } + } + } + } + + return maxPossibleBubbleSize / 100; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/ChartTypeRegistry.cs b/System.Web.DataVisualization/Common/ChartTypes/ChartTypeRegistry.cs new file mode 100644 index 000000000..bf6e8b3d3 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/ChartTypeRegistry.cs @@ -0,0 +1,453 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartTypeRegistry.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: ChartTypeRegistry, IChartType +// +// Purpose: ChartTypeRegistry is a repository for all standard +// and custom chart types. Each chart type has unique +// name and IChartType derived class which provides +// behaviour information about the chart type and +// also contains drwaing functionality. +// +// ChartTypeRegistry can be used by user for custom +// chart type registering and can be retrieved using +// Chart.GetService(typeof(ChartTypeRegistry)) method. +// +// Reviewed: AG - Aug 6, 2002 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Reflection; +using System.Drawing; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web.UI.DataVisualization.Charting; + + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// ChartTypeName class contains constant strings defining + /// names of all ChartTypes used in the Chart. + /// + internal static class ChartTypeNames + { + #region Chart type names + + internal const string Area = "Area"; + internal const string RangeBar = "RangeBar"; + internal const string Bar = "Bar"; + internal const string SplineArea = "SplineArea"; + internal const string BoxPlot = "BoxPlot"; + internal const string Bubble = "Bubble"; + internal const string Column = "Column"; + internal const string RangeColumn = "RangeColumn"; + internal const string Doughnut = "Doughnut"; + internal const string ErrorBar = "ErrorBar"; + internal const string FastLine = "FastLine"; + internal const string FastPoint = "FastPoint"; + internal const string Funnel = "Funnel"; + internal const string Pyramid = "Pyramid"; + internal const string Kagi = "Kagi"; + internal const string Spline = "Spline"; + internal const string Line = "Line"; + internal const string PointAndFigure = "PointAndFigure"; + internal const string Pie = "Pie"; + internal const string Point = "Point"; + internal const string Polar = "Polar"; + internal const string Radar = "Radar"; + internal const string SplineRange = "SplineRange"; + internal const string Range = "Range"; + internal const string Renko = "Renko"; + internal const string OneHundredPercentStackedArea = "100%StackedArea"; + internal const string StackedArea = "StackedArea"; + internal const string OneHundredPercentStackedBar = "100%StackedBar"; + internal const string StackedBar = "StackedBar"; + internal const string OneHundredPercentStackedColumn = "100%StackedColumn"; + internal const string StackedColumn = "StackedColumn"; + internal const string StepLine = "StepLine"; + internal const string Candlestick = "Candlestick"; + internal const string Stock = "Stock"; + internal const string ThreeLineBreak = "ThreeLineBreak"; + + #endregion // Keyword Names + } + + /// + /// ChartTypeRegistry class is a repository for all standard and custom + /// chart types. In order for the chart control to display the chart + /// type, it first must be registered using unique name and IChartType + /// derived class which provides the description of the chart type and + /// also responsible for all drawing and hit testing. + /// + /// ChartTypeRegistry can be used by user for custom chart type registering + /// and can be retrieved using Chart.GetService(typeof(ChartTypeRegistry)) + /// method. + /// + internal class ChartTypeRegistry : IServiceProvider, IDisposable + { + #region Fields + + // Chart types image resource manager + private ResourceManager _resourceManager = null; + + // Storage for registered/created chart types + internal Hashtable registeredChartTypes = new Hashtable(StringComparer.OrdinalIgnoreCase); + private Hashtable _createdChartTypes = new Hashtable(StringComparer.OrdinalIgnoreCase); + + #endregion + + #region Constructor and Services + + /// + /// Chart types registry public constructor. + /// + public ChartTypeRegistry() + { + } + + /// + /// Returns chart type registry service object. + /// + /// Service type to get. + /// Chart type registry service. + [EditorBrowsableAttribute(EditorBrowsableState.Never)] + object IServiceProvider.GetService(Type serviceType) + { + if(serviceType == typeof(ChartTypeRegistry)) + { + return this; + } + throw (new ArgumentException(SR.ExceptionChartTypeRegistryUnsupportedType( serviceType.ToString() ) ) ); + } + + #endregion + + #region Registry methods + + /// + /// Adds chart type into the registry. + /// + /// Chart type name. + /// Chart class type. + public void Register(string name, Type chartType) + { + // First check if chart type with specified name already registered + if(registeredChartTypes.Contains(name)) + { + // If same type provided - ignore + if(registeredChartTypes[name].GetType() == chartType) + { + return; + } + + // Error - throw exception + throw( new ArgumentException( SR.ExceptionChartTypeNameIsNotUnique( name ) ) ); + } + + // Make sure that specified class support IChartType interface + bool found = false; + Type[] interfaces = chartType.GetInterfaces(); + foreach(Type type in interfaces) + { + if(type == typeof(IChartType)) + { + found = true; + break; + } + } + if(!found) + { + throw (new ArgumentException(SR.ExceptionChartTypeHasNoInterface )); + } + + // Add chart type to the hash table + registeredChartTypes[name] = chartType; + } + + /// + /// Returns chart type object by name. + /// + /// Chart type. + /// Chart type object derived from IChartType. + public IChartType GetChartType(SeriesChartType chartType) + { + return this.GetChartType(Series.GetChartTypeName(chartType)); + } + + /// + /// Returns chart type object by name. + /// + /// Chart type name. + /// Chart type object derived from IChartType. + public IChartType GetChartType(string name) + { + // First check if chart type with specified name registered + if(!registeredChartTypes.Contains(name)) + { + throw( new ArgumentException( SR.ExceptionChartTypeUnknown( name ) ) ); + } + + // Check if the chart type object is already created + if(!_createdChartTypes.Contains(name)) + { + // Create chart type object + _createdChartTypes[name] = + ((Type)registeredChartTypes[name]).Assembly. + CreateInstance(((Type)registeredChartTypes[name]).ToString()); + } + + return (IChartType)_createdChartTypes[name]; + } + + /// + /// Chart images resource manager. + /// + public ResourceManager ResourceManager + { + get + { + // Create chart images resource manager + if(_resourceManager == null) + { + _resourceManager = new ResourceManager(typeof(Chart).Namespace + ".Design", Assembly.GetExecutingAssembly()); + } + return _resourceManager; + } + } + + #endregion + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + // Dispose managed resource + foreach (string name in this._createdChartTypes.Keys) + { + IChartType chartType = (IChartType)_createdChartTypes[name]; + chartType.Dispose(); + } + this._createdChartTypes.Clear(); + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + } + + /// + /// IChartType interface must be implemented for any standard or custom + /// chart type displayed in the chart control. This interface defines + /// properties which provide information on chart type behaviour including + /// how many Y values supported, is it a stacked chart type, how it + /// interacts with axes and much more. + /// + /// IChartType interface methods define how to draw series data point, + /// calculate Y values and process SmartLabelStyle. + /// + internal interface IChartType : IDisposable + { + #region Properties + + /// + /// Chart type name + /// + string Name { get; } + + /// + /// Gets chart type image + /// + /// Chart types registry object. + /// Chart type image. + System.Drawing.Image GetImage(ChartTypeRegistry registry); + + /// + /// True if chart type is stacked + /// + bool Stacked { get; } + + + /// + /// True if stacked chart type supports groups + /// + bool SupportStackedGroups { get; } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + bool StackSign { get; } + + /// + /// True if chart type supports axeses + /// + bool RequireAxes { get; } + + /// + /// True if chart type requires circular chart area. + /// + bool CircularChartArea { get; } + + /// + /// True if chart type supports logarithmic axes + /// + bool SupportLogarithmicAxes { get; } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + bool SwitchValueAxes { get; } + + /// + /// True if chart series can be placed side-by-side. + /// + bool SideBySideSeries { get; } + + /// + /// True if each data point of a chart must be represented in the legend + /// + bool DataPointsInLegend { get; } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + bool ApplyPaletteColorsToPoints { get; } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + bool ExtraYValuesConnectedToYAxis{ get; } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + bool ZeroCrossing { get; } + + /// + /// Number of supported Y value(s) per point + /// + int YValuesPerPoint{ get; } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + bool SecondYScale{ get; } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + bool HundredPercent{ get; } + + /// + /// Indicates that negative 100% stacked values are shown on + /// the other side of the X axis + /// + bool HundredPercentSupportNegative{ get; } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + LegendImageStyle GetLegendImageStyle(Series series); + + #endregion + + #region Painting and Selection methods + + /// + /// Draw chart on specified chart graphics. + /// + /// Chart grahhics object. + /// Common elements. + /// Chart area to draw on. + /// Chart series to draw. + void Paint(ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw); + + #endregion + + #region Y values methods + + /// + /// Helper function, which returns the Y value of the data point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "5#y")] + double GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex); + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list); + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/ColumnChart.cs b/System.Web.DataVisualization/Common/ChartTypes/ColumnChart.cs new file mode 100644 index 000000000..12a04e29d --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/ColumnChart.cs @@ -0,0 +1,1414 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ColumnChart.cs +// +// Namespace: System.Web.UI.DataVisualization.Charting.ChartTypes +// +// Classes: ColumnChart, RangeColumnChart +// +// Purpose: Provides 2D/3D drawing and hit testing functionality +// for the Column and RangeColumn charts. +// +// Reviewed: AG - Aug 8, 2002 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Utilities; +#else + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// ColumnChart class provides 2D/3D drawing and hit testing + /// functionality for the Column and RangeColumn charts. The + /// only difference between the RangeColumn and Column chart + /// is that 2 Y values are used to position top and bottom + /// side of each RangeColumn column. + /// + internal class ColumnChart : PointChart + { + #region Fields + + /// + /// Labels and markers have to be shifted if there + /// is more than one series for column chart. + /// + private double _shiftedX = 0; + + /// + /// Labels and markers have to be shifted if there + /// is more than one series for column chart. This property + /// will give a name of the series, which is used, for + /// labels and markers. Point chart + /// + private string _shiftedSerName = ""; + + /// + /// Indicates that two Y values are used to calculate column position + /// + protected bool useTwoValues = false; + + /// + /// Indicates that columns from different series are drawn side by side + /// + protected bool drawSeriesSideBySide = true; + + /// + /// Coordinates of COP used when sorting 3D points order + /// + protected COPCoordinates coordinates = COPCoordinates.X; + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.Column;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + /// + /// True if chart type is stacked + /// + override public bool Stacked { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + override public bool RequireAxes { get{ return true;} } + + /// + /// True if chart type supports logarithmic axes + /// + override public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + override public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + override public bool SideBySideSeries { get{ return true;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + override public bool DataPointsInLegend { get{ return false;} } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + override public bool ExtraYValuesConnectedToYAxis{ get { return false; } } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + override public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + override public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Number of supported Y value(s) per point + /// + override public int YValuesPerPoint{ get { return 1; } } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + override public bool ZeroCrossing { get{ return true;} } + + #endregion + + #region Constructor + + /// + /// Default constructor + /// + public ColumnChart() : base(false) + { + } + + #endregion + + #region Properties + + /// + /// Labels and markers have to be shifted if there + /// is more than one series for column chart. + /// + override public double ShiftedX + { + get + { + return _shiftedX; + } + set + { + _shiftedX = value; + } + } + + /// + /// Labels and markers have to be shifted if there + /// is more than one series for column chart. This property + /// will give a name of the series, which is used, for + /// labels and markers. + /// + override public string ShiftedSerName + { + get + { + return _shiftedSerName; + } + set + { + _shiftedSerName = value; + } + } + + #endregion + + #region Painting and selection methods + + /// + /// Paint Column Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + override public void Paint( + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw + ) + { + this.Common = common; + // Draw columns + ProcessChartType( false, false, graph, common, area, seriesToDraw ); + + // Draw labels and markers + ProcessChartType( true, false, graph, common, area, seriesToDraw ); + } + + /// + /// This method recalculates size of the columns and paint them or do the hit test. + /// This method is used from Paint or Select method. + /// + /// Mode which draws only labels and markers. + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + private void ProcessChartType( + bool labels, + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + // Prosess 3D chart type + if(area.Area3DStyle.Enable3D) + { + ProcessChartType3D( labels, selection, graph, common, area, seriesToDraw ); + return; + } + + // Get pixel size + SizeF pixelRelSize = graph.GetRelativeSize(new SizeF(1.1f, 1.1f)); + + // All data series from chart area which have Column chart type + List typeSeries = area.GetSeriesFromChartType(Name); + + // Check if series should be drawn side by side + bool currentDrawSeriesSideBySide = this.drawSeriesSideBySide; + foreach(string seriesName in typeSeries) + { + if(common.DataManager.Series[seriesName].IsCustomPropertySet(CustomPropertyName.DrawSideBySide)) + { + string attribValue = common.DataManager.Series[seriesName][CustomPropertyName.DrawSideBySide]; + if(String.Compare( attribValue, "False", StringComparison.OrdinalIgnoreCase) == 0 ) + { + currentDrawSeriesSideBySide = false; + } + else if(String.Compare( attribValue, "True", StringComparison.OrdinalIgnoreCase) == 0) + { + currentDrawSeriesSideBySide = true; + } + else if(String.Compare( attribValue, "Auto", StringComparison.OrdinalIgnoreCase) == 0) + { + // Do nothing + } + else + { + throw (new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid)); + } + } + } + + // Find the number of "Column chart" data series + double numOfSeries = typeSeries.Count; + if(!currentDrawSeriesSideBySide) + { + numOfSeries = 1; + } + + // Check if column chart series are indexed + bool indexedSeries = ChartHelper.IndexedSeries(this.Common, area.GetSeriesFromChartType(Name).ToArray()); + + //************************************************************ + //** Loop through all series + //************************************************************ + int seriesIndx = 0; + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with Column chart type + if( String.Compare( ser.ChartTypeName, Name, true, System.Globalization.CultureInfo.CurrentCulture) != 0 + || ser.ChartArea != area.Name || ser.Points.Count == 0 || !ser.IsVisible()) + { + continue; + } + + // Set shifted series name property + ShiftedSerName = ser.Name; + + // Set active vertical/horizontal axis + Axis vAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + Axis hAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + double horizontalViewMax = hAxis.ViewMaximum; + double horizontalViewMin = hAxis.ViewMinimum; + double verticalViewMax = vAxis.ViewMaximum; + double verticalViewMin = vAxis.ViewMinimum; + double verticalAxisCrossing = vAxis.GetPosition(vAxis.Crossing); + + // Get points interval: + // - set interval to 1 for indexed series + // - if points are not equaly spaced, the minimum interval between points is selected. + // - if points have same interval bars do not overlap each other. + bool sameInterval = false; + double interval = 1; + if(!indexedSeries) + { + if (ser.Points.Count == 1 && + (ser.XValueType == ChartValueType.Date || + ser.XValueType == ChartValueType.DateTime || + ser.XValueType == ChartValueType.Time || + ser.XValueType == ChartValueType.DateTimeOffset)) + { + // Check if interval is the same + area.GetPointsInterval(typeSeries, hAxis.IsLogarithmic, hAxis.logarithmBase, true, out sameInterval); + + // Special case when there is only one data point and date scale is used. + if (!double.IsNaN(hAxis.majorGrid.GetInterval()) && hAxis.majorGrid.GetIntervalType() != DateTimeIntervalType.NotSet) + { + interval = ChartHelper.GetIntervalSize(hAxis.minimum, hAxis.majorGrid.GetInterval(), hAxis.majorGrid.GetIntervalType()); + } + else + { + interval = ChartHelper.GetIntervalSize(hAxis.minimum, hAxis.Interval, hAxis.IntervalType); + } + } + else + { + interval = area.GetPointsInterval( typeSeries, hAxis.IsLogarithmic, hAxis.logarithmBase, true, out sameInterval ); + } + } + + // Get column width + double width = ser.GetPointWidth(graph, hAxis, interval, 0.8) / numOfSeries; + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + //************************************************************ + //** Loop through all points in series + //************************************************************ + int index = 0; + foreach( DataPoint point in ser.Points ) + { + // Change Y value if Column is out of plot area + double yValue = vAxis.GetLogValue( GetYValue(common, area, ser, point, index, (useTwoValues) ? 1 : 0) ); + + if( yValue > verticalViewMax ) + { + yValue = verticalViewMax; + } + if( yValue < verticalViewMin ) + { + yValue = verticalViewMin; + } + + // Recalculates Height position and zero position of Columns + double height = vAxis.GetLinearPosition( yValue ); + + // Set start position for a column + double columnStartPosition = 0; + if(useTwoValues) + { + // Point Y value (first) is used to determine the column starting position + double yValueStart = vAxis.GetLogValue( GetYValue(common, area, ser, point, index, 0 ) ); + if( yValueStart > verticalViewMax ) + { + yValueStart = verticalViewMax; + } + else if( yValueStart < verticalViewMin ) + { + yValueStart = verticalViewMin; + } + + columnStartPosition = vAxis.GetLinearPosition(yValueStart); + } + else + { + // Column starts on the horizontal axis crossing + columnStartPosition = verticalAxisCrossing; + } + + // Increase point index + index++; + + // Set x position + double xCenterVal; + double xPosition; + if( indexedSeries ) + { + // The formula for position is based on a distance + //from the grid line or nPoints position. + xPosition = hAxis.GetPosition( (double)index ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width; + xCenterVal = hAxis.GetPosition( (double)index ); + } + else if( sameInterval ) + { + xPosition = hAxis.GetPosition( point.XValue ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width; + xCenterVal = hAxis.GetPosition( point.XValue ); + } + else + { + xPosition = hAxis.GetPosition( point.XValue ); + xCenterVal = hAxis.GetPosition( point.XValue ); + } + + // Labels and markers have to be shifted if there + // is more than one series for column chart. + ShiftedX = xPosition - xCenterVal; + + + // Make sure that points with small values are still visible + if( height < columnStartPosition && + (columnStartPosition - height) < pixelRelSize.Height) + { + height = columnStartPosition - pixelRelSize.Height; + } + if( height > columnStartPosition && + (height - columnStartPosition) < pixelRelSize.Height) + { + height = columnStartPosition + pixelRelSize.Height; + } + + // Get column rectangle + RectangleF rectSize = RectangleF.Empty; + try + { + // Set the Column rectangle + rectSize.X = (float)(xPosition - width/2); + rectSize.Width = (float)(width); + + + // The top side of rectangle has always + // smaller value than a bottom value + if( columnStartPosition < height ) + { + rectSize.Y = (float)columnStartPosition; + rectSize.Height = (float)height - rectSize.Y; + } + else + { + rectSize.Y = (float)height; + rectSize.Height = (float)columnStartPosition - rectSize.Y; + } + + } + catch(OverflowException) + { + continue; + } + + // if data point is not empty + if( point.IsEmpty ) + { + continue; + } + + //************************************************************ + // Painting mode + //************************************************************ + if( common.ProcessModePaint ) + { + if( !labels ) + { + // Check if column is completly out of the data scaleView + double xValue = (indexedSeries) ? index : point.XValue; + xValue = hAxis.GetLogValue(xValue); + if(xValue < horizontalViewMin || xValue > horizontalViewMax ) + { + continue; + } + + // Check if column is partialy in the data scaleView + bool clipRegionSet = false; + if(rectSize.X < area.PlotAreaPosition.X || rectSize.Right > area.PlotAreaPosition.Right) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw the Column rectangle + DrawColumn2D(graph, vAxis, rectSize, point, ser); + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + } + else if(this.useTwoValues) + { + // Draw labels and markers + DrawLabel( + area, + graph, + common, + rectSize, + point, + ser, + index); + } + } + + //************************************************************ + // Hot Regions mode used for image maps, tool tips and + // hit test function + //************************************************************ + if( common.ProcessModeRegions && !labels) + { + common.HotRegionsList.AddHotRegion( rectSize, point, ser.Name, index - 1 ); + } + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + // Data series index + if(currentDrawSeriesSideBySide) + { + seriesIndx++; + } + + // Draw labels and markers using the base class algorithm + if( labels && !this.useTwoValues) + { + base.ProcessChartType( false, graph, common, area, seriesToDraw ); + } + } + } + + /// + /// Draws 2D column. + /// + /// Chart graphics. + /// Vertical axis. + /// Column position and size. + /// Column data point. + /// Column series. + protected virtual void DrawColumn2D( + ChartGraphics graph, + Axis vAxis, + RectangleF rectSize, + DataPoint point, + Series ser) + { + graph.FillRectangleRel( + rectSize, + point.Color, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + point.BackSecondaryColor, + point.BorderColor, + point.BorderWidth, + point.BorderDashStyle, + ser.ShadowColor, + ser.ShadowOffset, + PenAlignment.Inset, + ChartGraphics.GetBarDrawingStyle(point), + true); + } + + /// + /// Gets label position for the column depending on the Y value. + /// + /// Return automaticly detected label position. + /// Data series. + /// Point index. + /// Label aligning. + override protected LabelAlignmentStyles GetAutoLabelPosition(Series series, int pointIndex) + { + if( series.Points[pointIndex].YValues[0] >= 0 ) + return LabelAlignmentStyles.Top; + else + return LabelAlignmentStyles.Bottom; + } + + /// + /// Indicates that markers are drawnd on the X edge of the data scaleView. + /// + /// False. Column chart never draws markers on the edge. + override protected bool ShouldDrawMarkerOnViewEdgeX() + { + return false; + } + + #endregion + + #region 3D painting and selection methods + + /// + /// This method recalculates size of the columns and paint them or do the hit test in 3d space. + /// This method is used from Paint or Select method. + /// + /// Mode which draws only labels and markers. + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + private void ProcessChartType3D( bool labels, bool selection, ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + // Labels & markers are drawn with the data points in the first iteration + if(labels && !selection) + { + return; + } + + // Get pixel size + SizeF pixelRelSize = graph.GetRelativeSize(new SizeF(1.1f, 1.1f)); + + // Get list of series to draw + List typeSeries = null; + bool currentDrawSeriesSideBySide = this.drawSeriesSideBySide; + if( (area.Area3DStyle.IsClustered && this.SideBySideSeries) || + this.Stacked) + { + // Draw all series of the same chart type + typeSeries = area.GetSeriesFromChartType(Name); + + // Check if series should be drawn side by side + foreach(string seriesName in typeSeries) + { + if(common.DataManager.Series[seriesName].IsCustomPropertySet(CustomPropertyName.DrawSideBySide)) + { + string attribValue = common.DataManager.Series[seriesName][CustomPropertyName.DrawSideBySide]; + if(String.Compare( attribValue, "False", StringComparison.OrdinalIgnoreCase)==0) + { + currentDrawSeriesSideBySide = false; + } + else if(String.Compare( attribValue, "True", StringComparison.OrdinalIgnoreCase)==0) + { + currentDrawSeriesSideBySide = true; + } + else if(String.Compare( attribValue, "Auto", StringComparison.OrdinalIgnoreCase)==0) + { + // Do nothing + } + else + { + throw (new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid)); + } + } + } + } + else + { + // Draw just one chart series + typeSeries = new List(); + typeSeries.Add(seriesToDraw.Name); + } + + //************************************************************ + //** Get order of data points drawing + //************************************************************ + ArrayList dataPointDrawingOrder = area.GetDataPointDrawingOrder(typeSeries, this, selection, coordinates, null, this.YValueIndex, currentDrawSeriesSideBySide); + + //************************************************************ + //** Loop through all data poins + //************************************************************ + foreach(object obj in dataPointDrawingOrder) + { + // Get point & series + DataPoint3D pointEx = (DataPoint3D) obj; + DataPoint point = pointEx.dataPoint; + Series ser = point.series; + + // Get point bar drawing style + BarDrawingStyle barDrawingStyle = ChartGraphics.GetBarDrawingStyle(point); + + // Set active vertical/horizontal axis + Axis vAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + Axis hAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + + // Change Y value if Column is out of plot area + float topDarkening = 0f; + float bottomDarkening = 0f; + double yValue = GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, (useTwoValues) ? 1 : 0); + yValue = vAxis.GetLogValue(yValue); + if( yValue > vAxis.ViewMaximum ) + { + topDarkening = 0.5f; + yValue = vAxis.ViewMaximum; + } + if( yValue < vAxis.ViewMinimum ) + { + topDarkening = 0.5f; + yValue = vAxis.ViewMinimum; + } + + // Recalculates Height position and zero position of Columns + double height = vAxis.GetLinearPosition( yValue ); + + // Set start position for a column + double columnStartPosition = 0; + if(useTwoValues) + { + // Point Y value (first) is used to determine the column starting position + double yValueStart = vAxis.GetLogValue( GetYValue(common, area, ser, point, pointEx.index - 1, 0 ) ); + if( yValueStart > vAxis.ViewMaximum ) + { + bottomDarkening = 0.5f; + yValueStart = vAxis.ViewMaximum; + } + else if( yValueStart < vAxis.ViewMinimum ) + { + bottomDarkening = 0.5f; + yValueStart = vAxis.ViewMinimum; + } + + columnStartPosition = vAxis.GetLinearPosition(yValueStart); + } + else + { + // Column starts on the horizontal axis crossing + columnStartPosition = vAxis.GetPosition(vAxis.Crossing); + } + + // Labels and markers have to be shifted if there + // is more than one series for column chart. + if(!currentDrawSeriesSideBySide) + { + pointEx.xPosition = pointEx.xCenterVal; + } + ShiftedX = pointEx.xPosition - pointEx.xCenterVal; + + // Make sure that points with small values are still visible + if( height < columnStartPosition && + (columnStartPosition - height) < pixelRelSize.Height) + { + height = columnStartPosition - pixelRelSize.Height; + } + if( height > columnStartPosition && + (height - columnStartPosition) < pixelRelSize.Height) + { + height = columnStartPosition + pixelRelSize.Height; + } + + // Get column rectangle + RectangleF rectSize = RectangleF.Empty; + try + { + // Set the Column rectangle + rectSize.X = (float)(pointEx.xPosition - pointEx.width/2); + rectSize.Width = (float)(pointEx.width); + + // The top side of rectangle has always + // smaller value than a bottom value + if( columnStartPosition < height ) + { + float temp = bottomDarkening; + bottomDarkening = topDarkening; + topDarkening = temp; + + rectSize.Y = (float)columnStartPosition; + rectSize.Height = (float)height - rectSize.Y; + } + else + { + rectSize.Y = (float)height; + rectSize.Height = (float)columnStartPosition - rectSize.Y; + } + } + catch(OverflowException) + { + continue; + } + + //************************************************************ + //** Painting mode + //************************************************************ + // Path projection of 3D rect. + GraphicsPath rectPath = null; + + // Check if column is completly out of the data scaleView + double xValue = (pointEx.indexedSeries) ? pointEx.index : point.XValue; + xValue = hAxis.GetLogValue(xValue); + if(xValue < hAxis.ViewMinimum || xValue > hAxis.ViewMaximum ) + { + continue; + } + + // Check if column is partialy in the data scaleView + bool clipRegionSet = false; + if(rectSize.Right <= area.PlotAreaPosition.X || rectSize.X >= area.PlotAreaPosition.Right) + { + continue; + } + + if(rectSize.X < area.PlotAreaPosition.X) + { + rectSize.Width -= area.PlotAreaPosition.X - rectSize.X; + rectSize.X = area.PlotAreaPosition.X; + } + if(rectSize.Right > area.PlotAreaPosition.Right) + { + rectSize.Width -= rectSize.Right - area.PlotAreaPosition.Right; + } + if(rectSize.Width < 0) + { + rectSize.Width = 0; + } + + // Detect if we need to get graphical path of drawn object + DrawingOperationTypes drawingOperationType = DrawingOperationTypes.DrawElement; + + if( common.ProcessModeRegions ) + { + drawingOperationType |= DrawingOperationTypes.CalcElementPath; + } + + if(!point.IsEmpty && + rectSize.Height > 0f && + rectSize.Width > 0f) + { + // Start Svg Selection mode + graph.StartHotRegion( point ); + + rectPath = graph.Fill3DRectangle( + rectSize, + pointEx.zPosition, + pointEx.depth, + area.matrix3D, + area.Area3DStyle.LightStyle, + point.Color, + topDarkening, + bottomDarkening, + point.BorderColor, + point.BorderWidth, + point.BorderDashStyle, + barDrawingStyle, + true, + drawingOperationType); + + // End Svg Selection mode + graph.EndHotRegion( ); + + //************************************************************ + // Hot Regions mode used for image maps, tool tips and + // hit test function + //************************************************************ + if( common.ProcessModeRegions && !labels) + { + common.HotRegionsList.AddHotRegion( + rectPath, + false, + graph, + point, + ser.Name, + pointEx.index - 1 + ); + } + if (rectPath != null) + { + rectPath.Dispose(); + } + } + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + + // Draw Labels & markers for each data point + this.ProcessSinglePoint3D( + pointEx, + selection, + graph, + common, + area, + rectSize, + pointEx.index - 1 + ); + } + + // Finish processing 3D labels + this.DrawAccumulated3DLabels(graph, common, area); + } + + #endregion + + #region 2D and 3D Labels Drawing + + /// + /// This method draws label. + /// + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Column position + /// Data point + /// Data series + /// Data point index. + protected virtual void DrawLabel( + ChartArea area, + ChartGraphics graph, + CommonElements common, + RectangleF columnPosition, + DataPoint point, + Series ser, + int pointIndex) + { + // Labels drawing functionality is inhereted from the PointChart class. + } + + /// + /// Draws\Hit tests single 3D point. + /// + /// 3D point information. + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Column position + /// Point index. + protected virtual void ProcessSinglePoint3D( + DataPoint3D pointEx, + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + RectangleF columnPosition, + int pointIndex + ) + { + // Draw Labels & markers for each data point + base.ProcessSinglePoint3D( + pointEx, + graph, + common, + area + ); + } + + #endregion + } + + /// + /// ColumnChart class contains all the code necessary to draw + /// both Column and RangeColumn charts. The RangeColumnChart class + /// is used to override few default settings, so that 2 Y values + /// will be used to define top and bottom position of each column. + /// + internal class RangeColumnChart : ColumnChart + { + #region Constructor + + /// + /// Public constructor + /// + public RangeColumnChart() + { + // Set the flag to use two Y values, while drawing the columns + this.useTwoValues = true; + + // Coordinates of COP used when sorting 3D points order + this.coordinates = COPCoordinates.X | COPCoordinates.Y; + + // Index of the main Y value + this.YValueIndex = 1; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.RangeColumn;}} + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + override public bool ZeroCrossing { get{ return true;} } + + /// + /// Number of supported Y value(s) per point + /// + override public int YValuesPerPoint{ get { return 2; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + override public bool ExtraYValuesConnectedToYAxis{ get { return true; } } + + #endregion + + #region Y values related methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + override public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + // Calculate column height + if(yValueIndex == -1) + { + return -(base.GetYValue(common, area, series, point, pointIndex, 1) - + base.GetYValue(common, area, series, point, pointIndex, 0)); + } + + return base.GetYValue(common, area, series, point, pointIndex, yValueIndex); + } + + #endregion + + #region 2D and 3D Labels Drawing + + /// + /// This method draws label. + /// + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Column position + /// Data point + /// Data series + /// Data point index. + protected override void DrawLabel( + ChartArea area, + ChartGraphics graph, + CommonElements common, + RectangleF columnPosition, + DataPoint point, + Series series, + int pointIndex) + { + //************************************************************ + //** Get marker position and size + //************************************************************ + + // Get intersection between column rectangle and plotting area rectangle + RectangleF intersection = RectangleF.Intersect( + columnPosition, area.PlotAreaPosition.ToRectangleF() ); + + // If intersection is empty no drawing required + if(intersection.Height <= 0f || intersection.Width <= 0f) + { + return; + } + + // Get marker position + PointF markerPosition = PointF.Empty; + markerPosition.X = intersection.X + intersection.Width / 2f; + markerPosition.Y = intersection.Y; + + // Remeber pre-calculated point position + point.positionRel = new PointF(markerPosition.X, markerPosition.Y); + + // Get point some point properties and save them in variables + int pointMarkerSize = point.MarkerSize; + string pointMarkerImage = point.MarkerImage; + MarkerStyle pointMarkerStyle = point.MarkerStyle; + + // Get marker size + SizeF markerSize = base.GetMarkerSize( + graph, + common, + area, + point, + pointMarkerSize, + pointMarkerImage); + + //************************************************************ + //** Draw point chart + //************************************************************ + if(pointMarkerStyle != MarkerStyle.None || + pointMarkerImage.Length > 0) + { + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw the marker + graph.DrawMarkerRel(markerPosition, + (pointMarkerStyle == MarkerStyle.None) ? MarkerStyle.Circle : pointMarkerStyle, + (int)markerSize.Height, + (point.MarkerColor == Color.Empty) ? point.Color : point.MarkerColor, + (point.MarkerBorderColor == Color.Empty) ? point.BorderColor : point.MarkerBorderColor, + GetMarkerBorderSize(point), + pointMarkerImage, + point.MarkerImageTransparentColor, + (point.series != null) ? point.series.ShadowOffset : 0, + (point.series != null) ? point.series.ShadowColor : Color.Empty, + new RectangleF(markerPosition.X, markerPosition.Y, markerSize.Width, markerSize.Height)); + + // End Svg Selection mode + graph.EndHotRegion( ); + + //************************************************************ + // Hot Regions mode used for image maps, tool tips and + // hit test function + //************************************************************ + if( common.ProcessModeRegions ) + { + // Get relative marker size + SizeF relativeMarkerSize = graph.GetRelativeSize(markerSize); + + // Insert area just after the last custom area + int insertIndex = common.HotRegionsList.FindInsertIndex(); + + // Insert circle area + if(pointMarkerStyle == MarkerStyle.Circle) + { + float[] circCoord = new float[3]; + circCoord[0] = markerPosition.X; + circCoord[1] = markerPosition.Y; + circCoord[2] = relativeMarkerSize.Width/2f; + + common.HotRegionsList.AddHotRegion( + insertIndex, + graph, + circCoord[0], + circCoord[1], + circCoord[2], + point, + series.Name, + pointIndex - 1 ); + } + // All other markers represented as rectangles + else + { + common.HotRegionsList.AddHotRegion( + new RectangleF(markerPosition.X - relativeMarkerSize.Width/2f, markerPosition.Y - relativeMarkerSize.Height/2f, relativeMarkerSize.Width, relativeMarkerSize.Height), + point, + series.Name, + pointIndex - 1 ); + } + } + } + + + //************************************************************ + //** Draw LabelStyle + //************************************************************ + + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // Disable the clip region + Region oldClipRegion = graph.Clip; + graph.Clip = new Region(); + + if (point.IsValueShownAsLabel || point.Label.Length > 0) + { + // Get label text + string text; + if (point.Label.Length == 0) + { + // Round Y values for 100% stacked area + double pointLabelValue = GetYValue(common, area, series, point, pointIndex, 0); + + text = ValueConverter.FormatValue( + series.Chart, + point, + point.Tag, + pointLabelValue, + point.LabelFormat, + series.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + } + + // Calculate label position + PointF labelPosition = PointF.Empty; + labelPosition.X = intersection.X + intersection.Width / 2f; + labelPosition.Y = intersection.Y + intersection.Height / 2f; + + // Start Svg Selection mode + graph.StartHotRegion(point, true); + + // Get string size + SizeF sizeFont = graph.GetRelativeSize(graph.MeasureString(text, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic)); + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Width += sizeLabel.Width / text.Length; + sizeLabel.Height += sizeFont.Height / 8; + labelBackPosition = GetLabelPosition( + graph, + labelPosition, + sizeLabel, + format, + true); + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + labelPosition, + format, + point.LabelAngle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + series, + point, + pointIndex - 1); + } + + // End Svg Selection mode + graph.EndHotRegion(); + } + + // Restore old clip region + graph.Clip = oldClipRegion; + } + } + + /// + /// Draws\Hit tests single 3D point. + /// + /// 3D point information. + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Column position + /// Point index. + protected override void ProcessSinglePoint3D( + DataPoint3D pointEx, + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + RectangleF columnPosition, + int pointIndex + ) + { + DataPoint point = pointEx.dataPoint; + + // Check required Y values number + if(point.YValues.Length < this.YValuesPerPoint) + { + throw(new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name,this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)))); + } + + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // Disable the clip region + Region oldClipRegion = graph.Clip; + graph.Clip = new Region(); + + if (point.IsValueShownAsLabel || point.Label.Length > 0) + { + // Get label text + string text; + if (point.Label.Length == 0) + { + // Get Y value + double pointLabelValue = GetYValue(common, area, pointEx.dataPoint.series, point, pointEx.index - 1, 0); + text = ValueConverter.FormatValue( + pointEx.dataPoint.series.Chart, + point, + point.Tag, + pointLabelValue, + point.LabelFormat, + pointEx.dataPoint.series.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + + } + + // Calculate label position + PointF labelPosition = PointF.Empty; + labelPosition.X = columnPosition.X + columnPosition.Width / 2f; + labelPosition.Y = columnPosition.Y + columnPosition.Height / 2f; + + // Transform coordinates + Point3D[] marker3DPosition = new Point3D[1]; + marker3DPosition[0] = new Point3D(labelPosition.X, labelPosition.Y, (float)(pointEx.zPosition + pointEx.depth)); + area.matrix3D.TransformPoints(marker3DPosition); + + labelPosition.X = marker3DPosition[0].X; + labelPosition.Y = marker3DPosition[0].Y; + + // Start Svg Selection mode + graph.StartHotRegion(point, true); + + // Get string size + SizeF sizeFont = graph.GetRelativeSize(graph.MeasureString(text, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic)); + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Width += sizeLabel.Width / text.Length; + sizeLabel.Height += sizeFont.Height / 8; + labelBackPosition = GetLabelPosition( + graph, + labelPosition, + sizeLabel, + format, + true); + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + labelPosition, + format, + point.LabelAngle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + point.series, + point, + pointIndex); + } + + // End Svg Selection mode + graph.EndHotRegion(); + } + + // Restore old clip region + graph.Clip = oldClipRegion; + } + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/DoughnutChart.cs b/System.Web.DataVisualization/Common/ChartTypes/DoughnutChart.cs new file mode 100644 index 000000000..4e21ee536 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/DoughnutChart.cs @@ -0,0 +1,143 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: DoughnutChart.cs +// +// Namespace: System.Web.UI.DataVisualization.Charting.ChartTypes +// +// Classes: DoughnutChart +// +// Purpose: DoughnutChart class provide only the behaviour +// information for the Doughnut chart, all the drawing +// routines are located in the PieChart base class. +// +// Reviewed: GS - Aug 8, 2002 +// AG - Aug 8, 2002 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Drawing; + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// DoughnutChart class provide only the behaviour information for the + /// Doughnut chart, all the drawing routines are located in the PieChart + /// base class. + /// + internal class DoughnutChart : PieChart + { + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.Doughnut;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + /// + /// True if chart type is stacked + /// + override public bool Stacked { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + override public bool RequireAxes { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + override public bool SupportLogarithmicAxes { get{ return false;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + override public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + override public bool SideBySideSeries { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + override public bool ZeroCrossing { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + override public bool DataPointsInLegend { get{ return true;} } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + override public bool ExtraYValuesConnectedToYAxis{ get { return false; } } + + /// + /// True if palette colors should be applied for each data paint. + /// Otherwise the color is applied to the series. + /// + override public bool ApplyPaletteColorsToPoints { get { return true; } } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + override public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Number of supported Y value(s) per point + /// + override public int YValuesPerPoint{ get { return 1; } } + + /// + /// Chart is Doughnut or Pie type + /// + override public bool Doughnut{ get { return true; } } + + #endregion + + #region Methods + + /// + /// Default constructor + /// + public DoughnutChart() + { + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/ErrorBarChart.cs b/System.Web.DataVisualization/Common/ChartTypes/ErrorBarChart.cs new file mode 100644 index 000000000..77f6d6ebc --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/ErrorBarChart.cs @@ -0,0 +1,1887 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ErrorBarChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: ErrorBarChart +// +// Purpose: Provides 2D and 3D drawing and hit testing of the +// ErrorBar chart. +// +// Error Bar Chart Overview: +// ------------------------- +// Error bar charts consist of lines with markers that are used to +// display statistical information about the data displayed in a +// graph. An Error Bar chart type is a series that has 3 Y values. +// While it is true that these values can be assigned to each point +// in an Error Bar chart, in most cases, the values will be +// calculated from the data present in another series. +// +// The order of the Y values is important because each position in +// the array of values represents a value on the Error Bar: +// 0 - Center or Average point value +// 1 - Lower Error value +// 2 - Upper Error value +// +// Reviewed: GS - Jul 15, 2003 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel.Design; +using System.Globalization; +using System.Collections.Generic; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Utilities; +#else + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + #region Enumerations + + /// + /// Defines the way error amount is calculated. + /// + internal enum ErrorBarType + { + /// + /// Error is a fixed value. + /// + FixedValue, + + /// + /// Error is percentage of the center value. + /// + Percentage, + + /// + /// Error is standard deviation of all center values in series. + /// + StandardDeviation, + + /// + /// Error is standard error of all center values in series. + /// + StandardError + } + + /// + /// Error bars drawing styles. + /// + internal enum ErrorBarStyle + { + /// + /// Draws both lower and upper error bar. + /// + Both, + + /// + /// Draws only upper error bar. + /// + UpperError, + + /// + /// Draws only lower error bar. + /// + LowerError + } + + #endregion + + /// + /// ErrorBarChart class provides 2D and 3D drawing and hit testing of + /// the ErrorBar chart. + /// + internal class ErrorBarChart : IChartType + { + #region Fields + + /// + /// Vertical axis + /// + protected Axis vAxis = null; + + /// + /// Horizontal axis + /// + protected Axis hAxis = null; + + #endregion + + #region Constructor + + /// + /// Error bar chart constructor. + /// + public ErrorBarChart() + { + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.ErrorBar;}} + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axes + /// + virtual public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + public bool SideBySideSeries { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value ZeroCrossing should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return true; } } + + /// + /// Indicates that this is a one hundred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that this is a one hundred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Line; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint { get { return 3; } } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Painting and Selection methods + + /// + /// Paint error bar chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + ProcessChartType( false, graph, common, area, seriesToDraw ); + } + + /// + /// This method recalculates size of the bars. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual protected void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + // Prosess 3D chart type + if(area.Area3DStyle.Enable3D) + { + ProcessChartType3D( selection, graph, common, area, seriesToDraw ); + return; + } + + // All data series from chart area which have Error bar chart type + List typeSeries = area.GetSeriesFromChartType(this.Name); + + // Zero X values mode. + bool indexedSeries = ChartHelper.IndexedSeries(common, typeSeries.ToArray()); + + //************************************************************ + //** Loop through all series + //************************************************************ + int seriesIndex = 0; + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with error bar chart type + if( String.Compare( ser.ChartTypeName, this.Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Set active horizontal/vertical axis + hAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + vAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Get interval between points + double interval = (indexedSeries) ? 1 : area.GetPointsInterval( hAxis.IsLogarithmic, hAxis.logarithmBase ); + + // Calculates points width + float width = (float)(ser.GetPointWidth(graph, hAxis, interval, 0.4)); + + + // Align error bar X position with linked series + float sideBySideWidth = width; + int numberOfLinkedSeries = 1; + int indexOfLinkedSeries = 0; + bool showSideBySide = false; + string linkedSeriesName = string.Empty; + bool currentDrawSeriesSideBySide = false; + if(ser.IsCustomPropertySet(CustomPropertyName.ErrorBarSeries)) + { + // Get series name + linkedSeriesName = ser[CustomPropertyName.ErrorBarSeries]; + int valueTypeIndex = linkedSeriesName.IndexOf(":", StringComparison.Ordinal); + if(valueTypeIndex >= 0) + { + linkedSeriesName = linkedSeriesName.Substring(0, valueTypeIndex); + } + + // All linked data series from chart area which have Error bar chart type + string linkedSeriesChartType = common.DataManager.Series[linkedSeriesName].ChartTypeName; + ChartArea linkedSeriesArea = common.ChartPicture.ChartAreas[common.DataManager.Series[linkedSeriesName].ChartArea]; + List typeLinkedSeries = linkedSeriesArea.GetSeriesFromChartType(linkedSeriesChartType); + + // Get index of linked serries + foreach(string name in typeLinkedSeries) + { + if(name == linkedSeriesName) + { + break; + } + ++indexOfLinkedSeries; + } + + + currentDrawSeriesSideBySide = false; + if(String.Compare(linkedSeriesChartType, ChartTypeNames.Column, StringComparison.OrdinalIgnoreCase) ==0 + || String.Compare(linkedSeriesChartType, ChartTypeNames.RangeColumn, StringComparison.OrdinalIgnoreCase) == 0 + ) + { + currentDrawSeriesSideBySide = true; + } + foreach(string seriesName in typeLinkedSeries) + { + if(common.DataManager.Series[seriesName].IsCustomPropertySet(CustomPropertyName.DrawSideBySide)) + { + string attribValue = common.DataManager.Series[seriesName][CustomPropertyName.DrawSideBySide]; + if(String.Compare(attribValue, "False", StringComparison.OrdinalIgnoreCase) == 0) + { + currentDrawSeriesSideBySide = false; + } + else if(String.Compare(attribValue, "True", StringComparison.OrdinalIgnoreCase) == 0) + { + currentDrawSeriesSideBySide = true; + } + else if(String.Compare(attribValue, "Auto", StringComparison.OrdinalIgnoreCase) == 0) + { + // Do nothing + } + else + { + throw (new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid)); + } + } + } + + if(currentDrawSeriesSideBySide) + { + // Find the number of linked data series + numberOfLinkedSeries = typeLinkedSeries.Count; + width /= numberOfLinkedSeries; + showSideBySide = true; + + // Check if side by side + if(!indexedSeries) + { + area.GetPointsInterval( typeLinkedSeries, hAxis.IsLogarithmic, hAxis.logarithmBase, true, out showSideBySide ); + } + + sideBySideWidth = (float)(common.DataManager.Series[linkedSeriesName].GetPointWidth(graph, hAxis, interval, 0.8)) / numberOfLinkedSeries; + } + } + + // Check if side-by-side attribute is set + if(!currentDrawSeriesSideBySide && ser.IsCustomPropertySet(CustomPropertyName.DrawSideBySide)) + { + string attribValue = ser[CustomPropertyName.DrawSideBySide]; + if(String.Compare(attribValue, "False", StringComparison.OrdinalIgnoreCase) ==0) + { + showSideBySide = false; + } + else if(String.Compare(attribValue, "True", StringComparison.OrdinalIgnoreCase) ==0) + { + showSideBySide = true; + numberOfLinkedSeries = typeSeries.Count; + indexOfLinkedSeries = seriesIndex; + width /= numberOfLinkedSeries; + + // NOTE: Lines of code below were added to fix issue #4048 + sideBySideWidth = (float)(ser.GetPointWidth(graph, hAxis, interval, 0.8)) / numberOfLinkedSeries; + } + else if(String.Compare(attribValue, "Auto", StringComparison.OrdinalIgnoreCase) ==0) + { + } + else + { + throw (new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid)); + } + } + + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + + //************************************************************ + //** Series data points loop + //************************************************************ + int index = 1; + foreach( DataPoint point in ser.Points ) + { + // Check required Y values number + if(point.YValues.Length < this.YValuesPerPoint) + { + throw(new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)))); + } + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Get point X position + float xPosition = 0f; + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + // xPosition = (float)(hAxis.GetPosition( (double)index ) - sideBySideWidth * ((double) numberOfLinkedSeries) / 2.0 + sideBySideWidth/2 + indexOfLinkedSeries * sideBySideWidth); + } + + if( showSideBySide ) + { + xPosition = (float)(hAxis.GetPosition( xValue ) - sideBySideWidth * ((double) numberOfLinkedSeries) / 2.0 + sideBySideWidth/2 + indexOfLinkedSeries * sideBySideWidth); + } + else + { + xPosition = (float)hAxis.GetPosition( xValue ); + } + + double yValue0 = vAxis.GetLogValue( point.YValues[1] ); + double yValue1 = vAxis.GetLogValue( point.YValues[2] ); + xValue = hAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < hAxis.ViewMinimum || + xValue > hAxis.ViewMaximum || + (yValue0 < vAxis.ViewMinimum && yValue1 < vAxis.ViewMinimum) || + (yValue0 > vAxis.ViewMaximum && yValue1 > vAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Make sure High/Low values are in data scaleView range + double low = vAxis.GetLogValue( point.YValues[1] ); + double high = vAxis.GetLogValue( point.YValues[2] ); + + // Check if lower and/or upper error bar are drawn + ErrorBarStyle barStyle = ErrorBarStyle.Both; + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle) || ser.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle)) + { + string errorBarStyle = ser[CustomPropertyName.ErrorBarStyle]; + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle)) + { + errorBarStyle = point[CustomPropertyName.ErrorBarStyle]; + } + + if(String.Compare( errorBarStyle, "Both", StringComparison.OrdinalIgnoreCase ) == 0) + { + // default - do nothing + } + else if(String.Compare(errorBarStyle, "UpperError", StringComparison.OrdinalIgnoreCase ) == 0) + { + barStyle = ErrorBarStyle.UpperError; + low = vAxis.GetLogValue( point.YValues[0] ); + high = vAxis.GetLogValue( point.YValues[2] ); + } + else if(String.Compare(errorBarStyle, "LowerError", StringComparison.OrdinalIgnoreCase ) == 0) + { + barStyle = ErrorBarStyle.LowerError; + low = vAxis.GetLogValue( point.YValues[1] ); + high = vAxis.GetLogValue( point.YValues[0] ); + } + else + { + throw(new InvalidOperationException( SR.ExceptionCustomAttributeValueInvalid( point[CustomPropertyName.ErrorBarStyle], "ErrorBarStyle"))); + } + } + + // Check if values are in range + if( high > vAxis.ViewMaximum ) + { + high = vAxis.ViewMaximum; + } + if( high < vAxis.ViewMinimum ) + { + high = vAxis.ViewMinimum; + } + high = (float)vAxis.GetLinearPosition(high); + + if( low > vAxis.ViewMaximum ) + { + low = vAxis.ViewMaximum; + } + if( low < vAxis.ViewMinimum ) + { + low = vAxis.ViewMinimum; + } + low = vAxis.GetLinearPosition(low); + + // Remeber pre-calculated point position + point.positionRel = new PointF((float)xPosition, (float)Math.Min(high, low)); + + if( common.ProcessModePaint ) + { + + // Check if chart is partialy in the data scaleView + bool clipRegionSet = false; + if(xValue == hAxis.ViewMinimum || xValue == hAxis.ViewMaximum ) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw error bar line + graph.DrawLineRel( + point.Color, + point.BorderWidth, + point.BorderDashStyle, + new PointF(xPosition, (float)high), + new PointF(xPosition, (float)low), + ser.ShadowColor, + ser.ShadowOffset ); + + // Draw Error Bar marks + DrawErrorBarMarks(graph, barStyle, area, ser, point, xPosition, width); + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + } + + if( common.ProcessModeRegions ) + { + // Calculate rect around the error bar marks + RectangleF areaRect = RectangleF.Empty; + areaRect.X = xPosition - width / 2f; + areaRect.Y = (float)Math.Min(high, low); + areaRect.Width = width; + areaRect.Height = (float)Math.Max(high, low) - areaRect.Y; + + // Add area + common.HotRegionsList.AddHotRegion( areaRect, point, ser.Name, index - 1 ); + } + ++index; + } + + //************************************************************ + //** Second series data points loop, when labels are drawn. + //************************************************************ + if( !selection ) + { + index = 1; + foreach( DataPoint point in ser.Points ) + { + // Get point X position + float xPosition = 0f; + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + xPosition = (float)(hAxis.GetPosition( (double)index ) - sideBySideWidth * ((double) numberOfLinkedSeries) / 2.0 + sideBySideWidth/2 + indexOfLinkedSeries * sideBySideWidth); + } + else if( showSideBySide ) + { + xPosition = (float)(hAxis.GetPosition( xValue ) - sideBySideWidth * ((double) numberOfLinkedSeries) / 2.0 + sideBySideWidth/2 + indexOfLinkedSeries * sideBySideWidth); + } + else + { + xPosition = (float)hAxis.GetPosition( xValue ); + } + + double yValue0 = vAxis.GetLogValue( point.YValues[1] ); + double yValue1 = vAxis.GetLogValue( point.YValues[2] ); + xValue = hAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < hAxis.ViewMinimum || + xValue > hAxis.ViewMaximum || + (yValue0 < vAxis.ViewMinimum && yValue1 < vAxis.ViewMinimum) || + (yValue0 > vAxis.ViewMaximum && yValue1 > vAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Make sure High/Low values are in data scaleView range + double high = vAxis.GetLogValue( point.YValues[1] ); + double low = vAxis.GetLogValue( point.YValues[2] ); + + // Check if lower and/or upper error bar are drawn + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle) || ser.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle)) + { + string errorBarStyle = ser[CustomPropertyName.ErrorBarStyle]; + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle)) + { + errorBarStyle = point[CustomPropertyName.ErrorBarStyle]; + } + if(String.Compare(errorBarStyle, "Both", StringComparison.OrdinalIgnoreCase) == 0) + { + // default - do nothing + } + else if(String.Compare(errorBarStyle, "UpperError", StringComparison.OrdinalIgnoreCase) == 0) + { + low = vAxis.GetLogValue( point.YValues[0] ); + high = vAxis.GetLogValue( point.YValues[2] ); + } + else if(String.Compare(errorBarStyle, "LowerError", StringComparison.OrdinalIgnoreCase) == 0) + { + low = vAxis.GetLogValue( point.YValues[1] ); + high = vAxis.GetLogValue( point.YValues[0] ); + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(point[CustomPropertyName.ErrorBarStyle], "ErrorBarStyle"))); + } + } + + + if( high > vAxis.ViewMaximum ) + { + high = vAxis.ViewMaximum; + } + if( high < vAxis.ViewMinimum ) + { + high = vAxis.ViewMinimum; + } + high = (float)vAxis.GetLinearPosition(high); + + if( low > vAxis.ViewMaximum ) + { + low = vAxis.ViewMaximum; + } + if( low < vAxis.ViewMinimum ) + { + low = vAxis.ViewMinimum; + } + low = vAxis.GetLinearPosition(low); + + // Start Svg Selection mode + graph.StartHotRegion( point, true ); + + // Draw label + DrawLabel(common, area, graph, ser, point, new PointF(xPosition, (float)Math.Min(high, low)), index); + + // End Svg Selection mode + graph.EndHotRegion( ); + + ++index; + } + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + ++seriesIndex; + } + } + + /// + /// Draws error bar markers. + /// + /// Chart graphics object. + /// Style of the error bar. + /// Chart area. + /// Data point series. + /// Data point to draw. + /// X position. + /// Point width. + virtual protected void DrawErrorBarMarks( + ChartGraphics graph, + ErrorBarStyle barStyle, + ChartArea area, + Series ser, + DataPoint point, + float xPosition, + float width) + { + double yPosition = 0.0; + string markerStyle = String.Empty; + + // Draw lower error marker + if(barStyle == ErrorBarStyle.Both || barStyle == ErrorBarStyle.LowerError) + { + // Get Y position + yPosition = vAxis.GetLogValue( point.YValues[1] ); + + // Get marker style name + markerStyle = "LINE"; + if(point.MarkerStyle != MarkerStyle.None) + { + markerStyle = point.MarkerStyle.ToString(); + } + + // Draw marker + DrawErrorBarSingleMarker(graph, area, point, markerStyle, xPosition, (float)yPosition, 0f, width, false); + } + + // Draw upper error marker + if(barStyle == ErrorBarStyle.Both || barStyle == ErrorBarStyle.UpperError) + { + // Get Y position + yPosition = vAxis.GetLogValue( point.YValues[2] ); + + // Get marker style name + markerStyle = "LINE"; + if(point.MarkerStyle != MarkerStyle.None) + { + markerStyle = point.MarkerStyle.ToString(); + } + + // Draw marker + DrawErrorBarSingleMarker(graph, area, point, markerStyle, xPosition, (float)yPosition, 0f, width, false); + } + + // Draw center value marker + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarCenterMarkerStyle) || point.series.IsCustomPropertySet(CustomPropertyName.ErrorBarCenterMarkerStyle)) + { + // Get Y position + yPosition = vAxis.GetLogValue( point.YValues[0] ); + + // Get marker style name + markerStyle = point.series[CustomPropertyName.ErrorBarCenterMarkerStyle]; + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarCenterMarkerStyle)) + { + markerStyle = point[CustomPropertyName.ErrorBarCenterMarkerStyle]; + } + markerStyle = markerStyle.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + // Draw marker + DrawErrorBarSingleMarker(graph, area, point, markerStyle, xPosition, (float)yPosition, 0f, width, false); + } + } + + /// + /// Draws single marker on the error bar. + /// + /// Chart graphics. + /// Chart area. + /// Series point. + /// Marker style name. + /// X position. + /// Y position. + /// Z position. + /// Point width. + /// Used for 3d drawing. + private void DrawErrorBarSingleMarker( + ChartGraphics graph, + ChartArea area, + DataPoint point, + string markerStyle, + float xPosition, + float yPosition, + float zPosition, + float width, + bool draw3D) + { + markerStyle = markerStyle.ToUpper(CultureInfo.InvariantCulture); + if(markerStyle.Length > 0 && String.Compare(markerStyle, "None", StringComparison.OrdinalIgnoreCase) != 0) + { + // Make sure Y value is in range + if( yPosition > vAxis.ViewMaximum || yPosition < vAxis.ViewMinimum) + { + return; + } + yPosition = (float)vAxis.GetLinearPosition(yPosition); + + // 3D Transform coordinates + if(draw3D) + { + Point3D[] points = new Point3D[1]; + points[0] = new Point3D(xPosition, yPosition, zPosition); + area.matrix3D.TransformPoints(points); + xPosition = points[0].X; + yPosition = points[0].Y; + } + + // Draw horizontal line marker + if(String.Compare(markerStyle, "Line", StringComparison.OrdinalIgnoreCase) == 0) + { + graph.DrawLineRel( + point.Color, + point.BorderWidth, + point.BorderDashStyle, + new PointF(xPosition - width/2f, yPosition), + new PointF(xPosition + width/2f, yPosition), + (point.series != null) ? point.series.ShadowColor : Color.Empty, + (point.series != null) ? point.series.ShadowOffset : 0 ); + } + + // Draw standard marker + else + { + MarkerStyle marker = (MarkerStyle)Enum.Parse(typeof(MarkerStyle), markerStyle, true); + + // Get marker size + SizeF markerSize = GetMarkerSize( + graph, + area.Common, + area, + point, + point.MarkerSize, + point.MarkerImage); + + // Get marker color + Color markerColor = (point.MarkerColor == Color.Empty) ? point.Color : point.MarkerColor; + + // Draw the marker + graph.DrawMarkerRel( + new PointF(xPosition, yPosition), + marker, + point.MarkerSize, + markerColor, + point.MarkerBorderColor, + point.MarkerBorderWidth, + point.MarkerImage, + point.MarkerImageTransparentColor, + (point.series != null) ? point.series.ShadowOffset : 0, + (point.series != null) ? point.series.ShadowColor : Color.Empty, + new RectangleF(xPosition, yPosition, markerSize.Width, markerSize.Height)); + } + } + } + + /// + /// Returns marker size. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Data point. + /// Marker size. + /// Marker image. + /// Marker width and height. + virtual protected SizeF GetMarkerSize( + ChartGraphics graph, + CommonElements common, + ChartArea area, + DataPoint point, + int markerSize, + string markerImage) + { + SizeF size = new SizeF(markerSize, markerSize); + if (graph != null && graph.Graphics != null) + { + // Marker size is in pixels and we do the mapping for higher DPIs + size.Width = markerSize * graph.Graphics.DpiX / 96; + size.Height = markerSize * graph.Graphics.DpiY / 96; + } + + if(markerImage.Length > 0) + common.ImageLoader.GetAdjustedImageSize(markerImage, graph.Graphics, ref size); + + return size; + } + + + /// + /// Draws error bar chart data point label. + /// + /// The Common elements object + /// Chart area for this chart + /// Chart graphics object. + /// Data point series. + /// Data point to draw. + /// Label position. + /// Data point index. + virtual protected void DrawLabel( + CommonElements common, + ChartArea area, + ChartGraphics graph, + Series ser, + DataPoint point, + PointF position, + int pointIndex) + { + if(ser.IsValueShownAsLabel || point.IsValueShownAsLabel || point.Label.Length > 0) + { + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + if (point.LabelAngle == 0) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Far; + } + + // Get label text + string text; + if (point.Label.Length == 0) + { + text = ValueConverter.FormatValue( + ser.Chart, + point, + point.Tag, + point.YValues[0], + point.LabelFormat, + ser.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + } + + // Adjust label positio to the marker size + SizeF markerSizes = new SizeF(0f, 0f); + if (point.MarkerStyle != MarkerStyle.None) + { + markerSizes = graph.GetRelativeSize(new SizeF(point.MarkerSize, point.MarkerSize)); + position.Y -= markerSizes.Height / 2f; + } + + // Get text angle + int textAngle = point.LabelAngle; + + // Check if text contains white space only + if (text.Trim().Length != 0) + { + SizeF sizeFont = SizeF.Empty; + + + // Check if Smart Labels are enabled + if (ser.SmartLabelStyle.Enabled) + { + // Get text size + sizeFont = graph.GetRelativeSize( + graph.MeasureString(text, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic)); + + // Adjust label position using SmartLabelStyle algorithm + position = area.smartLabels.AdjustSmartLabelPosition( + common, + graph, + area, + ser.SmartLabelStyle, + position, + sizeFont, + format, + position, + markerSizes, + LabelAlignmentStyles.Top); + + // Smart labels always use 0 degrees text angle + textAngle = 0; + } + + + + // Draw label + if (!position.IsEmpty) + { + // Get text size + if (sizeFont.IsEmpty) + { + sizeFont = graph.GetRelativeSize( + graph.MeasureString(text, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic)); + } + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeFont.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = PointChart.GetLabelPosition( + graph, + position, + sizeLabel, + format, + true); + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + position, + format, + textAngle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + ser, + point, + pointIndex - 1); + } + } + } + } + } + } + + #endregion + + #region 3D Drawing and Selection methods + + /// + /// This method recalculates size of the bars. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual protected void ProcessChartType3D( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + // All data series from chart area which have Error Bar chart type + List typeSeries = area.GetSeriesFromChartType(this.Name); + + // Zero X values mode. + bool indexedSeries = ChartHelper.IndexedSeries(common, typeSeries.ToArray()); + + //************************************************************ + //** Loop through all series + //************************************************************ + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with stock chart type + if( String.Compare( ser.ChartTypeName, this.Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Check that we have at least 4 Y values + if(ser.YValuesPerPoint < 3) + { + throw(new ArgumentException(SR.ExceptionChartTypeRequiresYValues( ChartTypeNames.ErrorBar, ((int)(3)).ToString(CultureInfo.CurrentCulture)))); + } + + // Set active horizontal/vertical axis + hAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + vAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Get interval between points + double interval = (indexedSeries) ? 1 : area.GetPointsInterval( hAxis.IsLogarithmic, hAxis.logarithmBase ); + + // Calculates the width of the candles. + float width = (float)(ser.GetPointWidth(graph, hAxis, interval, 0.4)); + + // Align error bar X position with linked series + float sideBySideWidth = width; + int numberOfLinkedSeries = 1; + int indexOfLinkedSeries = 0; + bool showSideBySide = false; + if(ser.IsCustomPropertySet(CustomPropertyName.ErrorBarSeries)) + { + // Get series name + string attribValue = ser[CustomPropertyName.ErrorBarSeries]; + int valueTypeIndex = attribValue.IndexOf(":", StringComparison.Ordinal); + if(valueTypeIndex >= 0) + { + attribValue = attribValue.Substring(0, valueTypeIndex); + } + + // All linked data series from chart area which have Error bar chart type + string linkedSeriesChartType = common.DataManager.Series[attribValue].ChartTypeName; + List typeLinkedSeries = area.GetSeriesFromChartType(linkedSeriesChartType); + + // Get index of linked serries + foreach(string name in typeLinkedSeries) + { + if(name == attribValue) + { + break; + } + ++indexOfLinkedSeries; + } + + bool currentDrawSeriesSideBySide = false; + if(String.Compare(linkedSeriesChartType, ChartTypeNames.Column, StringComparison.OrdinalIgnoreCase ) == 0 + || String.Compare(linkedSeriesChartType, ChartTypeNames.RangeColumn, StringComparison.OrdinalIgnoreCase) == 0 + ) + { + currentDrawSeriesSideBySide = true; + } + foreach(string seriesName in typeLinkedSeries) + { + if(common.DataManager.Series[seriesName].IsCustomPropertySet(CustomPropertyName.DrawSideBySide)) + { + attribValue = common.DataManager.Series[seriesName][CustomPropertyName.DrawSideBySide]; + if(String.Compare(attribValue, "False", StringComparison.OrdinalIgnoreCase ) == 0) + { + currentDrawSeriesSideBySide = false; + } + else if(String.Compare(attribValue, "True", StringComparison.OrdinalIgnoreCase ) == 0) + { + currentDrawSeriesSideBySide = true; + } + else if(String.Compare(attribValue, "Auto", StringComparison.OrdinalIgnoreCase ) == 0) + { + // Do nothing + } + else + { + throw (new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid)); + } + } + } + + if(currentDrawSeriesSideBySide) + { + // Find the number of linked data series + numberOfLinkedSeries = typeLinkedSeries.Count; + width /= numberOfLinkedSeries; + + // Check if side by side + if(!indexedSeries) + { + area.GetPointsInterval( typeLinkedSeries, hAxis.IsLogarithmic, hAxis.logarithmBase, true, out showSideBySide ); + } + } + } + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + //************************************************************ + //** Get series depth and Z position + //************************************************************ + float seriesDepth, seriesZPosition; + area.GetSeriesZPositionAndDepth(ser, out seriesDepth, out seriesZPosition); + + //************************************************************ + //** Series data points loop + //************************************************************ + int index = 1; + foreach( DataPoint point in ser.Points ) + { + // Check required Y values number + if(point.YValues.Length < this.YValuesPerPoint) + { + throw(new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues( this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)))); + } + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Get point X position + float xPosition = 0f; + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + xPosition = (float)(hAxis.GetPosition( (double)index ) - sideBySideWidth * ((double) numberOfLinkedSeries) / 2.0 + sideBySideWidth/2 + indexOfLinkedSeries * sideBySideWidth); + } + else if( showSideBySide ) + { + xPosition = (float)(hAxis.GetPosition( xValue ) - sideBySideWidth * ((double) numberOfLinkedSeries) / 2.0 + sideBySideWidth/2 + indexOfLinkedSeries * sideBySideWidth); + } + else + { + xPosition = (float)hAxis.GetPosition( xValue ); + } + + double yValue0 = vAxis.GetLogValue( point.YValues[1] ); + double yValue1 = vAxis.GetLogValue( point.YValues[2] ); + xValue = hAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < hAxis.ViewMinimum || + xValue > hAxis.ViewMaximum || + (yValue0 < vAxis.ViewMinimum && yValue1 < vAxis.ViewMinimum) || + (yValue0 > vAxis.ViewMaximum && yValue1 > vAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Make sure High/Low values are in data scaleView range + double high = vAxis.GetLogValue( point.YValues[2] ); + double low = vAxis.GetLogValue( point.YValues[1] ); + + // Check if lower and/or upper error bar are drawn + ErrorBarStyle barStyle = ErrorBarStyle.Both; + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle) || ser.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle)) + { + string errorBarStyle = ser[CustomPropertyName.ErrorBarStyle]; + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle)) + { + errorBarStyle = point[CustomPropertyName.ErrorBarStyle]; + } + if(String.Compare(errorBarStyle, "Both", StringComparison.OrdinalIgnoreCase) == 0) + { + // default - do nothing + } + else if(String.Compare(errorBarStyle, "UpperError", StringComparison.OrdinalIgnoreCase) == 0) + { + barStyle = ErrorBarStyle.UpperError; + low = vAxis.GetLogValue( point.YValues[0] ); + high = vAxis.GetLogValue( point.YValues[2] ); + } + else if(String.Compare(errorBarStyle, "LowerError", StringComparison.OrdinalIgnoreCase) == 0) + { + barStyle = ErrorBarStyle.LowerError; + low = vAxis.GetLogValue( point.YValues[1] ); + high = vAxis.GetLogValue( point.YValues[0] ); + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(point[CustomPropertyName.ErrorBarStyle], "ErrorBarStyle"))); + } + } + + if( high > vAxis.ViewMaximum ) + { + high = vAxis.ViewMaximum; + } + if( high < vAxis.ViewMinimum ) + { + high = vAxis.ViewMinimum; + } + high = (float)vAxis.GetLinearPosition(high); + + if( low > vAxis.ViewMaximum ) + { + low = vAxis.ViewMaximum; + } + if( low < vAxis.ViewMinimum ) + { + low = vAxis.ViewMinimum; + } + low = vAxis.GetLinearPosition(low); + + // Remeber pre-calculated point position + point.positionRel = new PointF((float)xPosition, (float)Math.Min(high, low)); + + // 3D Transform coordinates + Point3D[] points = new Point3D[2]; + points[0] = new Point3D(xPosition, (float)high, seriesZPosition+seriesDepth/2f); + points[1] = new Point3D(xPosition, (float)low, seriesZPosition+seriesDepth/2f); + area.matrix3D.TransformPoints(points); + + if( common.ProcessModePaint ) + { + + // Check if chart is partialy in the data scaleView + bool clipRegionSet = false; + if(xValue == hAxis.ViewMinimum || xValue == hAxis.ViewMaximum ) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw error bar line + graph.DrawLineRel( + point.Color, + point.BorderWidth, + point.BorderDashStyle, + points[0].PointF, + points[1].PointF, + ser.ShadowColor, + ser.ShadowOffset ); + + // Draw Error Bar marks + DrawErrorBarMarks3D(graph, barStyle, area, ser, point, xPosition, width, seriesZPosition, seriesDepth); + xPosition = points[0].X; + high = points[0].Y; + low = points[1].Y; + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + } + + if( common.ProcessModeRegions ) + { + xPosition = points[0].X; + high = points[0].Y; + low = points[1].Y; + + // Calculate rect around the error bar marks + RectangleF areaRect = RectangleF.Empty; + areaRect.X = xPosition - width / 2f; + areaRect.Y = (float)Math.Min(high, low); + areaRect.Width = width; + areaRect.Height = (float)Math.Max(high, low) - areaRect.Y; + + // Add area + common.HotRegionsList.AddHotRegion( + areaRect, + point, + ser.Name, + index - 1 ); + } + + ++index; + } + + //************************************************************ + //** Second series data points loop, when labels are drawn. + //************************************************************ + if( !selection ) + { + index = 1; + foreach( DataPoint point in ser.Points ) + { + // Get point X position + float xPosition = 0f; + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + xPosition = (float)(hAxis.GetPosition( (double)index ) - sideBySideWidth * ((double) numberOfLinkedSeries) / 2.0 + sideBySideWidth/2 + indexOfLinkedSeries * sideBySideWidth); + } + else if( showSideBySide ) + { + xPosition = (float)(hAxis.GetPosition( xValue ) - sideBySideWidth * ((double) numberOfLinkedSeries) / 2.0 + sideBySideWidth/2 + indexOfLinkedSeries * sideBySideWidth); + } + else + { + xPosition = (float)hAxis.GetPosition( xValue ); + } + + + double yValue0 = vAxis.GetLogValue( point.YValues[1] ); + double yValue1 = vAxis.GetLogValue( point.YValues[2] ); + xValue = hAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < hAxis.ViewMinimum || + xValue > hAxis.ViewMaximum || + (yValue0 < vAxis.ViewMinimum && yValue1 < vAxis.ViewMinimum) || + (yValue0 > vAxis.ViewMaximum && yValue1 > vAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Make sure High/Low values are in data scaleView range + double high = vAxis.GetLogValue( point.YValues[2] ); + double low = vAxis.GetLogValue( point.YValues[1] ); + + // Check if lower and/or upper error bar are drawn + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle) || ser.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle)) + { + string errorBarStyle = ser[CustomPropertyName.ErrorBarStyle]; + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarStyle)) + { + errorBarStyle = point[CustomPropertyName.ErrorBarStyle]; + } + if(String.Compare(errorBarStyle, "Both", StringComparison.OrdinalIgnoreCase ) == 0) + { + // default - do nothing + } + else if(String.Compare(errorBarStyle, "UpperError", StringComparison.OrdinalIgnoreCase ) == 0) + { + low = vAxis.GetLogValue( point.YValues[0] ); + high = vAxis.GetLogValue( point.YValues[2] ); + } + else if(String.Compare(errorBarStyle, "LowerError", StringComparison.OrdinalIgnoreCase ) == 0) + { + low = vAxis.GetLogValue( point.YValues[1] ); + high = vAxis.GetLogValue( point.YValues[0] ); + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid( point[CustomPropertyName.ErrorBarStyle], "ErrorBarStyle"))); + } + } + + if( high > vAxis.ViewMaximum ) + { + high = vAxis.ViewMaximum; + } + if( high < vAxis.ViewMinimum ) + { + high = vAxis.ViewMinimum; + } + high = (float)vAxis.GetLinearPosition(high); + + if( low > vAxis.ViewMaximum ) + { + low = vAxis.ViewMaximum; + } + if( low < vAxis.ViewMinimum ) + { + low = vAxis.ViewMinimum; + } + low = vAxis.GetLinearPosition(low); + + + // 3D Transform coordinates + Point3D[] points = new Point3D[2]; + points[0] = new Point3D(xPosition, (float)high, seriesZPosition+seriesDepth/2f); + points[1] = new Point3D(xPosition, (float)low, seriesZPosition+seriesDepth/2f); + area.matrix3D.TransformPoints(points); + xPosition = points[0].X; + high = points[0].Y; + low = points[1].Y; + + // Draw label + DrawLabel(common, area, graph, ser, point, new PointF(xPosition, (float)Math.Min(high, low)), index); + + ++index; + } + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + } + } + + /// + /// Draws stock chart open-close marks depending on selected style. + /// + /// Chart graphics object. + /// Style of the error bar. + /// Chart area. + /// Data point series. + /// Data point to draw. + /// X position. + /// Point width. + /// Series Z position. + /// Series depth. + virtual protected void DrawErrorBarMarks3D( + ChartGraphics graph, + ErrorBarStyle barStyle, + ChartArea area, + Series ser, + DataPoint point, + float xPosition, + float width, + float zPosition, + float depth) + { + float yPosition = 0f; + string markerStyle = String.Empty; + + // Draw lower error marker + if(barStyle == ErrorBarStyle.Both || barStyle == ErrorBarStyle.LowerError) + { + // Get Y position + yPosition = (float)vAxis.GetLogValue( point.YValues[1] ); + + // Get marker style name + markerStyle = "LINE"; + if(point.MarkerStyle != MarkerStyle.None) + { + markerStyle = point.MarkerStyle.ToString(); + } + + // Draw marker + DrawErrorBarSingleMarker(graph, area, point, markerStyle, xPosition, yPosition, zPosition+depth/2f, width, true); + } + + // Draw upper error marker + if(barStyle == ErrorBarStyle.Both || barStyle == ErrorBarStyle.UpperError) + { + // Get Y position + yPosition = (float)vAxis.GetLogValue( point.YValues[2] ); + + // Get marker style name + markerStyle = "LINE"; + if(point.MarkerStyle != MarkerStyle.None) + { + markerStyle = point.MarkerStyle.ToString(); + } + + // Draw marker + DrawErrorBarSingleMarker(graph, area, point, markerStyle, xPosition, yPosition, zPosition+depth/2f, width, true); + } + + // Draw center value marker + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarCenterMarkerStyle) || point.series.IsCustomPropertySet(CustomPropertyName.ErrorBarCenterMarkerStyle)) + { + // Get Y position + yPosition = (float)vAxis.GetLogValue( point.YValues[0] ); + + // Get marker style name + markerStyle = point.series[CustomPropertyName.ErrorBarCenterMarkerStyle]; + if(point.IsCustomPropertySet(CustomPropertyName.ErrorBarCenterMarkerStyle)) + { + markerStyle = point[CustomPropertyName.ErrorBarCenterMarkerStyle]; + } + markerStyle = markerStyle.ToUpper(CultureInfo.InvariantCulture); + + // Draw marker + DrawErrorBarSingleMarker(graph, area, point, markerStyle, xPosition, yPosition, zPosition+depth/2f, width, true); + } + } + + #endregion + + #region Y values related methods + + /// + /// Helper function that returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + return point.YValues[yValueIndex]; + } + + #endregion + + #region Automatic Values Calculation methods + + /// + /// Calculates lower and upper error amount using specified formula. + /// + /// Error bar chart type series. + internal static void CalculateErrorAmount(Series errorBarSeries) + { + // Check input parameters + if(String.Compare(errorBarSeries.ChartTypeName, ChartTypeNames.ErrorBar, StringComparison.OrdinalIgnoreCase) != 0 ) + { + return; + } + + // Check if "ErrorBarType" custom attribute is set + if(!errorBarSeries.IsCustomPropertySet(CustomPropertyName.ErrorBarType) && + !errorBarSeries.IsCustomPropertySet(CustomPropertyName.ErrorBarSeries)) + { + return; + } + + // Parase the value of the ErrorBarType attribute. + double param = double.NaN; + ErrorBarType errorBarType = ErrorBarType.StandardError; + if(errorBarSeries.IsCustomPropertySet(CustomPropertyName.ErrorBarType)) + { + string typeName = errorBarSeries[CustomPropertyName.ErrorBarType]; + if(typeName.StartsWith("FixedValue", StringComparison.OrdinalIgnoreCase)) + { + errorBarType = ErrorBarType.FixedValue; + } + else if(typeName.StartsWith("Percentage", StringComparison.OrdinalIgnoreCase)) + { + errorBarType = ErrorBarType.Percentage; + } + else if(typeName.StartsWith("StandardDeviation", StringComparison.OrdinalIgnoreCase)) + { + errorBarType = ErrorBarType.StandardDeviation; + } + else if(typeName.StartsWith("StandardError", StringComparison.OrdinalIgnoreCase)) + { + errorBarType = ErrorBarType.StandardError; + } + else if(typeName.StartsWith("None", StringComparison.OrdinalIgnoreCase)) + { + return; + } + else + { + throw(new InvalidOperationException(SR.ExceptionErrorBarTypeInvalid(errorBarSeries[CustomPropertyName.ErrorBarType]))); + } + + // Check if parameter is specified + typeName = typeName.Substring(errorBarType.ToString().Length); + if(typeName.Length > 0) + { + // Must be followed by '(' and ends with ')' + if (!typeName.StartsWith("(", StringComparison.Ordinal) || !typeName.EndsWith(")", StringComparison.Ordinal)) + { + throw(new InvalidOperationException(SR.ExceptionErrorBarTypeFormatInvalid(errorBarSeries[CustomPropertyName.ErrorBarType]))); + } + typeName = typeName.Substring(1, typeName.Length - 2); + + + if(typeName.Length > 0) + { + if (!double.TryParse(typeName, NumberStyles.Any, CultureInfo.InvariantCulture, out param)) + { + throw (new InvalidOperationException(SR.ExceptionErrorBarTypeFormatInvalid(errorBarSeries[CustomPropertyName.ErrorBarType]))); + } + } + } + } + + // Points number + int pointNumber = errorBarSeries.Points.Count; + + // Find number of empty data points + int numberOfEmptyPoints = 0; + foreach(DataPoint point in errorBarSeries.Points) + { + if( point.IsEmpty ) + { + numberOfEmptyPoints++; + } + } + + // Number of poist without empty points + pointNumber -= numberOfEmptyPoints; + + if (double.IsNaN(param)) + { + param = DefaultErrorBarTypeValue(errorBarType); + } + + // Calculate error amount + double errorAmount = 0.0; + if(errorBarType == ErrorBarType.FixedValue) + { + errorAmount = param; + } + else if(errorBarType == ErrorBarType.Percentage) + { + // no processing or errorAmount + } + else if( errorBarType == ErrorBarType.StandardDeviation ) + { + // Formula for standard deviation need + // more then one data point + if( pointNumber > 1 ) + { + + // Calculate series mean value + double mean = 0.0; + foreach(DataPoint point in errorBarSeries.Points) + { + mean += point.YValues[0]; + } + mean /= pointNumber; + + // Calculate series variance + errorAmount = 0.0; + foreach(DataPoint point in errorBarSeries.Points) + { + if( !point.IsEmpty ) + { + errorAmount += Math.Pow(point.YValues[0] - mean, 2); + } + } + + errorAmount = param * Math.Sqrt(errorAmount/ ( pointNumber - 1 ) ); + } + else + { + errorAmount = 0; + } + } + else if( errorBarType == ErrorBarType.StandardError ) + { + // Formula for standard deviation need + // more then one data point + if( pointNumber > 1 ) + { + // Calculate standard error + errorAmount = 0.0; + foreach(DataPoint point in errorBarSeries.Points) + { + if( !point.IsEmpty ) + { + errorAmount += Math.Pow(point.YValues[0], 2); + } + } + + errorAmount = param * Math.Sqrt( errorAmount/( pointNumber * ( pointNumber - 1 ) ) ) / 2.0; + } + else + { + errorAmount = 0; + } + } + + + // Loop through all points to calculate error amount + foreach(DataPoint point in errorBarSeries.Points) + { + if(errorBarType == ErrorBarType.Percentage) + { + point.YValues[1] = point.YValues[0] - point.YValues[0] * param / 100.0; + point.YValues[2] = point.YValues[0] + point.YValues[0] * param / 100.0; + } + else + { + point.YValues[1] = point.YValues[0] - errorAmount; + point.YValues[2] = point.YValues[0] + errorAmount; + } + } + + } + + internal static double DefaultErrorBarTypeValue(ErrorBarType errorBarType) + { + switch (errorBarType) + { + case ErrorBarType.FixedValue: + case ErrorBarType.Percentage: + return 10.0; + case ErrorBarType.StandardDeviation: + case ErrorBarType.StandardError: + return 1.0; + default: + System.Diagnostics.Debug.Fail("Unknown ErrorBarType=" + errorBarType.ToString()); + break; + } + return 10.0; + } + + /// + /// Populates error bar center value using the linked series specified by + /// "ErrorBarSeries" custom attribute. + /// + /// Error bar chart type series. + internal static void GetDataFromLinkedSeries(Series errorBarSeries) + { + // Check input parameters + if(String.Compare(errorBarSeries.ChartTypeName, ChartTypeNames.ErrorBar, StringComparison.OrdinalIgnoreCase) != 0 || errorBarSeries.Chart == null) + { + return; + } + + // Check if "ErrorBarSeries" custom attribute is set + if(!errorBarSeries.IsCustomPropertySet(CustomPropertyName.ErrorBarSeries)) + { + return; + } + + // Get series and value name + string linkedSeriesName = errorBarSeries[CustomPropertyName.ErrorBarSeries]; + String valueName = "Y"; + int valueTypeIndex = linkedSeriesName.IndexOf(":", StringComparison.Ordinal); + if(valueTypeIndex >= 0) + { + valueName = linkedSeriesName.Substring(valueTypeIndex + 1); + linkedSeriesName = linkedSeriesName.Substring(0, valueTypeIndex); + } + + // Get reference to the chart control + Chart control = errorBarSeries.Chart; + if(control != null) + { + // Get linked series and check existance + if(control.Series.IndexOf(linkedSeriesName) == -1) + { + throw (new InvalidOperationException(SR.ExceptionDataSeriesNameNotFound(linkedSeriesName))); + } + Series linkedSeries = control.Series[linkedSeriesName]; + + // Make sure we use the same X and Y axis as the linked series + errorBarSeries.XAxisType = linkedSeries.XAxisType; + errorBarSeries.YAxisType = linkedSeries.YAxisType; + + // Get cennter values from the linked series + errorBarSeries.Points.Clear(); + foreach(DataPoint point in linkedSeries.Points) + { + // Add new point into the collection + errorBarSeries.Points.AddXY(point.XValue, point.GetValueByName(valueName)); + } + } + + } + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + // No data point markers supported for SmartLabelStyle + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} + diff --git a/System.Web.DataVisualization/Common/ChartTypes/FastLineChart.cs b/System.Web.DataVisualization/Common/ChartTypes/FastLineChart.cs new file mode 100644 index 000000000..2beee4626 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/FastLineChart.cs @@ -0,0 +1,738 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: FastLineChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: FastLineChart +// +// Purpose: When performance is critical, the FastLine chart +// type is a good alternative to the Line chart. FastLine +// charts significantly reduce the drawing time of a +// series that contains a very large number of data points. +// +// To make the FastLine chart a high performance chart, +// some charting features have been omitted. The features +// omitted include the ability to control Point level +// visual properties, the ability to draw markers, the +// use of data point labels, shadows, and the use of +// chart animation. +// +// FastLine chart performance was improved by limiting +// visual appearance features and by introducing data +// point compacting algorithm. When chart contains +// thousands of data points, it is common to have tens +// or hundreds points displayed in the area comparable +// to a single pixel. FastLine algorithm accumulates +// point information and only draw points if they extend +// outside currently filled pixels. +// +// Reviewed: AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; + +#if Microsoft_CONTROL +using System.Windows.Forms.DataVisualization.Charting.Utilities; +#else +using System.Web.UI.DataVisualization.Charting; + +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else +namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// FastLineChart class implements a simplified line chart drawing + /// algorithm which is optimized for the performance. + /// + internal class FastLineChart : IChartType + { + #region Fields and Constructor + + /// + /// Indicates that chart is drawn in 3D area + /// + internal bool chartArea3DEnabled = false; + + /// + /// Current chart graphics + /// + internal ChartGraphics Graph { get; set; } + + /// + /// Z coordinate of the 3D series + /// + internal float seriesZCoordinate = 0f; + + /// + /// 3D transformation matrix + /// + internal Matrix3D matrix3D = null; + + /// + /// Reference to common chart elements + /// + internal CommonElements Common { get; set; } + + /// + /// Default constructor + /// + public FastLineChart() + { + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.FastLine;}} + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + virtual public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + virtual public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + virtual public bool SideBySideSeries { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return false; } } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Line; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint { get { return 1; } } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Painting + + /// + /// Paint FastLine Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual public void Paint( + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + this.Common = common; + this.Graph = graph; + bool clipRegionSet = false; + if(area.Area3DStyle.Enable3D) + { + // Initialize variables + this.chartArea3DEnabled = true; + matrix3D = area.matrix3D; + } + else + { + this.chartArea3DEnabled = false; + } + + //************************************************************ + //** Loop through all series + //************************************************************ + foreach( Series series in common.DataManager.Series ) + { + // Process non empty series of the area with FastLine chart type + if( String.Compare( series.ChartTypeName, this.Name, true, System.Globalization.CultureInfo.CurrentCulture ) != 0 + || series.ChartArea != area.Name || + !series.IsVisible()) + { + continue; + } + + // Get 3D series depth and Z position + if(this.chartArea3DEnabled) + { + float seriesDepth; + area.GetSeriesZPositionAndDepth(series, out seriesDepth, out seriesZCoordinate); + this.seriesZCoordinate += seriesDepth/2.0f; + } + + // Set active horizontal/vertical axis + Axis hAxis = area.GetAxis(AxisName.X, series.XAxisType, (area.Area3DStyle.Enable3D) ? string.Empty : series.XSubAxisName); + Axis vAxis = area.GetAxis(AxisName.Y, series.YAxisType, (area.Area3DStyle.Enable3D) ? string.Empty : series.YSubAxisName); + double hAxisMin = hAxis.ViewMinimum; + double hAxisMax = hAxis.ViewMaximum; + double vAxisMin = vAxis.ViewMinimum; + double vAxisMax = vAxis.ViewMaximum; + + // Get "PermittedPixelError" attribute + float permittedPixelError = 1.0f; + if (series.IsCustomPropertySet(CustomPropertyName.PermittedPixelError)) + { + string attrValue = series[CustomPropertyName.PermittedPixelError]; + + float pixelError; + bool parseSucceed = float.TryParse(attrValue, NumberStyles.Any, CultureInfo.CurrentCulture, out pixelError); + + if (parseSucceed) + { + permittedPixelError = pixelError; + } + else + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid2("PermittedPixelError"))); + } + + // "PermittedPixelError" attribute value should be in range from zero to 1 + if (permittedPixelError < 0f || permittedPixelError > 1f) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeIsNotInRange0to1("PermittedPixelError"))); + } + } + + // Get pixel size in axes coordinates + SizeF pixelSize = graph.GetRelativeSize(new SizeF(permittedPixelError, permittedPixelError)); + SizeF axesMin = graph.GetRelativeSize(new SizeF((float)hAxisMin, (float)vAxisMin)); + double axesValuesPixelSizeX = Math.Abs(hAxis.PositionToValue(axesMin.Width + pixelSize.Width, false) - hAxis.PositionToValue(axesMin.Width, false)); + + // Create line pen + Pen linePen = new Pen(series.Color, series.BorderWidth); + linePen.DashStyle = graph.GetPenStyle( series.BorderDashStyle ); + linePen.StartCap = LineCap.Round; + linePen.EndCap = LineCap.Round; + + // Create empty line pen + Pen emptyLinePen = new Pen(series.EmptyPointStyle.Color, series.EmptyPointStyle.BorderWidth); + emptyLinePen.DashStyle = graph.GetPenStyle( series.EmptyPointStyle.BorderDashStyle ); + emptyLinePen.StartCap = LineCap.Round; + emptyLinePen.EndCap = LineCap.Round; + + // Check if series is indexed + bool indexedSeries = ChartHelper.IndexedSeries(this.Common, series.Name ); + + // Loop through all ponts in the series + int index = 0; + double yValueRangeMin = double.NaN; + double yValueRangeMax = double.NaN; + DataPoint pointRangeMin = null; + DataPoint pointRangeMax = null; + double xValue = 0; + double yValue = 0; + double xValuePrev = 0; + double yValuePrev = 0; + DataPoint prevDataPoint = null; + PointF lastVerticalSegmentPoint = PointF.Empty; + PointF prevPoint = PointF.Empty; + PointF currentPoint = PointF.Empty; + bool prevPointInAxesCoordinates = false; + bool verticalLineDetected = false; + bool prevPointIsEmpty = false; + bool currentPointIsEmpty = false; + bool firstNonEmptyPoint = false; + double xPixelConverter = (graph.Common.ChartPicture.Width - 1.0) / 100.0; + double yPixelConverter = (graph.Common.ChartPicture.Height - 1.0) / 100.0; + foreach( DataPoint point in series.Points ) + { + // Get point X and Y values + xValue = (indexedSeries) ? index + 1 : point.XValue; + xValue = hAxis.GetLogValue(xValue); + yValue = vAxis.GetLogValue(point.YValues[0]); + currentPointIsEmpty = point.IsEmpty; + + // NOTE: Fixes issue #7094 + // If current point is non-empty but the previous one was, + // use empty point style properties to draw it. + if (prevPointIsEmpty && !currentPointIsEmpty && !firstNonEmptyPoint) + { + firstNonEmptyPoint = true; + currentPointIsEmpty = true; + } + else + { + firstNonEmptyPoint = false; + } + + // Check if line is completly out of the data scaleView + if( !verticalLineDetected && + ((xValue < hAxisMin && xValuePrev < hAxisMin) || + (xValue > hAxisMax && xValuePrev > hAxisMax) || + (yValue < vAxisMin && yValuePrev < vAxisMin) || + (yValue > vAxisMax && yValuePrev > vAxisMax) )) + { + xValuePrev = xValue; + yValuePrev = yValue; + prevPointInAxesCoordinates = true; + ++index; + continue; + } + else if(!clipRegionSet) + { + // Check if line is partialy in the data scaleView + if(xValuePrev < hAxisMin || xValuePrev > hAxisMax || + xValue > hAxisMax || xValue < hAxisMin || + yValuePrev < vAxisMin || yValuePrev > vAxisMax || + yValue < vAxisMin || yValue > vAxisMax ) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + } + + // Check if point may be skipped + if(index > 0 && + currentPointIsEmpty == prevPointIsEmpty) + { + // Check if points X value in acceptable error boundary + if( Math.Abs(xValue - xValuePrev) < axesValuesPixelSizeX) + { + if(!verticalLineDetected) + { + verticalLineDetected = true; + if(yValue > yValuePrev) + { + yValueRangeMax = yValue; + yValueRangeMin = yValuePrev; + pointRangeMax = point; + pointRangeMin = prevDataPoint; + } + else + { + yValueRangeMax = yValuePrev; + yValueRangeMin = yValue; + pointRangeMax = prevDataPoint; + pointRangeMin = point; + } + + // NOTE: Prev. version code - A.G. +// yValueRangeMin = Math.Min(yValue, yValuePrev); +// yValueRangeMax = Math.Max(yValue, yValuePrev); + } + else + { + if(yValue > yValueRangeMax) + { + yValueRangeMax = yValue; + pointRangeMax = point; + } + + else if(yValue < yValueRangeMin) + { + yValueRangeMin = yValue; + pointRangeMin = point; + } + + // NOTE: Prev. version code - A.G. +// yValueRangeMin = Math.Min(yValue, yValueRangeMin); +// yValueRangeMax = Math.Max(yValue, yValueRangeMax); + } + + // Remember last point + prevDataPoint = point; + + // Remember last vertical range point + // Note! Point is in axes coordinate. + lastVerticalSegmentPoint.Y = (float)yValue; + + // Increase counter and proceed to next data point + ++index; + continue; + } + } + + // Get point pixel position + currentPoint.X = (float) + (hAxis.GetLinearPosition( xValue ) * xPixelConverter); + currentPoint.Y = (float) + (vAxis.GetLinearPosition( yValue ) * yPixelConverter); + + // Check if previous point must be converted from axes values to pixels + if(prevPointInAxesCoordinates) + { + prevPoint.X = (float) + (hAxis.GetLinearPosition( xValuePrev ) * xPixelConverter); + prevPoint.Y = (float) + (vAxis.GetLinearPosition( yValuePrev ) * yPixelConverter); + } + + // Draw accumulated vertical line (with minimal X values differences) + if(verticalLineDetected) + { + // Convert Y coordinates to pixels + yValueRangeMin = (vAxis.GetLinearPosition( yValueRangeMin ) * yPixelConverter); + yValueRangeMax = (vAxis.GetLinearPosition( yValueRangeMax ) * yPixelConverter); + + // Draw accumulated vertical line + DrawLine( + series, + prevDataPoint, + pointRangeMin, + pointRangeMax, + index, + (prevPointIsEmpty) ? emptyLinePen : linePen, + prevPoint.X, + (float)yValueRangeMin, + prevPoint.X, + (float)yValueRangeMax); + + // Reset vertical line detected flag + verticalLineDetected = false; + + // Convert last point of the vertical line segment to pixel coordinates + prevPoint.Y = (float) + (vAxis.GetLinearPosition( lastVerticalSegmentPoint.Y ) * yPixelConverter); + } + + // Draw line from previous to current point + if(index > 0) + { + DrawLine( + series, + point, + pointRangeMin, + pointRangeMax, + index, + (currentPointIsEmpty) ? emptyLinePen : linePen, + prevPoint.X, + prevPoint.Y, + currentPoint.X, + currentPoint.Y); + } + + // Remember last point coordinates + xValuePrev = xValue; + yValuePrev = yValue; + prevDataPoint = point; + prevPoint = currentPoint; + prevPointInAxesCoordinates = false; + prevPointIsEmpty = currentPointIsEmpty; + ++index; + } + + // Draw last accumulated line segment + if(verticalLineDetected) + { + // Check if previous point must be converted from axes values to pixels + if(prevPointInAxesCoordinates) + { + prevPoint.X = (float) + (hAxis.GetLinearPosition( xValuePrev ) * xPixelConverter); + prevPoint.Y = (float) + (vAxis.GetLinearPosition( yValuePrev ) * yPixelConverter); + } + + // Convert Y coordinates to pixels + yValueRangeMin = (vAxis.GetLinearPosition( yValueRangeMin ) * yPixelConverter); + yValueRangeMax = (vAxis.GetLinearPosition( yValueRangeMax ) * yPixelConverter); + + // Draw accumulated vertical line + DrawLine( + series, + prevDataPoint, + pointRangeMin, + pointRangeMax, + index - 1, + (prevPointIsEmpty) ? emptyLinePen : linePen, + prevPoint.X, + (float)yValueRangeMin, + prevPoint.X, + (float)yValueRangeMax); + + verticalLineDetected = false; + yValueRangeMin = double.NaN; + yValueRangeMax = double.NaN; + pointRangeMin = null; + pointRangeMax = null; + } + + } + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + + } + + /// + /// Draws a line connecting two PointF structures. + /// + /// Chart series. + /// Series last data point in the group. + /// Series minimum Y value data point in the group. + /// Series maximum Y value data point in the group. + /// Point index. + /// Pen object that determines the color, width, and style of the line. + /// First point X coordinate. + /// First point Y coordinate + /// Second point X coordinate. + /// Second point Y coordinate + public virtual void DrawLine( + Series series, + DataPoint point, + DataPoint pointMin, + DataPoint pointMax, + int pointIndex, + Pen pen, + float firstPointX, + float firstPointY, + float secondPointX, + float secondPointY + ) + { + // Transform 3D coordinates + if(chartArea3DEnabled) + { + Point3D [] points = new Point3D[2]; + + // All coordinates has to be transformed in relative coordinate system + // NOTE: Fixes issue #5496 + PointF firstPoint = Graph.GetRelativePoint(new PointF(firstPointX, firstPointY)); + PointF secondPoint = Graph.GetRelativePoint(new PointF(secondPointX, secondPointY)); + + points[0] = new Point3D(firstPoint.X, firstPoint.Y, seriesZCoordinate); + points[1] = new Point3D(secondPoint.X, secondPoint.Y, seriesZCoordinate); + matrix3D.TransformPoints( points ); + + // All coordinates has to be transformed back to pixels + // NOTE: Fixes issue #5496 + points[0].PointF = Graph.GetAbsolutePoint(points[0].PointF); + points[1].PointF = Graph.GetAbsolutePoint(points[1].PointF); + + firstPointX = points[0].X; + firstPointY = points[0].Y; + secondPointX = points[1].X; + secondPointY = points[1].Y; + } + + // Draw line + Graph.DrawLine(pen, firstPointX, firstPointY, secondPointX,secondPointY); + + // Process selection regions + if( this.Common.ProcessModeRegions ) + { + // Create grapics path object for the line + using (GraphicsPath path = new GraphicsPath()) + { + float width = pen.Width + 2; + + if (Math.Abs(firstPointX - secondPointX) > Math.Abs(firstPointY - secondPointY)) + { + path.AddLine(firstPointX, firstPointY - width, secondPointX, secondPointY - width); + path.AddLine(secondPointX, secondPointY + width, firstPointX, firstPointY + width); + path.CloseAllFigures(); + } + else + { + path.AddLine(firstPointX - width, firstPointY, secondPointX - width, secondPointY); + path.AddLine(secondPointX + width, secondPointY, firstPointX + width, firstPointY); + path.CloseAllFigures(); + } + + // Calculate bounding rectangle + RectangleF pathBounds = path.GetBounds(); + + // If one side of the bounding rectangle is less than 2 pixels + // use rectangle region shape to optimize used coordinates space + if (pathBounds.Width <= 2.0 || pathBounds.Height <= 2.0) + { + // Add hot region path as rectangle + pathBounds.Inflate(pen.Width, pen.Width); + this.Common.HotRegionsList.AddHotRegion( + Graph.GetRelativeRectangle(pathBounds), + point, + point.series.Name, + pointIndex); + } + else + { + // Add hot region path as polygon + this.Common.HotRegionsList.AddHotRegion( + path, + false, + Graph, + point, + point.series.Name, + pointIndex); + } + } + } + } + + #endregion + + #region Y values related methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + return point.YValues[yValueIndex]; + } + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + // Fast Line chart type do not support labels + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/FastPointChart.cs b/System.Web.DataVisualization/Common/ChartTypes/FastPointChart.cs new file mode 100644 index 000000000..167247631 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/FastPointChart.cs @@ -0,0 +1,700 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: FastPointChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: FastPointChart +// +// Purpose: When performance is critical, the FastPoint chart +// type is a good alternative to the Point chart. FastPoint +// charts significantly reduce the drawing time of a +// series that contains a very large number of data points. +// +// To make the FastPoint chart a high performance chart, +// some charting features have been omitted. The features +// omitted include the ability to control Point level +// visual properties the use of data point labels, shadows, +// and the use of chart animation. +// +// FastPoint chart performance was improved by limiting +// visual appearance features and by introducing data +// point compacting algorithm. When chart contains +// thousands of data points, it is common to have tens +// or hundreds points displayed in the area comparable +// to a single pixel. FastPoint algorithm accumulates +// point information and only draw points if they extend +// outside currently filled pixels. +// +// Reviewed: AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; + +#if Microsoft_CONTROL +using System.Windows.Forms.DataVisualization.Charting.Utilities; +#else +using System.Web.UI.DataVisualization.Charting; + +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else +namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + + /// + /// FastPointChart class implements a simplified point chart drawing + /// algorithm which is optimized for the performance. + /// + internal class FastPointChart : IChartType + { + #region Fields and Constructor + + /// + /// Indicates that chart is drawn in 3D area + /// + internal bool chartArea3DEnabled = false; + + /// + /// Current chart graphics + /// + internal ChartGraphics Graph { get; set; } + + /// + /// Z coordinate of the 3D series + /// + internal float seriesZCoordinate = 0f; + + /// + /// 3D transformation matrix + /// + internal Matrix3D matrix3D = null; + + /// + /// Reference to common chart elements + /// + internal CommonElements Common { get; set; } + + /// + /// Default constructor + /// + public FastPointChart() + { + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.FastPoint;}} + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + virtual public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + virtual public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + virtual public bool SideBySideSeries { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return false; } } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Marker; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint { get { return 1; } } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Painting + + /// + /// Paint FastPoint Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual public void Paint( + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + this.Common = common; + this.Graph = graph; + if(area.Area3DStyle.Enable3D) + { + // Initialize variables + this.chartArea3DEnabled = true; + matrix3D = area.matrix3D; + } + else + { + this.chartArea3DEnabled = false; + } + + //************************************************************ + //** Loop through all series + //************************************************************ + foreach( Series series in common.DataManager.Series ) + { + // Process non empty series of the area with FastPoint chart type + if( String.Compare( series.ChartTypeName, this.Name, true, System.Globalization.CultureInfo.CurrentCulture ) != 0 + || series.ChartArea != area.Name || + !series.IsVisible()) + { + continue; + } + + // Get 3D series depth and Z position + if(this.chartArea3DEnabled) + { + float seriesDepth; + area.GetSeriesZPositionAndDepth(series, out seriesDepth, out this.seriesZCoordinate); + this.seriesZCoordinate += seriesDepth/2.0f; + } + + // Set active horizontal/vertical axis + Axis hAxis = area.GetAxis(AxisName.X, series.XAxisType, (area.Area3DStyle.Enable3D) ? string.Empty : series.XSubAxisName); + Axis vAxis = area.GetAxis(AxisName.Y, series.YAxisType, (area.Area3DStyle.Enable3D) ? string.Empty : series.YSubAxisName); + double hAxisMin = hAxis.ViewMinimum; + double hAxisMax = hAxis.ViewMaximum; + double vAxisMin = vAxis.ViewMinimum; + double vAxisMax = vAxis.ViewMaximum; + + // Get "PermittedPixelError" attribute. + // By default use 1/3 of the marker size. + float permittedPixelError = series.MarkerSize / 3f; + if (series.IsCustomPropertySet(CustomPropertyName.PermittedPixelError)) + { + string attrValue = series[CustomPropertyName.PermittedPixelError]; + + float pixelError; + bool parseSucceed = float.TryParse(attrValue, NumberStyles.Any, CultureInfo.CurrentCulture, out pixelError); + + if (parseSucceed) + { + permittedPixelError = pixelError; + } + else + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid2("PermittedPixelError"))); + } + + // "PermittedPixelError" attribute value should be in range from zero to 1 + if (permittedPixelError < 0f || permittedPixelError > 1f) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeIsNotInRange0to1("PermittedPixelError"))); + } + } + + // Get pixel size in axes coordinates + SizeF pixelSize = graph.GetRelativeSize(new SizeF(permittedPixelError, permittedPixelError)); + SizeF axesMin = graph.GetRelativeSize(new SizeF((float)hAxisMin, (float)vAxisMin)); + double axesValuesPixelSizeX = Math.Abs(hAxis.PositionToValue(axesMin.Width + pixelSize.Width, false) - hAxis.PositionToValue(axesMin.Width, false)); + double axesValuesPixelSizeY = Math.Abs(vAxis.PositionToValue(axesMin.Height + pixelSize.Height, false) - vAxis.PositionToValue(axesMin.Height, false)); + + // Create point marker brush + SolidBrush markerBrush = new SolidBrush( ((series.MarkerColor.IsEmpty) ? series.Color : series.MarkerColor) ); + SolidBrush emptyMarkerBrush = new SolidBrush( ((series.EmptyPointStyle.MarkerColor.IsEmpty) ? series.EmptyPointStyle.Color : series.EmptyPointStyle.MarkerColor) ); + + // Create point marker border pen + Pen borderPen = null; + Pen emptyBorderPen = null; + if(!series.MarkerBorderColor.IsEmpty && series.MarkerBorderWidth > 0) + { + borderPen = new Pen(series.MarkerBorderColor, series.MarkerBorderWidth); + } + if(!series.EmptyPointStyle.MarkerBorderColor.IsEmpty && series.EmptyPointStyle.MarkerBorderWidth > 0) + { + emptyBorderPen = new Pen(series.EmptyPointStyle.MarkerBorderColor, series.EmptyPointStyle.MarkerBorderWidth); + } + + // Check if series is indexed + bool indexedSeries = ChartHelper.IndexedSeries(this.Common, series.Name ); + + // Get marker size taking in consideration current DPIs + int markerSize = series.MarkerSize; + if (graph != null && graph.Graphics != null) + { + // Marker size is in pixels and we do the mapping for higher DPIs + markerSize = (int)Math.Max(markerSize * graph.Graphics.DpiX / 96, markerSize * graph.Graphics.DpiY / 96); + } + + // Loop through all ponts in the series + int index = 0; + double xValue = 0.0; + double yValue = 0.0; + double xValuePrev = 0.0; + double yValuePrev = 0.0; + PointF currentPoint = PointF.Empty; + bool currentPointIsEmpty = false; + double xPixelConverter = (graph.Common.ChartPicture.Width - 1.0) / 100.0; + double yPixelConverter = (graph.Common.ChartPicture.Height - 1.0) / 100.0; + MarkerStyle markerStyle = series.MarkerStyle; + MarkerStyle emptyMarkerStyle = series.EmptyPointStyle.MarkerStyle; + foreach( DataPoint point in series.Points ) + { + // Get point X and Y values + xValue = (indexedSeries) ? index + 1 : point.XValue; + xValue = hAxis.GetLogValue(xValue); + yValue = vAxis.GetLogValue(point.YValues[0]); + currentPointIsEmpty = point.IsEmpty; + + // Check if point is completly out of the data scaleView + if( xValue < hAxisMin || + xValue > hAxisMax || + yValue < vAxisMin || + yValue > vAxisMax ) + { + xValuePrev = xValue; + yValuePrev = yValue; + ++index; + continue; + } + + // Check if point may be skipped + if(index > 0) + { + // Check if current point location is in the specified distance from the + // preious data location. + if(Math.Abs(xValue - xValuePrev) < axesValuesPixelSizeX && + Math.Abs(yValue - yValuePrev) < axesValuesPixelSizeY) + { + // Increase counter and proceed to the next data point + ++index; + continue; + } + } + + // Get point pixel position + currentPoint.X = (float) + (hAxis.GetLinearPosition( xValue ) * xPixelConverter); + currentPoint.Y = (float) + (vAxis.GetLinearPosition( yValue ) * yPixelConverter); + + // Draw point marker + MarkerStyle currentMarkerStyle = (currentPointIsEmpty) ? emptyMarkerStyle : markerStyle; + if(currentMarkerStyle != MarkerStyle.None) + { + this.DrawMarker( + graph, + point, + index, + currentPoint, + currentMarkerStyle, + markerSize, + (currentPointIsEmpty) ? emptyMarkerBrush : markerBrush, + (currentPointIsEmpty) ? emptyBorderPen : borderPen); + } + + // Remember last point coordinates + xValuePrev = xValue; + yValuePrev = yValue; + ++index; + } + + // Dispose used brushes and pens + markerBrush.Dispose(); + emptyMarkerBrush.Dispose(); + if(borderPen != null) + { + borderPen.Dispose(); + } + if(emptyBorderPen != null) + { + emptyBorderPen.Dispose(); + } + } + } + + /// + /// Draws a marker that represents a data point in FastPoint series. + /// + /// Chart graphics used to draw the marker. + /// Series data point drawn. + /// Data point index in the series. + /// Marker location in pixels. + /// Marker style. + /// Marker size in pixels. + /// Brush used to fill marker shape. + /// Marker border pen. + virtual protected void DrawMarker( + ChartGraphics graph, + DataPoint point, + int pointIndex, + PointF location, + MarkerStyle markerStyle, + int markerSize, + Brush brush, + Pen borderPen) + { + // Transform 3D coordinates + if(chartArea3DEnabled) + { + Point3D [] points = new Point3D[1]; + location = graph.GetRelativePoint(location); + points[0] = new Point3D(location.X, location.Y, this.seriesZCoordinate); + matrix3D.TransformPoints( points ); + location.X = points[0].X; + location.Y = points[0].Y; + location = graph.GetAbsolutePoint(location); + } + + // Create marker bounding rectangle in pixels + RectangleF markerBounds = new RectangleF( + location.X - markerSize / 2f, location.Y - markerSize / 2f, markerSize, markerSize); + + // Draw Marker + switch(markerStyle) + { + case(MarkerStyle.Star4): + case(MarkerStyle.Star5): + case(MarkerStyle.Star6): + case(MarkerStyle.Star10): + { + // Set number of corners + int cornerNumber = 4; + if(markerStyle == MarkerStyle.Star5) + { + cornerNumber = 5; + } + else if(markerStyle == MarkerStyle.Star6) + { + cornerNumber = 6; + } + else if(markerStyle == MarkerStyle.Star10) + { + cornerNumber = 10; + } + + // Get star polygon + PointF[] points = graph.CreateStarPolygon(markerBounds, cornerNumber); + + // Fill shape + graph.FillPolygon(brush, points); + + // Draw border + if(borderPen != null) + { + graph.DrawPolygon(borderPen, points); + } + break; + } + case(MarkerStyle.Circle): + { + graph.FillEllipse(brush, markerBounds); + + // Draw border + if(borderPen != null) + { + graph.DrawEllipse(borderPen, markerBounds); + } + + break; + } + case(MarkerStyle.Square): + { + graph.FillRectangle(brush, markerBounds); + + // Draw border + if(borderPen != null) + { + graph.DrawRectangle( + borderPen, + (int)Math.Round(markerBounds.X, 0), + (int)Math.Round(markerBounds.Y, 0), + (int)Math.Round(markerBounds.Width, 0), + (int)Math.Round(markerBounds.Height, 0) ); + } + + break; + } + case(MarkerStyle.Cross): + { + // Calculate cross line width and size + float crossLineWidth = (float)Math.Ceiling(markerSize/4F); + float crossSize = markerSize; // * (float)Math.Sin(45f/180f*Math.PI); + + // Calculate cross coordinates + PointF[] points = new PointF[12]; + points[0].X = location.X - crossSize/2F; + points[0].Y = location.Y + crossLineWidth/2F; + points[1].X = location.X - crossSize/2F; + points[1].Y = location.Y - crossLineWidth/2F; + + points[2].X = location.X - crossLineWidth/2F; + points[2].Y = location.Y - crossLineWidth/2F; + points[3].X = location.X - crossLineWidth/2F; + points[3].Y = location.Y - crossSize/2F; + points[4].X = location.X + crossLineWidth/2F; + points[4].Y = location.Y - crossSize/2F; + + points[5].X = location.X + crossLineWidth/2F; + points[5].Y = location.Y - crossLineWidth/2F; + points[6].X = location.X + crossSize/2F; + points[6].Y = location.Y - crossLineWidth/2F; + points[7].X = location.X + crossSize/2F; + points[7].Y = location.Y + crossLineWidth/2F; + + points[8].X = location.X + crossLineWidth/2F; + points[8].Y = location.Y + crossLineWidth/2F; + points[9].X = location.X + crossLineWidth/2F; + points[9].Y = location.Y + crossSize/2F; + points[10].X = location.X - crossLineWidth/2F; + points[10].Y = location.Y + crossSize/2F; + points[11].X = location.X - crossLineWidth/2F; + points[11].Y = location.Y + crossLineWidth/2F; + + // Rotate cross coordinates 45 degrees + Matrix rotationMatrix = new Matrix(); + rotationMatrix.RotateAt(45, location); + rotationMatrix.TransformPoints(points); + rotationMatrix.Dispose(); + + // Fill shape + graph.FillPolygon(brush, points); + + // Draw border + if(borderPen != null) + { + graph.DrawPolygon(borderPen, points); + } + break; + } + case(MarkerStyle.Diamond): + { + PointF[] points = new PointF[4]; + points[0].X = markerBounds.X; + points[0].Y = markerBounds.Y + markerBounds.Height/2F; + points[1].X = markerBounds.X + markerBounds.Width/2F; + points[1].Y = markerBounds.Top; + points[2].X = markerBounds.Right; + points[2].Y = markerBounds.Y + markerBounds.Height/2F; + points[3].X = markerBounds.X + markerBounds.Width/2F; + points[3].Y = markerBounds.Bottom; + + graph.FillPolygon(brush, points); + + // Draw border + if(borderPen != null) + { + graph.DrawPolygon(borderPen, points); + } + break; + } + case(MarkerStyle.Triangle): + { + PointF[] points = new PointF[3]; + points[0].X = markerBounds.X; + points[0].Y = markerBounds.Bottom; + points[1].X = markerBounds.X + markerBounds.Width/2F; + points[1].Y = markerBounds.Top; + points[2].X = markerBounds.Right; + points[2].Y = markerBounds.Bottom; + + graph.FillPolygon(brush, points); + + // Draw border + if(borderPen != null) + { + graph.DrawPolygon(borderPen, points); + } + break; + } + default: + { + throw (new InvalidOperationException(SR.ExceptionFastPointMarkerStyleUnknown)); + } + } + + // Process selection regions + if( this.Common.ProcessModeRegions ) + { + this.Common.HotRegionsList.AddHotRegion( + graph.GetRelativeRectangle(markerBounds), + point, + point.series.Name, + pointIndex ); + } + } + + #endregion + + #region Y values related methods + + /// + /// Helper function, which returns the Y value of the location. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the location. + /// Point object. + /// Index of the location. + /// Index of the Y value to get. + /// Y value of the location. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + return point.YValues[yValueIndex]; + } + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + // Fast Point chart type do not support labels + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/FunnelChart.cs b/System.Web.DataVisualization/Common/ChartTypes/FunnelChart.cs new file mode 100644 index 000000000..3afc18bd7 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/FunnelChart.cs @@ -0,0 +1,3044 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: FunnelChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: FunnelChart, PyramidChart, FunnelSegmentInfo, +// FunnelPointLabelInfo +// +// Purpose: Provides 2D/3D drawing and hit testing functionality +// for the Funnel and Pyramid charts. +// +// Funnel and Pyramid Chart types display data that +// equals 100% when totalled. This type of chart is a +// single series chart representing the data as portions +// of 100%, and this chart does not use any axes. +// +// Reviewed: AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Utilities; +#else + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion // Used namespaces + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else // Microsoft_CONTROL + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif // Microsoft_CONTROL +{ + #region Enumerations + + /// + /// Value type of the pyramid chart. + /// + internal enum PyramidValueType + { + /// + /// Each point value defines linear height of each segment. + /// + Linear, + + /// + /// Each point value defines surface of each segment. + /// + Surface + } + + /// + /// Funnel chart drawing style. + /// + internal enum FunnelStyle + { + /// + /// Shape of the funnel is fixed and point Y value controls the height of the segments. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "YIs")] + YIsHeight, + + /// + /// Height of each segment is the same and point Y value controls the diameter of the segment. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "YIs")] + YIsWidth + } + + /// + /// Outside labels placement. + /// + internal enum FunnelLabelPlacement + { + /// + /// Labels are placed on the right side of the funnel. + /// + Right, + + /// + /// Labels are placed on the left side of the funnel. + /// + Left + } + + /// + /// Vertical alignment of the data point labels + /// + internal enum FunnelLabelVerticalAlignment + { + /// + /// Label placed in the middle. + /// + Center, + + /// + /// Label placed on top. + /// + Top, + + /// + /// Label placed on the bottom. + /// + Bottom + } + + /// + /// Funnel chart 3D drawing style. + /// + internal enum Funnel3DDrawingStyle + { + /// + /// Circle will be used as a shape of the base. + /// + CircularBase, + + /// + /// Square will be used as a shape of the base. + /// + SquareBase + } + + + /// + /// Funnel chart labels style enumeration. + /// + internal enum FunnelLabelStyle + { + /// + /// Data point labels are located inside of the funnel. + /// + Inside, + + /// + /// Data point labels are located outside of the funnel. + /// + Outside, + + /// + /// Data point labels are located outside of the funnel in a column. + /// + OutsideInColumn, + + /// + /// Data point labels are disabled. + /// + Disabled + } + + #endregion // Enumerations + + /// + /// FunnelChart class provides 2D/3D drawing and hit testing functionality + /// for the Funnel and Pyramid charts. + /// + internal class FunnelChart : IChartType + { + #region Fields and Constructor + + // Array list of funnel segments + internal ArrayList segmentList = null; + + // List of data point labels information + internal ArrayList labelInfoList = null; + + // Chart graphics object. + internal ChartGraphics Graph { get; set; } + + // Chart area the chart type belongs to. + internal ChartArea Area { get; set; } + + // Common chart elements. + internal CommonElements Common { get; set; } + + // Spacing between each side of the funnel and chart area. + internal RectangleF plotAreaSpacing = new RectangleF(3f, 3f, 3f, 3f); + + // Current chart type series + private Series _chartTypeSeries = null; + + // Sum of all Y values in the data series + internal double yValueTotal = 0.0; + + // Maximum Y value in the data series + private double _yValueMax = 0.0; + + // Sum of all X values in the data series + private double _xValueTotal = 0.0; + + // Number of points in the series + internal int pointNumber; + + // Calculted plotting area of the chart + private RectangleF _plotAreaPosition = RectangleF.Empty; + + // Funnel chart drawing style + private FunnelStyle _funnelStyle = FunnelStyle.YIsHeight; + + // Define the shape of the funnel neck + private SizeF _funnelNeckSize = new SizeF(50f, 30f); + + // Gap between funnel segments + internal float funnelSegmentGap = 0f; + + // 3D funnel rotation angle + private int _rotation3D = 5; + + // Indicates that rounded shape is used to draw 3D chart type instead of square + internal bool round3DShape = true; + + // Indicates that Pyramid chart is rendered. + internal bool isPyramid = false; + + // Minimum data point height + private float _funnelMinPointHeight = 0f; + + // Name of the attribute that controls the height of the gap between the points + internal string funnelPointGapAttributeName = CustomPropertyName.FunnelPointGap; + + // Name of the attribute that controls the 3D funnel rotation angle + internal string funnelRotationAngleAttributeName = CustomPropertyName.Funnel3DRotationAngle; + + // Name of the attribute that controls the minimum height of the point + protected string funnelPointMinHeight = CustomPropertyName.FunnelMinPointHeight; + + // Name of the attribute that controls the minimum height of the point + internal string funnel3DDrawingStyleAttributeName = CustomPropertyName.Funnel3DDrawingStyle; + + // Name of the attribute that controls inside labels vertical alignment + internal string funnelInsideLabelAlignmentAttributeName = CustomPropertyName.FunnelInsideLabelAlignment; + + // Name of the attribute that controls outside labels placement (Left vs. Right) + protected string funnelOutsideLabelPlacementAttributeName = CustomPropertyName.FunnelOutsideLabelPlacement; + + // Name of the attribute that controls labels style + internal string funnelLabelStyleAttributeName = CustomPropertyName.FunnelLabelStyle; + + // Array of data point value adjusments in percentage + private double[] _valuePercentages = null; + + /// + /// Default constructor + /// + public FunnelChart() + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets the calculted plotting area of the chart + /// + internal RectangleF PlotAreaPosition + { + get { return _plotAreaPosition; } + set { _plotAreaPosition = value; } + } + + #endregion // Properties + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.Funnel;}} + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + virtual public bool RequireAxes { get{ return false;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + virtual public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + virtual public bool SideBySideSeries { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return true;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return true; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return false; } } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint { get { return 1; } } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Painting + + /// + /// Paint Funnel Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual public void Paint( + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + // Reset fields + this._chartTypeSeries = null; + this._funnelMinPointHeight = 0f; + + // Save reference to the input parameters + this.Graph = graph; + this.Common = common; + this.Area = area; + + // Funnel chart like a Pie chart shows each data point as part of the whole (100%). + // Calculate the sum of all Y and X values, which will be used to calculate point percentage. + GetDataPointValuesStatistic(); + + // Check if there are non-zero points + if(this.yValueTotal == 0.0 || this.pointNumber == 0) + { + return; + } + + // When Y value is funnel width at least 2 points required + this._funnelStyle = GetFunnelStyle( this.GetDataSeries() ); + if(this._funnelStyle == FunnelStyle.YIsWidth && + this.pointNumber == 1) + { + // At least 2 points required + return; + } + + // Get minimum point height + GetFunnelMinPointHeight( this.GetDataSeries() ); + + // Fill list of data point labels information + this.labelInfoList = CreateLabelsInfoList(); + + // Calculate the spacing required for the labels. + GetPlotAreaSpacing(); + + // Draw funnel + ProcessChartType(); + + // Draw data point labels + DrawLabels(); + } + + /// + /// Process chart type drawing. + /// + private void ProcessChartType() + { + // Reversed drawing order in 3D with positive rotation angle + if(this.Area.Area3DStyle.Enable3D && + ( (this._rotation3D > 0 && !this.isPyramid) || (this._rotation3D < 0 && this.isPyramid) ) ) + { + this.segmentList.Reverse(); + } + + // Check if series shadow should be drawn separatly + bool drawShadowSeparatly = true; + bool drawSegmentShadow = (this.Area.Area3DStyle.Enable3D) ? false : true; + + // Process all funnel segments shadows + Series series = this.GetDataSeries(); + if(drawSegmentShadow && + drawShadowSeparatly && + series != null && + series.ShadowOffset != 0) + { + foreach(FunnelSegmentInfo segmentInfo in this.segmentList) + { + // Draw funnel segment + this.DrawFunnelCircularSegment( + segmentInfo.Point, + segmentInfo.PointIndex, + segmentInfo.StartWidth, + segmentInfo.EndWidth, + segmentInfo.Location, + segmentInfo.Height, + segmentInfo.NothingOnTop, + segmentInfo.NothingOnBottom, + false, + true); + } + + drawSegmentShadow = false; + } + + // Process all funnel segments + foreach(FunnelSegmentInfo segmentInfo in this.segmentList) + { + // Draw funnel segment + this.DrawFunnelCircularSegment( + segmentInfo.Point, + segmentInfo.PointIndex, + segmentInfo.StartWidth, + segmentInfo.EndWidth, + segmentInfo.Location, + segmentInfo.Height, + segmentInfo.NothingOnTop, + segmentInfo.NothingOnBottom, + true, + drawSegmentShadow); + } + } + + /// + /// Gets funnel data point segment height and width. + /// + /// Chart type series. + /// Data point index in the series. + /// Segment top location. Bottom location if reversed drawing order. + /// Returns the height of the segment. + /// Returns top width of the segment. + /// Returns botom width of the segment. + protected virtual void GetPointWidthAndHeight( + Series series, + int pointIndex, + float location, + out float height, + out float startWidth, + out float endWidth) + { + PointF pointPositionAbs = PointF.Empty; + + // Get plotting area position in pixels + RectangleF plotAreaPositionAbs = this.Graph.GetAbsoluteRectangle(this.PlotAreaPosition); + + // Calculate total height of plotting area minus reserved space for the gaps + float plotAreaHeightAbs = plotAreaPositionAbs.Height - + this.funnelSegmentGap * (this.pointNumber - ((ShouldDrawFirstPoint()) ? 1 : 2) ); + if(plotAreaHeightAbs < 0f) + { + plotAreaHeightAbs = 0f; + } + + if( this._funnelStyle == FunnelStyle.YIsWidth ) + { + // Check if X values are provided + if(this._xValueTotal == 0.0) + { + // Calculate segment height in pixels by deviding + // plotting area height by number of points. + height = plotAreaHeightAbs / (this.pointNumber - 1); + } + else + { + // Calculate segment height as a part of total Y values in series + height = (float)(plotAreaHeightAbs * (GetXValue(series.Points[pointIndex]) / this._xValueTotal)); + } + + // Check for minimum segment height + height = CheckMinHeight(height); + + // Calculate start and end width of the segment based on Y value + // of previous and current data point. + startWidth = (float)(plotAreaPositionAbs.Width * (GetYValue(series.Points[pointIndex-1], pointIndex-1) / this._yValueMax)); + endWidth = (float)(plotAreaPositionAbs.Width * (GetYValue(series.Points[pointIndex], pointIndex) / this._yValueMax)); + + // Set point position for annotation anchoring + pointPositionAbs = new PointF( + plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f, + location + height); + } + else if( this._funnelStyle == FunnelStyle.YIsHeight ) + { + // Calculate segment height as a part of total Y values in series + height = (float)(plotAreaHeightAbs * (GetYValue(series.Points[pointIndex], pointIndex) / this.yValueTotal)); + + // Check for minimum segment height + height = CheckMinHeight(height); + + // Get intersection point of the horizontal line at the start of the segment + // with the left pre-defined wall of the funnel. + PointF startIntersection = ChartGraphics.GetLinesIntersection( + plotAreaPositionAbs.X, location, + plotAreaPositionAbs.Right, location, + plotAreaPositionAbs.X, plotAreaPositionAbs.Y, + plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f - this._funnelNeckSize.Width / 2f, + plotAreaPositionAbs.Bottom - this._funnelNeckSize.Height ); + + // Get intersection point of the horizontal line at the end of the segment + // with the left pre-defined wall of the funnel. + PointF endIntersection = ChartGraphics.GetLinesIntersection( + plotAreaPositionAbs.X, location + height, + plotAreaPositionAbs.Right, location + height, + plotAreaPositionAbs.X, plotAreaPositionAbs.Y, + plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f - this._funnelNeckSize.Width / 2f, + plotAreaPositionAbs.Bottom - this._funnelNeckSize.Height ); + + // Get segment start and end width + startWidth = (float)( plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f - + startIntersection.X) * 2f; + endWidth = (float)( plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f - + endIntersection.X) * 2f; + + // Set point position for annotation anchoring + pointPositionAbs = new PointF( + plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f, + location + height / 2f); + } + else + { + throw (new InvalidOperationException(SR.ExceptionFunnelStyleUnknown(this._funnelStyle.ToString()))); + } + + // Set pre-calculated point position + series.Points[pointIndex].positionRel = Graph.GetRelativePoint(pointPositionAbs); + } + + /// + /// Checks if first point in the series should be drawn. + /// When point Y value is used to define the diameter of the funnel + /// segment 2 points are required to draw 1 segment. In this case first + /// data point is not drawn. + /// + /// True if first point in the series should be drawn. + protected virtual bool ShouldDrawFirstPoint() + { + return ( this._funnelStyle == FunnelStyle.YIsHeight || this.isPyramid); + } + + /// + /// Draws funnel 3D square segment. + /// + /// Data point + /// Data point index. + /// Segment top width. + /// Segment bottom width. + /// Segment top location. + /// Segment height. + /// True if nothing is on the top of that segment. + /// True if nothing is on the bottom of that segment. + /// True if segment shadow should be drawn. + /// True if segment shadow should be drawn. + private void DrawFunnel3DSquareSegment( + DataPoint point, + int pointIndex, + float startWidth, + float endWidth, + float location, + float height, + bool nothingOnTop, + bool nothingOnBottom, + bool drawSegment, + bool drawSegmentShadow) + { + // Increase the height of the segment to make sure there is no gaps between segments + if(!nothingOnBottom) + { + height += 0.3f; + } + + // Get lighter and darker back colors + Color lightColor = ChartGraphics.GetGradientColor( point.Color, Color.White, 0.3 ); + Color darkColor = ChartGraphics.GetGradientColor( point.Color, Color.Black, 0.3 ); + + // Segment width can't be smaller than funnel neck width + if( this._funnelStyle == FunnelStyle.YIsHeight && !this.isPyramid ) + { + if(startWidth < this._funnelNeckSize.Width) + { + startWidth = this._funnelNeckSize.Width; + } + if(endWidth < this._funnelNeckSize.Width) + { + endWidth = this._funnelNeckSize.Width; + } + } + + // Get 3D rotation angle + float topRotationHeight = (float)( (startWidth / 2f) * Math.Sin(this._rotation3D / 180F * Math.PI) ); + float bottomRotationHeight = (float)( (endWidth / 2f) * Math.Sin(this._rotation3D / 180F * Math.PI) ); + + // Get plotting area position in pixels + RectangleF plotAreaPositionAbs = this.Graph.GetAbsoluteRectangle(this.PlotAreaPosition); + + // Get the horizontal center point in pixels + float xCenterPointAbs = plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f; + + // Start Svg Selection mode + this.Graph.StartHotRegion( point ); + + // Create segment path + GraphicsPath segmentPath = new GraphicsPath(); + + // Draw left part of the pyramid segment + // Add top line + if(startWidth > 0f) + { + segmentPath.AddLine( + xCenterPointAbs - startWidth / 2f, location, + xCenterPointAbs, location + topRotationHeight); + } + + // Add middle line + segmentPath.AddLine( + xCenterPointAbs, location + topRotationHeight, + xCenterPointAbs, location + height + bottomRotationHeight); + + // Add bottom line + if(endWidth > 0f) + { + segmentPath.AddLine( + xCenterPointAbs, location + height + bottomRotationHeight, + xCenterPointAbs - endWidth / 2f, location + height); + } + + // Add left line + segmentPath.AddLine( + xCenterPointAbs - endWidth / 2f, location + height, + xCenterPointAbs - startWidth / 2f, location); + + if( this.Common.ProcessModePaint ) + { + // Fill graphics path + this.Graph.DrawPathAbs( + segmentPath, + (drawSegment) ? lightColor : Color.Transparent, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + (drawSegment) ? point.BackSecondaryColor : Color.Transparent, + (drawSegment) ? point.BorderColor : Color.Transparent, + point.BorderWidth, + point.BorderDashStyle, + PenAlignment.Center, + (drawSegmentShadow) ? point.series.ShadowOffset : 0, + point.series.ShadowColor); + } + + if( this.Common.ProcessModeRegions ) + { + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + segmentPath, + false, + this.Graph, + point, + point.series.Name, + pointIndex); + } + segmentPath.Dispose(); + + + + // Draw right part of the pyramid segment + // Add top line + segmentPath = new GraphicsPath(); + if(startWidth > 0f) + { + segmentPath.AddLine( + xCenterPointAbs + startWidth / 2f, location, + xCenterPointAbs, location + topRotationHeight); + } + + // Add middle line + segmentPath.AddLine( + xCenterPointAbs, location + topRotationHeight, + xCenterPointAbs, location + height + bottomRotationHeight); + + // Add bottom line + if(endWidth > 0f) + { + segmentPath.AddLine( + xCenterPointAbs, location + height + bottomRotationHeight, + xCenterPointAbs + endWidth / 2f, location + height); + } + + // Add right line + segmentPath.AddLine( + xCenterPointAbs + endWidth / 2f, location + height, + xCenterPointAbs + startWidth / 2f, location); + + if( this.Common.ProcessModePaint ) + { + // Fill graphics path + this.Graph.DrawPathAbs( + segmentPath, + (drawSegment) ? darkColor : Color.Transparent, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + (drawSegment) ? point.BackSecondaryColor : Color.Transparent, + (drawSegment) ? point.BorderColor : Color.Transparent, + point.BorderWidth, + point.BorderDashStyle, + PenAlignment.Center, + (drawSegmentShadow) ? point.series.ShadowOffset : 0, + point.series.ShadowColor); + } + + if( this.Common.ProcessModeRegions ) + { + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + segmentPath, + false, + this.Graph, + point, + point.series.Name, + pointIndex); + } + segmentPath.Dispose(); + + + // Add top 3D surface + if(this._rotation3D > 0f && startWidth > 0f && nothingOnTop) + { + if(this.Area.Area3DStyle.Enable3D) + { + PointF[] sidePoints = new PointF[4]; + sidePoints[0] = new PointF(xCenterPointAbs + startWidth / 2f, location); + sidePoints[1] = new PointF(xCenterPointAbs, location + topRotationHeight); + sidePoints[2] = new PointF(xCenterPointAbs - startWidth / 2f, location); + sidePoints[3] = new PointF(xCenterPointAbs, location - topRotationHeight); + GraphicsPath topCurve = new GraphicsPath(); + topCurve.AddLines(sidePoints); + topCurve.CloseAllFigures(); + + if( this.Common.ProcessModePaint ) + { + // Fill graphics path + this.Graph.DrawPathAbs( + topCurve, + (drawSegment) ? ChartGraphics.GetGradientColor( point.Color, Color.Black, 0.4 ) : Color.Transparent, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + (drawSegment) ? point.BackSecondaryColor : Color.Transparent, + (drawSegment) ? point.BorderColor : Color.Transparent, + point.BorderWidth, + point.BorderDashStyle, + PenAlignment.Center, + (drawSegmentShadow) ? point.series.ShadowOffset : 0, + point.series.ShadowColor); + } + + if( this.Common.ProcessModeRegions ) + { + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + topCurve, + false, + this.Graph, + point, + point.series.Name, + pointIndex); + } + topCurve.Dispose(); + } + } + + // Add bottom 3D surface + if(this._rotation3D < 0f && startWidth > 0f && nothingOnBottom) + { + if(this.Area.Area3DStyle.Enable3D) + { + PointF[] sidePoints = new PointF[4]; + sidePoints[0] = new PointF(xCenterPointAbs + endWidth / 2f, location + height); + sidePoints[1] = new PointF(xCenterPointAbs, location + height + bottomRotationHeight); + sidePoints[2] = new PointF(xCenterPointAbs - endWidth / 2f, location + height); + sidePoints[3] = new PointF(xCenterPointAbs, location + height - bottomRotationHeight); + GraphicsPath topCurve = new GraphicsPath(); + topCurve.AddLines(sidePoints); + topCurve.CloseAllFigures(); + + if( this.Common.ProcessModePaint ) + { + // Fill graphics path + this.Graph.DrawPathAbs( + topCurve, + (drawSegment) ? ChartGraphics.GetGradientColor( point.Color, Color.Black, 0.4 ) : Color.Transparent, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + (drawSegment) ? point.BackSecondaryColor : Color.Transparent, + (drawSegment) ? point.BorderColor : Color.Transparent, + point.BorderWidth, + point.BorderDashStyle, + PenAlignment.Center, + (drawSegmentShadow) ? point.series.ShadowOffset : 0, + point.series.ShadowColor); + } + + if( this.Common.ProcessModeRegions ) + { + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + topCurve, + false, + this.Graph, + point, + point.series.Name, + pointIndex); + } + topCurve.Dispose(); + + } + } + + // End Svg Selection mode + this.Graph.EndHotRegion( ); + } + + /// + /// Draws funnel segment. + /// + /// Data point + /// Data point index. + /// Segment top width. + /// Segment bottom width. + /// Segment top location. + /// Segment height. + /// True if nothing is on the top of that segment. + /// True if nothing is on the bottom of that segment. + /// True if segment shadow should be drawn. + /// True if segment shadow should be drawn. + private void DrawFunnelCircularSegment( + DataPoint point, + int pointIndex, + float startWidth, + float endWidth, + float location, + float height, + bool nothingOnTop, + bool nothingOnBottom, + bool drawSegment, + bool drawSegmentShadow) + { + PointF leftSideLinePoint = PointF.Empty; + PointF rightSideLinePoint = PointF.Empty; + + // Check if square 3D segment should be drawn + if(this.Area.Area3DStyle.Enable3D && !round3DShape) + { + DrawFunnel3DSquareSegment( + point, + pointIndex, + startWidth, + endWidth, + location, + height, + nothingOnTop, + nothingOnBottom, + drawSegment, + drawSegmentShadow); + return; + } + + // Increase the height of the segment to make sure there is no gaps between segments + if(!nothingOnBottom) + { + height += 0.3f; + } + + // Segment width can't be smaller than funnel neck width + float originalStartWidth = startWidth; + float originalEndWidth = endWidth; + if( this._funnelStyle == FunnelStyle.YIsHeight && !this.isPyramid) + { + if(startWidth < this._funnelNeckSize.Width) + { + startWidth = this._funnelNeckSize.Width; + } + if(endWidth < this._funnelNeckSize.Width) + { + endWidth = this._funnelNeckSize.Width; + } + } + + // Get 3D rotation angle + float tension = 0.8f; + float topRotationHeight = (float)( (startWidth / 2f) * Math.Sin(this._rotation3D / 180F * Math.PI) ); + float bottomRotationHeight = (float)( (endWidth / 2f) * Math.Sin(this._rotation3D / 180F * Math.PI) ); + + // Get plotting area position in pixels + RectangleF plotAreaPositionAbs = this.Graph.GetAbsoluteRectangle(this.PlotAreaPosition); + + // Get the horizontal center point in pixels + float xCenterPointAbs = plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f; + + // Start Svg Selection mode + this.Graph.StartHotRegion( point ); + + // Create segment path + GraphicsPath segmentPath = new GraphicsPath(); + + // Add top line + if(startWidth > 0f) + { + if(this.Area.Area3DStyle.Enable3D) + { + PointF[] sidePoints = new PointF[4]; + sidePoints[0] = new PointF(xCenterPointAbs + startWidth / 2f, location); + sidePoints[1] = new PointF(xCenterPointAbs, location + topRotationHeight); + sidePoints[2] = new PointF(xCenterPointAbs - startWidth / 2f, location); + sidePoints[3] = new PointF(xCenterPointAbs, location - topRotationHeight); + GraphicsPath topCurve = new GraphicsPath(); + topCurve.AddClosedCurve(sidePoints, tension); + topCurve.Flatten(); + topCurve.Reverse(); + + Graph.AddEllipseSegment( + segmentPath, + topCurve, + null, + true, + 0f, + out leftSideLinePoint, + out rightSideLinePoint); + } + else + { + segmentPath.AddLine( + xCenterPointAbs - startWidth / 2f, location, + xCenterPointAbs + startWidth / 2f, location); + } + } + + // Add right line + if( this._funnelStyle == FunnelStyle.YIsHeight && + !this.isPyramid && + startWidth > this._funnelNeckSize.Width && + endWidth <= this._funnelNeckSize.Width) + { + // Get intersection point of the vertical line at the neck border + // with the left pre-defined wall of the funnel. + PointF intersection = ChartGraphics.GetLinesIntersection( + xCenterPointAbs + this._funnelNeckSize.Width / 2f, plotAreaPositionAbs.Top, + xCenterPointAbs + this._funnelNeckSize.Width / 2f, plotAreaPositionAbs.Bottom, + xCenterPointAbs + originalStartWidth / 2f, location, + xCenterPointAbs + originalEndWidth / 2f, location + height); + + // Adjust intersection point with top of the neck + intersection.Y = plotAreaPositionAbs.Bottom - this._funnelNeckSize.Height; + + // Add two segment line + segmentPath.AddLine( + xCenterPointAbs + startWidth / 2f, location, + intersection.X, intersection.Y); + segmentPath.AddLine( + intersection.X, intersection.Y, + intersection.X, location + height); + } + else + { + // Add straight line + segmentPath.AddLine( + xCenterPointAbs + startWidth / 2f, location, + xCenterPointAbs + endWidth / 2f, location + height); + } + + // Add bottom line + if(endWidth > 0f) + { + if(this.Area.Area3DStyle.Enable3D) + { + PointF[] sidePoints = new PointF[4]; + sidePoints[0] = new PointF(xCenterPointAbs + endWidth / 2f, location + height); + sidePoints[1] = new PointF(xCenterPointAbs, location + height + bottomRotationHeight); + sidePoints[2] = new PointF(xCenterPointAbs - endWidth / 2f, location + height); + sidePoints[3] = new PointF(xCenterPointAbs, location + height - bottomRotationHeight); + GraphicsPath topCurve = new GraphicsPath(); + topCurve.AddClosedCurve(sidePoints, tension); + topCurve.Flatten(); + topCurve.Reverse(); + + using (GraphicsPath tmp = new GraphicsPath()) + { + Graph.AddEllipseSegment( + tmp, + topCurve, + null, + true, + 0f, + out leftSideLinePoint, + out rightSideLinePoint); + + tmp.Reverse(); + if (tmp.PointCount > 0) + { + segmentPath.AddPath(tmp, false); + } + } + } + else + { + segmentPath.AddLine( + xCenterPointAbs + endWidth / 2f, location + height, + xCenterPointAbs - endWidth / 2f, location + height); + } + } + + // Add left line + if( this._funnelStyle == FunnelStyle.YIsHeight && + !this.isPyramid && + startWidth > this._funnelNeckSize.Width && + endWidth <= this._funnelNeckSize.Width) + { + // Get intersection point of the horizontal line at the start of the segment + // with the left pre-defined wall of the funnel. + PointF intersection = ChartGraphics.GetLinesIntersection( + xCenterPointAbs - this._funnelNeckSize.Width / 2f, plotAreaPositionAbs.Top, + xCenterPointAbs - this._funnelNeckSize.Width / 2f, plotAreaPositionAbs.Bottom, + xCenterPointAbs - originalStartWidth / 2f, location, + xCenterPointAbs - originalEndWidth / 2f, location + height); + + // Adjust intersection point with top of the neck + intersection.Y = plotAreaPositionAbs.Bottom - this._funnelNeckSize.Height; + + // Add two segment line + segmentPath.AddLine( + intersection.X, location + height, + intersection.X, intersection.Y); + segmentPath.AddLine( + intersection.X, intersection.Y, + xCenterPointAbs - startWidth / 2f, location); + } + else + { + segmentPath.AddLine( + xCenterPointAbs - endWidth / 2f, location + height, + xCenterPointAbs - startWidth / 2f, location); + } + + if( this.Common.ProcessModePaint ) + { + // Draw lightStyle source blink effect in 3D + if(this.Area.Area3DStyle.Enable3D && + Graph.ActiveRenderingType == RenderingType.Gdi ) + { + // Get lighter and darker back colors + Color lightColor = ChartGraphics.GetGradientColor( point.Color, Color.White, 0.3 ); + Color darkColor = ChartGraphics.GetGradientColor( point.Color, Color.Black, 0.3 ); + + // Create linear gradient brush + RectangleF boundsRect = segmentPath.GetBounds(); + if(boundsRect.Width == 0f) + { + boundsRect.Width = 1f; + } + if(boundsRect.Height == 0f) + { + boundsRect.Height = 1f; + } + using( LinearGradientBrush brush = new LinearGradientBrush( + boundsRect, + lightColor, + darkColor, + 0f) ) + { + // Set linear gradient brush interpolation colors + ColorBlend colorBlend = new ColorBlend(5); + colorBlend.Colors[0] = darkColor; + colorBlend.Colors[1] = darkColor; + colorBlend.Colors[2] = lightColor; + colorBlend.Colors[3] = darkColor; + colorBlend.Colors[4] = darkColor; + + colorBlend.Positions[0] = 0.0f; + colorBlend.Positions[1] = 0.0f; + colorBlend.Positions[2] = 0.5f; + colorBlend.Positions[3] = 1.0f; + colorBlend.Positions[4] = 1.0f; + + brush.InterpolationColors = colorBlend; + + // Fill path + this.Graph.Graphics.FillPath(brush, segmentPath); + + // Draw path border + Pen pen = new Pen(point.BorderColor, point.BorderWidth); + pen.DashStyle = this.Graph.GetPenStyle( point.BorderDashStyle ); + if(point.BorderWidth == 0 || + point.BorderDashStyle == ChartDashStyle.NotSet || + point.BorderColor == Color.Empty) + { + // Draw line of the darker color inside the cylinder + pen = new Pen(ChartGraphics.GetGradientColor( point.Color, Color.Black, 0.3 ), 1); + pen.Alignment = PenAlignment.Inset; + } + + pen.StartCap = LineCap.Round; + pen.EndCap = LineCap.Round; + pen.LineJoin = LineJoin.Bevel; + this.Graph.DrawPath(pen, segmentPath ); + pen.Dispose(); + } + } + else + { + // Fill graphics path + this.Graph.DrawPathAbs( + segmentPath, + (drawSegment) ? point.Color : Color.Transparent, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + (drawSegment) ? point.BackSecondaryColor : Color.Transparent, + (drawSegment) ? point.BorderColor : Color.Transparent, + point.BorderWidth, + point.BorderDashStyle, + PenAlignment.Center, + (drawSegmentShadow) ? point.series.ShadowOffset : 0, + point.series.ShadowColor); + } + } + + if( this.Common.ProcessModeRegions ) + { + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + segmentPath, + false, + this.Graph, + point, + point.series.Name, + pointIndex); + } + segmentPath.Dispose(); + + + // Add top 3D surface + if(this._rotation3D > 0f && startWidth > 0f && nothingOnTop) + { + if(this.Area.Area3DStyle.Enable3D) + { + PointF[] sidePoints = new PointF[4]; + sidePoints[0] = new PointF(xCenterPointAbs + startWidth / 2f, location); + sidePoints[1] = new PointF(xCenterPointAbs, location + topRotationHeight); + sidePoints[2] = new PointF(xCenterPointAbs - startWidth / 2f, location); + sidePoints[3] = new PointF(xCenterPointAbs, location - topRotationHeight); + GraphicsPath topCurve = new GraphicsPath(); + topCurve.AddClosedCurve(sidePoints, tension); + + if( this.Common.ProcessModePaint ) + { + // Fill graphics path + this.Graph.DrawPathAbs( + topCurve, + (drawSegment) ? ChartGraphics.GetGradientColor( point.Color, Color.Black, 0.4 ) : Color.Transparent, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + (drawSegment) ? point.BackSecondaryColor : Color.Transparent, + (drawSegment) ? point.BorderColor : Color.Transparent, + point.BorderWidth, + point.BorderDashStyle, + PenAlignment.Center, + (drawSegmentShadow) ? point.series.ShadowOffset : 0, + point.series.ShadowColor); + } + + if( this.Common.ProcessModeRegions ) + { + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + topCurve, + false, + this.Graph, + point, + point.series.Name, + pointIndex); + } + topCurve.Dispose(); + } + } + + // Add bottom 3D surface + if(this._rotation3D < 0f && startWidth > 0f && nothingOnBottom) + { + if(this.Area.Area3DStyle.Enable3D) + { + PointF[] sidePoints = new PointF[4]; + sidePoints[0] = new PointF(xCenterPointAbs + endWidth / 2f, location + height); + sidePoints[1] = new PointF(xCenterPointAbs, location + height + bottomRotationHeight); + sidePoints[2] = new PointF(xCenterPointAbs - endWidth / 2f, location + height); + sidePoints[3] = new PointF(xCenterPointAbs, location + height - bottomRotationHeight); + GraphicsPath topCurve = new GraphicsPath(); + topCurve.AddClosedCurve(sidePoints, tension); + + if( this.Common.ProcessModePaint ) + { + // Fill graphics path + this.Graph.DrawPathAbs( + topCurve, + (drawSegment) ? ChartGraphics.GetGradientColor( point.Color, Color.Black, 0.4 ) : Color.Transparent, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + (drawSegment) ? point.BackSecondaryColor : Color.Transparent, + (drawSegment) ? point.BorderColor : Color.Transparent, + point.BorderWidth, + point.BorderDashStyle, + PenAlignment.Center, + (drawSegmentShadow) ? point.series.ShadowOffset : 0, + point.series.ShadowColor); + } + + if( this.Common.ProcessModeRegions ) + { + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + topCurve, + false, + this.Graph, + point, + point.series.Name, + pointIndex); + } + topCurve.Dispose(); + + } + } + + // End Svg Selection mode + this.Graph.EndHotRegion( ); + } + + + /// + /// Fill list with information about every segment of the funnel. + /// + /// Funnel segment information list. + private ArrayList GetFunnelSegmentPositions() + { + // Create new list + ArrayList list = new ArrayList(); + + // Funnel chart process only first series in the chart area + // and cannot be combined with any other chart types. + Series series = GetDataSeries(); + if( series != null ) + { + // Get funnel drawing style + this._funnelStyle = GetFunnelStyle(series); + + // Check if round or square base is used in 3D chart + this.round3DShape = (GetFunnel3DDrawingStyle(series) == Funnel3DDrawingStyle.CircularBase); + + // Get funnel points gap + this.funnelSegmentGap = GetFunnelPointGap(series); + + // Get funnel neck size + this._funnelNeckSize = GetFunnelNeckSize(series); + + // Loop through all ponts in the data series + float currentLocation = this.Graph.GetAbsolutePoint(this.PlotAreaPosition.Location).Y; + if(this.isPyramid) + { + // Pyramid is drawn in reversed order. + currentLocation = this.Graph.GetAbsoluteRectangle(this.PlotAreaPosition).Bottom; + } + for( int pointIndex = 0; pointIndex >= 0 && pointIndex < series.Points.Count; pointIndex += 1 ) + { + DataPoint point = series.Points[pointIndex]; + + // Check if first data point should be drawn + if( pointIndex > 0 || ShouldDrawFirstPoint() ) + { + // Get height and width of each data point segment + float startWidth = 0f; + float endWidth = 0f; + float height = 0f; + GetPointWidthAndHeight( + series, + pointIndex, + currentLocation, + out height, + out startWidth, + out endWidth); + + // Check visibility of previous and next points + bool nothingOnTop = false; + bool nothingOnBottom = false; + if(this.funnelSegmentGap > 0) + { + nothingOnTop = true; + nothingOnBottom = true; + } + else + { + if(ShouldDrawFirstPoint()) + { + if(pointIndex == 0 || + series.Points[pointIndex-1].Color.A != 255) + { + if(this.isPyramid) + { + nothingOnBottom = true; + } + else + { + nothingOnTop = true; + } + } + } + else + { + if(pointIndex == 1 || + series.Points[pointIndex-1].Color.A != 255) + { + if(this.isPyramid) + { + nothingOnBottom = true; + } + else + { + nothingOnTop = true; + } + } + } + if( pointIndex == series.Points.Count - 1) + { + if(this.isPyramid) + { + nothingOnTop = true; + } + else + { + nothingOnBottom = true; + } + } + else if(series.Points[pointIndex+1].Color.A != 255) + { + if(this.isPyramid) + { + nothingOnTop = true; + } + else + { + nothingOnBottom = true; + } + } + } + + // Add segment information + FunnelSegmentInfo info = new FunnelSegmentInfo(); + info.Point = point; + info.PointIndex = pointIndex; + info.StartWidth = startWidth; + info.EndWidth = endWidth; + info.Location = (this.isPyramid) ? currentLocation - height : currentLocation; + info.Height = height; + info.NothingOnTop = nothingOnTop; + info.NothingOnBottom = nothingOnBottom; + list.Add(info); + + // Increase current Y location + if(this.isPyramid) + { + currentLocation -= height + this.funnelSegmentGap; + } + else + { + currentLocation += height + this.funnelSegmentGap; + } + } + } + } + + return list; + } + + #endregion + + #region Labels Methods + + /// + /// Draws funnel data point labels. + /// + private void DrawLabels() + { + // Loop through all labels + foreach(FunnelPointLabelInfo labelInfo in this.labelInfoList) + { + if(!labelInfo.Position.IsEmpty && + !float.IsNaN(labelInfo.Position.X) && + !float.IsNaN(labelInfo.Position.Y) && + !float.IsNaN(labelInfo.Position.Width) && + !float.IsNaN(labelInfo.Position.Height) ) + { + // Start Svg Selection mode + this.Graph.StartHotRegion( labelInfo.Point ); + + // Get size of a single character used for spacing + SizeF spacing = this.Graph.MeasureString( + "W", + labelInfo.Point.Font, + new SizeF(1000f, 1000F), + StringFormat.GenericTypographic ); + + // Draw a callout line + if( !labelInfo.CalloutPoint1.IsEmpty && + !labelInfo.CalloutPoint2.IsEmpty && + !float.IsNaN(labelInfo.CalloutPoint1.X) && + !float.IsNaN(labelInfo.CalloutPoint1.Y) && + !float.IsNaN(labelInfo.CalloutPoint2.X) && + !float.IsNaN(labelInfo.CalloutPoint2.Y) ) + { + // Add spacing between text and callout line + if(labelInfo.OutsidePlacement == FunnelLabelPlacement.Right) + { + labelInfo.CalloutPoint2.X -= spacing.Width / 2f; + + // Add a small spacing between a callout line and a segment + labelInfo.CalloutPoint1.X += 2; + } + else + { + labelInfo.CalloutPoint2.X += spacing.Width / 2f; + + // Add a small spacing between a callout line and a segment + labelInfo.CalloutPoint1.X += 2; + } + + // Get callout line color + Color lineColor = GetCalloutLineColor(labelInfo.Point); + + // Draw callout line + this.Graph.DrawLineAbs( + lineColor, + 1, + ChartDashStyle.Solid, + labelInfo.CalloutPoint1, + labelInfo.CalloutPoint2 ); + + } + + // Get label background position + RectangleF labelBackPosition = labelInfo.Position; + labelBackPosition.Inflate(spacing.Width / 2f, spacing.Height / 8f); + labelBackPosition = this.Graph.GetRelativeRectangle(labelBackPosition); + + // Center label in the middle of the background rectangle + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // Draw label text + using (Brush brush = new SolidBrush(labelInfo.Point.LabelForeColor)) + { + + this.Graph.DrawPointLabelStringRel( + this.Common, + labelInfo.Text, + labelInfo.Point.Font, + brush, + labelBackPosition, + format, + labelInfo.Point.LabelAngle, + labelBackPosition, + + labelInfo.Point.LabelBackColor, + labelInfo.Point.LabelBorderColor, + labelInfo.Point.LabelBorderWidth, + labelInfo.Point.LabelBorderDashStyle, + labelInfo.Point.series, + labelInfo.Point, + labelInfo.PointIndex); + } + + // End Svg Selection mode + this.Graph.EndHotRegion(); + } + } + } + } + + /// + /// Creates a list of structures with the data point labels information. + /// + /// Array list of labels information. + private ArrayList CreateLabelsInfoList() + { + ArrayList list = new ArrayList(); + + // Get area position in pixels + RectangleF plotAreaPositionAbs = this.Graph.GetAbsoluteRectangle( this.Area.Position.ToRectangleF() ); + + // Get funnel chart type series + Series series = GetDataSeries(); + if( series != null ) + { + // Loop through all ponts in the data series + int pointIndex = 0; + foreach( DataPoint point in series.Points ) + { + // Ignore empty points + if( !point.IsEmpty ) + { + // Get some properties for performance + string pointLabel = point.Label; + bool pointShowLabelAsValue = point.IsValueShownAsLabel; + + // Check if label text exists + if(pointShowLabelAsValue || pointLabel.Length > 0) + { + // Create new point label information class + FunnelPointLabelInfo labelInfo = new FunnelPointLabelInfo(); + labelInfo.Point = point; + labelInfo.PointIndex = pointIndex; + + // Get point label text + if( pointLabel.Length == 0 ) + { + labelInfo.Text = ValueConverter.FormatValue( + point.series.Chart, + point, + point.Tag, + point.YValues[0], + point.LabelFormat, + point.series.YValueType, + ChartElementType.DataPoint); + } + else + { + labelInfo.Text = point.ReplaceKeywords(pointLabel); + } + + // Get label style + labelInfo.Style = GetLabelStyle(point); + + // Get inside label vertical alignment + if(labelInfo.Style == FunnelLabelStyle.Inside) + { + labelInfo.VerticalAlignment = GetInsideLabelAlignment(point); + } + + // Get outside labels placement + if(labelInfo.Style != FunnelLabelStyle.Inside) + { + labelInfo.OutsidePlacement = GetOutsideLabelPlacement(point); + } + + // Measure string size + labelInfo.Size = this.Graph.MeasureString( + labelInfo.Text, + point.Font, + plotAreaPositionAbs.Size, + StringFormat.GenericTypographic); + + // Add label information into the list + if(labelInfo.Text.Length > 0 && + labelInfo.Style != FunnelLabelStyle.Disabled) + { + list.Add(labelInfo); + } + } + } + ++pointIndex; + } + } + return list; + } + + /// + /// Changes required plotting area spacing, so that all labels fit. + /// + /// Return True if no resizing required. + private bool FitPointLabels() + { + // Convert plotting area position to pixels. + // Make rectangle 4 pixels smaller on each side. + RectangleF plotAreaPositionAbs = this.Graph.GetAbsoluteRectangle(PlotAreaPosition); + plotAreaPositionAbs.Inflate(-4f, -4f); + + // Get position of each label + GetLabelsPosition(); + + // Get spacing required to draw labels + RectangleF requiredSpacing = this.Graph.GetAbsoluteRectangle( new RectangleF(1f, 1f, 1f, 1f) ); + foreach(FunnelPointLabelInfo labelInfo in this.labelInfoList) + { + // Add additional horizontal spacing for outside labels + RectangleF position = labelInfo.Position; + if(labelInfo.Style == FunnelLabelStyle.Outside || + labelInfo.Style == FunnelLabelStyle.OutsideInColumn) + { + float spacing = 10f; + if(labelInfo.OutsidePlacement == FunnelLabelPlacement.Right) + { + position.Width += spacing; + } + else if(labelInfo.OutsidePlacement == FunnelLabelPlacement.Left) + { + position.X -= spacing; + position.Width += spacing; + } + } + + // Horizontal coordinates are ignored for Inside label style + if(labelInfo.Style != FunnelLabelStyle.Inside) + { + if( (plotAreaPositionAbs.X - position.X) > requiredSpacing.X ) + { + requiredSpacing.X = plotAreaPositionAbs.X - position.X; + } + + if( (position.Right - plotAreaPositionAbs.Right) > requiredSpacing.Width ) + { + requiredSpacing.Width = position.Right - plotAreaPositionAbs.Right; + } + } + + // Vertical spacing + if( (plotAreaPositionAbs.Y - position.Y) > requiredSpacing.Y ) + { + requiredSpacing.Y = plotAreaPositionAbs.Y - position.Y; + } + + if( (position.Bottom - plotAreaPositionAbs.Bottom) > requiredSpacing.Height ) + { + requiredSpacing.Height = position.Bottom - plotAreaPositionAbs.Bottom; + } + } + + // Convert spacing rectangle to relative coordinates + requiredSpacing = this.Graph.GetRelativeRectangle(requiredSpacing); + + // Check if non-default spacing was used + if(requiredSpacing.X > 1f || + requiredSpacing.Y > 1f || + requiredSpacing.Width > 1f || + requiredSpacing.Height > 1f ) + { + this.plotAreaSpacing = requiredSpacing; + + // Get NEW plotting area position + this.PlotAreaPosition = GetPlotAreaPosition(); + + // Get NEW list of segments + this.segmentList = GetFunnelSegmentPositions(); + + // Get NEW position of each label + GetLabelsPosition(); + + return false; + } + + return true; + } + + /// + /// Loops through the point labels list and calculates labels position + /// based on their size, position and funnel chart shape. + /// + private void GetLabelsPosition() + { + // Convert plotting area position to pixels + RectangleF plotAreaPositionAbs = this.Graph.GetAbsoluteRectangle(PlotAreaPosition); + float plotAreaCenterXAbs = plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f; + + // Define label spacing + SizeF labelSpacing = new SizeF(3f, 3f); + + //Loop through all labels + foreach(FunnelPointLabelInfo labelInfo in this.labelInfoList) + { + // Get ----osiated funnel segment information + bool lastLabel = false; + int pointIndex = labelInfo.PointIndex + ((ShouldDrawFirstPoint()) ? 0 : 1); + if(pointIndex > this.segmentList.Count && !ShouldDrawFirstPoint() ) + { + // Use last point index if first point is not drawn + pointIndex = this.segmentList.Count; + lastLabel = true; + } + FunnelSegmentInfo segmentInfo = null; + foreach(FunnelSegmentInfo info in this.segmentList) + { + if(info.PointIndex == pointIndex) + { + segmentInfo = info; + break; + } + } + + // Check if segment was found + if(segmentInfo != null) + { + // Set label width and height + labelInfo.Position.Width = labelInfo.Size.Width; + labelInfo.Position.Height = labelInfo.Size.Height; + + //****************************************************** + //** Labels are placed OUTSIDE of the funnel + //****************************************************** + if(labelInfo.Style == FunnelLabelStyle.Outside || + labelInfo.Style == FunnelLabelStyle.OutsideInColumn) + { + // Define position + if( this._funnelStyle == FunnelStyle.YIsHeight ) + { + // Get segment top and bottom diameter + float topDiameter = segmentInfo.StartWidth; + float bottomDiameter = segmentInfo.EndWidth; + if(!this.isPyramid) + { + if(topDiameter < this._funnelNeckSize.Width) + { + topDiameter = this._funnelNeckSize.Width; + } + if(bottomDiameter < this._funnelNeckSize.Width) + { + bottomDiameter = this._funnelNeckSize.Width; + } + + // Adjust label position because segment is bent to make a neck + if(segmentInfo.StartWidth >= this._funnelNeckSize.Width && + segmentInfo.EndWidth < this._funnelNeckSize.Width) + { + bottomDiameter = segmentInfo.EndWidth; + } + } + + // Get Y position + labelInfo.Position.Y = (segmentInfo.Location + segmentInfo.Height / 2f) - + labelInfo.Size.Height / 2f; + + // Get X position + if(labelInfo.Style == FunnelLabelStyle.OutsideInColumn) + { + if(labelInfo.OutsidePlacement == FunnelLabelPlacement.Right) + { + labelInfo.Position.X = plotAreaPositionAbs.Right + + 4f * labelSpacing.Width; + + // Set callout line coordinates + if(!this.isPyramid) + { + labelInfo.CalloutPoint1.X = plotAreaCenterXAbs + + Math.Max(this._funnelNeckSize.Width/2f, (topDiameter + bottomDiameter) / 4f); + } + else + { + labelInfo.CalloutPoint1.X = plotAreaCenterXAbs + + (topDiameter + bottomDiameter) / 4f; + } + labelInfo.CalloutPoint2.X = labelInfo.Position.X; + } + else + { + labelInfo.Position.X = plotAreaPositionAbs.X - + labelInfo.Size.Width - + 4f * labelSpacing.Width; + + // Set callout line coordinates + if(!this.isPyramid) + { + labelInfo.CalloutPoint1.X = plotAreaCenterXAbs - + Math.Max(this._funnelNeckSize.Width/2f, (topDiameter + bottomDiameter) / 4f); + } + else + { + labelInfo.CalloutPoint1.X = plotAreaCenterXAbs - + (topDiameter + bottomDiameter) / 4f; + } + labelInfo.CalloutPoint2.X = labelInfo.Position.Right; + } + + // Fill rest of coordinates required for the callout line + labelInfo.CalloutPoint1.Y = segmentInfo.Location + segmentInfo.Height / 2f; + labelInfo.CalloutPoint2.Y = labelInfo.CalloutPoint1.Y; + } + else + { + if(labelInfo.OutsidePlacement == FunnelLabelPlacement.Right) + { + labelInfo.Position.X = plotAreaCenterXAbs + + (topDiameter + bottomDiameter) / 4f + + 4f * labelSpacing.Width; + } + else + { + labelInfo.Position.X = plotAreaCenterXAbs - + labelInfo.Size.Width - + (topDiameter + bottomDiameter) / 4f - + 4f * labelSpacing.Width; + } + } + } + else + { + // Use bottom part of the segment for the last point + if(lastLabel) + { + if(labelInfo.OutsidePlacement == FunnelLabelPlacement.Right) + { + labelInfo.Position.X = plotAreaCenterXAbs + + segmentInfo.EndWidth / 2f + + 4f * labelSpacing.Width; + } + else + { + labelInfo.Position.X = plotAreaCenterXAbs - + labelInfo.Size.Width - + segmentInfo.EndWidth / 2f - + 4f * labelSpacing.Width; + } + labelInfo.Position.Y = segmentInfo.Location + + segmentInfo.Height - + labelInfo.Size.Height / 2f; + } + else + { + if(labelInfo.OutsidePlacement == FunnelLabelPlacement.Right) + { + labelInfo.Position.X = plotAreaCenterXAbs + + segmentInfo.StartWidth / 2f + + 4f * labelSpacing.Width; + } + else + { + labelInfo.Position.X = plotAreaCenterXAbs - + labelInfo.Size.Width - + segmentInfo.StartWidth / 2f - + 4f * labelSpacing.Width; + } + labelInfo.Position.Y = segmentInfo.Location - + labelInfo.Size.Height / 2f; + } + + if(labelInfo.Style == FunnelLabelStyle.OutsideInColumn) + { + if(labelInfo.OutsidePlacement == FunnelLabelPlacement.Right) + { + labelInfo.Position.X = plotAreaPositionAbs.Right + + 4f * labelSpacing.Width; + + // Set callout line coordinates + labelInfo.CalloutPoint1.X = plotAreaCenterXAbs + + ( (lastLabel) ? segmentInfo.EndWidth : segmentInfo.StartWidth) / 2f; + labelInfo.CalloutPoint2.X = labelInfo.Position.X; + + } + else + { + labelInfo.Position.X = plotAreaPositionAbs.X - + labelInfo.Size.Width - + 4f * labelSpacing.Width; + + // Set callout line coordinates + labelInfo.CalloutPoint1.X = plotAreaCenterXAbs - + ( (lastLabel) ? segmentInfo.EndWidth : segmentInfo.StartWidth) / 2f; + labelInfo.CalloutPoint2.X = labelInfo.Position.Right; + } + + // Fill rest of coordinates required for the callout line + labelInfo.CalloutPoint1.Y = segmentInfo.Location; + if(lastLabel) + { + labelInfo.CalloutPoint1.Y += segmentInfo.Height; + } + labelInfo.CalloutPoint2.Y = labelInfo.CalloutPoint1.Y; + + } + } + } + + //****************************************************** + //** Labels are placed INSIDE of the funnel + //****************************************************** + else if(labelInfo.Style == FunnelLabelStyle.Inside) + { + // Define position + labelInfo.Position.X = plotAreaCenterXAbs - labelInfo.Size.Width / 2f; + if( this._funnelStyle == FunnelStyle.YIsHeight ) + { + labelInfo.Position.Y = (segmentInfo.Location + segmentInfo.Height / 2f) - + labelInfo.Size.Height / 2f; + if(labelInfo.VerticalAlignment == FunnelLabelVerticalAlignment.Top) + { + labelInfo.Position.Y -= segmentInfo.Height / 2f - labelInfo.Size.Height / 2f - labelSpacing.Height; + } + else if(labelInfo.VerticalAlignment == FunnelLabelVerticalAlignment.Bottom) + { + labelInfo.Position.Y += segmentInfo.Height / 2f - labelInfo.Size.Height / 2f - labelSpacing.Height; + } + } + else + { + labelInfo.Position.Y = segmentInfo.Location - labelInfo.Size.Height / 2f; + if(labelInfo.VerticalAlignment == FunnelLabelVerticalAlignment.Top) + { + labelInfo.Position.Y -= labelInfo.Size.Height / 2f + labelSpacing.Height; + } + else if(labelInfo.VerticalAlignment == FunnelLabelVerticalAlignment.Bottom) + { + labelInfo.Position.Y += labelInfo.Size.Height / 2f + labelSpacing.Height; + } + + // Use bottom part of the segment for the last point + if(lastLabel) + { + labelInfo.Position.Y += segmentInfo.Height; + } + } + + // Adjust label Y position in 3D + if(this.Area.Area3DStyle.Enable3D) + { + labelInfo.Position.Y += (float)( ( (segmentInfo.EndWidth + segmentInfo.StartWidth) / 4f) * Math.Sin(this._rotation3D / 180F * Math.PI) ); + } + } + + //****************************************************** + //** Check if label overlaps any previous label + //****************************************************** + int interation = 0; + while( IsLabelsOverlap(labelInfo) && interation < 1000) + { + float shiftSize = (this.isPyramid) ? -3f : 3f; + + // Move label down + labelInfo.Position.Y += shiftSize; + + // Move callout second point down + if(!labelInfo.CalloutPoint2.IsEmpty) + { + labelInfo.CalloutPoint2.Y += shiftSize; + } + + ++interation; + } + + } + } + } + + /// + /// Checks if specified label overlaps any previous labels. + /// + /// Label to test. + /// True if labels overlapp. + private bool IsLabelsOverlap(FunnelPointLabelInfo testLabelInfo) + { + // Increase rectangle size by 1 pixel + RectangleF rect = testLabelInfo.Position; + rect.Inflate(1f, 1f); + + // Increase label rectangle if border is drawn around the label + if(!testLabelInfo.Point.LabelBackColor.IsEmpty || + (testLabelInfo.Point.LabelBorderWidth > 0 && + !testLabelInfo.Point.LabelBorderColor.IsEmpty && + testLabelInfo.Point.LabelBorderDashStyle != ChartDashStyle.NotSet) ) + { + rect.Inflate(4f, 4f); + } + + //Loop through all labels + foreach(FunnelPointLabelInfo labelInfo in this.labelInfoList) + { + // Stop searching + if(labelInfo.PointIndex == testLabelInfo.PointIndex) + { + break; + } + + // Check if label position overlaps + if(!labelInfo.Position.IsEmpty && + labelInfo.Position.IntersectsWith(rect) ) + { + return true; + } + } + + return false; + } + + /// + /// Gets label style of the data point. + /// + /// Label style of the data point. + private FunnelLabelStyle GetLabelStyle(DataPointCustomProperties properties) + { + // Set default label style + FunnelLabelStyle labelStyle = FunnelLabelStyle.OutsideInColumn; + + // Get string value of the custom attribute + string attrValue = properties[this.funnelLabelStyleAttributeName]; + if(attrValue != null && attrValue.Length > 0) + { + // Convert string to the labels style + try + { + labelStyle = (FunnelLabelStyle)Enum.Parse(typeof(FunnelLabelStyle), attrValue, true); + } + catch + { + throw(new InvalidOperationException( SR.ExceptionCustomAttributeValueInvalid(labelStyle.ToString(), this.funnelLabelStyleAttributeName) ) ); + } + } + return labelStyle; + } + + #endregion // Labels Methods + + #region Position Methods + + /// + /// Calculate the spacing required for the labels. + /// + private void GetPlotAreaSpacing() + { + // Provide small spacing on the sides of chart area + this.plotAreaSpacing = new RectangleF(1f, 1f, 1f, 1f); + + // Get plotting area position + this.PlotAreaPosition = GetPlotAreaPosition(); + + // Get list of segments + this.segmentList = GetFunnelSegmentPositions(); + + // If plotting area position is automatic + if( Area.InnerPlotPosition.Auto ) + { + // Set a position so that data labels fit + // This method is called several time to adjust label position while + // funnel side angle is changed + int iteration = 0; + while(!FitPointLabels() && iteration < 5) + { + iteration++; + } + } + else + { + // Just get labels position + GetLabelsPosition(); + } + + } + + /// + /// Gets a rectangle in relative coordinates where the funnel will chart + /// will be drawn. + /// + /// Plotting are of the chart in relative coordinates. + private RectangleF GetPlotAreaPosition() + { + // Get plotting area rectangle position + RectangleF plotAreaPosition = ( Area.InnerPlotPosition.Auto ) ? + Area.Position.ToRectangleF() : Area.PlotAreaPosition.ToRectangleF(); + + // NOTE: Fixes issue #4085 + // Do not allow decreasing of the plot area height more than 50% + if(plotAreaSpacing.Y > plotAreaPosition.Height / 2f) + { + plotAreaSpacing.Y = plotAreaPosition.Height / 2f; + } + if(plotAreaSpacing.Height > plotAreaPosition.Height / 2f) + { + plotAreaSpacing.Height = plotAreaPosition.Height / 2f; + } + + // Decrease plotting are position using pre-calculated ratio + plotAreaPosition.X += plotAreaSpacing.X; + plotAreaPosition.Y += plotAreaSpacing.Y; + plotAreaPosition.Width -= plotAreaSpacing.X + plotAreaSpacing.Width; + plotAreaPosition.Height -= plotAreaSpacing.Y + plotAreaSpacing.Height; + + // Apply vertical spacing on top and bottom to fit the 3D surfaces + if(this.Area.Area3DStyle.Enable3D) + { + // Convert position to pixels + RectangleF plotAreaPositionAbs = this.Graph.GetAbsoluteRectangle(plotAreaPosition); + + // Funnel chart process only first series in the chart area + // and cannot be combined with any other chart types. + Series series = GetDataSeries(); + if( series != null ) + { + // Get 3D funnel rotation angle (from 10 to -10) + this._rotation3D = GetFunnelRotation(series); + } + + // Get top and bottom spacing + float topSpacing = (float)Math.Abs( (plotAreaPositionAbs.Width/ 2f) * Math.Sin(this._rotation3D / 180F * Math.PI) ); + float bottomSpacing = (float)Math.Abs( (plotAreaPositionAbs.Width/ 2f) * Math.Sin(this._rotation3D / 180F * Math.PI) ); + + // Adjust position + if(this.isPyramid) + { + // Only bottom spacing for the pyramid + plotAreaPositionAbs.Height -= bottomSpacing; + } + else + { + // Add top/bottom spacing + plotAreaPositionAbs.Y += topSpacing; + plotAreaPositionAbs.Height -= topSpacing + bottomSpacing; + } + + // Convert position back to relative coordinates + plotAreaPosition = this.Graph.GetRelativeRectangle(plotAreaPositionAbs); + } + + return plotAreaPosition; + } + + #endregion // Position Methods + + #region Helper Methods + + /// + /// Checks for minimum segment height. + /// + /// Current segment height. + /// Adjusted segment height. + protected float CheckMinHeight(float height) + { + // When point gap is used do not allow to have the segment heigth to be zero. + float minSize = Math.Min(2f, this.funnelSegmentGap / 2f); + if(this.funnelSegmentGap > 0 && + height < minSize) + { + return minSize; + } + + return height; + } + + /// + /// Gets minimum point height in pixels. + /// + /// Minimum point height in pixels. + private void GetFunnelMinPointHeight(DataPointCustomProperties properties) + { + // Set default minimum point size + this._funnelMinPointHeight = 0f; + + // Get string value of the custom attribute + string attrValue = properties[this.funnelPointMinHeight]; + if (attrValue != null && attrValue.Length > 0) + { + // Convert string to the point gap size + + float pointHeight; + bool parseSucceed = float.TryParse(attrValue, NumberStyles.Any, CultureInfo.InvariantCulture, out pointHeight); + if (parseSucceed) + { + this._funnelMinPointHeight = pointHeight; + } + + if (!parseSucceed || this._funnelMinPointHeight < 0f || this._funnelMinPointHeight > 100f) + { + throw (new InvalidOperationException(SR.ExceptionFunnelMinimumPointHeightAttributeInvalid)); + } + + // Check if specified value is too big + this._funnelMinPointHeight = (float)(this.yValueTotal * this._funnelMinPointHeight / 100f); + + // Get data statistic again using Min value + GetDataPointValuesStatistic(); + } + + return; + } + + /// + /// Gets 3D funnel rotation angle. + /// + /// Rotation angle. + private int GetFunnelRotation(DataPointCustomProperties properties) + { + // Set default gap size + int angle = 5; + + // Get string value of the custom attribute + string attrValue = properties[this.funnelRotationAngleAttributeName]; + if (attrValue != null && attrValue.Length > 0) + { + // Convert string to the point gap size + + int a; + bool parseSucceed = int.TryParse(attrValue, NumberStyles.Any, CultureInfo.InvariantCulture, out a); + if (parseSucceed) + { + angle = a; + } + + // Validate attribute value + if (!parseSucceed || angle < -10 || angle > 10) + { + throw (new InvalidOperationException(SR.ExceptionFunnelAngleRangeInvalid)); + } + } + + return angle; + } + + /// + /// Gets callout line color. + /// + /// Callout line color. + private Color GetCalloutLineColor(DataPointCustomProperties properties) + { + // Set default gap size + Color color = Color.Black; + + // Get string value of the custom attribute + string attrValue = properties[CustomPropertyName.CalloutLineColor]; + if(attrValue != null && attrValue.Length > 0) + { + // Convert string to Color + bool failed = false; + ColorConverter colorConverter = new ColorConverter(); + try + { + color = (Color)colorConverter.ConvertFromInvariantString(attrValue); + } + catch (ArgumentException) + { + failed = true; + } + catch (NotSupportedException) + { + failed = true; + } + + // In case of an error try to convert using local settings + if(failed) + { + try + { + color = (Color)colorConverter.ConvertFromString(attrValue); + } + catch(ArgumentException) + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid( attrValue, "CalloutLineColor") ) ); + } + } + + } + + return color; + } + + /// + /// Gets funnel neck size when shape of the funnel do not change. + /// + /// Funnel neck width and height. + private SizeF GetFunnelNeckSize(DataPointCustomProperties properties) + { + // Set default gap size + SizeF neckSize = new SizeF(5f, 5f); + + // Get string value of the custom attribute + string attrValue = properties[CustomPropertyName.FunnelNeckWidth]; + if (attrValue != null && attrValue.Length > 0) + { + // Convert string to the point gap size + + float w; + bool parseSucceed = float.TryParse(attrValue, NumberStyles.Any, CultureInfo.InvariantCulture, out w); + if (parseSucceed) + { + neckSize.Width = w; + } + + // Validate attribute value + if (!parseSucceed || neckSize.Width < 0 || neckSize.Width > 100) + { + throw (new InvalidOperationException(SR.ExceptionFunnelNeckWidthInvalid)); + } + } + + // Get string value of the custom attribute + attrValue = properties[CustomPropertyName.FunnelNeckHeight]; + if (attrValue != null && attrValue.Length > 0) + { + // Convert string to the point gap size + float h; + bool parseSucceed = float.TryParse(attrValue, NumberStyles.Any, CultureInfo.InvariantCulture, out h); + if (parseSucceed) + { + neckSize.Height = h; + } + + + if (!parseSucceed || neckSize.Height < 0 || neckSize.Height > 100) + { + throw (new InvalidOperationException(SR.ExceptionFunnelNeckHeightInvalid)); + } + } + + // Make sure the neck size do not exceed the plotting area size + if(neckSize.Height > this.PlotAreaPosition.Height/2f) + { + neckSize.Height = this.PlotAreaPosition.Height/2f; + } + if(neckSize.Width > this.PlotAreaPosition.Width/2f) + { + neckSize.Width = this.PlotAreaPosition.Width/2f; + } + + // Convert from relative coordinates to pixels + return this.Graph.GetAbsoluteSize(neckSize); + } + + /// + /// Gets gap between points in pixels. + /// + /// Gap between funnel points. + private float GetFunnelPointGap(DataPointCustomProperties properties) + { + // Set default gap size + float gapSize = 0f; + + // Get string value of the custom attribute + string attrValue = properties[this.funnelPointGapAttributeName]; + if (attrValue != null && attrValue.Length > 0) + { + // Convert string to the point gap size + + float gs; + bool parseSucceed = float.TryParse(attrValue, NumberStyles.Any, CultureInfo.InvariantCulture, out gs); + if (parseSucceed) + { + gapSize = gs; + } + else + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(attrValue, this.funnelPointGapAttributeName))); + } + + // Make sure the total gap size for all points do not exceed the total height of the plotting area + float maxGapSize = this.PlotAreaPosition.Height / (this.pointNumber - ((ShouldDrawFirstPoint()) ? 1 : 2)); + if (gapSize > maxGapSize) + { + gapSize = maxGapSize; + } + if (gapSize < 0) + { + gapSize = 0; + } + + // Convert from relative coordinates to pixels + gapSize = this.Graph.GetAbsoluteSize(new SizeF(gapSize, gapSize)).Height; + } + + return gapSize; + } + + /// + /// Gets funnel drawing style. + /// + /// funnel drawing style. + private FunnelStyle GetFunnelStyle(DataPointCustomProperties properties) + { + // Set default funnel drawing style + FunnelStyle drawingStyle = FunnelStyle.YIsHeight; + + // Get string value of the custom attribute + if(!this.isPyramid) + { + string attrValue = properties[CustomPropertyName.FunnelStyle]; + if(attrValue != null && attrValue.Length > 0) + { + // Convert string to the labels style + try + { + drawingStyle = (FunnelStyle)Enum.Parse(typeof(FunnelStyle), attrValue, true); + } + catch + { + throw(new InvalidOperationException( SR.ExceptionCustomAttributeValueInvalid( attrValue, "FunnelStyle") ) ); + } + } + } + return drawingStyle; + } + + /// + /// Gets outside labels placement. + /// + /// Outside labels placement. + private FunnelLabelPlacement GetOutsideLabelPlacement(DataPointCustomProperties properties) + { + // Set default vertical alignment for the inside labels + FunnelLabelPlacement placement = FunnelLabelPlacement.Right; + + // Get string value of the custom attribute + string attrValue = properties[this.funnelOutsideLabelPlacementAttributeName]; + if(attrValue != null && attrValue.Length > 0) + { + // Convert string to the labels placement + try + { + placement = (FunnelLabelPlacement)Enum.Parse(typeof(FunnelLabelPlacement), attrValue, true); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(attrValue, this.funnelOutsideLabelPlacementAttributeName ))); + } + } + return placement; + } + + /// + /// Gets inside labels vertical alignment. + /// + /// Inside labels vertical alignment. + private FunnelLabelVerticalAlignment GetInsideLabelAlignment(DataPointCustomProperties properties) + { + // Set default vertical alignment for the inside labels + FunnelLabelVerticalAlignment alignment = FunnelLabelVerticalAlignment.Center; + + // Get string value of the custom attribute + string attrValue = properties[this.funnelInsideLabelAlignmentAttributeName]; + if(attrValue != null && attrValue.Length > 0) + { + // Convert string to the labels style + try + { + alignment = (FunnelLabelVerticalAlignment)Enum.Parse(typeof(FunnelLabelVerticalAlignment), attrValue, true); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(attrValue, this.funnelInsideLabelAlignmentAttributeName))); + } + } + return alignment; + } + + /// + /// Gets funnel 3D drawing style. + /// + /// funnel drawing style. + private Funnel3DDrawingStyle GetFunnel3DDrawingStyle(DataPointCustomProperties properties) + { + // Set default funnel drawing style + Funnel3DDrawingStyle drawingStyle = (this.isPyramid) ? + Funnel3DDrawingStyle.SquareBase : Funnel3DDrawingStyle.CircularBase; + + // Get string value of the custom attribute + string attrValue = properties[funnel3DDrawingStyleAttributeName]; + if(attrValue != null && attrValue.Length > 0) + { + // Convert string to the labels style + try + { + drawingStyle = (Funnel3DDrawingStyle)Enum.Parse(typeof(Funnel3DDrawingStyle), attrValue, true); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(attrValue, funnel3DDrawingStyleAttributeName) ) ); + } + } + + return drawingStyle; + } + + /// + /// Get data point Y and X values statistics: + /// - Total of all Y values + /// - Total of all X values + /// - Maximum Y value + /// Negative values are treated as positive. + /// + private void GetDataPointValuesStatistic() + { + // Get funnel chart type series + Series series = GetDataSeries(); + if( series != null ) + { + // Reset values + this.yValueTotal = 0.0; + this._xValueTotal = 0.0; + this._yValueMax = 0.0; + this.pointNumber = 0; + + // Get value type + this._valuePercentages = null; + PyramidValueType valueType = this.GetPyramidValueType( series ); + if(valueType == PyramidValueType.Surface) + { + // Calculate the total surface area + double triangleArea = 0.0; + int pointIndex = 0; + foreach( DataPoint point in series.Points ) + { + // Ignore empty points + if( !point.IsEmpty ) + { + // Get Y value + triangleArea += GetYValue(point, pointIndex); + } + ++pointIndex; + } + + // Calculate the base + double triangleHeight = 100.0; + double triangleBase = (2* triangleArea) / triangleHeight; + + // Calculate the base to height ratio + double baseRatio = triangleBase / triangleHeight; + + // Calcuate the height percentage for each value + double[] percentages = new double[series.Points.Count]; + double sumArea = 0.0; + for(int loop = 0; loop < percentages.Length; loop++) + { + double yValue = GetYValue(series.Points[loop], loop); + sumArea += yValue; + percentages[loop] = Math.Sqrt((2 * sumArea) / baseRatio); + } + this._valuePercentages = percentages; + } + + // Loop through all ponts in the data series + foreach( DataPoint point in series.Points ) + { + // Ignore empty points + if( !point.IsEmpty ) + { + // Get Y value + double yValue = GetYValue(point, this.pointNumber); + + // Get data point Y and X values statistics + this.yValueTotal += yValue; + this._yValueMax = Math.Max(this._yValueMax, yValue); + this._xValueTotal += GetXValue(point); + } + + ++this.pointNumber; + } + + } + } + + /// + /// Gets funnel chart series that belongs to the current chart area. + /// Method also checks that only one visible Funnel series exists in the chart area. + /// + /// Funnel chart type series. + private Series GetDataSeries() + { + // Check if funnel series was already found + if(this._chartTypeSeries == null) + { + // Loop through all series + Series funnelSeries = null; + foreach( Series series in Common.DataManager.Series ) + { + // Check if series is visible and belong to the current chart area + if( series.IsVisible() && + series.ChartArea == this.Area.Name ) + { + // Check series chart type is Funnel + if( String.Compare( series.ChartTypeName, this.Name, true, System.Globalization.CultureInfo.CurrentCulture ) == 0 ) + { + if(funnelSeries == null) + { + funnelSeries = series; + } + } + else if(!this.Common.ChartPicture.SuppressExceptions) + { + // Funnel chart can not be combined with other chart type + throw (new InvalidOperationException(SR.ExceptionFunnelCanNotCombine)); + } + } + } + + // Remember the chart type series + this._chartTypeSeries = funnelSeries; + } + + return this._chartTypeSeries; + } + + /// + /// Gets pyramid value type. Each point value may represent a "Linear" height of + /// the segment or "Surface" of the segment. + /// + /// Pyramid value type. + private PyramidValueType GetPyramidValueType(DataPointCustomProperties properties) + { + // Set default funnel drawing style + PyramidValueType valueType = PyramidValueType.Linear; + + // Get string value of the custom attribute + if(this.isPyramid) + { + string attrValue = properties[CustomPropertyName.PyramidValueType]; + if(attrValue != null && attrValue.Length > 0) + { + // Convert string to the labels style + try + { + valueType = (PyramidValueType)Enum.Parse(typeof(PyramidValueType), attrValue, true); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(attrValue,"PyramidValueType") ) ); + } + } + } + return valueType; + } + + #endregion // Helper Methods + + #region Y & X values related methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Point object. + /// Point index. + /// Y value of the point. + virtual public double GetYValue(DataPoint point, int pointIndex) + { + double yValue = 0.0; + if( !point.IsEmpty ) + { + // Get Y value + yValue = point.YValues[0]; + + // Adjust point value + if(this._valuePercentages != null && + this._valuePercentages.Length > pointIndex ) + { + yValue = yValue / 100.0 * this._valuePercentages[pointIndex]; + } + + if(this.Area.AxisY.IsLogarithmic) + { + yValue = Math.Abs(Math.Log( yValue, this.Area.AxisY.LogarithmBase )); + } + else + { + yValue = Math.Abs( yValue ); + if(yValue < this._funnelMinPointHeight) + { + yValue = this._funnelMinPointHeight; + } + } + } + return yValue; + } + + /// + /// Helper function, which returns the X value of the point. + /// + /// Point object. + /// X value of the point. + virtual public double GetXValue(DataPoint point) + { + if(this.Area.AxisX.IsLogarithmic) + { + return Math.Abs(Math.Log( point.XValue, this.Area.AxisX.LogarithmBase )); + } + return Math.Abs(point.XValue); + } + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + return point.YValues[yValueIndex]; + } + + #endregion // Y & X values related methods + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + // Fast Line chart type do not support labels + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } + + /// + /// PyramidChart class overrides some of the functionality of FunnelChart class. + /// Most of drawing and othere processing is done in the FunnelChart. + /// + internal class PyramidChart : FunnelChart + { + #region Fields and Constructor + + /// + /// Default constructor + /// + public PyramidChart() + { + // Renering of the pyramid chart type + base.isPyramid = true; + + // Pyramid chart type uses square base by default + base.round3DShape = false; + + // Pyramid properties names + base.funnelLabelStyleAttributeName = CustomPropertyName.PyramidLabelStyle; + base.funnelPointGapAttributeName = CustomPropertyName.PyramidPointGap; + base.funnelRotationAngleAttributeName = CustomPropertyName.Pyramid3DRotationAngle; + base.funnelPointMinHeight = CustomPropertyName.PyramidMinPointHeight; + base.funnel3DDrawingStyleAttributeName = CustomPropertyName.Pyramid3DDrawingStyle; + base.funnelInsideLabelAlignmentAttributeName = CustomPropertyName.PyramidInsideLabelAlignment; + base.funnelOutsideLabelPlacementAttributeName = CustomPropertyName.PyramidOutsideLabelPlacement; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.Pyramid;}} + + #endregion + + #region Methods + + /// + /// Gets pyramid data point segment height and width. + /// + /// Chart type series. + /// Data point index in the series. + /// Segment top location. Bottom location if reversed drawing order. + /// Returns the height of the segment. + /// Returns top width of the segment. + /// Returns botom width of the segment. + protected override void GetPointWidthAndHeight( + Series series, + int pointIndex, + float location, + out float height, + out float startWidth, + out float endWidth) + { + PointF pointPositionAbs = PointF.Empty; + + // Get plotting area position in pixels + RectangleF plotAreaPositionAbs = this.Graph.GetAbsoluteRectangle(this.PlotAreaPosition); + + // Calculate total height of plotting area minus reserved space for the gaps + float plotAreaHeightAbs = plotAreaPositionAbs.Height - + this.funnelSegmentGap * (this.pointNumber - ((ShouldDrawFirstPoint()) ? 1 : 2) ); + if(plotAreaHeightAbs < 0f) + { + plotAreaHeightAbs = 0f; + } + + // Calculate segment height as a part of total Y values in series + height = (float)(plotAreaHeightAbs * (GetYValue(series.Points[pointIndex], pointIndex) / this.yValueTotal)); + + // Check for minimum segment height + height = CheckMinHeight(height); + + // Get intersection point of the horizontal line at the start of the segment + // with the left pre-defined wall of the funnel. + PointF startIntersection = ChartGraphics.GetLinesIntersection( + plotAreaPositionAbs.X, location - height, + plotAreaPositionAbs.Right, location - height, + plotAreaPositionAbs.X, plotAreaPositionAbs.Bottom, + plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f, plotAreaPositionAbs.Y ); + if(startIntersection.X > (plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f) ) + { + startIntersection.X = plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f; + } + + // Get intersection point of the horizontal line at the end of the segment + // with the left pre-defined wall of the funnel. + PointF endIntersection = ChartGraphics.GetLinesIntersection( + plotAreaPositionAbs.X, location, + plotAreaPositionAbs.Right, location, + plotAreaPositionAbs.X, plotAreaPositionAbs.Bottom, + plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f, plotAreaPositionAbs.Y ); + if(endIntersection.X > (plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f)) + { + endIntersection.X = plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f; + } + + // Get segment start and end width + startWidth = (float)Math.Abs( plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f - + startIntersection.X) * 2f; + endWidth = (float)Math.Abs( plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f - + endIntersection.X) * 2f; + + // Set point position for annotation anchoring + pointPositionAbs = new PointF( + plotAreaPositionAbs.X + plotAreaPositionAbs.Width / 2f, + location - height / 2f); + + // Set pre-calculated point position + series.Points[pointIndex].positionRel = Graph.GetRelativePoint(pointPositionAbs); + } + + #endregion // Methods + } + + /// + /// Helper data structure used to store information about single funnel segment. + /// + internal class FunnelSegmentInfo + { + #region Fields + + // ----osiated data point + public DataPoint Point = null; + + // Data point index + public int PointIndex = 0; + + // Segment top position + public float Location = 0f; + + // Segment height + public float Height = 0f; + + // Segment top width + public float StartWidth = 0f; + + // Segment bottom width + public float EndWidth = 0f; + + // Segment has nothing on the top + public bool NothingOnTop = false; + + // Segment has nothing on the bottom + public bool NothingOnBottom = false; + + #endregion // Fields + } + + /// + /// Helper data structure used to store information about funnel data point label. + /// + internal class FunnelPointLabelInfo + { + #region Fields + + // ----osiated data point + public DataPoint Point = null; + + // Data point index + public int PointIndex = 0; + + // Label text + public string Text = string.Empty; + + // Data point label size + public SizeF Size = SizeF.Empty; + + // Position of the data point label + public RectangleF Position = RectangleF.Empty; + + // Label style + public FunnelLabelStyle Style = FunnelLabelStyle.OutsideInColumn; + + // Inside label vertical alignment + public FunnelLabelVerticalAlignment VerticalAlignment = FunnelLabelVerticalAlignment.Center; + + // Outside labels placement + public FunnelLabelPlacement OutsidePlacement = FunnelLabelPlacement.Right; + + // Label callout first point + public PointF CalloutPoint1 = PointF.Empty; + + // Label callout second point + public PointF CalloutPoint2 = PointF.Empty; + + #endregion // Fields + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/KagiChart.cs b/System.Web.DataVisualization/Common/ChartTypes/KagiChart.cs new file mode 100644 index 000000000..a722479e7 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/KagiChart.cs @@ -0,0 +1,996 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: KagiChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: Provides 2D and 3D drawing and hit testing of the +// Kagi chart. +// +// Purpose: +// +// Kagi Chart Overview: +// -------------------- +// +// Kagi charts are believed to have been created around the time +// that the Japanese stock market began trading in the 1870's. Kagi +// charts display a series of connecting vertical lines where the +// thickness and direction of the lines are dependent on the action +// of the price value. These charts ignore the passage of time, but +// can be used to illustrate the forces of supply and demand on a +// security. +// +// When working with this type of chart, the following should be +// taken into account: +// +// - The X values of data points are automatically indexed. +// +// - There is a formula applied to the original data before plotting, +// which changes the number of points and their X/Y values. +// +// - Due to the data being recalculated we do not recommend setting +// the minimum and/or maximum values for the X axis, since it cannot +// be determined how many data points will actually get plotted. +// However, if the axis' maximum or minimum is set then the Maximum +// or Minimum properties should use data point index values. +// +// - Data point anchoring, used for annotations, is not supported +// with this type of chart. +// +// Reviewed: AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel.Design; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web.UI.DataVisualization.Charting; + +using System.Web.UI.DataVisualization.Charting.ChartTypes; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else +namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// KagiChart class provides 2D and 3D drawing and hit testing of + /// the Kagi chart. + /// + internal class KagiChart : StepLineChart + { + #region Fields + + // Color used to draw up direction lines + internal Color kagiUpColor = Color.Empty; + + // Current properties used for kagi line (1 up; -1 down; 0 none) + internal int currentKagiDirection = 0; + + #endregion // Fields + + #region Methods + + /// + /// Prepares Kagi chart type for rendering. + /// + /// Series to be prepared. + internal static void PrepareData(Series series) + { + // Check series chart type + if (String.Compare(series.ChartTypeName, ChartTypeNames.Kagi, StringComparison.OrdinalIgnoreCase) != 0 || !series.IsVisible()) + { + return; + } + + // Get reference to the chart control + Chart chart = series.Chart; + if(chart == null) + { + throw(new InvalidOperationException(SR.ExceptionKagiNullReference)); + } + + // Kagi chart may not be combined with any other chart types + ChartArea area = chart.ChartAreas[series.ChartArea]; + foreach (Series currentSeries in chart.Series) + { + if (currentSeries.IsVisible() && currentSeries != series && area == chart.ChartAreas[currentSeries.ChartArea]) + { + throw (new InvalidOperationException(SR.ExceptionKagiCanNotCombine)); + } + } + + // Create a temp series which will hold original series data points + string tempSeriesName = "KAGI_ORIGINAL_DATA_" + series.Name; + if (chart.Series.IndexOf(tempSeriesName) != -1) + { + return; // the temp series has already been added + } + Series seriesOriginalData = new Series(tempSeriesName, series.YValuesPerPoint); + seriesOriginalData.Enabled = false; + seriesOriginalData.IsVisibleInLegend = false; + chart.Series.Add(seriesOriginalData); + foreach(DataPoint dp in series.Points) + { + seriesOriginalData.Points.Add(dp); + } + series.Points.Clear(); + if(series.IsCustomPropertySet("TempDesignData")) + { + seriesOriginalData["TempDesignData"] = "true"; + } + + + // Remember prev. series parameters + series["OldXValueIndexed"] = series.IsXValueIndexed.ToString(CultureInfo.InvariantCulture); + series["OldYValuesPerPoint"] = series.YValuesPerPoint.ToString(CultureInfo.InvariantCulture); + series.IsXValueIndexed = true; + + // Calculate date-time interval for indexed series + if(series.ChartArea.Length > 0 && + series.IsXValueDateTime()) + { + // Get X axis connected to the series + Axis xAxis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName); + + // Change interval for auto-calculated interval only + if(xAxis.Interval == 0 && xAxis.IntervalType == DateTimeIntervalType.Auto) + { + // Check if original data has X values set to date-time values and + // calculate min/max X values. + bool nonZeroXValues = false; + double minX = double.MaxValue; + double maxX = double.MinValue; + foreach(DataPoint dp in seriesOriginalData.Points) + { + if(!dp.IsEmpty) + { + if(dp.XValue != 0.0) + { + nonZeroXValues = true; + } + if(dp.XValue > maxX) + { + maxX = dp.XValue; + } + if(dp.XValue < minX) + { + minX = dp.XValue; + } + } + } + + if(nonZeroXValues) + { + // Save flag that axis interval is automatic + series["OldAutomaticXAxisInterval"] = "true"; + + // Calculate and set axis date-time interval + DateTimeIntervalType intervalType = DateTimeIntervalType.Auto; + xAxis.interval = xAxis.CalcInterval(minX, maxX, true, out intervalType, series.XValueType); + xAxis.intervalType = intervalType; + } + } + } + + // Calculate Kagi bricks data points values + FillKagiData(series, seriesOriginalData); + } + + /// + /// Remove any changes done while preparing Kagi chart type for rendering. + /// + /// Series to be un-prepared. + /// True if series was removed from collection. + internal static bool UnPrepareData(Series series) + { + if(series.Name.StartsWith("KAGI_ORIGINAL_DATA_", StringComparison.Ordinal)) + { + // Get reference to the chart control + Chart chart = series.Chart; + if(chart == null) + { + throw (new InvalidOperationException(SR.ExceptionKagiNullReference)); + } + + // Get original Kagi series + Series kagiSeries = chart.Series[series.Name.Substring(19)]; + Series.MovePositionMarkers(kagiSeries, series); + // Copy data back to original Kagi series + kagiSeries.Points.Clear(); + if(!series.IsCustomPropertySet("TempDesignData")) + { + foreach(DataPoint dp in series.Points) + { + kagiSeries.Points.Add(dp); + } + } + + // Restore series properties + bool xValIndexed; + bool parseSucceed = bool.TryParse(kagiSeries["OldXValueIndexed"], out xValIndexed); + kagiSeries.IsXValueIndexed = parseSucceed && xValIndexed; + + int yValPerPoint; + parseSucceed = int.TryParse(kagiSeries["OldYValuesPerPoint"], NumberStyles.Any, CultureInfo.InvariantCulture, out yValPerPoint); + if (parseSucceed) + { + kagiSeries.YValuesPerPoint = yValPerPoint; + } + + kagiSeries.DeleteCustomProperty("OldXValueIndexed"); + kagiSeries.DeleteCustomProperty("OldYValuesPerPoint"); + + series["OldAutomaticXAxisInterval"] = "true"; + if(kagiSeries.IsCustomPropertySet("OldAutomaticXAxisInterval")) + { + kagiSeries.DeleteCustomProperty("OldAutomaticXAxisInterval"); + + // Reset automatic interval for X axis + if(kagiSeries.ChartArea.Length > 0) + { + // Get X axis connected to the series + ChartArea area = chart.ChartAreas[kagiSeries.ChartArea]; + Axis xAxis = area.GetAxis(AxisName.X, kagiSeries.XAxisType, kagiSeries.XSubAxisName); + + xAxis.interval = 0.0; + xAxis.intervalType = DateTimeIntervalType.Auto; + } + } + + // Remove series from the collection + chart.Series.Remove(series); + return true; + } + + return false; + } + + /// + /// Gets reversal amount of the kagi chart. + /// + /// Step line chart series used to dispaly the kagi chart. + /// Returns reversal amount in percentage. + private static double GetReversalAmount(Series series, out double percentOfPrice) + { + // Check "ReversalAmount" custom attribute + double reversalAmount = 1.0; + percentOfPrice = 3.0; + if (series.IsCustomPropertySet(CustomPropertyName.ReversalAmount)) + { + string attrValue = series[CustomPropertyName.ReversalAmount].Trim(); + bool usePercentage = attrValue.EndsWith("%", StringComparison.Ordinal); + if (usePercentage) + { + attrValue = attrValue.Substring(0, attrValue.Length - 1); + } + + if (usePercentage) + { + double percent; + bool parseSucceed = double.TryParse(attrValue, NumberStyles.Any, CultureInfo.InvariantCulture, out percent); + if (parseSucceed) + { + percentOfPrice = percent; + } + else + { + throw (new InvalidOperationException(SR.ExceptionKagiAttributeFormatInvalid("ReversalAmount"))); + } + } + else + { + double amount; + bool parseSucceed = double.TryParse(attrValue, NumberStyles.Any, CultureInfo.InvariantCulture, out amount); + if (parseSucceed) + { + reversalAmount = amount; + percentOfPrice = 0.0; + } + else + { + throw (new InvalidOperationException(SR.ExceptionKagiAttributeFormatInvalid("ReversalAmount"))); + } + } + + } + + return reversalAmount; + } + + + /// + /// Fills step line series with data to draw the Kagi chart. + /// + /// Step line chart series used to dispaly the Kagi chart. + /// Series with original data. + private static void FillKagiData(Series series, Series originalData) + { + // Get index of the Y values used + int yValueIndex = 0; + if (series.IsCustomPropertySet(CustomPropertyName.UsedYValue)) + { + int yi; + bool parseSucceed = int.TryParse(series[CustomPropertyName.UsedYValue], NumberStyles.Any, CultureInfo.InvariantCulture, out yi); + + if (parseSucceed) + { + yValueIndex = yi; + } + else + { + throw (new InvalidOperationException(SR.ExceptionKagiAttributeFormatInvalid("UsedYValue"))); + } + + if (yValueIndex >= series.YValuesPerPoint) + { + throw (new InvalidOperationException(SR.ExceptionKagiAttributeOutOfRange("UsedYValue"))); + } + } + + // Calculate reversal amount + double reversalAmountPercentage = 0.0; + double reversalAmount = GetReversalAmount(series, out reversalAmountPercentage); + + // Fill points + double prevClose = double.NaN; + int prevDirection = 0; // 1 up; -1 down; 0 none + int pointIndex = 0; + foreach(DataPoint dataPoint in originalData.Points) + { + // Check if previus values exists + if(double.IsNaN(prevClose)) + { + prevClose = dataPoint.YValues[yValueIndex]; + + // Add first point + DataPoint newDataPoint = (DataPoint)dataPoint.Clone(); + newDataPoint["OriginalPointIndex"] = pointIndex.ToString(CultureInfo.InvariantCulture); + newDataPoint.series = series; + newDataPoint.XValue = dataPoint.XValue; + newDataPoint.YValues[0] = dataPoint.YValues[yValueIndex]; + newDataPoint.Tag = dataPoint; + series.Points.Add(newDataPoint); + ++pointIndex; + continue; + } + + // Calculate reversal amount as percentage of previous price + if(reversalAmountPercentage != 0.0) + { + reversalAmount = (prevClose / 100.0) * reversalAmountPercentage; + } + + // Check direction of the price change + int direction = 0; + if(dataPoint.YValues[yValueIndex] > prevClose) + { + direction = 1; + } + else if(dataPoint.YValues[yValueIndex] < prevClose) + { + direction = -1; + } + else + { + direction = 0; + } + + // Check if value was changed - otherwise do nothing + if(direction != 0) + { + // Extend line in same direction + if(direction == prevDirection) + { + series.Points[series.Points.Count - 1].YValues[0] = + dataPoint.YValues[yValueIndex]; + series.Points[series.Points.Count - 1]["OriginalPointIndex"] = pointIndex.ToString(CultureInfo.InvariantCulture); + series.Points[series.Points.Count - 1].Tag = dataPoint; + } + else if( Math.Abs(dataPoint.YValues[yValueIndex] - prevClose) < reversalAmount) + { + // Ignore opposite direction change if value is less than reversal amount + ++pointIndex; + continue; + } + else + { + // Opposite direction by more than reversal amount + DataPoint newDataPoint = (DataPoint)dataPoint.Clone(); + newDataPoint["OriginalPointIndex"] = pointIndex.ToString(CultureInfo.InvariantCulture); + newDataPoint.series = series; + newDataPoint.XValue = dataPoint.XValue; + newDataPoint.YValues[0] = dataPoint.YValues[yValueIndex]; + newDataPoint.Tag = dataPoint; + // Add Kagi to the range step line series + series.Points.Add(newDataPoint); + } + + // Save previous close value and direction + prevClose = dataPoint.YValues[yValueIndex]; + prevDirection = direction; + } + ++pointIndex; + } + } + + #endregion // Methods + + #region Line drawing and selecting methods + + /// + /// Draw chart line using horisontal and vertical lines. + /// + /// Graphics object. + /// The Common elements object + /// Point to draw the line for. + /// Point series. + /// Array of points coordinates. + /// Index of point to draw. + /// Line tension + override protected void DrawLine( + ChartGraphics graph, + CommonElements common, + DataPoint point, + Series series, + PointF[] points, + int pointIndex, + float tension) + { + // Start drawing from the second point + if(pointIndex <= 0) + { + return; + } + + if(currentKagiDirection == 0) + { + // Get up price color + this.kagiUpColor = ChartGraphics.GetGradientColor(series.Color, Color.Black, 0.5); + string priceUpColorString = series[CustomPropertyName.PriceUpColor]; + ColorConverter colorConverter = new ColorConverter(); + if(priceUpColorString != null) + { + try + { + this.kagiUpColor = (Color)colorConverter.ConvertFromString(null, CultureInfo.InvariantCulture, priceUpColorString); + } + catch + { + throw(new InvalidOperationException(SR.ExceptionKagiAttributeFormatInvalid("Up Brick color"))); + } + } + + // Check direction of first line (up or down) + currentKagiDirection = (points[pointIndex - 1].Y > points[pointIndex].Y) ? + 1 : -1; + } + + // Set up movement colors and width + Color lineColor = (currentKagiDirection == 1) ? this.kagiUpColor : point.Color; + + // Prepare coordinate to draw 2 or 3 segments of the step line + PointF point1 = points[pointIndex - 1]; + PointF point2 = new PointF(points[pointIndex].X, points[pointIndex - 1].Y); + PointF point3 = points[pointIndex]; + PointF point4 = PointF.Empty; + + // Check if vertical line should be draw as to segments of different color + if(pointIndex >= 2) + { + // Check current direction + int direction = (points[pointIndex - 1].Y > points[pointIndex].Y) ? + 1 : -1; + + // Proceed only when direction is changed + if(direction != currentKagiDirection) + { + // Find prev line low & high + PointF prevPoint = points[pointIndex - 2]; + bool twoVertSegments = false; + if(point1.Y > prevPoint.Y && + point1.Y > point3.Y && + prevPoint.Y > point3.Y) + { + twoVertSegments = true; + } + else if(point1.Y < prevPoint.Y && + point1.Y < point3.Y && + prevPoint.Y < point3.Y) + { + twoVertSegments = true; + } + + if(twoVertSegments) + { + // Calculate point where vertical line is split + point4.Y = prevPoint.Y; + point4.X = point2.X; + } + } + } + + // Round line point values + point1.X = (float)Math.Round(point1.X); + point1.Y = (float)Math.Round(point1.Y); + point2.X = (float)Math.Round(point2.X); + point2.Y = (float)Math.Round(point2.Y); + point3.X = (float)Math.Round(point3.X); + point3.Y = (float)Math.Round(point3.Y); + if(!point4.IsEmpty) + { + point4.X = (float)Math.Round(point4.X); + point4.Y = (float)Math.Round(point4.Y); + } + + + // Draw horizontal segment + graph.DrawLineRel( lineColor, point.BorderWidth, point.BorderDashStyle, + graph.GetRelativePoint(point1), graph.GetRelativePoint(point2), + series.ShadowColor, series.ShadowOffset ); + + // Check if vertical segment should be drawn as one ore two segments + if(point4.IsEmpty) + { + // Draw 1 vertical segment + graph.DrawLineRel( lineColor, point.BorderWidth, point.BorderDashStyle, + graph.GetRelativePoint(point2), graph.GetRelativePoint(point3), + series.ShadowColor, series.ShadowOffset ); + } + else + { + // Draw firts part of vertical segment + graph.DrawLineRel( lineColor, point.BorderWidth, point.BorderDashStyle, + graph.GetRelativePoint(point2), graph.GetRelativePoint(point4), + series.ShadowColor, series.ShadowOffset ); + + // Change direction + currentKagiDirection = (currentKagiDirection == 1) ? -1 : 1; + + // Set color + lineColor = (currentKagiDirection == 1) ? this.kagiUpColor : point.Color; + + // Draw second part of vertical segment + graph.DrawLineRel( lineColor, point.BorderWidth, point.BorderDashStyle, + graph.GetRelativePoint(point4), graph.GetRelativePoint(point3), + series.ShadowColor, series.ShadowOffset ); + } + + if( common.ProcessModeRegions ) + { + // Create grapics path object dor the curve + using (GraphicsPath path = new GraphicsPath()) + { + try + { + path.AddLine(point1, point2); + path.AddLine(point2, point3); + path.Widen(new Pen(point.Color, point.BorderWidth + 2)); + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + + // Allocate array of floats + PointF pointNew = PointF.Empty; + float[] coord = new float[path.PointCount * 2]; + PointF[] pathPoints = path.PathPoints; + for (int i = 0; i < path.PointCount; i++) + { + pointNew = graph.GetRelativePoint(pathPoints[i]); + coord[2 * i] = pointNew.X; + coord[2 * i + 1] = pointNew.Y; + } + + common.HotRegionsList.AddHotRegion( + path, + false, + coord, + point, + series.Name, + pointIndex); + } + } + + } + + /// + /// Fills a PointF array of data points absolute pixel positions. + /// + /// Graphics object. + /// Point series. + /// Indicate that point index should be used as X value. + /// Array of data points position. + override protected PointF[] GetPointsPosition(ChartGraphics graph, Series series, bool indexedSeries) + { + PointF[] pointPos = new PointF[series.Points.Count]; + int index = 0; + foreach( DataPoint point in series.Points ) + { + // Change Y value if line is out of plot area + double yValue = GetYValue(Common, Area, series, point, index, this.YValueIndex); + + // Recalculates y position + double yPosition = VAxis.GetPosition( yValue ); + + // Recalculates x position + double xPosition = HAxis.GetPosition( point.XValue ); + if( indexedSeries ) + { + xPosition = HAxis.GetPosition( index + 1 ); + } + + // Add point position into array + pointPos[index] = new PointF( + (float)(xPosition * (graph.Common.ChartPicture.Width - 1) / 100F), + (float)(yPosition * (graph.Common.ChartPicture.Height - 1) / 100F)); + + index++; + } + + return pointPos; + } + + #endregion + + #region 3D Line drawing and selection + + /// + /// Draws a 3D surface connecting the two specified points in 2D space. + /// Used to draw Line based charts. + /// + /// Chart area reference. + /// Chart graphics. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Previous data point object. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Array of points. + /// Index of point to draw. + /// Index of points loop. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Darkenning scale for top surface. 0 - None. + /// Darkenning scale for bottom surface. 0 - None. + /// Position where the third point is actually located or float.NaN if same as in "firstPoint". + /// Position where the fourth point is actually located or float.NaN if same as in "secondPoint". + /// Indicates that drawn segment is 3D clipped. Only top/bottom should be drawn. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + protected override GraphicsPath Draw3DSurface( + ChartArea area, + ChartGraphics graph, + Matrix3D matrix, + LightStyle lightStyle, + DataPoint3D prevDataPointEx, + float positionZ, + float depth, + ArrayList points, + int pointIndex, + int pointLoopIndex, + float tension, + DrawingOperationTypes operationType, + float topDarkening, + float bottomDarkening, + PointF thirdPointPosition, + PointF fourthPointPosition, + bool clippedSegment) + { + // Create graphics path for selection + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + // Check if points are drawn from sides to center (do only once) + if(centerPointIndex == int.MaxValue) + { + centerPointIndex = GetCenterPointIndex(points); + } + + //************************************************************ + //** Find line first & second points + //************************************************************ + DataPoint3D secondPoint = (DataPoint3D)points[pointIndex]; + int pointArrayIndex = pointIndex; + DataPoint3D firstPoint = ChartGraphics.FindPointByIndex( + points, + secondPoint.index - 1, + (this.multiSeries) ? secondPoint : null, + ref pointArrayIndex); + + // Fint point with line properties + DataPoint3D pointAttr = secondPoint; + if(prevDataPointEx.dataPoint.IsEmpty) + { + pointAttr = prevDataPointEx; + } + else if(firstPoint.index > secondPoint.index) + { + pointAttr = firstPoint; + } + + // Adjust point visual properties + Color color = (useBorderColor) ? pointAttr.dataPoint.BorderColor : pointAttr.dataPoint.Color; + ChartDashStyle dashStyle = pointAttr.dataPoint.BorderDashStyle; + if( pointAttr.dataPoint.IsEmpty && pointAttr.dataPoint.Color == Color.Empty) + { + color = Color.Gray; + } + if( pointAttr.dataPoint.IsEmpty && pointAttr.dataPoint.BorderDashStyle == ChartDashStyle.NotSet ) + { + dashStyle = ChartDashStyle.Solid; + } + + // Set up kagi chart + if(currentKagiDirection == 0) + { + // Get up price color + this.kagiUpColor = secondPoint.dataPoint.series.Color; + string priceUpColorString = secondPoint.dataPoint.series[CustomPropertyName.PriceUpColor]; + ColorConverter colorConverter = new ColorConverter(); + if(priceUpColorString != null) + { + try + { + this.kagiUpColor = (Color)colorConverter.ConvertFromString(null, CultureInfo.InvariantCulture, priceUpColorString); + } + catch + { + throw(new InvalidOperationException(SR.ExceptionKagiAttributeFormatInvalid("Up Brick color"))); + } + } + + // Check direction of first line (up or down) + currentKagiDirection = (firstPoint.yPosition > secondPoint.yPosition) ? + 1 : -1; + } + + // Set up movement colors and width + Color lineColor = (currentKagiDirection == 1) ? this.kagiUpColor : color; + + //************************************************************ + //** Create "middle" point + //************************************************************ + DataPoint3D middlePoint = new DataPoint3D(); + middlePoint.xPosition = secondPoint.xPosition; + middlePoint.yPosition = firstPoint.yPosition; + + // Check if reversed drawing order required + bool originalDrawOrder = true; + if((pointIndex + 1) < points.Count) + { + DataPoint3D p = (DataPoint3D)points[pointIndex + 1]; + if(p.index == firstPoint.index) + { + originalDrawOrder = false; + } + } + + // Check in which order vertical & horizontal lines segments should be drawn + if(centerPointIndex != int.MaxValue) + { + if(pointIndex >= centerPointIndex) + { + originalDrawOrder = false; + } + } + + + // Check if vertical line should be draw as to segments of different color + DataPoint3D vertSplitPoint = null; + if(secondPoint.index >= 3) //Point3D.index is 1 based + { + // Check current direction + int direction = (firstPoint.yPosition > secondPoint.yPosition) ? + 1 : -1; + + // Proceed only when direction is changed + if(direction != currentKagiDirection) + { + // Find prev line low & high + DataPoint3D prevPoint = ChartGraphics.FindPointByIndex( + points, + secondPoint.index - 2, + (this.multiSeries) ? secondPoint : null, + ref pointArrayIndex); + + bool twoVertSegments = false; + if(firstPoint.yPosition > prevPoint.yPosition && + firstPoint.yPosition > secondPoint.yPosition && + prevPoint.yPosition > secondPoint.yPosition) + { + twoVertSegments = true; + } + else if(firstPoint.yPosition < prevPoint.yPosition && + firstPoint.yPosition < secondPoint.yPosition && + prevPoint.yPosition < secondPoint.yPosition) + { + twoVertSegments = true; + } + + if(twoVertSegments) + { + vertSplitPoint = new DataPoint3D(); + vertSplitPoint.xPosition = secondPoint.xPosition; + vertSplitPoint.yPosition = prevPoint.yPosition; + vertSplitPoint.dataPoint = secondPoint.dataPoint; + } + } + } + + // Draw two or three segments of the step line + GraphicsPath[] resultPathLine = new GraphicsPath[3]; + for(int segmentIndex = 0; segmentIndex < 2; segmentIndex++) + { + DataPoint3D point1 = firstPoint, point2 = secondPoint; + LineSegmentType lineSegmentType = LineSegmentType.First; + + if(segmentIndex == 0) + { + lineSegmentType = (originalDrawOrder) ? LineSegmentType.First : LineSegmentType.Last; + middlePoint.dataPoint = (originalDrawOrder) ? secondPoint.dataPoint : firstPoint.dataPoint; + point1 = (originalDrawOrder) ? firstPoint : middlePoint; + point2 = (originalDrawOrder) ? middlePoint : secondPoint; + } + else if(segmentIndex == 1) + { + lineSegmentType = (!originalDrawOrder) ? LineSegmentType.First : LineSegmentType.Last; + middlePoint.dataPoint = (!originalDrawOrder) ? secondPoint.dataPoint : secondPoint.dataPoint; + point1 = (!originalDrawOrder) ? firstPoint : middlePoint; + point2 = (!originalDrawOrder) ? middlePoint : secondPoint; + } + + // Draw horizontal surface + if(lineSegmentType == LineSegmentType.First || + vertSplitPoint == null) + { + resultPathLine[segmentIndex] = new GraphicsPath(); + resultPathLine[segmentIndex] = graph.Draw3DSurface( + area, matrix, lightStyle, SurfaceNames.Top, positionZ, depth, lineColor, + pointAttr.dataPoint.BorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + point1, point2, + points, pointIndex, 0f, operationType, lineSegmentType, + (this.showPointLines) ? true : false, false, + area.ReverseSeriesOrder, + this.multiSeries, 0, true); + } + else + { + if(!originalDrawOrder) + { + lineColor = (currentKagiDirection == -1) ? this.kagiUpColor : color; + } + + // Draw verticla line as two segments + resultPathLine[segmentIndex] = new GraphicsPath(); + resultPathLine[segmentIndex] = graph.Draw3DSurface( + area, matrix, lightStyle, SurfaceNames.Top, positionZ, depth, lineColor, + pointAttr.dataPoint.BorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + point1, vertSplitPoint, + points, pointIndex, 0f, operationType, LineSegmentType.Middle, + (this.showPointLines) ? true : false, false, + area.ReverseSeriesOrder, + this.multiSeries, 0, true); + + // No second draw of the prev. front line required + graph.frontLinePen = null; + + // Change direction + currentKagiDirection = (currentKagiDirection == 1) ? -1 : 1; + + // Set color + if(originalDrawOrder) + { + lineColor = (currentKagiDirection == 1) ? this.kagiUpColor : color; + } + else + { + lineColor = (currentKagiDirection == -1) ? this.kagiUpColor : color; + } + + resultPathLine[2] = new GraphicsPath(); + resultPathLine[2] = graph.Draw3DSurface( + area, matrix, lightStyle, SurfaceNames.Top, positionZ, depth, lineColor, + pointAttr.dataPoint.BorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + vertSplitPoint, point2, + points, pointIndex, 0f, operationType, lineSegmentType, + (this.showPointLines) ? true : false, false, + area.ReverseSeriesOrder, + this.multiSeries, 0, true); + + if(!originalDrawOrder) + { + lineColor = (currentKagiDirection == 1) ? this.kagiUpColor : color; + } + + } + + // No second draw of the prev. front line required + graph.frontLinePen = null; + } + + if(resultPath != null) + { + if(resultPathLine[0] != null) + resultPath.AddPath(resultPathLine[0], true); + if(resultPathLine[1] != null) + resultPath.AddPath(resultPathLine[1], true); + if(resultPathLine[2] != null) + resultPath.AddPath(resultPathLine[2], true); + } + return resultPath; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.Kagi;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + #endregion + + #region Painting and selection methods + + /// + /// Paint Line Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this char.t + /// Chart series to draw. + public override void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + // Reset current direction + this.currentKagiDirection = 0; + + // Call base class methods + base.Paint(graph, common, area, seriesToDraw); + } + + #endregion // Painting and selection methods + } +} + diff --git a/System.Web.DataVisualization/Common/ChartTypes/LineChart.cs b/System.Web.DataVisualization/Common/ChartTypes/LineChart.cs new file mode 100644 index 000000000..dd0a45040 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/LineChart.cs @@ -0,0 +1,2472 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: LineChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: LineChart, SplineChart +// +// Purpose: Provides 2D/3D drawing and hit testing +// functionality for the Line and Spline charts. +// +// Reviewed: AG - August 6, 2002 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Utilities; +#else + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// SplineChart class extends the LineChart class by + /// providing a different initial tension for the line. + /// + internal class SplineChart : LineChart + { + #region Constructor + + /// + /// Default constructor. + /// + public SplineChart() + { + // Set default line tension + base.lineTension = 0.5f; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + public override string Name { get{ return ChartTypeNames.Spline;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Helper methods + + /// + /// Checks if line tension is supported by the chart type. + /// + /// True if line tension is supported. + protected override bool IsLineTensionSupported() + { + return true; + } + + /// + /// Fills a PointF array of data points positions. + /// + /// Graphics object. + /// Point series. + /// Indicate that point index should be used as X value. + /// Array of data points position. + override protected PointF[] GetPointsPosition( + ChartGraphics graph, + Series series, + bool indexedSeries) + { + // Check tension attribute in the series + base.lineTension = GetDefaultTension(); + if(IsLineTensionSupported() && series.IsCustomPropertySet(CustomPropertyName.LineTension)) + { + base.lineTension = CommonElements.ParseFloat(series[CustomPropertyName.LineTension]); + } + + // Call base LineChart class + return base.GetPointsPosition(graph, series, indexedSeries); + } + + /// + /// Gets default line tension. + /// + /// Default line tension. + override protected float GetDefaultTension() + { + return 0.5f; + } + + #endregion + } + + /// + /// LineChart class provides 2D/3D drawing and hit testing + /// functionality for the Line and Spline charts. The only + /// difference of the Spline chart is the default tension + /// of the line. + /// + /// PointChart base class provides functionality realted + /// to drawing labels and markers. + /// + internal class LineChart : PointChart + { + #region Fields and Constructor + + /// + /// Line tension + /// + protected float lineTension = 0f; + + /// + /// Index of the drawing center point. int.MaxValue if drawn from left->right or right->left. + /// + protected int centerPointIndex = int.MaxValue; + + /// + /// Inicates that border color attribute must be used to draw the line + /// + protected bool useBorderColor = false; + + /// + /// Inicates that line shadow should not be drawn + /// + protected bool disableShadow = false; + + /// + /// Inicates that only line shadow must be drawn + /// + protected bool drawShadowOnly = false; + + // Pen used to draw the line chart + private Pen _linePen = new Pen(Color.Black); + + /// + /// Horizontal axis minimum value + /// + protected double hAxisMin = 0.0; + + /// + /// Horizontal axis maximum value + /// + protected double hAxisMax = 0.0; + + /// + /// Vertical axis minimum value + /// + protected double vAxisMin = 0.0; + + /// + /// Vertical axis maximum value + /// + protected double vAxisMax = 0.0; + + /// + /// Clip region indicator + /// + protected bool clipRegionSet = false; + + /// + /// Indicates that several series are drawn at the same time. Stacked or Side-by-side. + /// + protected bool multiSeries = false; + + /// + /// Indicates which coordinates should be tested against the COP. + /// + protected COPCoordinates COPCoordinatesToCheck = COPCoordinates.X; + + /// + /// Number of data points loops required to draw chart. + /// + protected int allPointsLoopsNumber = 1; + + /// + /// Indicates that line markers are shown at data point. + /// + protected bool showPointLines = false; + + /// + /// Indicates that that lines outside the area should be still processed while drawing. + /// + protected bool drawOutsideLines = false; + + + /// + /// Indicates if base (point) chart type should be processed + /// + private bool _processBaseChart = false; + + /// + /// Default constructor + /// + public LineChart() : base(false) + { + // Draw markers on the front edge + middleMarker = false; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + public override string Name { get{ return ChartTypeNames.Line;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + /// + /// True if chart type is stacked + /// + public override bool Stacked { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + public override bool RequireAxes { get{ return true;} } + + /// + /// True if chart type supports logarithmic axes + /// + public override bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + public override bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + override public bool SideBySideSeries { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + override public bool ZeroCrossing { get{ return true;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + public override bool DataPointsInLegend { get{ return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + public override bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + override public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Line; + } + + /// + /// Number of supported Y value(s) per point + /// + public override int YValuesPerPoint{ get { return 1; } } + + #endregion + + #region Painting and selection methods + + /// + /// Paint Line Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this char.t + /// Chart series to draw. + public override void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + // Save chart area reference + this.Area = area; + this.Common = common; + // Draw lines + _processBaseChart = false; + ProcessChartType( false, graph, common, area, seriesToDraw ); + + // Draw labels and markers using base class PointChart + if(_processBaseChart) + { + base.ProcessChartType( false, graph, common, area, seriesToDraw ); + } + } + + /// + /// Draws or perform the hit test for the line chart. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + protected override void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + this.Common = common; + // Prosess 3D chart type + if(area.Area3DStyle.Enable3D) + { + _processBaseChart = true; + ProcessLineChartType3D( selection, graph, common, area, seriesToDraw ); + return; + } + + + // All data series from chart area which have Bar chart type + List typeSeries = area.GetSeriesFromChartType(this.Name); + + // Check if series are indexed + bool indexedSeries = ChartHelper.IndexedSeries(this.Common, typeSeries.ToArray()); + + //************************************************************ + //** Loop through all series + //************************************************************ + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with Line chart type + if( String.Compare( ser.ChartTypeName, this.Name, true, System.Globalization.CultureInfo.CurrentCulture ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Check if only 1 specified series must be processed + if (seriesToDraw != null && seriesToDraw.Name != ser.Name) + { + continue; + } + + // Set active horizontal/vertical axis + HAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + VAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + hAxisMin = HAxis.ViewMinimum; + hAxisMax = HAxis.ViewMaximum; + vAxisMin = VAxis.ViewMinimum; + vAxisMax = VAxis.ViewMaximum; + + float chartWidthPercentage = (graph.Common.ChartPicture.Width - 1) / 100F; + float chartHeightPercentage = (graph.Common.ChartPicture.Height - 1) / 100F; + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + // Check tension attribute in the series + this.lineTension = GetDefaultTension(); + if (IsLineTensionSupported() && ser.IsCustomPropertySet(CustomPropertyName.LineTension)) + { + this.lineTension = CommonElements.ParseFloat(ser[CustomPropertyName.LineTension]); + } + + // Fill the array of data points coordinates (absolute) + bool dataPointPosFilled = false; + PointF[] dataPointPos = null; + if(this.lineTension == 0 && !common.ProcessModeRegions) + { + dataPointPos = new PointF[ser.Points.Count]; + } + else + { + dataPointPosFilled = true; + dataPointPos = GetPointsPosition(graph, ser, indexedSeries); + + //************************************************************************* + //** Solution for the "Out of Memory" exception in the DrawCurve method + //** All points in the array should be at least 0.1 pixel apart. + //************************************************************************* + if(this.lineTension != 0) + { + float minDifference = 0.1f; + for(int pointIndex = 1; pointIndex < dataPointPos.Length; pointIndex++) + { + if( Math.Abs(dataPointPos[pointIndex - 1].X - dataPointPos[pointIndex].X ) < minDifference ) + { + if(dataPointPos[pointIndex].X > dataPointPos[pointIndex - 1].X) + { + dataPointPos[pointIndex].X = dataPointPos[pointIndex - 1].X + minDifference; + } + else + { + dataPointPos[pointIndex].X = dataPointPos[pointIndex - 1].X - minDifference; + } + } + if( Math.Abs(dataPointPos[pointIndex - 1].Y - dataPointPos[pointIndex].Y ) < minDifference ) + { + if(dataPointPos[pointIndex].Y > dataPointPos[pointIndex - 1].Y) + { + dataPointPos[pointIndex].Y = dataPointPos[pointIndex - 1].Y + minDifference; + } + else + { + dataPointPos[pointIndex].Y = dataPointPos[pointIndex - 1].Y - minDifference; + } + } + } + } + + } + + // Draw line if we have more than one data point + if(dataPointPos.Length > 1) + { + // Draw each data point + int index = 0; + DataPoint prevDataPoint = null; + double yValuePrev = 0.0; + double xValuePrev = 0.0; + bool showLabelAsValue = ser.IsValueShownAsLabel; + bool prevPointInArray = false; + foreach( DataPoint point in ser.Points ) + { + prevPointInArray = false; + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + //************************************************************ + //** Check if point marker or label is visible + //************************************************************ + if(!_processBaseChart) + { + string pointMarkerImage = point.MarkerImage; + MarkerStyle pointMarkerStyle = point.MarkerStyle; + + if( alwaysDrawMarkers || + pointMarkerStyle != MarkerStyle.None || + pointMarkerImage.Length > 0 || + showLabelAsValue || + point.IsValueShownAsLabel || + point.Label.Length > 0 ) + { + _processBaseChart = true; + } + } + + // Change Y value if line is out of plot area + double yValue = GetYValue(common, area, ser, point, index, this.YValueIndex); + + // Recalculates x position + double xValue = (indexedSeries) ? index + 1 : point.XValue; + + // If not first point + if(index != 0) + { + // Axes are logarithmic + yValue = VAxis.GetLogValue( yValue ); + xValue = HAxis.GetLogValue( xValue ); + + // Check if line is completly out of the data scaleView + if( (xValue <= hAxisMin && xValuePrev < hAxisMin) || + (xValue >= hAxisMax && xValuePrev > hAxisMax) || + (yValue <= vAxisMin && yValuePrev < vAxisMin) || + (yValue >= vAxisMax && yValuePrev > vAxisMax) ) + { + if(!drawOutsideLines) + { + // Check if next point also outside of the scaleView and on the + // same side as current point. If not line has to be processed + // to correctly handle tooltips. + // NOTE: Fixes issue #4961 + bool skipPoint = true; + if( common.ProcessModeRegions && + (index + 1) < ser.Points.Count) + { + DataPoint nextPoint = ser.Points[index + 1]; + + // Recalculates x position + double xValueNext = (indexedSeries) ? index + 2 : nextPoint.XValue; + + if( (xValue < hAxisMin && xValueNext > hAxisMin) || + (xValue > hAxisMax && xValueNext < hAxisMax) ) + { + skipPoint = false; + } + + + // Change Y value if line is out of plot area + if(skipPoint) + { + if( (yValue < vAxisMin && xValueNext > vAxisMin) || + (yValue > vAxisMax && xValueNext < vAxisMax) ) + { + skipPoint = false; + } + } + } + + // Skip point + if(skipPoint) + { + ++index; + prevDataPoint = point; + yValuePrev = yValue; + xValuePrev = xValue; + continue; + } + } + } + + // Check if line is partialy in the data scaleView + clipRegionSet = false; + if(this.lineTension != 0.0 || + xValuePrev < hAxisMin || xValuePrev > hAxisMax || + xValue > hAxisMax || xValue < hAxisMin || + yValuePrev < vAxisMin || yValuePrev > vAxisMax || + yValue < vAxisMin || yValue > vAxisMax ) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + + if(this.lineTension == 0 && !dataPointPosFilled) + { + float yPosition = 0f; + float xPosition = 0f; + + // Line reqires two points to draw + // Check if previous point is in the array + if(!prevPointInArray) + { + // Recalculates x/y position + yPosition = (float)VAxis.GetLinearPosition( yValuePrev ); + xPosition = (float)HAxis.GetLinearPosition( xValuePrev ); + + // Add point position into array + // IMPORTANT: Rounding was removed from this part of code because of + // very bad drawing in Flash. + dataPointPos[index - 1] = new PointF( + xPosition * chartWidthPercentage, + yPosition * chartHeightPercentage); + } + + + // Recalculates x/y position + yPosition = (float)VAxis.GetLinearPosition( yValue ); + xPosition = (float)HAxis.GetLinearPosition( xValue ); + + // Add point position into array + // IMPORTANT: Rounding was removed from this part of code because of + // very bad drawing in Flash. + dataPointPos[index] = new PointF( + xPosition * chartWidthPercentage, + yPosition * chartHeightPercentage); + + prevPointInArray = true; + } + + // Remeber pre-calculated point position + point.positionRel = graph.GetRelativePoint(dataPointPos[index]); + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + if( index != 0 && prevDataPoint.IsEmpty ) + { + // IsEmpty data point - second line + DrawLine( + graph, + common, + prevDataPoint, + ser, + dataPointPos, + index, + this.lineTension); + } + else + { + // Regular data point and empty point - first line + DrawLine( + graph, + common, + point, + ser, + dataPointPos, + index, + this.lineTension); + } + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + + // Remember previous point data + prevDataPoint = point; + yValuePrev = yValue; + xValuePrev = xValue; + } + else + { + // Get Y values of the current and previous data points + prevDataPoint = point; + yValuePrev = GetYValue(common, area, ser, point, index, 0); + xValuePrev = (indexedSeries) ? index + 1 : point.XValue; + yValuePrev = VAxis.GetLogValue( yValuePrev ); + xValuePrev = HAxis.GetLogValue( xValuePrev ); + + // Remeber pre-calculated point position + point.positionRel = new PointF( + (float)HAxis.GetPosition( xValuePrev ), + (float)VAxis.GetPosition( yValuePrev ) ); + } + + // Process image map selection for the first point + if(index == 0) + { + DrawLine( + graph, + common, + point, + ser, + dataPointPos, + index, + this.lineTension); + } + + // Increase data point index + ++index; + } + } + else if(dataPointPos.Length == 1 && + ser.Points.Count == 1) + { + //************************************************************ + //** Check if point marker or label is visible + //************************************************************ + if(!_processBaseChart) + { + if( alwaysDrawMarkers || + ser.Points[0].MarkerStyle != MarkerStyle.None || + ser.Points[0].MarkerImage.Length > 0 || + ser.IsValueShownAsLabel || + ser.Points[0].IsValueShownAsLabel || + ser.Points[0].Label.Length > 0 ) + { + _processBaseChart = true; + } + } + } + + // Reset points array + dataPointPos = null; + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + } + } + + /// + /// Calculate position and draw one chart line and/or shadow. + /// + /// Graphics object. + /// The Common elements object. + /// Point to draw the line for. + /// Point series. + /// Array of oints coordinates. + /// Index of point to draw. + /// Line tension. + virtual protected void DrawLine( + ChartGraphics graph, + CommonElements common, + DataPoint point, + Series series, + PointF[] points, + int pointIndex, + float tension) + { + int pointBorderWidth = point.BorderWidth; + + // **************************************************** + // Paint Mode + // **************************************************** + if( common.ProcessModePaint ) + { + // Start drawing from the second point + if(pointIndex > 0) + { + Color color = (useBorderColor) ? point.BorderColor : point.Color; + ChartDashStyle dashStyle = point.BorderDashStyle; + + // Draw line shadow + if(!disableShadow && series.ShadowOffset != 0 && series.ShadowColor != Color.Empty) + { + if(color != Color.Empty && color != Color.Transparent && pointBorderWidth > 0 && dashStyle != ChartDashStyle.NotSet) + { + Pen shadowPen = new Pen((series.ShadowColor.A != 255) ? series.ShadowColor : Color.FromArgb((useBorderColor) ? point.BorderColor.A/2 : point.Color.A/2, series.ShadowColor), pointBorderWidth); + shadowPen.DashStyle = graph.GetPenStyle( point.BorderDashStyle ); + shadowPen.StartCap = LineCap.Round; + shadowPen.EndCap = LineCap.Round; + + // Translate curve + GraphicsState graphicsState = graph.Save(); + Matrix transform = graph.Transform.Clone(); + transform.Translate(series.ShadowOffset, series.ShadowOffset); + graph.Transform = transform; + + // Draw shadow + if(this.lineTension == 0) + { + try + { + graph.DrawLine(shadowPen, points[pointIndex - 1], points[pointIndex]); + } + catch (OverflowException) + { + this.DrawTruncatedLine(graph, shadowPen, points[pointIndex - 1], points[pointIndex]); + } + } + else + { + graph.DrawCurve(shadowPen, points, pointIndex - 1, 1, tension); + } + graph.Restore(graphicsState); + } + } + + // If only shadow must be drawn - return + if(drawShadowOnly) + { + return; + } + + //// IsEmpty data ` color and style + // DT - removed code - line chart will have MS Office behavior for empty points -> broken line. + //if( point.IsEmpty ) + //{ + // if( point.Color == Color.IsEmpty) + // { + // color = Color.Black; + // } + // if( point.BorderDashStyle == ChartDashStyle.NotSet ) + // { + // dashStyle = ChartDashStyle.Dash; + // } + //} + + // Draw data point line + if(color != Color.Empty && pointBorderWidth > 0 && dashStyle != ChartDashStyle.NotSet) + { + if(_linePen.Color != color) + { + _linePen.Color = color; + } + if(_linePen.Width != pointBorderWidth) + { + _linePen.Width = pointBorderWidth; + } + if(_linePen.DashStyle != graph.GetPenStyle( dashStyle )) + { + _linePen.DashStyle = graph.GetPenStyle( dashStyle ); + } + + // Set Rounded Cap + if(_linePen.StartCap != LineCap.Round) + _linePen.StartCap = LineCap.Round; + if(_linePen.EndCap != LineCap.Round) + _linePen.EndCap = LineCap.Round; + + if(tension == 0) + { + // VSTS: 9698 - issue: the line start from X = 0 when GDI overflows (before we expected exception) + if (IsLinePointsOverflow(points[pointIndex - 1]) || IsLinePointsOverflow(points[pointIndex])) + { + this.DrawTruncatedLine(graph, _linePen, points[pointIndex - 1], points[pointIndex]); + } + else + { + try + { + graph.DrawLine(_linePen, points[pointIndex - 1], points[pointIndex]); + } + catch (OverflowException) + { + this.DrawTruncatedLine(graph, _linePen, points[pointIndex - 1], points[pointIndex]); + } + } + } + else + { + graph.DrawCurve(_linePen, points, pointIndex - 1, 1, tension); + } + } + } + } + + //************************************************************ + // Hot Regions mode used for image maps, tool tips and + // hit test function + //************************************************************ + if( common.ProcessModeRegions ) + { + int width = pointBorderWidth + 2; + + // Create grapics path object dor the curve + using (GraphicsPath path = new GraphicsPath()) + { + + // If line tension is zero - it's a straight line + if (this.lineTension == 0) + { + // Add half line segment prior to the data point + if (pointIndex > 0) + { + PointF first = points[pointIndex - 1]; + PointF second = points[pointIndex]; + first.X = (first.X + second.X) / 2f; + first.Y = (first.Y + second.Y) / 2f; + + if (Math.Abs(first.X - second.X) > Math.Abs(first.Y - second.Y)) + { + path.AddLine(first.X, first.Y - width, second.X, second.Y - width); + path.AddLine(second.X, second.Y + width, first.X, first.Y + width); + path.CloseAllFigures(); + } + else + { + path.AddLine(first.X - width, first.Y, second.X - width, second.Y); + path.AddLine(second.X + width, second.Y, first.X + width, first.Y); + path.CloseAllFigures(); + + } + } + + // Add half line segment after the data point + if (pointIndex + 1 < points.Length) + { + PointF first = points[pointIndex]; + PointF second = points[pointIndex + 1]; + second.X = (first.X + second.X) / 2f; + second.Y = (first.Y + second.Y) / 2f; + + // Set a marker in the path to separate from the first line segment + if (pointIndex > 0) + { + path.SetMarkers(); + } + + if (Math.Abs(first.X - second.X) > Math.Abs(first.Y - second.Y)) + { + path.AddLine(first.X, first.Y - width, second.X, second.Y - width); + path.AddLine(second.X, second.Y + width, first.X, first.Y + width); + path.CloseAllFigures(); + } + else + { + path.AddLine(first.X - width, first.Y, second.X - width, second.Y); + path.AddLine(second.X + width, second.Y, first.X + width, first.Y); + path.CloseAllFigures(); + } + } + + } + else if (pointIndex > 0) + { + try + { + path.AddCurve(points, pointIndex - 1, 1, this.lineTension); + path.Widen(new Pen(point.Color, pointBorderWidth + 2)); + path.Flatten(); + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + } + + // Path is empty + if (path.PointCount == 0) + { + return; + } + + // Allocate array of floats + PointF pointNew = PointF.Empty; + float[] coord = new float[path.PointCount * 2]; + PointF[] pathPoints = path.PathPoints; + for (int i = 0; i < path.PointCount; i++) + { + pointNew = graph.GetRelativePoint(pathPoints[i]); + coord[2 * i] = pointNew.X; + coord[2 * i + 1] = pointNew.Y; + } + + common.HotRegionsList.AddHotRegion(path, false, coord, point, series.Name, pointIndex); + } + } + } + + + private const long maxGDIRange = 0x800000; + // VSTS: 9698 - issue: the line start from X = 0 when GDI overflows (before we expected exception) + private bool IsLinePointsOverflow(PointF point) + { + return point.X <= -maxGDIRange || point.X >= maxGDIRange || point.Y <= -maxGDIRange || point.Y >= maxGDIRange; + } + + /// + /// During zooming there are scenarios when the line coordinates are extremly large and + /// originate outside of the chart pixel boundaries. This cause GDI+ line drawing methods + /// to throw stack overflow exceptions. + /// This method tries to change the coordinates into the chart boundaries and draw the line. + /// + /// Chart graphics. + /// Pen object that determines the color, width, and style of the line. + /// PointF structure that represents the first point to connect. + /// PointF structure that represents the second point to connect. + private void DrawTruncatedLine(ChartGraphics graph, Pen pen, PointF pt1, PointF pt2) + { + PointF adjustedPoint1 = PointF.Empty; + PointF adjustedPoint2 = PointF.Empty; + + // Check line angle. Intersection with vertical or horizontal lines will be done based on the results + bool topBottomLine = (Math.Abs(pt2.Y - pt1.Y) > Math.Abs(pt2.X - pt1.X)); + RectangleF rect = new RectangleF(0, 0, graph.Common.ChartPicture.Width, graph.Common.ChartPicture.Height); + if (topBottomLine) + { + // Find the intersection point between the original line and Y = 0 and Y = Height lines + adjustedPoint1 = rect.Contains(pt1) ? pt1 : GetIntersectionY(pt1, pt2, 0); + adjustedPoint2 = rect.Contains(pt2) ? pt2 : GetIntersectionY(pt1, pt2, graph.Common.ChartPicture.Height); + } + else + { + // Find the intersection point between the original line and X = 0 and X = Width lines + adjustedPoint1 = rect.Contains(pt1) ? pt1 : GetIntersectionX(pt1, pt2, 0); + adjustedPoint2 = rect.Contains(pt2) ? pt2 : GetIntersectionX(pt1, pt2, graph.Common.ChartPicture.Width); + } + + // Draw Line + graph.DrawLine(pen, adjustedPoint1, adjustedPoint2); + } + + /// + /// Gets intersection point coordinates between point line and and horizontal + /// line specified by Y coordinate. + /// + /// First data point. + /// Second data point. + /// Y coordinate. + /// Intersection point coordinates. + internal static PointF GetIntersectionY(PointF firstPoint, PointF secondPoint, float pointY) + { + PointF intersectionPoint = new PointF(); + intersectionPoint.Y = pointY; + intersectionPoint.X = (pointY - firstPoint.Y) * + (secondPoint.X - firstPoint.X) / + (secondPoint.Y - firstPoint.Y) + + firstPoint.X; + return intersectionPoint; + } + + /// + /// Gets intersection point coordinates between point line and and vertical + /// line specified by X coordinate. + /// + /// First data point. + /// Second data point. + /// X coordinate. + /// Intersection point coordinates. + internal static PointF GetIntersectionX(PointF firstPoint, PointF secondPoint, float pointX) + { + PointF intersectionPoint = new PointF(); + intersectionPoint.X = pointX; + intersectionPoint.Y = (pointX - firstPoint.X) * + (secondPoint.Y - firstPoint.Y) / + (secondPoint.X - firstPoint.X) + + firstPoint.Y; + return intersectionPoint; + } + + /// + /// Draw chart line. + /// + /// Graphics object. + /// Point to draw the line for. + /// Point series. + /// First line point. + /// Seconf line point. + protected void DrawLine( + ChartGraphics graph, + DataPoint point, + Series series, + PointF firstPoint, + PointF secondPoint) + { + graph.DrawLineRel( point.Color, point.BorderWidth, point.BorderDashStyle, firstPoint, secondPoint, series.ShadowColor, series.ShadowOffset ); + } + + /// + /// Checks if line tension is supported by the chart type. + /// + /// True if line tension is supported. + protected virtual bool IsLineTensionSupported() + { + return false; + } + + #endregion + + #region Position helper methods + + /// + /// Gets default line tension. + /// + /// Default line tension. + virtual protected float GetDefaultTension() + { + return 0f; + } + + /// + /// Gets label position depending on the prev/next point values. + /// This method will reduce label overlapping with the chart itself (line). + /// + /// Data series. + /// Point index. + /// Return automaticly detected label position. + override protected LabelAlignmentStyles GetAutoLabelPosition(Series series, int pointIndex) + { + int pointsCount = series.Points.Count; // Number of data points + double previous; // Y Value from the previous data point + double next; // Y Value from the next data point + + // There is only one data point + if( pointsCount == 1 ) + { + return LabelAlignmentStyles.Top; + } + + // Y Value from the current data point + double current = GetYValue(Common, Area, series, series.Points[pointIndex], pointIndex, 0); + + // The data point is between two data points + if( pointIndex < pointsCount - 1 && pointIndex > 0 ) + { + // Y Value from the previous data point + previous = GetYValue(Common, Area, series, series.Points[pointIndex-1], pointIndex-1, 0); + + // Y Value from the next data point + next = GetYValue(Common, Area, series, series.Points[pointIndex+1], pointIndex+1, 0); + + // Put the label below lines + if( previous > current && next > current ) + { + return LabelAlignmentStyles.Bottom; + } + } + + // This is the last data point + if( pointIndex == pointsCount - 1 ) + { + // Y Value from the previous data point + previous = GetYValue(Common, Area, series, series.Points[pointIndex-1], pointIndex-1, 0); + + // Put the label below line + if( previous > current ) + { + return LabelAlignmentStyles.Bottom; + } + } + + // This is the first data point + if( pointIndex == 0 ) + { + // Y Value from the next data point + next = GetYValue(Common, Area, series, series.Points[pointIndex + 1], pointIndex + 1, 0); + + // Put the label below line + if( next > current ) + { + return LabelAlignmentStyles.Bottom; + } + } + + return LabelAlignmentStyles.Top; + } + + /// + /// Fills a PointF array of data points absolute pixel positions. + /// + /// Graphics object. + /// Point series. + /// Indicate that point index should be used as X value. + /// Array of data points position. + virtual protected PointF[] GetPointsPosition(ChartGraphics graph, Series series, bool indexedSeries) + { + PointF[] pointPos = new PointF[series.Points.Count]; + int index = 0; + foreach( DataPoint point in series.Points ) + { + // Change Y value if line is out of plot area + double yValue = GetYValue(Common, Area, series, point, index, this.YValueIndex); + + // Recalculates y position + double yPosition = VAxis.GetPosition( yValue ); + + // Recalculates x position + double xPosition = HAxis.GetPosition( point.XValue ); + if( indexedSeries ) + { + xPosition = HAxis.GetPosition( index + 1 ); + } + + // Add point position into array + // IMPORTANT: Rounding was removed from this part of code because of + // very bad drawing in Flash. + pointPos[index] = new PointF( + (float)xPosition * (graph.Common.ChartPicture.Width - 1) / 100F, + (float)yPosition * (graph.Common.ChartPicture.Height - 1) / 100F); + + index++; + } + + return pointPos; + } + + #endregion + + #region 3D Drawing and selection methods + + /// + /// Draws or perform the hit test for the line chart in 3D. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + protected void ProcessLineChartType3D( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + + // Reset graphics fields + graph.frontLinePen = null; + graph.frontLinePoint1 = PointF.Empty; + graph.frontLinePoint2 = PointF.Empty; + + // Get list of series to draw + List typeSeries = null; + if( (area.Area3DStyle.IsClustered && this.SideBySideSeries) || + this.Stacked) + { + // Draw all series of the same chart type + typeSeries = area.GetSeriesFromChartType(Name); + } + else + { + // Draw just one chart series + typeSeries = new List(); + typeSeries.Add(seriesToDraw.Name); + } + + //*************************************************************** + //** Check that data points XValues. Must be sorted or set to 0. + //*************************************************************** + foreach(string seriesName in typeSeries) + { + // Get series object + Series currentSeries = common.DataManager.Series[seriesName]; + + // Do not check indexed series + if(currentSeries.IsXValueIndexed) + { + continue; + } + + // Loop through all data points in the series + bool allZeros = true; + int order = int.MaxValue; // 0 - Ascending; 1 - Descending; + double prevValue = double.NaN; + foreach(DataPoint dp in currentSeries.Points) + { + // Check if X values were set (or all zeros) + if(allZeros && dp.XValue == 0.0) + { + continue; + } + allZeros = false; + + // Check X values order + bool validOrder = true; + if(!double.IsNaN(prevValue) && dp.XValue != prevValue) + { + // Determine sorting order + if(order == int.MaxValue) + { + order = (dp.XValue > prevValue) ? 0 : 1; // 0 - Ascending; 1 - Descending; + } + + // Compare current X value with previous + if(dp.XValue > prevValue && order == 1) + { + validOrder = false; + } + if(dp.XValue < prevValue && order == 0) + { + validOrder = false; + } + } + + // Throw error exception + if(!validOrder) + { + throw (new InvalidOperationException(SR.Exception3DChartPointsXValuesUnsorted)); + } + + // Remember previous value + prevValue = dp.XValue; + } + } + + //************************************************************ + //** Get order of data points drawing + //************************************************************ + ArrayList dataPointDrawingOrder = area.GetDataPointDrawingOrder( + typeSeries, + this, + selection, + this.COPCoordinatesToCheck, + null, + 0, + false); + + + //************************************************************ + //** Get line tension attribute + //************************************************************ + this.lineTension = GetDefaultTension(); + if(dataPointDrawingOrder.Count > 0) + { + Series firstSeries = firstSeries = ((DataPoint3D)dataPointDrawingOrder[0]).dataPoint.series; + if(IsLineTensionSupported() && firstSeries.IsCustomPropertySet(CustomPropertyName.LineTension)) + { + this.lineTension = CommonElements.ParseFloat(firstSeries[CustomPropertyName.LineTension]); + } + } + + //************************************************************ + //** Check if second ALL points loop is required + //************************************************************ + allPointsLoopsNumber = GetPointLoopNumber(selection, dataPointDrawingOrder); + + //************************************************************ + //** Loop through all data poins (one or two times) + //************************************************************ + for(int pointsLoop = 0; pointsLoop < allPointsLoopsNumber; pointsLoop++) + { + int index = 0; + this.centerPointIndex = int.MaxValue; + foreach(object obj in dataPointDrawingOrder) + { + // Get point & series + DataPoint3D pointEx = (DataPoint3D) obj; + DataPoint point = pointEx.dataPoint; + Series ser = point.series; + + // Set active horizontal/vertical axis + HAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + VAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + hAxisMin = HAxis.ViewMinimum; + hAxisMax = HAxis.ViewMaximum; + vAxisMin = VAxis.ViewMinimum; + vAxisMax = VAxis.ViewMaximum; + + // First point is not drawn as a 3D line + if(pointEx.index > 1) + { + //************************************************************ + //** Get previous data point using the point index in the series + //************************************************************ + int pointArrayIndex = index; + DataPoint3D prevDataPointEx = ChartGraphics.FindPointByIndex( + dataPointDrawingOrder, + pointEx.index - 1, + (this.multiSeries) ? pointEx : null, + ref pointArrayIndex); + + //************************************************************ + //** Painting mode + //************************************************************ + GraphicsPath rectPath = null; + + // Get Y values of the current and previous data points + double yValue = GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, 0); + double yValuePrev = GetYValue(common, area, ser, prevDataPointEx.dataPoint, prevDataPointEx.index - 1, 0); + double xValue = (pointEx.indexedSeries) ? pointEx.index : pointEx.dataPoint.XValue; + double xValuePrev = (prevDataPointEx.indexedSeries) ? prevDataPointEx.index : prevDataPointEx.dataPoint.XValue; + + // Axes are logarithmic + yValue = VAxis.GetLogValue( yValue ); + yValuePrev = VAxis.GetLogValue( yValuePrev ); + + xValue = HAxis.GetLogValue( xValue ); + xValuePrev = HAxis.GetLogValue( xValuePrev ); + + //************************************************************ + //** Draw line + //************************************************************ + DataPoint3D pointAttr = (prevDataPointEx.dataPoint.IsEmpty) ? prevDataPointEx : pointEx; + if(pointAttr.dataPoint.Color != Color.Empty) + { + // Detect if we need to get graphical path of drawn object + DrawingOperationTypes drawingOperationType = DrawingOperationTypes.DrawElement; + + if( common.ProcessModeRegions ) + { + drawingOperationType |= DrawingOperationTypes.CalcElementPath; + } + + // Check if point markers lines should be drawn + this.showPointLines = false; + if(pointAttr.dataPoint.IsCustomPropertySet(CustomPropertyName.ShowMarkerLines)) + { + if(String.Compare(pointAttr.dataPoint[CustomPropertyName.ShowMarkerLines], "TRUE", StringComparison.OrdinalIgnoreCase) == 0) + { + this.showPointLines = true; + } + } + else + { + if(pointAttr.dataPoint.series.IsCustomPropertySet(CustomPropertyName.ShowMarkerLines)) + { + if (String.Compare(pointAttr.dataPoint.series[CustomPropertyName.ShowMarkerLines], "TRUE", StringComparison.OrdinalIgnoreCase) == 0) + { + this.showPointLines = true; + } + } + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw line surface + area.IterationCounter = 0; + rectPath = Draw3DSurface( + area, + graph, + area.matrix3D, + area.Area3DStyle.LightStyle, + prevDataPointEx, + pointAttr.zPosition, + pointAttr.depth, + dataPointDrawingOrder, + index, + pointsLoop, + lineTension, + drawingOperationType, + 0f, 0f, + new PointF(float.NaN, float.NaN), + new PointF(float.NaN, float.NaN), + false); + + // End Svg Selection mode + graph.EndHotRegion( ); + } + + //************************************************************ + // Hot Regions mode used for image maps, tool tips and + // hit test function + //************************************************************ + if( common.ProcessModeRegions && rectPath != null) + { + common.HotRegionsList.AddHotRegion( + rectPath, + false, + graph, + point, + ser.Name, + pointEx.index - 1 ); + } + if (rectPath != null) + { + rectPath.Dispose(); + } + } + + // Increase point index + ++index; + } + } + } + + /// + /// Draws a 3D surface connecting the two specified points in 2D space. + /// Used to draw Line based charts. + /// + /// Chart area reference. + /// Chart graphics. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Previous data point object. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Array of points. + /// Index of point to draw. + /// Index of points loop. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Darkenning scale for top surface. 0 - None. + /// Darkenning scale for bottom surface. 0 - None. + /// Position where the third point is actually located or float.NaN if same as in "firstPoint". + /// Position where the fourth point is actually located or float.NaN if same as in "secondPoint". + /// Indicates that drawn segment is 3D clipped. Only top/bottom should be drawn. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + protected virtual GraphicsPath Draw3DSurface( + ChartArea area, + ChartGraphics graph, + Matrix3D matrix, + LightStyle lightStyle, + DataPoint3D prevDataPointEx, + float positionZ, + float depth, + ArrayList points, + int pointIndex, + int pointLoopIndex, + float tension, + DrawingOperationTypes operationType, + float topDarkening, + float bottomDarkening, + PointF thirdPointPosition, + PointF fourthPointPosition, + bool clippedSegment) + { + // Check if points are drawn from sides to center (do only once) + if(centerPointIndex == int.MaxValue) + { + centerPointIndex = GetCenterPointIndex(points); + } + + //************************************************************ + //** Find line first & second points + //************************************************************ + DataPoint3D secondPoint = (DataPoint3D)points[pointIndex]; + int pointArrayIndex = pointIndex; + DataPoint3D firstPoint = ChartGraphics.FindPointByIndex( + points, + secondPoint.index - 1, + (this.multiSeries) ? secondPoint : null, + ref pointArrayIndex); + + + // Fint point with line properties + DataPoint3D pointAttr = secondPoint; + if(prevDataPointEx.dataPoint.IsEmpty) + { + pointAttr = prevDataPointEx; + } + else if(firstPoint.index > secondPoint.index) + { + pointAttr = firstPoint; + } + + // Adjust point visual properties + Color color = (useBorderColor) ? pointAttr.dataPoint.BorderColor : pointAttr.dataPoint.Color; + ChartDashStyle dashStyle = pointAttr.dataPoint.BorderDashStyle; + if( pointAttr.dataPoint.IsEmpty && pointAttr.dataPoint.Color == Color.Empty) + { + color = Color.Gray; + } + if( pointAttr.dataPoint.IsEmpty && pointAttr.dataPoint.BorderDashStyle == ChartDashStyle.NotSet ) + { + dashStyle = ChartDashStyle.Solid; + } + + // Draw point using 2 points + return graph.Draw3DSurface( + area, + matrix, + lightStyle, + SurfaceNames.Top, + positionZ, + depth, + color, + pointAttr.dataPoint.BorderColor, + pointAttr.dataPoint.BorderWidth, + dashStyle, + firstPoint, + secondPoint, + points, + pointIndex, + tension, + operationType, + LineSegmentType.Single, + (this.showPointLines) ? true : false, + false, + area.ReverseSeriesOrder, + this.multiSeries, + 0, + true); + } + + /// + /// Gets index of center point. + /// + /// Points list. + /// Index of center point or int.MaxValue. + protected int GetCenterPointIndex(ArrayList points) + { + for(int pointIndex = 1; pointIndex < points.Count; pointIndex++) + { + DataPoint3D firstPoint = (DataPoint3D)points[pointIndex - 1]; + DataPoint3D secondPoint = (DataPoint3D)points[pointIndex]; + if(Math.Abs(secondPoint.index - firstPoint.index) != 1) + { + return pointIndex - 1; + } + } + return int.MaxValue; + } + + /// + /// Returns how many loops through all data points is required (1 or 2) + /// + /// Selection indicator. + /// Points array list. + /// Number of loops (1 or 2). + virtual protected int GetPointLoopNumber(bool selection, ArrayList pointsArray) + { + return 1; + } + + /// + /// Clips the top (left and right) points of the segment to plotting area. + /// Used in area and range charts. + /// + /// Segment area path. + /// First data point. + /// Second data point. + /// Points are in reversed order. + /// Chart area reference. + /// Chart graphics. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Previous data point object. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Array of points. + /// Index of point to draw. + /// Index of points loop. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Define surface segment type if it consists of several segments. + /// Darkenning scale for top surface. 0 - None. + /// Darkenning scale for bottom surface. 0 - None. + /// Returns element shape path if operationType parameter is set to CalcElementPath, otherwise Null. + protected bool ClipTopPoints( + GraphicsPath resultPath, + ref DataPoint3D firstPoint, + ref DataPoint3D secondPoint, + bool reversed, + ChartArea area, + ChartGraphics graph, + Matrix3D matrix, + LightStyle lightStyle, + DataPoint3D prevDataPointEx, + float positionZ, + float depth, + ArrayList points, + int pointIndex, + int pointLoopIndex, + float tension, + DrawingOperationTypes operationType, + LineSegmentType surfaceSegmentType, + float topDarkening, + float bottomDarkening) + { + // Do not allow recursion to go too deep + ++area.IterationCounter; + if(area.IterationCounter > 20) + { + area.IterationCounter = 0; + return true; + } + + //**************************************************************** + //** Check point values + //**************************************************************** + if( double.IsNaN(firstPoint.xPosition) || + double.IsNaN(firstPoint.yPosition) || + double.IsNaN(secondPoint.xPosition) || + double.IsNaN(secondPoint.yPosition) ) + { + return true; + } + + //**************************************************************** + //** Round plot are position and point coordinates + //**************************************************************** + int decimals = 3; + decimal plotAreaPositionX = Math.Round((decimal)area.PlotAreaPosition.X, decimals); + decimal plotAreaPositionY = Math.Round((decimal)area.PlotAreaPosition.Y, decimals); + decimal plotAreaPositionRight = Math.Round((decimal)area.PlotAreaPosition.Right, decimals); + decimal plotAreaPositionBottom = Math.Round((decimal)area.PlotAreaPosition.Bottom, decimals); + + // Make area a little bit bigger + plotAreaPositionX -= 0.001M; + plotAreaPositionY -= 0.001M; + plotAreaPositionRight += 0.001M; + plotAreaPositionBottom += 0.001M; + + // Round top points coordinates + firstPoint.xPosition = Math.Round(firstPoint.xPosition, decimals); + firstPoint.yPosition = Math.Round(firstPoint.yPosition, decimals); + secondPoint.xPosition = Math.Round(secondPoint.xPosition, decimals); + secondPoint.yPosition = Math.Round(secondPoint.yPosition, decimals); + + + //**************************************************************** + //** Clip area data points inside the plotting area + //**************************************************************** + + // Chech data points X values + if((decimal)firstPoint.xPosition < plotAreaPositionX || + (decimal)firstPoint.xPosition > plotAreaPositionRight || + (decimal)secondPoint.xPosition < plotAreaPositionX || + (decimal)secondPoint.xPosition > plotAreaPositionRight ) + { + // Check if surface completly out of the plot area + if((decimal)firstPoint.xPosition < plotAreaPositionX && + (decimal)secondPoint.xPosition < plotAreaPositionX) + { + return true; + } + // Check if surface completly out of the plot area + if((decimal)firstPoint.xPosition > plotAreaPositionRight && + (decimal)secondPoint.xPosition > plotAreaPositionRight) + { + return true; + } + + // Only part of the surface is outside - fix X value and adjust Y value + if((decimal)firstPoint.xPosition < plotAreaPositionX) + { + firstPoint.yPosition = ((double)plotAreaPositionX - secondPoint.xPosition) / + (firstPoint.xPosition - secondPoint.xPosition) * + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.yPosition; + firstPoint.xPosition = (double)plotAreaPositionX; + } + else if((decimal)firstPoint.xPosition > plotAreaPositionRight) + { + firstPoint.yPosition = ((double)plotAreaPositionRight - secondPoint.xPosition) / + (firstPoint.xPosition - secondPoint.xPosition) * + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.yPosition; + firstPoint.xPosition = (double)plotAreaPositionRight; + } + if((decimal)secondPoint.xPosition < plotAreaPositionX) + { + secondPoint.yPosition = ((double)plotAreaPositionX - secondPoint.xPosition) / + (firstPoint.xPosition - secondPoint.xPosition) * + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.yPosition; + secondPoint.xPosition = (double)plotAreaPositionX; + } + else if((decimal)secondPoint.xPosition > plotAreaPositionRight) + { + secondPoint.yPosition = ((double)plotAreaPositionRight - secondPoint.xPosition) / + (firstPoint.xPosition - secondPoint.xPosition) * + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.yPosition; + secondPoint.xPosition = (double)plotAreaPositionRight; + } + } + + // Chech data points Y values + if((decimal)firstPoint.yPosition < plotAreaPositionY || + (decimal)firstPoint.yPosition > plotAreaPositionBottom || + (decimal)secondPoint.yPosition < plotAreaPositionY || + (decimal)secondPoint.yPosition > plotAreaPositionBottom ) + { + // Remember previous y positions + double prevFirstPointY = firstPoint.yPosition; + double prevSecondPointY = secondPoint.yPosition; + + // Check if whole line is outside plotting region + bool surfaceCompletlyOutside = false; + bool outsideBottom = false; + if((decimal)firstPoint.yPosition < plotAreaPositionY && + (decimal)secondPoint.yPosition < plotAreaPositionY) + { + surfaceCompletlyOutside = true; + firstPoint.yPosition = (double)plotAreaPositionY; + secondPoint.yPosition = (double)plotAreaPositionY; + } + if((decimal)firstPoint.yPosition > plotAreaPositionBottom && + (decimal)secondPoint.yPosition > plotAreaPositionBottom) + { + surfaceCompletlyOutside = true; + outsideBottom = true; + firstPoint.yPosition = (double)plotAreaPositionBottom; + secondPoint.yPosition = (double)plotAreaPositionBottom; + } + + // Draw just one surface + if(surfaceCompletlyOutside) + { + resultPath = Draw3DSurface( firstPoint, secondPoint, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, surfaceSegmentType, + 0.5f, 0f, + new PointF(float.NaN, float.NaN), + new PointF(float.NaN, float.NaN), + outsideBottom, + false, true); + + // Restore previous y positions + firstPoint.yPosition = prevFirstPointY; + secondPoint.yPosition = prevSecondPointY; + + return true; + } + + // Get intersection point + DataPoint3D intersectionPoint = new DataPoint3D(); + intersectionPoint.yPosition = (double)plotAreaPositionY; + if((decimal)firstPoint.yPosition > plotAreaPositionBottom || + (decimal)secondPoint.yPosition > plotAreaPositionBottom ) + { + intersectionPoint.yPosition = (double)plotAreaPositionBottom; + } + intersectionPoint.xPosition = (intersectionPoint.yPosition - secondPoint.yPosition) * + (firstPoint.xPosition - secondPoint.xPosition) / + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.xPosition; + + if(double.IsNaN(intersectionPoint.xPosition) || + double.IsInfinity(intersectionPoint.xPosition) || + double.IsNaN(intersectionPoint.yPosition) || + double.IsInfinity(intersectionPoint.yPosition) ) + { + return true; + } + + // Check if there are 2 intersection points (3 segments) + int segmentNumber = 2; + DataPoint3D intersectionPoint2 = null; + if( ((decimal)firstPoint.yPosition < plotAreaPositionY && + (decimal)secondPoint.yPosition > plotAreaPositionBottom) || + ((decimal)firstPoint.yPosition > plotAreaPositionBottom && + (decimal)secondPoint.yPosition < plotAreaPositionY)) + { + segmentNumber = 3; + intersectionPoint2 = new DataPoint3D(); + if((decimal)intersectionPoint.yPosition == plotAreaPositionY) + { + intersectionPoint2.yPosition = (double)plotAreaPositionBottom; + } + else + { + intersectionPoint2.yPosition = (double)plotAreaPositionY; + } + intersectionPoint2.xPosition = (intersectionPoint2.yPosition - secondPoint.yPosition) * + (firstPoint.xPosition - secondPoint.xPosition) / + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.xPosition; + + if(double.IsNaN(intersectionPoint2.xPosition) || + double.IsInfinity(intersectionPoint2.xPosition) || + double.IsNaN(intersectionPoint2.yPosition) || + double.IsInfinity(intersectionPoint2.yPosition) ) + { + return true; + } + + // Switch intersection points + if((decimal)firstPoint.yPosition > plotAreaPositionBottom) + { + DataPoint3D tempPoint = new DataPoint3D(); + tempPoint.xPosition = intersectionPoint.xPosition; + tempPoint.yPosition = intersectionPoint.yPosition; + intersectionPoint.xPosition = intersectionPoint2.xPosition; + intersectionPoint.yPosition = intersectionPoint2.yPosition; + intersectionPoint2.xPosition = tempPoint.xPosition; + intersectionPoint2.yPosition = tempPoint.yPosition; + } + } + + + // Adjust points Y values + bool firstSegmentVisible = true; + bool firstSegmentOutsideBottom = false; + bool secondSegmentOutsideBottom = false; + if((decimal)firstPoint.yPosition < plotAreaPositionY) + { + firstSegmentVisible = false; + firstPoint.yPosition = (double)plotAreaPositionY; + } + else if((decimal)firstPoint.yPosition > plotAreaPositionBottom) + { + firstSegmentOutsideBottom = true; + firstSegmentVisible = false; + firstPoint.yPosition = (double)plotAreaPositionBottom; + } + if((decimal)secondPoint.yPosition < plotAreaPositionY) + { + secondPoint.yPosition = (double)plotAreaPositionY; + } + else if((decimal)secondPoint.yPosition > plotAreaPositionBottom) + { + secondSegmentOutsideBottom = true; + secondPoint.yPosition = (double)plotAreaPositionBottom; + } + + // Draw surfaces in 2 or 3 segments + for(int segmentIndex = 0; segmentIndex < 3; segmentIndex++) + { + GraphicsPath segmentPath = null; + if(segmentIndex == 0 && !reversed || + segmentIndex == 2 && reversed) + { + // Draw first segment + if(intersectionPoint2 == null) + { + intersectionPoint2 = intersectionPoint; + } + intersectionPoint2.dataPoint = secondPoint.dataPoint; + intersectionPoint2.index = secondPoint.index; + intersectionPoint2.xCenterVal = secondPoint.xCenterVal; + + segmentPath = Draw3DSurface( firstPoint, intersectionPoint2, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, + (surfaceSegmentType == LineSegmentType.Middle) ? LineSegmentType.Middle : LineSegmentType.First, + (firstSegmentVisible && segmentNumber != 3) ? 0f : 0.5f, 0f, + new PointF(float.NaN, float.NaN), + new PointF((float)intersectionPoint2.xPosition, float.NaN), + firstSegmentOutsideBottom, + false, true); + + } + + if(segmentIndex == 1 && intersectionPoint2 != null && segmentNumber == 3) + { + // Draw middle segment + intersectionPoint2.dataPoint = secondPoint.dataPoint; + intersectionPoint2.index = secondPoint.index; + intersectionPoint2.xCenterVal = secondPoint.xCenterVal; + + intersectionPoint.xCenterVal = firstPoint.xCenterVal; + intersectionPoint.index = firstPoint.index; + intersectionPoint.dataPoint = firstPoint.dataPoint; + + segmentPath = Draw3DSurface( intersectionPoint, intersectionPoint2, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, LineSegmentType.Middle, + topDarkening, bottomDarkening, + new PointF((float)intersectionPoint.xPosition, float.NaN), + new PointF((float)intersectionPoint2.xPosition, float.NaN), + false, + false, true); + + } + + if(segmentIndex == 2 && !reversed || + segmentIndex == 0 && reversed) + { + // Draw second segment + intersectionPoint.dataPoint = firstPoint.dataPoint; + intersectionPoint.index = firstPoint.index; + intersectionPoint.xCenterVal = firstPoint.xCenterVal; + + segmentPath = Draw3DSurface( intersectionPoint, secondPoint, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, + (surfaceSegmentType == LineSegmentType.Middle) ? LineSegmentType.Middle : LineSegmentType.Last, + (!firstSegmentVisible && segmentNumber != 3) ? 0f : 0.5f, 0f, + new PointF((float)intersectionPoint.xPosition, float.NaN), + new PointF(float.NaN, float.NaN), + secondSegmentOutsideBottom, + false, true); + + } + + // Add segment path + if(resultPath != null && segmentPath != null && segmentPath.PointCount > 0) + { + resultPath.AddPath(segmentPath, true); + } + } + + // Restore previous y positions + firstPoint.yPosition = prevFirstPointY; + secondPoint.yPosition = prevSecondPointY; + + return true; + } + return false; + } + + /// + /// Clips the bottom (left and right) points of the segment to plotting area. + /// Used in area and range charts. + /// + /// + /// First data point. + /// Second data point. + /// Coordinates of the bottom left point. + /// Coordinates of the bottom right point. + /// Points are in reversed order. + /// Chart area reference. + /// Chart graphics. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Previous data point object. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Array of points. + /// Index of point to draw. + /// Index of points loop. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Define surface segment type if it consists of several segments. + /// Darkenning scale for top surface. 0 - None. + /// Darkenning scale for bottom surface. 0 - None. + /// Returns element shape path if operationType parameter is set to CalcElementPath, otherwise Null. + protected bool ClipBottomPoints( + GraphicsPath resultPath, + ref DataPoint3D firstPoint, + ref DataPoint3D secondPoint, + ref PointF thirdPoint, + ref PointF fourthPoint, + bool reversed, + ChartArea area, + ChartGraphics graph, + Matrix3D matrix, + LightStyle lightStyle, + DataPoint3D prevDataPointEx, + float positionZ, + float depth, + ArrayList points, + int pointIndex, + int pointLoopIndex, + float tension, + DrawingOperationTypes operationType, + LineSegmentType surfaceSegmentType, + float topDarkening, + float bottomDarkening) + { + // Do not allow recursion to go too deep + ++area.IterationCounter; + if(area.IterationCounter > 20) + { + area.IterationCounter = 0; + return true; + } + + //**************************************************************** + //** Round plot are position and point coordinates + //**************************************************************** + int decimals = 3; + decimal plotAreaPositionX = Math.Round((decimal)area.PlotAreaPosition.X, decimals); + decimal plotAreaPositionY = Math.Round((decimal)area.PlotAreaPosition.Y, decimals); + decimal plotAreaPositionRight = Math.Round((decimal)area.PlotAreaPosition.Right, decimals); + decimal plotAreaPositionBottom = Math.Round((decimal)area.PlotAreaPosition.Bottom, decimals); + + // Make area a little bit bigger + plotAreaPositionX -= 0.001M; + plotAreaPositionY -= 0.001M; + plotAreaPositionRight += 0.001M; + plotAreaPositionBottom += 0.001M; + + + + // Round top points coordinates + firstPoint.xPosition = Math.Round(firstPoint.xPosition, decimals); + firstPoint.yPosition = Math.Round(firstPoint.yPosition, decimals); + secondPoint.xPosition = Math.Round(secondPoint.xPosition, decimals); + secondPoint.yPosition = Math.Round(secondPoint.yPosition, decimals); + + thirdPoint.X = (float)Math.Round(thirdPoint.X, decimals); + thirdPoint.Y = (float)Math.Round(thirdPoint.Y, decimals); + + fourthPoint.X = (float)Math.Round(fourthPoint.X, decimals); + fourthPoint.Y = (float)Math.Round(fourthPoint.Y, decimals); + + //**************************************************************** + //** Clip area data points inside the plotting area + //**************************************************************** + + // Chech data points Y values + if((decimal)thirdPoint.Y < plotAreaPositionY || + (decimal)thirdPoint.Y > plotAreaPositionBottom || + (decimal)fourthPoint.Y < plotAreaPositionY || + (decimal)fourthPoint.Y > plotAreaPositionBottom ) + { + // Remember previous y positions + PointF prevThirdPoint = new PointF(thirdPoint.X, thirdPoint.Y); + PointF prevFourthPoint = new PointF(fourthPoint.X, fourthPoint.Y); + + // Check if whole line is outside plotting region + bool surfaceCompletlyOutside = false; + bool outsideTop = false; + if((decimal)thirdPoint.Y < plotAreaPositionY && + (decimal)fourthPoint.Y < plotAreaPositionY) + { + outsideTop = true; + surfaceCompletlyOutside = true; + thirdPoint.Y = area.PlotAreaPosition.Y; + fourthPoint.Y = area.PlotAreaPosition.Y; + } + if((decimal)thirdPoint.Y > plotAreaPositionBottom && + (decimal)fourthPoint.Y > plotAreaPositionBottom) + { + surfaceCompletlyOutside = true; + thirdPoint.Y = area.PlotAreaPosition.Bottom; + fourthPoint.Y = area.PlotAreaPosition.Bottom; + } + + // Draw just one surface + if(surfaceCompletlyOutside) + { + resultPath = Draw3DSurface( firstPoint, secondPoint, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, surfaceSegmentType, + topDarkening, 0.5f, + new PointF(thirdPoint.X, thirdPoint.Y), + new PointF(fourthPoint.X, fourthPoint.Y), + outsideTop, + false, false); + + // Restore previous x\y positions + thirdPoint = new PointF(prevThirdPoint.X, prevThirdPoint.Y); + fourthPoint = new PointF(prevFourthPoint.X, prevFourthPoint.Y); + + return true; + } + + // Get intersection point + DataPoint3D intersectionPoint = new DataPoint3D(); + bool firstIntersectionOnBottom = false; + intersectionPoint.yPosition = (double)plotAreaPositionY; + if((decimal)thirdPoint.Y > plotAreaPositionBottom || + (decimal)fourthPoint.Y > plotAreaPositionBottom ) + { + intersectionPoint.yPosition = (double)area.PlotAreaPosition.Bottom; + firstIntersectionOnBottom = true; + } + intersectionPoint.xPosition = (intersectionPoint.yPosition - fourthPoint.Y) * + (thirdPoint.X - fourthPoint.X) / + (thirdPoint.Y - fourthPoint.Y) + + fourthPoint.X; + + // Intersection point must be between first and second points + intersectionPoint.yPosition = (intersectionPoint.xPosition - secondPoint.xPosition) / + (firstPoint.xPosition - secondPoint.xPosition) * + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.yPosition; + + if(double.IsNaN(intersectionPoint.xPosition) || + double.IsInfinity(intersectionPoint.xPosition) || + double.IsNaN(intersectionPoint.yPosition) || + double.IsInfinity(intersectionPoint.yPosition) ) + { + return true; + } + + // Check if there are 2 intersection points (3 segments) + int segmentNumber = 2; + DataPoint3D intersectionPoint2 = null; + bool switchPoints = false; + if( ((decimal)thirdPoint.Y < plotAreaPositionY && + (decimal)fourthPoint.Y > plotAreaPositionBottom) || + ((decimal)thirdPoint.Y > plotAreaPositionBottom && + (decimal)fourthPoint.Y < plotAreaPositionY)) + { + segmentNumber = 3; + intersectionPoint2 = new DataPoint3D(); + if(!firstIntersectionOnBottom) + { + intersectionPoint2.yPosition = (double)area.PlotAreaPosition.Bottom; + } + else + { + intersectionPoint2.yPosition = (double)area.PlotAreaPosition.Y; + } + intersectionPoint2.xPosition = (intersectionPoint2.yPosition - fourthPoint.Y) * + (thirdPoint.X - fourthPoint.X) / + (thirdPoint.Y - fourthPoint.Y) + + fourthPoint.X; + + intersectionPoint2.yPosition = (intersectionPoint2.xPosition - secondPoint.xPosition) / + (firstPoint.xPosition - secondPoint.xPosition) * + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.yPosition; + + if(double.IsNaN(intersectionPoint2.xPosition) || + double.IsInfinity(intersectionPoint2.xPosition) || + double.IsNaN(intersectionPoint2.yPosition) || + double.IsInfinity(intersectionPoint2.yPosition) ) + { + return true; + } + + + // Switch intersection points + //if(firstPoint.yPosition > plotAreaPositionBottom) + if((decimal)thirdPoint.Y > plotAreaPositionBottom) + { + switchPoints = true; + /* + DataPoint3D tempPoint = new DataPoint3D(); + tempPoint.xPosition = intersectionPoint.xPosition; + tempPoint.yPosition = intersectionPoint.yPosition; + intersectionPoint.xPosition = intersectionPoint2.xPosition; + intersectionPoint.yPosition = intersectionPoint2.yPosition; + intersectionPoint2.xPosition = tempPoint.xPosition; + intersectionPoint2.yPosition = tempPoint.yPosition; + */ + } + } + + + // Adjust points Y values + bool firstSegmentVisible = true; + float bottomDarken = bottomDarkening; + bool firstSegmentOutsideTop = false; + bool secondSegmentOutsideTop = false; + if((decimal)thirdPoint.Y < plotAreaPositionY) + { + firstSegmentOutsideTop = true; + firstSegmentVisible = false; + thirdPoint.Y = area.PlotAreaPosition.Y; + bottomDarken = 0.5f; + } + else if((decimal)thirdPoint.Y > plotAreaPositionBottom) + { + firstSegmentVisible = false; + thirdPoint.Y = area.PlotAreaPosition.Bottom; + if(firstPoint.yPosition >= thirdPoint.Y) + { + bottomDarken = 0.5f; + } + } + if((decimal)fourthPoint.Y < plotAreaPositionY) + { + secondSegmentOutsideTop = true; + fourthPoint.Y = area.PlotAreaPosition.Y; + bottomDarken = 0.5f; + } + else if((decimal)fourthPoint.Y > plotAreaPositionBottom) + { + fourthPoint.Y = area.PlotAreaPosition.Bottom; + if(fourthPoint.Y <= secondPoint.yPosition) + { + bottomDarken = 0.5f; + } + } + + // Draw surfaces in 2 or 3 segments + for(int segmentIndex = 0; segmentIndex < 3; segmentIndex++) + { + GraphicsPath segmentPath = null; + if(segmentIndex == 0 && !reversed || + segmentIndex == 2 && reversed) + { + // Draw first segment + if(intersectionPoint2 == null) + { + intersectionPoint2 = intersectionPoint; + } + + if(switchPoints) + { + DataPoint3D tempPoint = new DataPoint3D(); + tempPoint.xPosition = intersectionPoint.xPosition; + tempPoint.yPosition = intersectionPoint.yPosition; + intersectionPoint.xPosition = intersectionPoint2.xPosition; + intersectionPoint.yPosition = intersectionPoint2.yPosition; + intersectionPoint2.xPosition = tempPoint.xPosition; + intersectionPoint2.yPosition = tempPoint.yPosition; + } + + + intersectionPoint2.dataPoint = secondPoint.dataPoint; + intersectionPoint2.index = secondPoint.index; + intersectionPoint2.xCenterVal = secondPoint.xCenterVal; + + segmentPath = Draw3DSurface( firstPoint, intersectionPoint2, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, + (surfaceSegmentType == LineSegmentType.Middle) ? LineSegmentType.Middle : LineSegmentType.First, + topDarkening, bottomDarken, + new PointF(float.NaN, thirdPoint.Y), + new PointF((float)intersectionPoint2.xPosition, (!firstSegmentVisible || segmentNumber == 3) ? thirdPoint.Y : fourthPoint.Y), + firstSegmentOutsideTop, + false, false); + + if(switchPoints) + { + DataPoint3D tempPoint = new DataPoint3D(); + tempPoint.xPosition = intersectionPoint.xPosition; + tempPoint.yPosition = intersectionPoint.yPosition; + intersectionPoint.xPosition = intersectionPoint2.xPosition; + intersectionPoint.yPosition = intersectionPoint2.yPosition; + intersectionPoint2.xPosition = tempPoint.xPosition; + intersectionPoint2.yPosition = tempPoint.yPosition; + } + + } + + if(segmentIndex == 1 && intersectionPoint2 != null && segmentNumber == 3) + { + if(!switchPoints) + { + DataPoint3D tempPoint = new DataPoint3D(); + tempPoint.xPosition = intersectionPoint.xPosition; + tempPoint.yPosition = intersectionPoint.yPosition; + intersectionPoint.xPosition = intersectionPoint2.xPosition; + intersectionPoint.yPosition = intersectionPoint2.yPosition; + intersectionPoint2.xPosition = tempPoint.xPosition; + intersectionPoint2.yPosition = tempPoint.yPosition; + } + + // Draw middle segment + intersectionPoint2.dataPoint = secondPoint.dataPoint; + intersectionPoint2.index = secondPoint.index; + intersectionPoint2.xCenterVal = secondPoint.xCenterVal; + + intersectionPoint.xCenterVal = firstPoint.xCenterVal; + intersectionPoint.index = firstPoint.index; + intersectionPoint.dataPoint = firstPoint.dataPoint; + + segmentPath = Draw3DSurface( intersectionPoint, intersectionPoint2, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, LineSegmentType.Middle, + topDarkening, bottomDarkening, + new PointF((float)intersectionPoint.xPosition, thirdPoint.Y), + new PointF((float)intersectionPoint2.xPosition, fourthPoint.Y), + false, + false, false); + + if(!switchPoints) + { + DataPoint3D tempPoint = new DataPoint3D(); + tempPoint.xPosition = intersectionPoint.xPosition; + tempPoint.yPosition = intersectionPoint.yPosition; + intersectionPoint.xPosition = intersectionPoint2.xPosition; + intersectionPoint.yPosition = intersectionPoint2.yPosition; + intersectionPoint2.xPosition = tempPoint.xPosition; + intersectionPoint2.yPosition = tempPoint.yPosition; + } + + } + + if(segmentIndex == 2 && !reversed || + segmentIndex == 0 && reversed) + { + if(switchPoints) + { + DataPoint3D tempPoint = new DataPoint3D(); + tempPoint.xPosition = intersectionPoint.xPosition; + tempPoint.yPosition = intersectionPoint.yPosition; + intersectionPoint.xPosition = intersectionPoint2.xPosition; + intersectionPoint.yPosition = intersectionPoint2.yPosition; + intersectionPoint2.xPosition = tempPoint.xPosition; + intersectionPoint2.yPosition = tempPoint.yPosition; + } + + // Draw second segment + intersectionPoint.dataPoint = firstPoint.dataPoint; + intersectionPoint.index = firstPoint.index; + intersectionPoint.xCenterVal = firstPoint.xCenterVal; + + float thirdPointNewY = (!firstSegmentVisible || segmentNumber == 3) ? thirdPoint.Y : fourthPoint.Y; + if(segmentNumber == 3) + { + thirdPointNewY = (secondSegmentOutsideTop) ? thirdPoint.Y : fourthPoint.Y; + } + + segmentPath = Draw3DSurface( intersectionPoint, secondPoint, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, + (surfaceSegmentType == LineSegmentType.Middle) ? LineSegmentType.Middle : LineSegmentType.Last, + topDarkening, bottomDarken, + new PointF((float)intersectionPoint.xPosition, thirdPointNewY), + new PointF(float.NaN, fourthPoint.Y), + secondSegmentOutsideTop, + false, false); + + if(switchPoints) + { + DataPoint3D tempPoint = new DataPoint3D(); + tempPoint.xPosition = intersectionPoint.xPosition; + tempPoint.yPosition = intersectionPoint.yPosition; + intersectionPoint.xPosition = intersectionPoint2.xPosition; + intersectionPoint.yPosition = intersectionPoint2.yPosition; + intersectionPoint2.xPosition = tempPoint.xPosition; + intersectionPoint2.yPosition = tempPoint.yPosition; + } + + } + + // Add segment path + if(resultPath != null && segmentPath != null && segmentPath.PointCount > 0) + { + resultPath.AddPath(segmentPath, true); + } + } + + // Restore previous x\y positions + thirdPoint = new PointF(prevThirdPoint.X, prevThirdPoint.Y); + fourthPoint = new PointF(prevFourthPoint.X, prevFourthPoint.Y); + return true; + } + return false; + } + + /// + /// Draws a 3D surface connecting the two specified points in 2D space. + /// Used to draw Line based charts. + /// + /// First data point. + /// Second data point. + /// Points are in reversed order. + /// Chart area reference. + /// Chart graphics. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Previous data point object. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Array of points. + /// Index of point to draw. + /// Index of points loop. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Define surface segment type if it consists of several segments. + /// Darkenning scale for top surface. 0 - None. + /// Darkenning scale for bottom surface. 0 - None. + /// Position where the third point is actually located or float.NaN if same as in "firstPoint". + /// Position where the fourth point is actually located or float.NaN if same as in "secondPoint". + /// Indicates that drawn segment is 3D clipped. Only top/bottom should be drawn. + /// Indicates that top segment line should be clipped to the pkot area. + /// Indicates that bottom segment line should be clipped to the pkot area. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + protected virtual GraphicsPath Draw3DSurface( + DataPoint3D firstPoint, + DataPoint3D secondPoint, + bool reversed, + ChartArea area, + ChartGraphics graph, + Matrix3D matrix, + LightStyle lightStyle, + DataPoint3D prevDataPointEx, + float positionZ, + float depth, + ArrayList points, + int pointIndex, + int pointLoopIndex, + float tension, + DrawingOperationTypes operationType, + LineSegmentType surfaceSegmentType, + float topDarkening, + float bottomDarkening, + PointF thirdPointPosition, + PointF fourthPointPosition, + bool clippedSegment, + bool clipOnTop, + bool clipOnBottom) + { + // Implemented in area and range chart + return null; + } + #endregion + + #region IDisposable overrides + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Dispose managed resources + if (this._linePen != null) + { + this._linePen.Dispose(); + this._linePen = null; + } + } + base.Dispose(disposing); + } + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/PieChart.cs b/System.Web.DataVisualization/Common/ChartTypes/PieChart.cs new file mode 100644 index 000000000..ae0bb9487 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/PieChart.cs @@ -0,0 +1,5703 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: PieChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: PieChart +// +// Purpose: Provides 2D/3D drawing and hit testing functionality +// for the Pie chart. A pie chart shows how proportions +// of data, shown as pie-shaped pieces, contribute to +// the data as a whole. +// +// PieChart class is used as a base class for the +// DoughnutChart class. +// +// Reviewed: GS - Aug 8, 2002 +// AG - Aug 8, 2002 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel.Design; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Utilities; +#else + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + #region Enumerations + + /// + /// Pie Labels style + /// + internal enum PieLabelStyle + { + /// + /// Labels are inside pie slice + /// + Inside, + + /// + /// Labels are outside pie slice + /// + Outside, + + /// + /// Labels are disabled + /// + Disabled, + + }; + + #endregion + + /// + /// PieChart class provides 2D/3D drawing and hit testing functionality + /// for the Pie chart. + /// + internal class PieChart : IChartType + { + #region Enumerations + + /// + /// Labels Mode for preparing data + /// + enum LabelsMode + { + /// + /// There are no labels + /// + Off, + + /// + /// Drawing labels mode + /// + Draw, + + /// + /// Labels Estimation mode + /// + EstimateSize, + + /// + /// Labels Overlap Mode + /// + LabelsOverlap + }; + + #endregion + + #region Fields + + // True if labels fit inside plot area. + private bool _labelsFit = true; + + // Field that is used to resize pie + // because of labels. + private float _sizeCorrection = 0.95F; + + // True if any pie slice is exploded + private bool _sliceExploded = false; + + // True if labels overlap for 2D Pie and outside labels + private bool _labelsOverlap = false; + + // Left Lable column used for 3D chart and outside labels + internal LabelColumn labelColumnLeft; + + // Right Lable column used for 3D chart and outside labels + internal LabelColumn labelColumnRight; + + // Array of label rectangles used to prevent labels overlapping + // for 2D pie chart outside labels. + private ArrayList _labelsRectangles = new ArrayList(); + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.Pie;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + virtual public bool RequireAxes { get{ return false;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return false;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + virtual public bool SideBySideSeries { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return true;} } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return false; } } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return true; } } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint{ get { return 1; } } + + /// + /// Chart is Doughnut or Pie type + /// + virtual public bool Doughnut{ get { return false; } } + + #endregion + + #region Methods + + /// + /// Default constructor + /// + public PieChart() + { + } + + + + /// + /// Calculates Collected pie slice if required. + /// + /// Series to be prepared. + internal static void PrepareData(Series series) + { + // Check series chart type + if( String.Compare(series.ChartTypeName, ChartTypeNames.Pie, StringComparison.OrdinalIgnoreCase ) != 0 && + String.Compare(series.ChartTypeName, ChartTypeNames.Doughnut, StringComparison.OrdinalIgnoreCase ) != 0 + ) + { + return; + } + + // Check if collected threshold value is set + double threshold = 0.0; + if (series.IsCustomPropertySet(CustomPropertyName.CollectedThreshold)) + { + double t; + bool parseSucceed = double.TryParse(series[CustomPropertyName.CollectedThreshold], NumberStyles.Any, CultureInfo.InvariantCulture, out t); + if (parseSucceed) + { + threshold = t; + } + else + { + throw (new InvalidOperationException(SR.ExceptionDoughnutCollectedThresholdInvalidFormat)); + } + + if (threshold < 0.0) + { + throw (new InvalidOperationException(SR.ExceptionDoughnutThresholdInvalid)); + } + } + + // Check if threshold is set + if(threshold > 0.0) + { + // Get reference to the chart control + Chart chart = series.Chart; + if(chart == null) + { + throw (new InvalidOperationException(SR.ExceptionDoughnutNullReference)); + } + + // Create a temp series which will hold original series data points + Series seriesOriginalData = new Series("PIE_ORIGINAL_DATA_" + series.Name, series.YValuesPerPoint); + seriesOriginalData.Enabled = false; + seriesOriginalData.IsVisibleInLegend = false; + chart.Series.Add(seriesOriginalData); + foreach(DataPoint dp in series.Points) + { + seriesOriginalData.Points.Add(dp.Clone()); + } + + // Copy temporary design data attribute + if(series.IsCustomPropertySet("TempDesignData")) + { + seriesOriginalData["TempDesignData"] = "true"; + } + + // Calculate total value of all data points. IsEmpty points are + // ignored. Absolute value is used. + double total = 0.0; + foreach(DataPoint dp in series.Points) + { + if(!dp.IsEmpty) + { + total += Math.Abs(dp.YValues[0]); + } + } + + // Check if threshold value is set in percents + bool percent = true; + if(series.IsCustomPropertySet(CustomPropertyName.CollectedThresholdUsePercent)) + { + if(string.Compare(series[CustomPropertyName.CollectedThresholdUsePercent], "True", StringComparison.OrdinalIgnoreCase) == 0) + { + percent = true; + } + else if (string.Compare(series[CustomPropertyName.CollectedThresholdUsePercent], "False", StringComparison.OrdinalIgnoreCase) == 0) + { + percent = false; + } + else + { + throw (new InvalidOperationException(SR.ExceptionDoughnutCollectedThresholdUsePercentInvalid)); + } + } + + // Convert from percent valur to data point value + if(percent) + { + if(threshold > 100.0) + { + throw (new InvalidOperationException(SR.ExceptionDoughnutCollectedThresholdInvalidRange)); + } + + threshold = total * threshold / 100.0; + } + + // Count how many points will be collected and remove collected points + DataPoint collectedPoint = null; + double collectedTotal = 0.0; + int collectedCount = 0; + int firstCollectedPointIndex = 0; + int originalDataPointIndex = 0; + for(int dataPointIndex = 0; dataPointIndex < series.Points.Count; dataPointIndex++) + { + DataPoint dataPoint = series.Points[dataPointIndex]; + if(!dataPoint.IsEmpty && Math.Abs(dataPoint.YValues[0]) <= threshold) + { + // Keep statistics + ++collectedCount; + collectedTotal += Math.Abs(dataPoint.YValues[0]); + + // Make a template for the collected point using the first removed point + if(collectedPoint == null) + { + firstCollectedPointIndex = dataPointIndex; + collectedPoint = dataPoint.Clone(); + } + + // Remove first collected point only when second collected point found + if(collectedCount == 2) + { + series.Points.RemoveAt(firstCollectedPointIndex); + --dataPointIndex; + } + + // Remove collected point + if(collectedCount > 1) + { + series.Points.RemoveAt(dataPointIndex); + --dataPointIndex; + } + } + + // Set point index that will be used for tooltips + dataPoint["OriginalPointIndex"] = originalDataPointIndex.ToString(CultureInfo.InvariantCulture); + ++originalDataPointIndex; + } + + // Add collected data point into the series + if(collectedCount > 1 && collectedPoint != null) + { + collectedPoint["_COLLECTED_DATA_POINT"] = "TRUE"; + collectedPoint.YValues[0] = collectedTotal; + series.Points.Add(collectedPoint); + + // Set collected point color + if(series.IsCustomPropertySet(CustomPropertyName.CollectedColor)) + { + ColorConverter colorConverter = new ColorConverter(); + try + { + collectedPoint.Color = (Color)colorConverter.ConvertFromString(null, CultureInfo.InvariantCulture, series[CustomPropertyName.CollectedColor]); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionDoughnutCollectedColorInvalidFormat)); + } + } + + // Set collected point exploded attribute + if(series.IsCustomPropertySet(CustomPropertyName.CollectedSliceExploded)) + { + collectedPoint[CustomPropertyName.Exploded] = series[CustomPropertyName.CollectedSliceExploded]; + } + + // Set collected point tooltip + if(series.IsCustomPropertySet(CustomPropertyName.CollectedToolTip)) + { + collectedPoint.ToolTip = series[CustomPropertyName.CollectedToolTip]; + } + + // Set collected point legend text + if(series.IsCustomPropertySet(CustomPropertyName.CollectedLegendText)) + { + collectedPoint.LegendText = series[CustomPropertyName.CollectedLegendText]; + } + else + { + collectedPoint.LegendText = SR.DescriptionCustomAttributeCollectedLegendDefaultText; + } + + // Set collected point label + if(series.IsCustomPropertySet(CustomPropertyName.CollectedLabel)) + { + collectedPoint.Label = series[CustomPropertyName.CollectedLabel]; + } + } + } + } + + /// + /// Remove any changes done while preparing Pie/Doughnut charts + /// to draw the collected slice. + /// + /// Series to be un-prepared. + /// True if series was removed from collection. + internal static bool UnPrepareData(Series series) + { + if(series.Name.StartsWith("PIE_ORIGINAL_DATA_", StringComparison.Ordinal)) + { + // Get reference to the chart control + Chart chart = series.Chart; + if(chart == null) + { + throw (new InvalidOperationException(SR.ExceptionDoughnutNullReference)); + } + + // Get original Renko series + Series pieSeries = chart.Series[series.Name.Substring(18)]; + + // Copy data back to original Pie series + pieSeries.Points.Clear(); + if(!series.IsCustomPropertySet("TempDesignData")) + { + foreach(DataPoint dp in series.Points) + { + pieSeries.Points.Add(dp); + } + } + + // Remove series from the collection + chart.Series.Remove(series); + return true; + } + return false; + } + + + + /// + /// Paint Pie Chart + /// + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Chart series to draw. + public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + // Pie chart cannot be combined with other chart types + foreach( Series series in common.DataManager.Series ) + { + // Check if series is visible and belong to the current chart area + if( series.IsVisible() && + series.ChartArea == area.Name ) + { + // Check if series chart type matches + if( String.Compare( series.ChartTypeName, this.Name, true, System.Globalization.CultureInfo.CurrentCulture ) != 0 ) + { + if(!common.ChartPicture.SuppressExceptions) + { + // Pie/Doughnut chart can not be combined with other chart type + throw (new InvalidOperationException(SR.ExceptionChartCanNotCombine( this.Name ))); + } + } + } + } + + // 3D Pie Chart + if( area.Area3DStyle.Enable3D ) + { + + float pieWidth = 10 * area.Area3DStyle.PointDepth / 100; + + // Set Clip Region + graph.SetClip(area.Position.ToRectangleF()); + + // Make reversed X angle because of default angle. + area.Area3DStyle.Inclination *= -1; + int oldYAngle = area.Area3DStyle.Rotation; + area.Area3DStyle.Rotation = area.GetRealYAngle( ); + + // Draw Pie + ProcessChartType3D( false, graph, common, area, pieWidth ); + + // Make reversed X angle because of default angle. + area.Area3DStyle.Inclination *= -1; + area.Area3DStyle.Rotation = oldYAngle; + + // Reset Clip Region + graph.ResetClip(); + + } + else + { + // Reset overlapped labels flag + this._labelsOverlap = false; + + //Set Clip Region + ((ChartGraphics)graph).SetClip( area.Position.ToRectangleF() ); + + // Resize pie because of labels + SizeCorrection( graph, common, area ); + + // Draw Pie labels + ProcessChartType( false, graph, common, area, false, LabelsMode.LabelsOverlap ); + + // If overlapping labels are detected they will be drawn in "columns" on each + // side of the pie. Adjust plotting area to fit the labels + if(this._labelsOverlap) + { + // Resize pie because of labels + SizeCorrection( graph, common, area ); + + // Reset overlapped labels flag + this._labelsOverlap = false; + + // Draw Pie labels + ProcessChartType( false, graph, common, area, false, LabelsMode.LabelsOverlap ); + } + + // Draw Shadow + ProcessChartType( false, graph, common, area, true, LabelsMode.Off ); + + // Draw Pie + ProcessChartType( false, graph, common, area, false, LabelsMode.Off ); + + // Draw Pie labels + ProcessChartType( false, graph, common, area, false, LabelsMode.Draw ); + + //Reset Clip Region + ((ChartGraphics)graph).ResetClip(); + } + } + + /// + /// Take Relative Minimum Pie Size attribute + /// + /// Chart Area + /// Custom attribute value. + private double MinimumRelativePieSize( ChartArea area ) + { + // Default value + double minimumSize = 0.3; + + // All data series from chart area which have Pie chart type + List typeSeries = area.GetSeriesFromChartType(Name); + + // Data series collection + SeriesCollection dataSeries = area.Common.DataManager.Series; + + // Take Relative Minimum Pie Size attribute + if(dataSeries[typeSeries[0]].IsCustomPropertySet(CustomPropertyName.MinimumRelativePieSize)) + { + minimumSize = CommonElements.ParseFloat(dataSeries[typeSeries[0]][CustomPropertyName.MinimumRelativePieSize]) / 100.0; + + // Validation + if( minimumSize < 0.1 || minimumSize > 0.7 ) + throw (new ArgumentException(SR.ExceptionPieMinimumRelativePieSizeInvalid)); + + } + + return minimumSize; + } + + /// + /// Method that is used to resize pie + /// because of labels. + /// + private void SizeCorrection( ChartGraphics graph, CommonElements common, ChartArea area ) + { + float correction = (this._labelsOverlap) ? this._sizeCorrection : 0.95F; + _sliceExploded = false; + + // Estimate Labels + if( area.InnerPlotPosition.Auto ) + { + for( ; correction >= (float)MinimumRelativePieSize( area ); correction -= 0.05F ) + { + // Decrease Pie size + this._sizeCorrection = correction; + + // Check if labels fit. + ProcessChartType( false, graph, common, area, false, LabelsMode.EstimateSize ); + if( _labelsFit ) + { + break; + } + } + + // Size correction for exploded pie can not be larger then 0.8 + if( _sliceExploded && _sizeCorrection > 0.8F ) + { + _sizeCorrection = 0.8F; + } + } + else + { + _sizeCorrection = 0.95F; + } + } + + /// + /// This method recalculates position of pie slices + /// or checks if pie slice is selected. + /// + /// If True selection mode is active, otherwise paint mode is active + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Draw pie shadow + /// Pie labels + private void ProcessChartType( bool selection, ChartGraphics graph, CommonElements common, ChartArea area, bool shadow, LabelsMode labels ) + { + float startAngle = 0; // Angle in degrees measured clockwise from the x-axis to the first side of the pie section. + string explodedAttrib = ""; // Exploded attribute + bool exploded; // Exploded pie slice + float midAngle; // Angle between Start Angle and End Angle + + // Data series collection + SeriesCollection dataSeries = common.DataManager.Series; + + // Clear Labels overlap collection + if( labels == LabelsMode.LabelsOverlap ) + { + _labelsRectangles.Clear(); + } + + // All data series from chart area which have Pie chart type + List typeSeries = area.GetSeriesFromChartType(Name); + if(typeSeries.Count == 0) + { + return; + } + + // Get first pie starting angle + if(typeSeries.Count > 0) + { + if (dataSeries[typeSeries[0]].IsCustomPropertySet(CustomPropertyName.PieStartAngle)) + { + float angle; + bool parseSucceed = float.TryParse(dataSeries[typeSeries[0]][CustomPropertyName.PieStartAngle], NumberStyles.Any, CultureInfo.InvariantCulture, out angle); + if (parseSucceed) + { + startAngle = angle; + } + + if (!parseSucceed || startAngle > 360f || startAngle < 0f) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeAngleOutOfRange("PieStartAngle"))); + } + } + } + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(dataSeries[typeSeries[0]], graph, common, area.PlotAreaPosition)); + } + + // The data points loop. Find Sum of data points. + double sum = 0.0; + foreach( DataPoint point in dataSeries[typeSeries[0]].Points ) + { + if( !point.IsEmpty ) + { + sum += Math.Abs( point.YValues[0] ); + } + } + + // No points or all points have zero values + if(sum == 0.0) + { + return; + } + + // Take radius attribute + float doughnutRadius = 60f; + if(dataSeries[typeSeries[0]].IsCustomPropertySet(CustomPropertyName.DoughnutRadius)) + { + doughnutRadius = CommonElements.ParseFloat(dataSeries[typeSeries[0]][CustomPropertyName.DoughnutRadius]); + + // Validation + if( doughnutRadius < 0f || doughnutRadius > 99f ) + throw (new ArgumentException(SR.ExceptionPieRadiusInvalid)); + + } + + // This method is introduced to check colors of palette. For + // pie chart the first pie slice and the second pie slice can + // not have same color because they are connected. + CheckPaleteColors( dataSeries[typeSeries[0]].Points ); + + //************************************************************ + //** Data point loop + //************************************************************ + int pointIndx = 0; + int nonEmptyPointIndex = 0; + foreach( DataPoint point in dataSeries[typeSeries[0]].Points ) + { + // Do not process empty points + if( point.IsEmpty ) + { + pointIndx++; + continue; + } + + // Rectangle size + RectangleF rectangle; + if( area.InnerPlotPosition.Auto ) + { + rectangle = new RectangleF( area.Position.ToRectangleF().X, area.Position.ToRectangleF().Y, area.Position.ToRectangleF().Width, area.Position.ToRectangleF().Height ); + } + else + { + rectangle = new RectangleF( area.PlotAreaPosition.ToRectangleF().X, area.PlotAreaPosition.ToRectangleF().Y, area.PlotAreaPosition.ToRectangleF().Width, area.PlotAreaPosition.ToRectangleF().Height ); + } + if(rectangle.Width < 0f || rectangle.Height < 0f) + { + return; + } + + // Find smallest edge + SizeF absoluteSize = graph.GetAbsoluteSize( new SizeF( rectangle.Width, rectangle.Height ) ); + float absRadius = ( absoluteSize.Width < absoluteSize.Height ) ? absoluteSize.Width : absoluteSize.Height; + + // Size of the square, which will be used for drawing pie. + SizeF relativeSize = graph.GetRelativeSize( new SizeF( absRadius, absRadius ) ); + + // Center of the pie + PointF middlePoint = new PointF( rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2 ); + + // Rectangle which will always create circle, never ellipse. + rectangle = new RectangleF( middlePoint.X - relativeSize.Width / 2, middlePoint.Y - relativeSize.Height / 2, relativeSize.Width, relativeSize.Height ); + + // Size correction because of exploded or labels + if( _sizeCorrection != 1 ) + { + rectangle.X += rectangle.Width * ( 1 - _sizeCorrection ) / 2; + rectangle.Y += rectangle.Height * ( 1 - _sizeCorrection ) / 2; + rectangle.Width = rectangle.Width * _sizeCorrection; + rectangle.Height = rectangle.Height * _sizeCorrection; + + // Adjust inner plot position + if(area.InnerPlotPosition.Auto) + { + RectangleF rect = rectangle; + rect.X = (rect.X - area.Position.X) / area.Position.Width * 100f; + rect.Y = (rect.Y - area.Position.Y) / area.Position.Height * 100f; + rect.Width = rect.Width / area.Position.Width * 100f; + rect.Height = rect.Height / area.Position.Height * 100f; + area.InnerPlotPosition.SetPositionNoAuto(rect.X, rect.Y, rect.Width, rect.Height); + } + } + + float sweepAngle = (float)( Math.Abs(point.YValues[0]) / sum * 360); + + // Check Exploded attribute for data point + exploded = false; + if(point.IsCustomPropertySet(CustomPropertyName.Exploded)) + { + explodedAttrib = point[CustomPropertyName.Exploded]; + if( String.Compare(explodedAttrib,"true", StringComparison.OrdinalIgnoreCase) == 0 ) + exploded = true; + else + exploded = false; + } + + Color pieLineColor = Color.Empty; + ColorConverter colorConverter = new ColorConverter(); + + // Check if special color properties are set + if(point.IsCustomPropertySet(CustomPropertyName.PieLineColor) || dataSeries[typeSeries[0]].IsCustomPropertySet(CustomPropertyName.PieLineColor)) + { + bool failed = false; + try + { + pieLineColor = (Color)colorConverter.ConvertFromString( + (point.IsCustomPropertySet(CustomPropertyName.PieLineColor)) ? point[CustomPropertyName.PieLineColor] : dataSeries[typeSeries[0]][CustomPropertyName.PieLineColor]); + failed = false; + } + catch (ArgumentException) + { + failed = true; + } + catch (NotSupportedException) + { + failed = true; + } + + if (failed) + { + pieLineColor = (Color)colorConverter.ConvertFromInvariantString( + (point.IsCustomPropertySet(CustomPropertyName.PieLineColor)) ? point[CustomPropertyName.PieLineColor] : dataSeries[typeSeries[0]][CustomPropertyName.PieLineColor]); + } + } + + // Find Direction to move exploded pie slice + if( exploded ) + { + _sliceExploded = true; + midAngle = ( 2 * startAngle + sweepAngle ) / 2; + double xComponent = Math.Cos( midAngle * Math.PI / 180 ) * rectangle.Width / 10; + double yComponent = Math.Sin( midAngle * Math.PI / 180 ) * rectangle.Height / 10; + + rectangle.Offset( (float)xComponent, (float)yComponent ); + } + + // Hot regions of the data points. Labels hot regions are processed aftre drawing. + if( common.ProcessModeRegions && labels == LabelsMode.Draw ) + { + Map( common, point, startAngle, sweepAngle, rectangle, Doughnut, doughnutRadius, graph, pointIndx ); + } + + // Painting mode + if( common.ProcessModePaint ) + { + // Draw Shadow + if( shadow ) + { + double offset = graph.GetRelativeSize( new SizeF( point.series.ShadowOffset, point.series.ShadowOffset ) ).Width; + + // Offset is zero. Do not draw shadow pie slice. + if( offset == 0.0 ) + { + break; + } + + // Shadow Rectangle + RectangleF shadowRect = new RectangleF( rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height ); + shadowRect.Offset( (float)offset, (float)offset ); + + // Change shadow color + Color shcolor = new Color(); + Color shGradientColor = new Color(); + Color shBorderColor = new Color(); + + // Solid color + if( point.Color.A != 255 ) + shcolor = Color.FromArgb( point.Color.A/2, point.series.ShadowColor ); + else + shcolor = point.series.ShadowColor; + + // Gradient Color + if( !point.BackSecondaryColor.IsEmpty ) + { + if( point.BackSecondaryColor.A != 255 ) + shGradientColor = Color.FromArgb( point.BackSecondaryColor.A/2, point.series.ShadowColor ); + else + shGradientColor = point.series.ShadowColor; + } + else + shGradientColor = Color.Empty; + + // Border color + if( !point.BorderColor.IsEmpty ) + { + if( point.BorderColor.A != 255 ) + shBorderColor = Color.FromArgb( point.BorderColor.A/2, point.series.ShadowColor ); + else + shBorderColor = point.series.ShadowColor; + } + else + shBorderColor = Color.Empty; + + // Draw shadow of pie slice + graph.DrawPieRel( + shadowRect, + startAngle, + sweepAngle, + shcolor, + ChartHatchStyle.None, + "", + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackGradientStyle, + shGradientColor, + shBorderColor, + point.BorderWidth, + point.BorderDashStyle, + true, + Doughnut, + doughnutRadius, + PieDrawingStyle.Default); + } + else + { + if( labels == LabelsMode.Off ) + { + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw pie slice + graph.DrawPieRel( + rectangle, + startAngle, + sweepAngle, + point.Color, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackGradientStyle, + point.BackSecondaryColor, + point.BorderColor, + point.BorderWidth, + point.BorderDashStyle, + false, + Doughnut, + doughnutRadius, + ChartGraphics.GetPieDrawingStyle(point) ); + + // End Svg Selection mode + graph.EndHotRegion( ); + } + } + + // Estimate labels + if( labels == LabelsMode.EstimateSize ) + { + EstimateLabels( graph, middlePoint, rectangle.Size, startAngle, sweepAngle, point, exploded, area ); + if( _labelsFit == false ) + { + return; + } + } + + // Labels overlap test + if( labels == LabelsMode.LabelsOverlap ) + { + DrawLabels( graph, middlePoint, rectangle.Size, startAngle, sweepAngle, point, doughnutRadius, exploded, area, true, nonEmptyPointIndex, pieLineColor ); + } + + // Draw labels and markers + if( labels == LabelsMode.Draw ) + { + DrawLabels( graph, middlePoint, rectangle.Size, startAngle, sweepAngle, point, doughnutRadius, exploded, area, false, nonEmptyPointIndex, pieLineColor ); + } + + } + + if( common.ProcessModeRegions && labels == LabelsMode.Draw ) + { + // Add labels hot regions if it was not done during the painting + if( !common.ProcessModePaint ) + { + DrawLabels( graph, middlePoint, rectangle.Size, startAngle, sweepAngle, point, doughnutRadius, exploded, area, false, nonEmptyPointIndex, pieLineColor ); + } + } + + + //************************************************** + //** Remember point relative position + //************************************************** + point.positionRel = new PointF(float.NaN, float.NaN); + + + // If exploded the shift is bigger + float expShift = 1; + if( exploded ) + expShift = 1.2F; + + midAngle = startAngle + sweepAngle / 2; + + // Find first line position + point.positionRel.X = (float)Math.Cos( (midAngle) * Math.PI / 180 ) * rectangle.Width * expShift / 2 + middlePoint.X; + point.positionRel.Y = (float)Math.Sin( (midAngle) * Math.PI / 180 ) * rectangle.Height * expShift / 2 + middlePoint.Y; + + // Increase point index and sweep angle + pointIndx++; + nonEmptyPointIndex++; + startAngle += sweepAngle; + if(startAngle >= 360) + { + startAngle -= 360; + } + } + + if( labels == LabelsMode.LabelsOverlap && this._labelsOverlap ) + { + this._labelsOverlap = PrepareLabels( area.Position.ToRectangleF() ); + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(dataSeries[typeSeries[0]], graph, common, area.PlotAreaPosition)); + } + } + + /// + /// Draw Pie labels or test for overlaping. + /// + /// Chart Graphics object + /// Center of the pie chart + /// Size of the square, which will be used for drawing pie. + /// Starting angle of a pie slice + /// Sweep angle of a pie slice + /// Data point + /// Radius for Doughnut Chart in % + /// The pie slice is exploded + /// Chart area + /// True if test mode is on + /// Data Point Index + /// Color of line labels + public void DrawLabels( ChartGraphics graph, PointF middlePoint, SizeF relativeSize, float startAngle, float sweepAngle, DataPoint point, float doughnutRadius, bool exploded, ChartArea area, bool overlapTest, int pointIndex, Color pieLineColor ) + { + bool added = false; // Indicates that label position was added + float x; // Label Position + float y; // Label Position + Series series; // Data Series + float labelsHorizontalLineSize = 1; // Horizontal line size for outside labels + float labelsRadialLineSize = 1; // Radial line size for outside labels + string text; + + // Disable the clip region + Region oldClipRegion = graph.Clip; + graph.Clip = new Region(); + + // Get label text + text = this.GetLabelText( point ); + if(text.Length == 0) + { + return; + } + + float shift; + + series = point.series; + + PieLabelStyle style = PieLabelStyle.Inside; + + // Get label style attribute from series + if(series.IsCustomPropertySet(CustomPropertyName.LabelStyle)) + { + string labelStyleAttrib = series[CustomPropertyName.LabelStyle]; + + // Labels Disabled + if( String.Compare(labelStyleAttrib,"disabled",StringComparison.OrdinalIgnoreCase) == 0 ) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + else if(series.IsCustomPropertySet(CustomPropertyName.PieLabelStyle)) + { + string labelStyleAttrib = series[CustomPropertyName.PieLabelStyle]; + + // Labels Disabled + if (String.Compare(labelStyleAttrib, "disabled", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + + // Get label style attribute from point + if(point.IsCustomPropertySet(CustomPropertyName.LabelStyle)) + { + string labelStyleAttrib = point[CustomPropertyName.LabelStyle]; + + // Labels Disabled + if (String.Compare(labelStyleAttrib, "disabled", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + // Get label style attribute from point + else if(point.IsCustomPropertySet(CustomPropertyName.PieLabelStyle)) + { + string labelStyleAttrib = point[CustomPropertyName.PieLabelStyle]; + + // Labels Disabled + if (String.Compare(labelStyleAttrib, "disabled", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + + + // Take labels radial line size attribute from series + if(series.IsCustomPropertySet(CustomPropertyName.LabelsRadialLineSize)) + { + string labelsRadialLineSizeAttrib = series[CustomPropertyName.LabelsRadialLineSize]; + labelsRadialLineSize = CommonElements.ParseFloat( labelsRadialLineSizeAttrib); + + // Validation + if( labelsRadialLineSize < 0 || labelsRadialLineSize > 100 ) + throw new InvalidOperationException(SR.ExceptionPieRadialLineSizeInvalid); + } + + // Take labels radial line size attribute from point + if(point.IsCustomPropertySet(CustomPropertyName.LabelsRadialLineSize)) + { + string labelsRadialLineSizeAttrib = point[CustomPropertyName.LabelsRadialLineSize]; + labelsRadialLineSize = CommonElements.ParseFloat( labelsRadialLineSizeAttrib); + + // Validation + if( labelsRadialLineSize < 0 || labelsRadialLineSize > 100 ) + throw new InvalidOperationException(SR.ExceptionPieRadialLineSizeInvalid); + } + + // Take labels horizontal line size attribute from series + if(series.IsCustomPropertySet(CustomPropertyName.LabelsHorizontalLineSize)) + { + string labelsHorizontalLineSizeAttrib = series[CustomPropertyName.LabelsHorizontalLineSize]; + labelsHorizontalLineSize = CommonElements.ParseFloat( labelsHorizontalLineSizeAttrib); + + // Validation + if( labelsHorizontalLineSize < 0 || labelsHorizontalLineSize > 100 ) + throw new InvalidOperationException(SR.ExceptionPieHorizontalLineSizeInvalid); + } + + // Take labels horizontal line size attribute from point + if(point.IsCustomPropertySet(CustomPropertyName.LabelsHorizontalLineSize)) + { + string labelsHorizontalLineSizeAttrib = point[CustomPropertyName.LabelsHorizontalLineSize]; + labelsHorizontalLineSize = CommonElements.ParseFloat( labelsHorizontalLineSizeAttrib); + + // Validation + if( labelsHorizontalLineSize < 0 || labelsHorizontalLineSize > 100 ) + throw new InvalidOperationException(SR.ExceptionPieHorizontalLineSizeInvalid); + } + + float expShift = 1; + + // ******************************************** + // Labels are set inside pie + // ******************************************** + if( style == PieLabelStyle.Inside && !overlapTest ) + { + float width; + float height; + + // If exploded the shift is bigger + if( exploded ) + { + expShift = 1.4F; + } + + // Get offset of the inside labels position + // NOTE: This custom attribute is NOT released! + float positionRatio = 4.0f; + if(point.IsCustomPropertySet("InsideLabelOffset")) + { + bool parseSucceed = float.TryParse(point["InsideLabelOffset"], NumberStyles.Any, CultureInfo.InvariantCulture, out positionRatio); + if(!parseSucceed || positionRatio < 0f || positionRatio > 100f) + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeIsNotInRange0to100("InsideLabelOffset"))); + } + positionRatio = 4f / (1f + positionRatio / 100f); + } + + + // Shift the string for Doughnut type + if( Doughnut ) + { + width = relativeSize.Width * expShift / positionRatio * ( 1 + ( 100 - doughnutRadius ) / 100F ); + height = relativeSize.Height * expShift / positionRatio * ( 1 + ( 100 - doughnutRadius ) / 100F ); + } + else + { + width = relativeSize.Width * expShift / positionRatio; + height = relativeSize.Height * expShift / positionRatio; + } + + // Find string position + x = (float)Math.Cos( (startAngle + sweepAngle / 2) * Math.PI / 180 ) * width + middlePoint.X; + y = (float)Math.Sin( (startAngle + sweepAngle / 2) * Math.PI / 180 ) * height + middlePoint.Y; + + // Center the string horizontally and vertically. + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + SizeF sizeFont = graph.GetRelativeSize( + graph.MeasureString( + text.Replace("\\n", "\n"), + point.Font, + new SizeF(1000f, 1000f), + StringFormat.GenericTypographic)); + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeLabel.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = PointChart.GetLabelPosition( + graph, + new PointF(x, y), + sizeLabel, + format, + true); + + // Draw the label inside the pie + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + area.Common, + text, + point.Font, + brush, + new PointF(x, y), + format, + point.LabelAngle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + series, + point, + pointIndex); + } + } + } + + // ******************************************** + // Labels are set outside pie + // ******************************************** + else if( style == PieLabelStyle.Outside ) + { + + // Coefficient which represent shift from pie border + shift = 0.5F + labelsRadialLineSize * 0.1F; + + // If exploded the shift is bigger + if( exploded ) + expShift = 1.2F; + + float midAngle = startAngle + sweepAngle / 2; + + // Find first line position + float x1 = (float)Math.Cos( (midAngle) * Math.PI / 180 ) * relativeSize.Width * expShift / 2 + middlePoint.X; + float y1 = (float)Math.Sin( (midAngle) * Math.PI / 180 ) * relativeSize.Height * expShift / 2 + middlePoint.Y; + + float x2 = (float)Math.Cos( (midAngle) * Math.PI / 180 ) * relativeSize.Width * shift * expShift + middlePoint.X; + float y2 = (float)Math.Sin( (midAngle) * Math.PI / 180 ) * relativeSize.Height * shift * expShift + middlePoint.Y; + + if( pieLineColor == Color.Empty ) + { + pieLineColor = point.BorderColor; + } + + // Draw first line + if( !overlapTest ) + { + graph.DrawLineRel( pieLineColor, point.BorderWidth, ChartDashStyle.Solid, new PointF( x1, y1 ), new PointF( x2, y2 ) ); + } + + // Set string alingment + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // Find second line position + float y3 = (float)Math.Sin((midAngle) * Math.PI / 180) * relativeSize.Height * shift * expShift + middlePoint.Y; + float x3; + float x3Overlap; + + RectangleF labelRect = RectangleF.Empty; + RectangleF labelRectOver = RectangleF.Empty; + + if (midAngle > 90 && midAngle < 270) + { + format.Alignment = StringAlignment.Far; + x3Overlap = -relativeSize.Width * shift * expShift + middlePoint.X - relativeSize.Width / 10 * labelsHorizontalLineSize; + x3 = (float)Math.Cos((midAngle) * Math.PI / 180) * relativeSize.Width * shift * expShift + middlePoint.X - relativeSize.Width / 10 * labelsHorizontalLineSize; + + if (overlapTest) + { + x3Overlap = x3; + } + + // This method returns calculated rectangle from point position + // for outside label. Rectangle mustn’t be out of chart area. + labelRect = GetLabelRect(new PointF(x3, y3), area, text, format, graph, point, true); + labelRectOver = GetLabelRect(new PointF(x3Overlap, y3), area, text, format, graph, point, true); + } + else + { + format.Alignment = StringAlignment.Near; + + x3Overlap = relativeSize.Width * shift * expShift + middlePoint.X + relativeSize.Width / 10 * labelsHorizontalLineSize; + x3 = (float)Math.Cos((midAngle) * Math.PI / 180) * relativeSize.Width * shift * expShift + middlePoint.X + relativeSize.Width / 10 * labelsHorizontalLineSize; + + if (overlapTest) + { + x3Overlap = x3; + } + + // This method returns calculated rectangle from point position + // for outside label. Rectangle mustn’t be out of chart area. + labelRect = GetLabelRect(new PointF(x3, y3), area, text, format, graph, point, false); + labelRectOver = GetLabelRect(new PointF(x3Overlap, y3), area, text, format, graph, point, false); + } + + // Draw second line + if (!overlapTest) + { + if (this._labelsOverlap) + { + float calculatedY3 = (((RectangleF)this._labelsRectangles[pointIndex]).Top + ((RectangleF)this._labelsRectangles[pointIndex]).Bottom) / 2f; + graph.DrawLineRel(pieLineColor, point.BorderWidth, ChartDashStyle.Solid, new PointF(x2, y2), new PointF(x3Overlap, calculatedY3)); + } + else + { + graph.DrawLineRel(pieLineColor, point.BorderWidth, ChartDashStyle.Solid, new PointF(x2, y2), new PointF(x3, y3)); + } + } + + // Draw the string + if (!overlapTest) + { + RectangleF rect = new RectangleF(labelRect.Location, labelRect.Size); + if (this._labelsOverlap) + { + // Draw label from collection if original labels overlap. + rect = (RectangleF)this._labelsRectangles[pointIndex]; + rect.X = labelRectOver.X; + rect.Width = labelRectOver.Width; + } + + // Get label background position + SizeF valueTextSize = graph.MeasureStringRel(text.Replace("\\n", "\n"), point.Font); + valueTextSize.Height += valueTextSize.Height / 8; + float spacing = valueTextSize.Width / text.Length / 2; + valueTextSize.Width += spacing; + RectangleF labelBackPosition = new RectangleF( + rect.X, + rect.Y + rect.Height / 2f - valueTextSize.Height / 2f, + valueTextSize.Width, + valueTextSize.Height); + + // Adjust position based on alignment + if (format.Alignment == StringAlignment.Near) + { + labelBackPosition.X -= spacing / 2f; + } + else if (format.Alignment == StringAlignment.Center) + { + labelBackPosition.X = rect.X + (rect.Width - valueTextSize.Width) / 2f; + } + else if (format.Alignment == StringAlignment.Far) + { + labelBackPosition.X = rect.Right - valueTextSize.Width - spacing / 2f; + } + + // Draw label text outside + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + area.Common, + text, + point.Font, + brush, + rect, + format, + point.LabelAngle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + series, + point, + pointIndex); + } + } + else + { + // Insert labels in label collection. This + // code is executed only if labels overlap. + this.InsertOverlapLabel(labelRectOver); + added = true; + } + } + } + // Restore old clip region + graph.Clip = oldClipRegion; + + + // Add empty overlap empty position + if(!added) + { + InsertOverlapLabel( RectangleF.Empty ); + } + + return; + + } + + + /// + /// This method returns calculated rectangle from point position + /// for outside label. Rectangle mustn’t be out of chart area. + /// + /// The first position for label + /// Chart area used for chart area position + /// Label text + /// Text format + /// Chart Graphics object + /// Data point + /// Orientation for label. It could be left or right. + /// Calculated rectangle for label + private RectangleF GetLabelRect( PointF labelPosition, ChartArea area, string text, StringFormat format, ChartGraphics graph, DataPoint point, bool leftOrientation ) + { + RectangleF labelRect = RectangleF.Empty; + if( leftOrientation ) + { + labelRect.X = area.Position.X; + labelRect.Y = area.Position.Y; + labelRect.Width = labelPosition.X - area.Position.X; + labelRect.Height = area.Position.Height; + } + else + { + labelRect.X = labelPosition.X; + labelRect.Y = area.Position.Y; + labelRect.Width = area.Position.Right - labelPosition.X; + labelRect.Height = area.Position.Height; + } + + // Find bounding rectangle of the text + SizeF size = graph.MeasureStringRel( text.Replace("\\n", "\n"), point.Font, labelRect.Size, format ); + labelRect.Y = labelPosition.Y - size.Height / 2 * 1.8f; + labelRect.Height = size.Height * 1.8f; + + return labelRect; + } + + + + /// + /// This method returns Pie Label Style enumeration + /// from Data Point Custom attribute. + /// + /// Data Point + /// Pie label style enumeration + private PieLabelStyle GetLabelStyle( DataPoint point ) + { + Series series = point.series; + + PieLabelStyle style = PieLabelStyle.Inside; + + // Get label style attribute from series + if(series.IsCustomPropertySet(CustomPropertyName.LabelStyle)) + { + string labelStyleAttrib = series[CustomPropertyName.LabelStyle]; + + // Labels Disabled + if (String.Compare(labelStyleAttrib, "disabled", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + else if(series.IsCustomPropertySet(CustomPropertyName.PieLabelStyle)) + { + string labelStyleAttrib = series[CustomPropertyName.PieLabelStyle]; + + // Labels Disabled + if (String.Compare(labelStyleAttrib, "disabled", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + + // Get label style attribute from point + if(point.IsCustomPropertySet(CustomPropertyName.LabelStyle)) + { + string labelStyleAttrib = point[CustomPropertyName.LabelStyle]; + + // Labels Disabled + if (String.Compare(labelStyleAttrib, "disabled", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + else if(point.IsCustomPropertySet(CustomPropertyName.PieLabelStyle)) + { + string labelStyleAttrib = point[CustomPropertyName.PieLabelStyle]; + + // Labels Disabled + if (String.Compare(labelStyleAttrib, "disabled", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + + return style; + } + + /// + /// Estimate Labels. + /// + /// Chart Graphics object + /// Center of the pie chart + /// Size of the square, which will be used for drawing pie. + /// Starting angle of a pie slice + /// Sweep angle of a pie slice + /// Data point + /// The pie slice is exploded + /// Chart area + public bool EstimateLabels( ChartGraphics graph, PointF middlePoint, SizeF relativeSize, float startAngle, float sweepAngle, DataPoint point, bool exploded, ChartArea area ) + { + float labelsHorizontalLineSize = 1; // Horizontal line size for outside labels + float labelsRadialLineSize = 1; // Radial line size for outside labels + float shift; + + string pointLabel = this.GetPointLabel(point); + + Series series = point.series; + + PieLabelStyle style = PieLabelStyle.Inside; + + // Get label style attribute from series + if(series.IsCustomPropertySet(CustomPropertyName.LabelStyle)) + { + string labelStyleAttrib = series[CustomPropertyName.LabelStyle]; + + // Labels Disabled + if( String.Compare(labelStyleAttrib,"disabled", StringComparison.OrdinalIgnoreCase) == 0 ) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + else if(series.IsCustomPropertySet(CustomPropertyName.PieLabelStyle)) + { + string labelStyleAttrib = series[CustomPropertyName.PieLabelStyle]; + + // Labels Disabled + if (String.Compare(labelStyleAttrib, "disabled", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + + // Get label style attribute from point + if(point.IsCustomPropertySet(CustomPropertyName.LabelStyle)) + { + string labelStyleAttrib = point[CustomPropertyName.LabelStyle]; + + // Labels Disabled + if (String.Compare(labelStyleAttrib, "disabled", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + else if(point.IsCustomPropertySet(CustomPropertyName.PieLabelStyle)) + { + string labelStyleAttrib = point[CustomPropertyName.PieLabelStyle]; + + // Labels Disabled + if (String.Compare(labelStyleAttrib, "disabled", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Disabled; + else if (String.Compare(labelStyleAttrib, "outside", StringComparison.OrdinalIgnoreCase) == 0) + style = PieLabelStyle.Outside; + else + style = PieLabelStyle.Inside; + } + + // Take labels radial line size attribute from series + if(series.IsCustomPropertySet(CustomPropertyName.LabelsRadialLineSize)) + { + string labelsRadialLineSizeAttrib = series[CustomPropertyName.LabelsRadialLineSize]; + labelsRadialLineSize = CommonElements.ParseFloat( labelsRadialLineSizeAttrib ); + + // Validation + if( labelsRadialLineSize < 0 || labelsRadialLineSize > 100 ) + throw new InvalidOperationException(SR.ExceptionPieRadialLineSizeInvalid); + } + + // Take labels radial line size attribute from point + if(point.IsCustomPropertySet(CustomPropertyName.LabelsRadialLineSize)) + { + string labelsRadialLineSizeAttrib = point[CustomPropertyName.LabelsRadialLineSize]; + labelsRadialLineSize = CommonElements.ParseFloat( labelsRadialLineSizeAttrib ); + + // Validation + if( labelsRadialLineSize < 0 || labelsRadialLineSize > 100 ) + throw new InvalidOperationException(SR.ExceptionPieRadialLineSizeInvalid); + } + + // Take labels horizontal line size attribute from series + if(series.IsCustomPropertySet(CustomPropertyName.LabelsHorizontalLineSize)) + { + string labelsHorizontalLineSizeAttrib = series[CustomPropertyName.LabelsHorizontalLineSize]; + labelsHorizontalLineSize = CommonElements.ParseFloat( labelsHorizontalLineSizeAttrib ); + + // Validation + if( labelsHorizontalLineSize < 0 || labelsHorizontalLineSize > 100 ) + throw new InvalidOperationException(SR.ExceptionPieHorizontalLineSizeInvalid); + } + + // Take labels horizontal line size attribute from point + if(point.IsCustomPropertySet(CustomPropertyName.LabelsHorizontalLineSize)) + { + string labelsHorizontalLineSizeAttrib = point[CustomPropertyName.LabelsHorizontalLineSize]; + labelsHorizontalLineSize = CommonElements.ParseFloat( labelsHorizontalLineSizeAttrib ); + + // Validation + if( labelsHorizontalLineSize < 0 || labelsHorizontalLineSize > 100 ) + throw new InvalidOperationException(SR.ExceptionPieHorizontalLineSizeInvalid); + } + + float expShift = 1; + + + // ******************************************** + // Labels are set outside pie + // ******************************************** + if( style == PieLabelStyle.Outside ) + { + // Coefficient which represent shift from pie border + shift = 0.5F + labelsRadialLineSize * 0.1F; + + // If exploded the shift is bigger + if( exploded ) + expShift = 1.2F; + + float midAngle = startAngle + sweepAngle / 2; + + + // Find second line position + float y3 = (float)Math.Sin( (midAngle) * Math.PI / 180 ) * relativeSize.Height * shift * expShift + middlePoint.Y; + float x3; + + if( midAngle > 90 && midAngle < 270 ) + { + x3 = (float)Math.Cos( (midAngle) * Math.PI / 180 ) * relativeSize.Width * shift * expShift + middlePoint.X - relativeSize.Width / 10 * labelsHorizontalLineSize; + } + else + { + x3 = (float)Math.Cos( (midAngle) * Math.PI / 180 ) * relativeSize.Width * shift * expShift + middlePoint.X + relativeSize.Width / 10 * labelsHorizontalLineSize; + } + + // Get label text + string text; + if( pointLabel.Length == 0 && point.IsValueShownAsLabel ) + { + text = ValueConverter.FormatValue( + series.Chart, + point, + point.Tag, + point.YValues[0], + point.LabelFormat, + point.series.YValueType, + ChartElementType.DataPoint); + } + else + { + text = pointLabel; + } + + SizeF size = graph.MeasureStringRel( text.Replace("\\n", "\n"), point.Font); + + _labelsFit = true; + + if(this._labelsOverlap) + { + if( midAngle > 90 && midAngle < 270 ) + { + float xOverlap = -relativeSize.Width * shift * expShift + middlePoint.X - relativeSize.Width / 10 * labelsHorizontalLineSize; + if( (xOverlap - size.Width) < area.Position.X ) + { + _labelsFit = false; + } + } + else + { + float xOverlap = relativeSize.Width * shift * expShift + middlePoint.X + relativeSize.Width / 10 * labelsHorizontalLineSize; + if( (xOverlap + size.Width) > area.Position.Right ) + { + _labelsFit = false; + } + } + } + else + { + if( midAngle > 90 && midAngle < 270 ) + { + if( x3 - size.Width < area.PlotAreaPosition.ToRectangleF().Left ) + _labelsFit = false; + } + else + { + if( x3 + size.Width > area.PlotAreaPosition.ToRectangleF().Right ) + _labelsFit = false; + } + + if( midAngle > 180 && midAngle < 360 ) + { + if( y3 - size.Height/2 < area.PlotAreaPosition.ToRectangleF().Top ) + _labelsFit = false; + } + else + { + if( y3 + size.Height/2 > area.PlotAreaPosition.ToRectangleF().Bottom ) + _labelsFit = false; + } + } + + } + return true; + } + + /// + /// This method adds map area information. + /// + /// The Common elements object + /// Data Point + /// Start Angle + /// Sweep Angle + /// Rectangle of the pie + /// True if doughnut + /// Doughnut radius in % + /// Chart graphics object + /// Data point index + private void Map( CommonElements common, DataPoint point, float startAngle, float sweepAngle, RectangleF rectangle, bool doughnut, float doughnutRadius, ChartGraphics graph, int pointIndex ) + { + // Create a graphics path + using (GraphicsPath path = new GraphicsPath()) + { + + // Create the interior doughnut rectangle + RectangleF doughnutRect = RectangleF.Empty; + + doughnutRect.X = rectangle.X + rectangle.Width * (1 - (100 - doughnutRadius) / 100) / 2; + doughnutRect.Y = rectangle.Y + rectangle.Height * (1 - (100 - doughnutRadius) / 100) / 2; + doughnutRect.Width = rectangle.Width * (100 - doughnutRadius) / 100; + doughnutRect.Height = rectangle.Height * (100 - doughnutRadius) / 100; + + // Get absolute coordinates of the pie rectangle + rectangle = graph.GetAbsoluteRectangle(rectangle); + + // Add the pie to the graphics path + path.AddPie(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, startAngle, sweepAngle); + // VSTS #250394 (Dev10:591140) Fix - Control should not return “useless” map areas + if (sweepAngle <= 0) + { + return; + } + // If the chart type is doughnut + if (doughnut) + { + + // Get absolute coordinates of the interior doughnut rectangle + doughnutRect = graph.GetAbsoluteRectangle(doughnutRect); + + // Add the interior doughnut region to the graphics path + path.AddPie(doughnutRect.X, doughnutRect.Y, doughnutRect.Width, doughnutRect.Width, startAngle, sweepAngle); + } + + // Make a polygon from curves + path.Flatten(new Matrix(), 1f); + + // Create an area of points and convert them to + // relative coordinates. + PointF[] pointNew = new PointF[path.PointCount]; + for (int i = 0; i < path.PointCount; i++) + { + pointNew[i] = graph.GetRelativePoint(path.PathPoints[i]); + } + + // Allocate array of floats + float[] coord = new float[path.PointCount * 2]; + + // Transfer path points + for (int index = 0; index < path.PointCount; index++) + { + coord[2 * index] = pointNew[index].X; + coord[2 * index + 1] = pointNew[index].Y; + } + + + + // Check if processing collected data point + if (point.IsCustomPropertySet("_COLLECTED_DATA_POINT")) + { + // Add point to the map area + common.HotRegionsList.AddHotRegion( + graph, + path, + false, + point.ReplaceKeywords(point.ToolTip), +#if Microsoft_CONTROL + string.Empty, + string.Empty, + string.Empty, +#else // Microsoft_CONTROL + point.ReplaceKeywords(point.Url), + point.ReplaceKeywords(point.MapAreaAttributes), + point.ReplaceKeywords(point.PostBackValue), +#endif // Microsoft_CONTROL + point, + ChartElementType.DataPoint); + + return; + } + + + + // Add points to the map area + common.HotRegionsList.AddHotRegion( + path, + false, + coord, + point, + point.series.Name, + pointIndex + ); + } + } + + /// + /// This method is introduced to check colors of palette. For + /// pie chart the first pie slice and the second pie slice can + /// not have same color because they are connected. + /// + /// Data points used for pie chart + private void CheckPaleteColors( DataPointCollection points ) + { + DataPoint firstPoint, lastPoint; + + firstPoint = points[0]; + lastPoint = points[ points.Count - 1 ]; + + // Change color for last point if same as the first and if it is from pallete. + if( firstPoint.tempColorIsSet && lastPoint.tempColorIsSet && firstPoint.Color == lastPoint.Color ) + { + lastPoint.Color = points[ points.Count / 2 ].Color; + lastPoint.tempColorIsSet = true; + } + } + + #endregion + + #region 2DLabels + + /// + /// This method finds vertical position for left and + /// right labels on that way that labels do not + /// overlap each other. + /// + /// Chart area position + /// True if it is possible to find position that labels do not overlap each other. + private bool PrepareLabels( RectangleF area ) + { + // Initialization of local variables + float splitPoint = area.X + area.Width / 2f; + int numberOfLeft = 0; + int numberOfRight = 0; + + // Find the number of left and right labels. + foreach( RectangleF rect in this._labelsRectangles ) + { + if( rect.X < splitPoint ) + { + numberOfLeft++; + } + else + { + numberOfRight++; + } + } + + // ********************************************** + // Find the best position for LEFT labels + // ********************************************** + bool leftResult = true; + if(numberOfLeft > 0) + { + double [] startPoints = new double[numberOfLeft]; + double [] endPoints = new double[numberOfLeft]; + int [] positionIndex = new Int32[numberOfLeft]; + + // Fill double arrays with Top and Bottom coordinates + // from the label rectangle. + int splitIndex = 0; + for( int index = 0; index < _labelsRectangles.Count; index++ ) + { + RectangleF rect = (RectangleF)_labelsRectangles[index]; + if( rect.X < splitPoint ) + { + startPoints[ splitIndex ] = rect.Top; + endPoints[ splitIndex ] = rect.Bottom; + positionIndex[ splitIndex ] = index; + splitIndex++; + } + } + + // Sort label positions + this.SortIntervals( startPoints, endPoints, positionIndex ); + + // Find no overlapping positions if possible. + if( this.ArrangeOverlappingIntervals( startPoints, endPoints, area.Top, area.Bottom ) ) + { + // Fill label rectangle top and bottom coordinates + // from double arrays. + splitIndex = 0; + for( int index = 0; index < _labelsRectangles.Count; index++ ) + { + RectangleF rect = (RectangleF)_labelsRectangles[index]; + if( rect.X < splitPoint ) + { + rect.Y = (float)startPoints[ splitIndex ]; + rect.Height = (float)(endPoints[ splitIndex ] - rect.Top); + _labelsRectangles[positionIndex[ splitIndex ]] = rect; + splitIndex++; + + } + } + } + else + { + leftResult = false; + } + } + + // ********************************************** + // Find the best position for Right labels + // ********************************************** + bool rigthResult = true; + if(numberOfRight > 0) + { + double [] startPoints = new double[numberOfRight]; + double [] endPoints = new double[numberOfRight]; + int [] positionIndex = new Int32[numberOfRight]; + + // Fill double arrays with Top and Bottom coordinates + // from the label rectangle. + int splitIndex = 0; + for( int index = 0; index < _labelsRectangles.Count; index++ ) + { + RectangleF rect = (RectangleF)_labelsRectangles[index]; + if( rect.X >= splitPoint ) + { + startPoints[ splitIndex ] = rect.Top; + endPoints[ splitIndex ] = rect.Bottom; + positionIndex[ splitIndex ] = index; + splitIndex++; + } + } + + // Sort label positions + this.SortIntervals( startPoints, endPoints, positionIndex ); + + // Find no overlapping positions if possible. + if( this.ArrangeOverlappingIntervals( startPoints, endPoints, area.Top, area.Bottom ) ) + { + // Fill label rectangle top and bottom coordinates + // from double arrays. + splitIndex = 0; + for( int index = 0; index < _labelsRectangles.Count; index++ ) + { + RectangleF rect = (RectangleF)_labelsRectangles[index]; + if( rect.X >= splitPoint ) + { + rect.Y = (float)startPoints[ splitIndex ]; + rect.Height = (float)(endPoints[ splitIndex ] - rect.Top); + _labelsRectangles[positionIndex[ splitIndex ]] = rect; + splitIndex++; + } + } + } + else + { + rigthResult = false; + } + } + + return ( (!leftResult || !rigthResult) ? true : false ); + } + + /// + /// This algorithm sorts labels vertical intervals. + /// + /// Double array of label interval start points + /// Double array of label interval end points + /// Integer array of label interval indexes + private void SortIntervals( double [] startOfIntervals, double [] endOfIntervals, int [] positinIndex ) + { + double firstCenter; + double secondCenter; + double midDouble; + int midInt; + + // Sorting loops + for( int firstIndex = 0; firstIndex < startOfIntervals.Length; firstIndex++ ) + { + for( int secondIndex = firstIndex; secondIndex < startOfIntervals.Length; secondIndex++ ) + { + firstCenter = ( startOfIntervals[ firstIndex ] + endOfIntervals[ firstIndex ] ) / 2.0; + secondCenter = ( startOfIntervals[ secondIndex ] + endOfIntervals[ secondIndex ] ) / 2.0; + + if( firstCenter > secondCenter ) + { + // Sort start points + midDouble = startOfIntervals[ firstIndex ]; + startOfIntervals[ firstIndex ] = startOfIntervals[ secondIndex ]; + startOfIntervals[ secondIndex ] = midDouble; + + // Sort end points + midDouble = endOfIntervals[ firstIndex ]; + endOfIntervals[ firstIndex ] = endOfIntervals[ secondIndex ]; + endOfIntervals[ secondIndex ] = midDouble; + + // Sort indexes + midInt = positinIndex[ firstIndex ]; + positinIndex[ firstIndex ] = positinIndex[ secondIndex ]; + positinIndex[ secondIndex ] = midInt; + } + } + } + } + + /// + /// This method inserts label rectangles + /// into the collection. + /// + /// Label Rectangle + private void InsertOverlapLabel( RectangleF labelRect ) + { + // Check if any pair of labels overlap + if(!labelRect.IsEmpty) + { + foreach( RectangleF rect in _labelsRectangles ) + { + if( labelRect.IntersectsWith( rect ) ) + { + this._labelsOverlap = true; + } + } + } + + // Add rectangle to the collection + _labelsRectangles.Add( labelRect ); + } + + /// + /// This method will find the best position for labels. + /// It is based on finding non overlap intervals for + /// left or right side of the pie. This is + /// recursive algorithm. + /// + /// The start positions of intervals. + /// The end positions of intervals. + /// Start position of chart area vertical range. + /// End position of chart area vertical range. + /// False if non overlapping positions for intervals can not be found. + private bool ArrangeOverlappingIntervals( double [] startOfIntervals, double [] endOfIntervals, double startArea, double endArea ) + { + + // Invalidation + if( startOfIntervals.Length != endOfIntervals.Length ) + { + throw new InvalidOperationException(SR.ExceptionPieIntervalsInvalid); + } + + ShiftOverlappingIntervals( startOfIntervals, endOfIntervals ); + + // Find amount of empty space between intervals. + double emptySpace = 0; + for( int intervalIndex = 0; intervalIndex < startOfIntervals.Length - 1; intervalIndex++ ) + { + // Check overlapping + if( startOfIntervals[ intervalIndex + 1 ] < endOfIntervals[ intervalIndex ] ) + { + //throw new InvalidOperationException( SR.ExceptionPieIntervalsOverlapping ); + } + + emptySpace += startOfIntervals[ intervalIndex + 1 ] - endOfIntervals[ intervalIndex ]; + } + + //Find how much intervals are out of area. Out of area could be positive value only. + double outOfArea = ( endOfIntervals[ endOfIntervals.Length - 1 ] - endArea ) + ( startArea - startOfIntervals[ 0 ] ); + if( outOfArea <= 0 ) + { + // This algorithm shifts all intervals for the same + // amount. It is trying to put all intervals inside + // chart area range. + ShiftIntervals( startOfIntervals, endOfIntervals, startArea, endArea ); + return true; + } + + // There is no enough space for all intervals. + if( outOfArea > emptySpace ) + { + return false; + } + + // This method reduces empty space between intervals. + ReduceEmptySpace( startOfIntervals, endOfIntervals, ( emptySpace - outOfArea ) / emptySpace ); + + // This algorithm shifts all intervals for the same + // amount. It is trying to put all intervals inside + // chart area range. + ShiftIntervals( startOfIntervals, endOfIntervals, startArea, endArea ); + + return true; + } + + /// + /// This method reduces empty space between intervals. + /// + /// The start positions of intervals. + /// The end positions of intervals. + /// Relative value which presents size reduction. + private void ReduceEmptySpace( double [] startOfIntervals, double [] endOfIntervals, double reduction ) + { + for( int intervalIndex = 0; intervalIndex < startOfIntervals.Length - 1; intervalIndex++ ) + { + // Check overlapping + if( startOfIntervals[ intervalIndex + 1 ] < endOfIntervals[ intervalIndex ] ) + { + //throw new InvalidOperationException( SR.ExceptionPieIntervalsOverlapping ); + } + + // Reduce space + double shift = ( startOfIntervals[ intervalIndex + 1 ] - endOfIntervals[ intervalIndex ] ) - ( startOfIntervals[ intervalIndex + 1 ] - endOfIntervals[ intervalIndex ] ) * reduction; + for( int reductionIndex = intervalIndex + 1; reductionIndex < startOfIntervals.Length; reductionIndex++ ) + { + startOfIntervals[ reductionIndex ] -= shift; + endOfIntervals[ reductionIndex ] -= shift; + } + } + } + + /// + /// This algorithm shifts all intervals for the same + /// amount. It is trying to put all intervals inside + /// chart area range. + /// + /// The start positions of intervals. + /// The end positions of intervals. + /// Start position of chart area vertical range. + /// End position of chart area vertical range. + private void ShiftIntervals( double [] startOfIntervals, double [] endOfIntervals, double startArea, double endArea ) + { + + double shift = 0; + + if( startOfIntervals[ 0 ] < startArea ) + { + shift = startArea - startOfIntervals[ 0 ]; + } + else if( endOfIntervals[ endOfIntervals.Length - 1 ] > endArea ) + { + shift = endArea - endOfIntervals[ endOfIntervals.Length - 1 ]; + } + + for( int index = 0; index < startOfIntervals.Length; index++ ) + { + startOfIntervals[ index ] += shift; + endOfIntervals[ index ] += shift; + } + } + + /// + /// This is used to find non overlapping position for intervals. + /// + /// The start positions of intervals. + /// The end positions of intervals. + /// Returns true if any label overlaps before method is used. + private void ShiftOverlappingIntervals( double [] startOfIntervals, double [] endOfIntervals ) + { + // Invalidation + if( startOfIntervals.Length != endOfIntervals.Length ) + { + throw new InvalidOperationException(SR.ExceptionPieIntervalsInvalid); + } + + // Find first overlaping intervals + for( int index = 0; index < startOfIntervals.Length - 1; index++ ) + { + // Intervals overlap + if( endOfIntervals[ index ] > startOfIntervals[ index + 1 ] ) + { + double overlapRange = endOfIntervals[ index ] - startOfIntervals[ index + 1 ]; + SpreadInterval( startOfIntervals, endOfIntervals, index, Math.Floor( overlapRange / 2.0 ) ); + } + } + } + + /// + /// This method spread all intervals down or up from + /// splitIndex. Intervals are spread only if there is no + /// empty space which will compensate shifting of intervals. + /// + /// The start positions of intervals. + /// The end positions of intervals. + /// Position of the interval which ovelap. + /// The half of the overlapping range. + private void SpreadInterval( double [] startOfIntervals, double [] endOfIntervals, int splitIndex, double overlapShift ) + { + // Move first overlapping intervals. + endOfIntervals[ splitIndex ] -= overlapShift; + startOfIntervals[ splitIndex ] -= overlapShift; + + endOfIntervals[ splitIndex + 1 ] += overlapShift; + startOfIntervals[ splitIndex + 1 ] += overlapShift; + + // Move up other intervals if there is no enough empty space + // to compensate overlapping intervals. + if( splitIndex > 0 ) + { + for( int index = splitIndex - 1; index >= 0; index-- ) + { + if( endOfIntervals[ index ] > startOfIntervals[ index + 1 ] - overlapShift ) + { + endOfIntervals[ index ] -= overlapShift; + startOfIntervals[ index ] -= overlapShift; + } + else + { + break; + } + } + } + + // Move down other intervals if there is no enough empty space + // to compensate overlapping intervals. + if( splitIndex + 2 < startOfIntervals.Length - 1 ) + { + for( int index = splitIndex + 2; index < startOfIntervals.Length; index++ ) + { + if( startOfIntervals[ index ] > endOfIntervals[ index - 1 ] + overlapShift ) + { + endOfIntervals[ index ] += overlapShift; + startOfIntervals[ index ] += overlapShift; + } + else + { + break; + } + } + } + } + + #endregion + + #region Y values related methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + return point.YValues[yValueIndex]; + } + + #endregion + + #region 3D painting and selection methods + + /// + /// This method recalculates position of pie slices + /// or checks if pie slice is selected. + /// + /// If True selection mode is active, otherwise paint mode is active + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Pie width. + private void ProcessChartType3D( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + float pieWidth ) + { + string explodedAttrib = ""; // Exploded attribute + bool exploded; // Exploded pie slice + float midAngle; // Angle between Start Angle and End Angle + + + // Data series collection + SeriesCollection dataSeries = common.DataManager.Series; + + // All data series from chart area which have Pie chart type + List typeSeries = area.GetSeriesFromChartType(Name); + + if( typeSeries.Count == 0 ) + { + return; + } + + // Get first pie starting angle + if (dataSeries[typeSeries[0]].IsCustomPropertySet(CustomPropertyName.PieStartAngle)) + { + int angle; + bool parseSucceed = int.TryParse(dataSeries[typeSeries[0]][CustomPropertyName.PieStartAngle], NumberStyles.Any, CultureInfo.InvariantCulture, out angle); + + if (parseSucceed) + { + if (angle > 180 && angle <= 360) + { + angle = -(360 - angle); + } + area.Area3DStyle.Rotation = angle; + } + + + if (!parseSucceed || area.Area3DStyle.Rotation > 180 || area.Area3DStyle.Rotation < -180) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeAngleOutOfRange("PieStartAngle"))); + } + } + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(dataSeries[typeSeries[0]], graph, common, area.PlotAreaPosition)); + } + + // The data points loop. Find Sum of data points. + double sum = 0; + foreach( DataPoint point in dataSeries[typeSeries[0]].Points ) + { + if( !point.IsEmpty ) + { + sum += Math.Abs(point.YValues[0]); + } + } + + // Is exploded if only one is exploded + bool isExploded = false; + foreach( DataPoint point in dataSeries[typeSeries[0]].Points ) + { + if(point.IsCustomPropertySet(CustomPropertyName.Exploded)) + { + explodedAttrib = point[CustomPropertyName.Exploded]; + if( String.Compare(explodedAttrib,"true",StringComparison.OrdinalIgnoreCase) == 0 ) + { + isExploded = true; + } + } + } + + // Take radius attribute + float doughnutRadius = 60f; + if(dataSeries[typeSeries[0]].IsCustomPropertySet(CustomPropertyName.DoughnutRadius)) + { + doughnutRadius = CommonElements.ParseFloat(dataSeries[typeSeries[0]][CustomPropertyName.DoughnutRadius] ); + + // Validation + if( doughnutRadius < 0f || doughnutRadius > 99f ) + throw (new ArgumentException(SR.ExceptionPieRadiusInvalid)); + + } + + // Take 3D Label Line Size attribute + float labelLineSize = 100f; + if(dataSeries[typeSeries[0]].IsCustomPropertySet(CustomPropertyName._3DLabelLineSize)) + { + labelLineSize = CommonElements.ParseFloat(dataSeries[typeSeries[0]][CustomPropertyName._3DLabelLineSize] ); + + // Validation + if( labelLineSize < 30f || labelLineSize > 200f ) + throw (new ArgumentException(SR.ExceptionPie3DLabelLineSizeInvalid)); + + } + labelLineSize = labelLineSize * 0.1F / 100F; + + //************************************************************ + //** Data point loop + //************************************************************ + float [] startAngleList; + float [] sweepAngleList; + int [] pointIndexList; + + // This method is introduced to check colors of palette. For + // pie chart the first pie slice and the second pie slice can + // not have same color because they are connected. + CheckPaleteColors( dataSeries[typeSeries[0]].Points ); + + bool sameBackFront; + DataPoint [] points = PointOrder( dataSeries[typeSeries[0]], area, out startAngleList, out sweepAngleList, out pointIndexList, out sameBackFront ); + + // There are no points or all points are empty. + if( points == null ) + { + return; + } + + RectangleF plotingRectangle = new RectangleF( area.Position.ToRectangleF().X + 1, area.Position.ToRectangleF().Y + 1, area.Position.ToRectangleF().Width-2, area.Position.ToRectangleF().Height-2 ); + + // Check if any data point has outside label + bool outside = false; + foreach( DataPoint point in points ) + { + if( GetLabelStyle( point ) == PieLabelStyle.Outside ) + { + outside = true; + } + } + + // If outside labels resize Pie size + if( outside ) + { + InitPieSize( graph, area, ref plotingRectangle, ref pieWidth, points, startAngleList, sweepAngleList, dataSeries[typeSeries[0]], labelLineSize ); + } + + // Initialize Matrix 3D + area.matrix3D.Initialize( + plotingRectangle, + pieWidth, + area.Area3DStyle.Inclination, + 0F, + 0, + false); + + //*********************************************************** + //** Initialize Lighting + //*********************************************************** + area.matrix3D.InitLight( + area.Area3DStyle.LightStyle + ); + + // Turns are introduce because of special case – Big pie slice, which + // is bigger, then 180 degree and it is back and + // front point in same time. If special case exists drawing has to be split + // into 4 parts: 1. Drawing back pie slices, 2. Drawing the first part of + // big slice and other points, 3. Drawing second part of big slice and + // 4. Drawing top of the pie slices. + for( int turn = 0; turn < 5; turn++ ) + { + int pointIndx = 0; + foreach( DataPoint point in points ) + { + // Reset point anchor location + point.positionRel = PointF.Empty; + + // Do not process empty points + if( point.IsEmpty ) + { + pointIndx++; + continue; + } + + float sweepAngle = sweepAngleList[pointIndx]; + float startAngle = startAngleList[pointIndx]; + + // Rectangle size + RectangleF rectangle; + if( area.InnerPlotPosition.Auto ) + rectangle = new RectangleF( plotingRectangle.X, plotingRectangle.Y, plotingRectangle.Width, plotingRectangle.Height ); + else + rectangle = new RectangleF( area.PlotAreaPosition.ToRectangleF().X, area.PlotAreaPosition.ToRectangleF().Y, area.PlotAreaPosition.ToRectangleF().Width, area.PlotAreaPosition.ToRectangleF().Height ); + + // Find smallest edge + SizeF absoluteSize = graph.GetAbsoluteSize( new SizeF( rectangle.Width, rectangle.Height ) ); + float absRadius = ( absoluteSize.Width < absoluteSize.Height ) ? absoluteSize.Width : absoluteSize.Height; + + // Size of the square, which will be used for drawing pie. + SizeF relativeSize = graph.GetRelativeSize( new SizeF( absRadius, absRadius ) ); + + // Center of the pie + PointF middlePoint = new PointF( rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2 ); + + // Rectangle which will always create circle, never ellipse. + rectangle = new RectangleF( middlePoint.X - relativeSize.Width / 2, middlePoint.Y - relativeSize.Height / 2, relativeSize.Width, relativeSize.Height ); + + // Check Exploded attribute for data point + exploded = false; + if(point.IsCustomPropertySet(CustomPropertyName.Exploded)) + { + explodedAttrib = point[CustomPropertyName.Exploded]; + if( String.Compare(explodedAttrib,"true",StringComparison.OrdinalIgnoreCase) == 0 ) + exploded = true; + else + exploded = false; + } + + // Size correction because of exploded or labels + float sizeCorrection = 1.0F; + if( isExploded ) + { + sizeCorrection = 0.82F; + + rectangle.X += rectangle.Width * ( 1 - sizeCorrection ) / 2; + rectangle.Y += rectangle.Height * ( 1 - sizeCorrection ) / 2; + rectangle.Width = rectangle.Width * sizeCorrection; + rectangle.Height = rectangle.Height * sizeCorrection; + } + + + // Find Direction to move exploded pie slice + if( exploded ) + { + _sliceExploded = true; + midAngle = ( 2 * startAngle + sweepAngle ) / 2; + double xComponent = Math.Cos( midAngle * Math.PI / 180 ) * rectangle.Width / 10; + double yComponent = Math.Sin( midAngle * Math.PI / 180 ) * rectangle.Height / 10; + + rectangle.Offset( (float)xComponent, (float)yComponent ); + } + + // Adjust inner plot position + if(area.InnerPlotPosition.Auto) + { + RectangleF rect = rectangle; + rect.X = (rect.X - area.Position.X) / area.Position.Width * 100f; + rect.Y = (rect.Y - area.Position.Y) / area.Position.Height * 100f; + rect.Width = rect.Width / area.Position.Width * 100f; + rect.Height = rect.Height / area.Position.Height * 100f; + area.InnerPlotPosition.SetPositionNoAuto(rect.X, rect.Y, rect.Width, rect.Height); + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Drawing or selection of pie clice + Draw3DPie( turn, graph, point, area, rectangle, startAngle, sweepAngle, doughnutRadius, pieWidth, sameBackFront, exploded, pointIndexList[pointIndx] ); + + // End Svg Selection mode + graph.EndHotRegion( ); + + if( turn == 1 ) + { + // Outside labels + if( GetLabelStyle( point ) == PieLabelStyle.Outside ) + { + FillPieLabelOutside( graph, area, rectangle, pieWidth, point, startAngle, sweepAngle, pointIndx, doughnutRadius, exploded ); + } + } + if( turn == 2 ) + { + + // Outside labels + if( GetLabelStyle( point ) == PieLabelStyle.Outside && pointIndx == 0 ) + { + labelColumnLeft.Sort(); + labelColumnLeft.AdjustPositions(); + labelColumnRight.Sort(); + labelColumnRight.AdjustPositions(); + } + + } + + // Increae point index + pointIndx++; + } + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(dataSeries[typeSeries[0]], graph, common, area.PlotAreaPosition)); + } + } + + /// + /// This method draws a part of a pie slice. Which part is drown + /// depend on turn. There is special case if there is a big pie + /// slice (>180) when one pie slice has to be split on parts + /// and between that other small pie slices has to be drawn. + /// + /// Turn for drawing. + /// Chart Graphics + /// Data Point to draw + /// Chart area + /// Rectangle used for drawing pie clice. + /// Start angle for pie slice + /// End angle for pie slice + /// Inner Radius if chart is doughnut + /// Width of the pie + /// Pie slice is >180 and same pie slice is back and front slice + /// Pie slice is exploded + /// Point Index + private void Draw3DPie( + int turn, + ChartGraphics graph, + DataPoint point, + ChartArea area, + RectangleF rectangle, + float startAngle, + float sweepAngle, + float doughnutRadius, + float pieWidth, + bool sameBackFront, + bool exploded, + int pointIndex + ) + { + SolidBrush brush = new SolidBrush(point.Color); + + // For lightStyle style Non, Border color always exist. + Color penColor = Color.Empty; + Color penCurveColor = Color.Empty; + + if( point.BorderColor == Color.Empty && area.Area3DStyle.LightStyle == LightStyle.None ) + { + penColor = ChartGraphics.GetGradientColor( point.Color, Color.Black, 0.5 ); + } + else if( point.BorderColor == Color.Empty ) + { + penColor = point.Color; + } + else + { + penColor = point.BorderColor; + } + + if( point.BorderColor != Color.Empty || area.Area3DStyle.LightStyle == LightStyle.None ) + { + penCurveColor = penColor; + } + + Pen pen = new Pen(penColor, point.BorderWidth); + pen.DashStyle = graph.GetPenStyle( point.BorderDashStyle ); + + // Pen for back side slice. + Pen backSlicePen; + if( point.BorderColor == Color.Empty ) + { + backSlicePen = new Pen(point.Color); + } + else + { + backSlicePen = pen; + } + + Pen penCurve = new Pen(penCurveColor, point.BorderWidth); + penCurve.DashStyle = graph.GetPenStyle( point.BorderDashStyle ); + + // Set Border Width; + PointF [] points = GetPiePoints( graph, area, pieWidth, rectangle, startAngle, sweepAngle, true, doughnutRadius, exploded ); + + if( points == null ) + return; + + // Remember data point anchor location + point.positionRel.X = points[(int)PiePoints.TopLabelLine].X; + point.positionRel.Y = points[(int)PiePoints.TopLabelLine].Y; + point.positionRel = graph.GetRelativePoint(point.positionRel); + + + float midAngle = startAngle + sweepAngle / 2F; + float endAngle = startAngle + sweepAngle; + + if( turn == 0 ) + { + // Draw back pie slice (do not fill). + // Used for transparency. + if( !this.Doughnut ) + { + graph.FillPieSlice( + area, + point, + brush, + backSlicePen, + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomStart], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.BottomEnd], + points[(int)PiePoints.BottomCenter], + startAngle, + sweepAngle, + false, + pointIndex + ); + } + else + { + graph.FillDoughnutSlice( + area, + point, + brush, + backSlicePen, + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomStart], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.BottomEnd], + points[(int)PiePoints.DoughnutBottomEnd], + points[(int)PiePoints.DoughnutBottomStart], + startAngle, + sweepAngle, + false, + doughnutRadius, + pointIndex + ); + } + + } + else if( turn == 1 ) + { + // Case when there is big pie slice ( > 180 ) and big slice is + // back and front point in same time. + if( sameBackFront ) + { + + + // Draw the first part of the curve of the big slice and + // all curves from other slices. Big pie slice could be on the + // right or the left side. + if( midAngle > -90 && midAngle < 90 || midAngle > 270 && midAngle < 450 ) + { + // Draw Inner Arc for Doughnut + if( Doughnut ) + { + DrawDoughnutCurves( graph, area, point, startAngle, sweepAngle, points, brush, penCurve, false, true, pointIndex ); + } + + DrawPieCurves( graph, area, point, startAngle, sweepAngle, points, brush, penCurve, true, true, pointIndex ); + } + else + { + // Draw Inner Arc for Doughnut + if( Doughnut ) + { + DrawDoughnutCurves( graph, area, point, startAngle, sweepAngle, points, brush, penCurve, true, true, pointIndex ); + } + + DrawPieCurves( graph, area, point, startAngle, sweepAngle, points, brush, penCurve, false, true, pointIndex ); + } + + // Draw sides of pie slices + graph.FillPieSides( area, area.Area3DStyle.Inclination, startAngle, sweepAngle, points, brush, pen, Doughnut ); + + + } + else + { + // Draw Inner Arc for Doughnut + if( Doughnut ) + { + DrawDoughnutCurves( graph, area, point, startAngle, sweepAngle, points, brush, penCurve, false, false, pointIndex ); + } + + // This is regular case. There is no big pie slice + // which is back nad front point in same time. + graph.FillPieSides( area, area.Area3DStyle.Inclination, startAngle, sweepAngle, points, brush, pen, Doughnut ); + + DrawPieCurves( graph, area, point, startAngle, sweepAngle, points, brush, penCurve, false, false, pointIndex ); + } + + } + else if( turn == 2 ) + { + // This second turned is used only for big pie slice (>180). If big pie + // slice exist it has to be split if it is necessary. If the big pie slice + // cover other pie slice from both sides, the big pie slice have to curves. + // The first curve from big pie slice is drawn first, after that all other + // pie slices and at the end second curve from big pie slice. + if( sameBackFront && sweepAngle > 180 ) + { + // Condition when two draw Doughnut arcs after sides for big pie slice ( > 180 ). + bool BackFrontDoughnut = ( startAngle > -180 && startAngle < 0 || startAngle > 180 && startAngle < 360 ) && ( endAngle > -180 && endAngle < 0 || endAngle > 180 && endAngle < 360 ); + + if( area.Area3DStyle.Inclination > 0 ) + BackFrontDoughnut = !BackFrontDoughnut; + + if( midAngle > -90 && midAngle < 90 || midAngle > 270 && midAngle < 450 ) + { + // Draw Inner Arc for Doughnut + if( Doughnut ) + { + // Draw second part of doughnut curve only for very big slices > 300 ( Visibility issue for Big point depth ). + if( BackFrontDoughnut && sweepAngle > 300 ) + { + DrawDoughnutCurves( graph, area, point, startAngle, sweepAngle, points, brush, penCurve, true, true, pointIndex ); + } + } + + DrawPieCurves( graph, area, point, startAngle, sweepAngle, points, brush, penCurve, false, true, pointIndex ); + } + else + { + // Draw Inner Arc for Doughnut + if( Doughnut ) + { + // Draw second part of doughnut curve only for very big slices > 300( Visibility issue for Big point depth ). + if( BackFrontDoughnut && sweepAngle > 300 ) + { + DrawDoughnutCurves( graph, area, point, startAngle, sweepAngle, points, brush, penCurve, false, true, pointIndex ); + } + } + DrawPieCurves( graph, area, point, startAngle, sweepAngle, points, brush, penCurve, true, true, pointIndex ); + } + } + } + else if( turn == 3 ) + { + if( !this.Doughnut ) + { + // Fill pie slice + graph.FillPieSlice( + area, + point, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.TopCenter], + startAngle, + sweepAngle, + true, + pointIndex + ); + + // Draw Border + graph.FillPieSlice( + area, + point, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.TopCenter], + startAngle, + sweepAngle, + false, + pointIndex + ); + } + else + { + // Fill + graph.FillDoughnutSlice( + area, + point, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.DoughnutTopEnd], + points[(int)PiePoints.DoughnutTopStart], + startAngle, + sweepAngle, + true, + doughnutRadius, + pointIndex + ); + + // Draw Border + graph.FillDoughnutSlice( + area, + point, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.DoughnutTopEnd], + points[(int)PiePoints.DoughnutTopStart], + startAngle, + sweepAngle, + false, + doughnutRadius, + pointIndex + ); + } + + // Draw 3D Outside labels + if( GetLabelStyle( point ) == PieLabelStyle.Outside ) + { + // Check if special color properties are set + Color pieLineColor = pen.Color; + if(point.IsCustomPropertySet(CustomPropertyName.PieLineColor) || (point.series != null && point.series.IsCustomPropertySet(CustomPropertyName.PieLineColor)) ) + { + ColorConverter colorConverter = new ColorConverter(); + bool failed = false; + + try + { + if(point.IsCustomPropertySet(CustomPropertyName.PieLineColor)) + { + pieLineColor = (Color)colorConverter.ConvertFromString(point[CustomPropertyName.PieLineColor]); + } + else if(point.series != null && point.series.IsCustomPropertySet(CustomPropertyName.PieLineColor)) + { + pieLineColor = (Color)colorConverter.ConvertFromString(point.series[CustomPropertyName.PieLineColor]); + } + } + catch (ArgumentException) + { + failed = true; + } + catch (NotSupportedException) + { + failed = true; + } + + if(failed) + { + if(point.IsCustomPropertySet(CustomPropertyName.PieLineColor)) + { + pieLineColor = (Color)colorConverter.ConvertFromInvariantString(point[CustomPropertyName.PieLineColor]); + } + else if(point.series != null && point.series.IsCustomPropertySet(CustomPropertyName.PieLineColor)) + { + pieLineColor = (Color)colorConverter.ConvertFromInvariantString(point.series[CustomPropertyName.PieLineColor]); + } + } + } + + // Draw labels + using (Pen labelPen = new Pen(pieLineColor, pen.Width)) + { + Draw3DOutsideLabels(graph, area, labelPen, points, point, midAngle, pointIndex); + } + } + + } + else + { + + // Draw 3D Inside labels + if( GetLabelStyle( point ) == PieLabelStyle.Inside ) + { + Draw3DInsideLabels( graph, points, point, pointIndex ); + } + } + + //Clean up resources + if (brush!=null) + brush.Dispose(); + if (pen != null) + pen.Dispose(); + if (penCurve != null) + penCurve.Dispose(); + } + + /// + /// This method transforms in 3D space important points for + /// doughnut or pie slice. + /// + /// Chart Graphics + /// Chart Area + /// The width of a pie. + /// Rectangle used for drawing pie clice. + /// Start angle for pie slice. + /// End angle for pie slice. + /// true if relative coordinates has to be returned. + /// Doughnut Radius + /// Exploded pie slice + /// Returns 3D Transformed pie or doughnut points. + private PointF [] GetPiePoints( + ChartGraphics graph, + ChartArea area, + float pieWidth, + RectangleF rectangle, + float startAngle, + float sweepAngle, + bool relativeCoordinates, + float doughnutRadius, + bool exploded + ) + { + doughnutRadius = 1 - doughnutRadius / 100F; + + Point3D [] points; + PointF [] result; + + // Doughnut chart has 12 more points + if( Doughnut ) + { + points = new Point3D[29]; + result = new PointF[29]; + } + else + { + points = new Point3D[17]; + result = new PointF[17]; + } + + // Angle 180 Top point on the arc + points[(int)PiePoints.Top180] = new Point3D( + rectangle.X + (float)Math.Cos( 180 * Math.PI / 180 ) * rectangle.Width / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( 180 * Math.PI / 180 ) * rectangle.Height / 2F + rectangle.Height / 2F, + pieWidth ); + + // Angle 180 Bottom point on the arc + points[(int)PiePoints.Bottom180] = new Point3D( + rectangle.X + (float)Math.Cos( 180 * Math.PI / 180 ) * rectangle.Width / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( 180 * Math.PI / 180 ) * rectangle.Height / 2F + rectangle.Height / 2F, + 0 ); + + // Angle 0 Top point on the arc + points[(int)PiePoints.Top0] = new Point3D( + rectangle.X + (float)Math.Cos( 0 * Math.PI / 180 ) * rectangle.Width / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( 0 * Math.PI / 180 ) * rectangle.Height / 2F + rectangle.Height / 2F, + pieWidth ); + + // Angle 0 Bottom point on the arc + points[(int)PiePoints.Bottom0] = new Point3D( + rectangle.X + (float)Math.Cos( 0 * Math.PI / 180 ) * rectangle.Width / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( 0 * Math.PI / 180 ) * rectangle.Height / 2F + rectangle.Height / 2F, + 0 ); + + // Top Start Angle point on the arc + points[(int)PiePoints.TopStart] = new Point3D( + rectangle.X + (float)Math.Cos( startAngle * Math.PI / 180 ) * rectangle.Width / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( startAngle * Math.PI / 180 ) * rectangle.Height / 2F + rectangle.Height / 2F, + pieWidth ); + + // Top End Angle point on the arc + points[(int)PiePoints.TopEnd] = new Point3D( + rectangle.X + (float)Math.Cos( ( startAngle + sweepAngle ) * Math.PI / 180 ) * rectangle.Width / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( ( startAngle + sweepAngle ) * Math.PI / 180 ) * rectangle.Height / 2F + rectangle.Height / 2F, + pieWidth ); + + // Bottom Start Angle point on the arc + points[(int)PiePoints.BottomStart] = new Point3D( + rectangle.X + (float)Math.Cos( startAngle * Math.PI / 180 ) * rectangle.Width / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( startAngle * Math.PI / 180 ) * rectangle.Height / 2F + rectangle.Height / 2F, + 0 ); + + // Bottom End Angle point on the arc + points[(int)PiePoints.BottomEnd] = new Point3D( + rectangle.X + (float)Math.Cos( ( startAngle + sweepAngle ) * Math.PI / 180 ) * rectangle.Width / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( ( startAngle + sweepAngle ) * Math.PI / 180 ) * rectangle.Height / 2F + rectangle.Height / 2F, + 0 ); + + // Center Top + points[(int)PiePoints.TopCenter] = new Point3D( + rectangle.X + rectangle.Width / 2F, + rectangle.Y + rectangle.Height / 2F, + pieWidth ); + + // Center Bottom + points[(int)PiePoints.BottomCenter] = new Point3D( + rectangle.X + rectangle.Width / 2F, + rectangle.Y + rectangle.Height / 2F, + 0 ); + + // Top Label Line + points[(int)PiePoints.TopLabelLine] = new Point3D( + rectangle.X + (float)Math.Cos( ( startAngle + sweepAngle / 2 ) * Math.PI / 180 ) * rectangle.Width / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( ( startAngle + sweepAngle / 2 ) * Math.PI / 180 ) * rectangle.Height / 2F + rectangle.Height / 2F, + pieWidth ); + + // If Pie slice is exploded Label line out size is changed + float sizeOut; + if( exploded ) + { + sizeOut = 1.1F; + } + else + { + sizeOut = 1.3F; + } + + // Top Label Line Out + points[(int)PiePoints.TopLabelLineout] = new Point3D( + rectangle.X + (float)Math.Cos( ( startAngle + sweepAngle / 2 ) * Math.PI / 180 ) * rectangle.Width * sizeOut / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( ( startAngle + sweepAngle / 2 ) * Math.PI / 180 ) * rectangle.Height * sizeOut / 2F + rectangle.Height / 2F, + pieWidth ); + + // Top Label Center + if( this.Doughnut ) + { + points[(int)PiePoints.TopLabelCenter] = new Point3D( + rectangle.X + (float)Math.Cos( ( startAngle + sweepAngle / 2 ) * Math.PI / 180 ) * rectangle.Width * ( 1 + doughnutRadius ) / 4F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( ( startAngle + sweepAngle / 2 ) * Math.PI / 180 ) * rectangle.Height * ( 1 + doughnutRadius ) / 4F + rectangle.Height / 2F, + pieWidth ); + } + else + { + points[(int)PiePoints.TopLabelCenter] = new Point3D( + rectangle.X + (float)Math.Cos( ( startAngle + sweepAngle / 2 ) * Math.PI / 180 ) * rectangle.Width * 0.5F / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( ( startAngle + sweepAngle / 2 ) * Math.PI / 180 ) * rectangle.Height * 0.5F / 2F + rectangle.Height / 2F, + pieWidth ); + } + + + // Top Rectangle Top Left Point + points[(int)PiePoints.TopRectTopLeftPoint] = new Point3D(rectangle.X,rectangle.Y,pieWidth); + + // Top Rectangle Right Bottom Point + points[(int)PiePoints.TopRectBottomRightPoint] = new Point3D(rectangle.Right,rectangle.Bottom,pieWidth); + + // Bottom Rectangle Top Left Point + points[(int)PiePoints.BottomRectTopLeftPoint] = new Point3D(rectangle.X,rectangle.Y,0); + + // Bottom Rectangle Right Bottom Point + points[(int)PiePoints.BottomRectBottomRightPoint] = new Point3D(rectangle.Right,rectangle.Bottom,0); + + if( Doughnut ) + { + // Angle 180 Top point on the Doughnut arc + points[(int)PiePoints.DoughnutTop180] = new Point3D( + rectangle.X + (float)Math.Cos( 180 * Math.PI / 180 ) * rectangle.Width * doughnutRadius / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( 180 * Math.PI / 180 ) * rectangle.Height * doughnutRadius / 2F + rectangle.Height / 2F, + pieWidth ); + + // Angle 180 Bottom point on the Doughnut arc + points[(int)PiePoints.DoughnutBottom180] = new Point3D( + rectangle.X + (float)Math.Cos( 180 * Math.PI / 180 ) * rectangle.Width * doughnutRadius / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( 180 * Math.PI / 180 ) * rectangle.Height * doughnutRadius / 2F + rectangle.Height / 2F, + 0 ); + + // Angle 0 Top point on the Doughnut arc + points[(int)PiePoints.DoughnutTop0] = new Point3D( + rectangle.X + (float)Math.Cos( 0 * Math.PI / 180 ) * rectangle.Width * doughnutRadius / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( 0 * Math.PI / 180 ) * rectangle.Height * doughnutRadius / 2F + rectangle.Height / 2F, + pieWidth ); + + // Angle 0 Bottom point on the Doughnut arc + points[(int)PiePoints.DoughnutBottom0] = new Point3D( + rectangle.X + (float)Math.Cos( 0 * Math.PI / 180 ) * rectangle.Width * doughnutRadius / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( 0 * Math.PI / 180 ) * rectangle.Height * doughnutRadius / 2F + rectangle.Height / 2F, + 0 ); + + // Top Start Angle point on the Doughnut arc + points[(int)PiePoints.DoughnutTopStart] = new Point3D( + rectangle.X + (float)Math.Cos( startAngle * Math.PI / 180 ) * rectangle.Width * doughnutRadius / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( startAngle * Math.PI / 180 ) * rectangle.Height * doughnutRadius / 2F + rectangle.Height / 2F, + pieWidth ); + + // Top End Angle point on the Doughnut arc + points[(int)PiePoints.DoughnutTopEnd] = new Point3D( + rectangle.X + (float)Math.Cos( ( startAngle + sweepAngle ) * Math.PI / 180 ) * rectangle.Width * doughnutRadius / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( ( startAngle + sweepAngle ) * Math.PI / 180 ) * rectangle.Height * doughnutRadius / 2F + rectangle.Height / 2F, + pieWidth ); + + // Bottom Start Angle point on the Doughnut arc + points[(int)PiePoints.DoughnutBottomStart] = new Point3D( + rectangle.X + (float)Math.Cos( startAngle * Math.PI / 180 ) * rectangle.Width * doughnutRadius / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( startAngle * Math.PI / 180 ) * rectangle.Height * doughnutRadius / 2F + rectangle.Height / 2F, + 0 ); + + // Bottom End Angle point on the Doughnut arc + points[(int)PiePoints.DoughnutBottomEnd] = new Point3D( + rectangle.X + (float)Math.Cos( ( startAngle + sweepAngle ) * Math.PI / 180 ) * rectangle.Width * doughnutRadius / 2F + rectangle.Width / 2F, + rectangle.Y + (float)Math.Sin( ( startAngle + sweepAngle ) * Math.PI / 180 ) * rectangle.Height * doughnutRadius / 2F + rectangle.Height / 2F, + 0 ); + + rectangle.Inflate( -rectangle.Width * (1 - doughnutRadius) / 2F, -rectangle.Height * (1 - doughnutRadius) / 2F); + + // Doughnut Top Rectangle Top Left Point + points[(int)PiePoints.DoughnutTopRectTopLeftPoint] = new Point3D(rectangle.X,rectangle.Y,pieWidth); + + // Doughnut Top Rectangle Right Bottom Point + points[(int)PiePoints.DoughnutTopRectBottomRightPoint] = new Point3D(rectangle.Right,rectangle.Bottom,pieWidth); + + // Doughnut Bottom Rectangle Top Left Point + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint] = new Point3D(rectangle.X,rectangle.Y,0); + + // Doughnut Bottom Rectangle Right Bottom Point + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint] = new Point3D(rectangle.Right,rectangle.Bottom,0); + + + } + + // Make 3D transformations + area.matrix3D.TransformPoints(points); + + int pointIndx = 0; + foreach( Point3D point in points ) + { + result[pointIndx] = point.PointF; + + // Convert Relative coordinates to absolute. + if( relativeCoordinates ) + { + result[pointIndx] = graph.GetAbsolutePoint(result[pointIndx]); + } + pointIndx++; + } + + return result; + + } + + + + + #endregion + + #region 3D Drawing surfaces + + /// + /// This method is used for drawing curve around pie slices. This is + /// the most complex part of 3D Pie slice. There is special case if + /// pie slice is bigger then 180 degree. + /// + /// Chart Grahics. + /// Chart Area. + /// Data Point used for pie slice. + /// Start angle of a pie slice. + /// Sweep angle of a pie slice. + /// Important 3d points of a pie slice. + /// Brush without lithing efects. + /// Pen used for border. + /// Position of the curve of big pie slice. Big pie slice coud have to visible curves - left and right + /// This is big pie slice which is in same time back and front slice. + /// Data Point Index + private void DrawPieCurves( + ChartGraphics graph, + ChartArea area, + DataPoint dataPoint, + float startAngle, + float sweepAngle, + PointF [] points, + SolidBrush brushWithoutLight, + Pen pen, + bool rightPosition, + bool sameBackFront, + int pointIndex + ) + { + // Create a graphics path + using (GraphicsPath path = new GraphicsPath()) + { + Brush brush; + + if (area.Area3DStyle.LightStyle == LightStyle.None) + { + brush = brushWithoutLight; + } + else + { + brush = graph.GetGradientBrush(graph.GetAbsoluteRectangle(area.Position.ToRectangleF()), Color.FromArgb(brushWithoutLight.Color.A, 0, 0, 0), brushWithoutLight.Color, GradientStyle.VerticalCenter); + } + + float endAngle = startAngle + sweepAngle; + + // Very big pie slice ( > 180 degree ) + if (sweepAngle > 180) + { + if (DrawPieCurvesBigSlice(graph, area, dataPoint, startAngle, sweepAngle, points, brush, pen, rightPosition, sameBackFront, pointIndex)) + return; + } + + // Pie slice pass throw 180 degree. Curve has to be spited. + if (startAngle < 180 && endAngle > 180) + { + if (area.Area3DStyle.Inclination < 0) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.Top180], + points[(int)PiePoints.BottomStart], + points[(int)PiePoints.Bottom180], + startAngle, + 180 - startAngle, + pointIndex + ); + + } + else + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.Top180], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.Bottom180], + points[(int)PiePoints.BottomEnd], + 180, + startAngle + sweepAngle - 180, + pointIndex + ); + + } + } + + // Pie slice pass throw 0 degree. Curve has to be spited. + else if (startAngle < 0 && endAngle > 0) + { + if (area.Area3DStyle.Inclination > 0) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.Top0], + points[(int)PiePoints.BottomStart], + points[(int)PiePoints.Bottom0], + startAngle, + -startAngle, + pointIndex + ); + + } + else + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.Top0], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.Bottom0], + points[(int)PiePoints.BottomEnd], + 0, + sweepAngle + startAngle, + pointIndex + ); + + } + } + // Pie slice pass throw 360 degree. Curve has to be spited. + else if (startAngle < 360 && endAngle > 360) + { + if (area.Area3DStyle.Inclination > 0) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.Top0], + points[(int)PiePoints.BottomStart], + points[(int)PiePoints.Bottom0], + startAngle, + 360 - startAngle, + pointIndex + ); + + } + else + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.Top0], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.Bottom0], + points[(int)PiePoints.BottomEnd], + 0, + endAngle - 360, + pointIndex + ); + } + } + else + { + // *************************************************** + // REGULAR CASE: The curve is not split. + // *************************************************** + if (startAngle < 180 && startAngle >= 0 && area.Area3DStyle.Inclination < 0 + || startAngle < 540 && startAngle >= 360 && area.Area3DStyle.Inclination < 0 + || startAngle >= 180 && startAngle < 360 && area.Area3DStyle.Inclination > 0 + || startAngle >= -180 && startAngle < 0 && area.Area3DStyle.Inclination > 0 + ) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.BottomStart], + points[(int)PiePoints.BottomEnd], + startAngle, + sweepAngle, + pointIndex + ); + } + } + } + } + + /// + /// This method is used for special case when big pie slice has to be drawn. + /// + /// Chart Grahics. + /// Chart Area. + /// Data Point used for pie slice. + /// Start angle of a pie slice. + /// Sweep angle of a pie slice. + /// Important 3d points of a pie slice. + /// Brush without lithing efects. + /// Pen used for border. + /// Position of the curve of big pie slice. Big pie slice coud have to visible curves - left and right + /// This is big pie slice which is in same time back and front slice. + /// Data Point Index + /// True if slice is special case and it is drawn as a special case. + private bool DrawPieCurvesBigSlice + ( + ChartGraphics graph, + ChartArea area, + DataPoint dataPoint, + float startAngle, + float sweepAngle, + PointF [] points, + Brush brush, + Pen pen, + bool rightPosition, + bool sameBackFront, + int pointIndex + ) + { + float endAngle = startAngle + sweepAngle; + + // Two different cases connected with X angle. + // ***************************************************** + // X angle is positive + // ***************************************************** + if( area.Area3DStyle.Inclination > 0 ) + { + // Show curve from 0 to 180. + if( startAngle < 180 && endAngle > 360 ) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.Top0], + points[(int)PiePoints.Top180], + points[(int)PiePoints.Bottom0], + points[(int)PiePoints.Bottom180], + 0, + -180, + pointIndex + ); + } + else if( startAngle < 0 && endAngle > 180 ) + { + // There is big data point which is back and + // front point in same time. + if( sameBackFront ) + { + // The big pie slice has to be split. This part makes + // decision which part of this big slice will be + // drawn first. + if( rightPosition ) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.Top180], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.Bottom180], + points[(int)PiePoints.BottomEnd], + 180, + endAngle - 180, + pointIndex + ); + } + else + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.Top0], + points[(int)PiePoints.BottomStart], + points[(int)PiePoints.Bottom0], + startAngle, + -startAngle, + pointIndex + ); + } + } + else + { + // There is big pie slice (>180), but that pie slice + // is not back and front point in same time. + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.Top0], + points[(int)PiePoints.BottomStart], + points[(int)PiePoints.Bottom0], + startAngle, + -startAngle, + pointIndex + ); + + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.Top180], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.Bottom180], + points[(int)PiePoints.BottomEnd], + 180, + endAngle - 180, + pointIndex + ); + } + + } + else + { + // Big pie slice behaves as normal pie slice. Continue + // Non special case alghoritham + return false; + } + } + // ********************************************* + // X angle negative + // ********************************************* + else + { + // Show curve from 0 to 180. + if( startAngle < 0 && endAngle > 180 ) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.Top0], + points[(int)PiePoints.Top180], + points[(int)PiePoints.Bottom0], + points[(int)PiePoints.Bottom180], + 0, + 180, + pointIndex + ); + } + else if( startAngle < 180 && endAngle > 360 ) + { + // There is big data point which is back and + // front point in same time. + if( sameBackFront ) + { + // The big pie slice has to be split. This part makes + // decision which part of this big slice will be + // drawn first. + if( rightPosition ) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.Top180], + points[(int)PiePoints.BottomStart], + points[(int)PiePoints.Bottom180], + startAngle, + 180 - startAngle, + pointIndex + ); + } + else + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.Top0], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.Bottom0], + points[(int)PiePoints.BottomEnd], + 0, + endAngle - 360, + pointIndex + ); + } + } + else + { + // There is big pie slice (>180), but that pie slice + // is not back and front point in same time. + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.Top0], + points[(int)PiePoints.TopEnd], + points[(int)PiePoints.Bottom0], + points[(int)PiePoints.BottomEnd], + 0, + endAngle - 360, + pointIndex + ); + + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.TopRectTopLeftPoint], + points[(int)PiePoints.TopRectBottomRightPoint], + points[(int)PiePoints.BottomRectTopLeftPoint], + points[(int)PiePoints.BottomRectBottomRightPoint], + points[(int)PiePoints.TopStart], + points[(int)PiePoints.Top180], + points[(int)PiePoints.BottomStart], + points[(int)PiePoints.Bottom180], + startAngle, + 180 - startAngle, + pointIndex + ); + } + + } + else + { + // Big pie slice behaves as normal pie slice. Continue + // Non special case alghoritham + return false; + } + } + + return true; + } + + /// + /// This method is used for drawing curve around doughnut slices - inner curve. + /// This is the most complex part of 3D Doughnut slice. There is special case if + /// pie slice is bigger then 180 degree. + /// + /// Chart Grahics. + /// Chart Area. + /// Data Point used for pie slice. + /// Start angle of a pie slice. + /// Sweep angle of a pie slice. + /// Important 3d points of a pie slice. + /// Brush without lithing efects. + /// Pen used for border. + /// Position of the curve of big pie slice. Big pie slice coud have to visible curves - left and right + /// This is big pie slice which is in same time back and front slice. + /// Data Point Index + private void DrawDoughnutCurves( + ChartGraphics graph, + ChartArea area, + DataPoint dataPoint, + float startAngle, + float sweepAngle, + PointF [] points, + SolidBrush brushWithoutLight, + Pen pen, + bool rightPosition, + bool sameBackFront, + int pointIndex + ) + { + // Create a graphics path + using (GraphicsPath path = new GraphicsPath()) + { + + Brush brush; + + if (area.Area3DStyle.LightStyle == LightStyle.None) + { + brush = brushWithoutLight; + } + else + { + brush = graph.GetGradientBrush(graph.GetAbsoluteRectangle(area.Position.ToRectangleF()), Color.FromArgb(brushWithoutLight.Color.A, 0, 0, 0), brushWithoutLight.Color, GradientStyle.VerticalCenter); + } + + float endAngle = startAngle + sweepAngle; + + // Very big pie slice ( > 180 degree ) + if (sweepAngle > 180) + { + if (DrawDoughnutCurvesBigSlice(graph, area, dataPoint, startAngle, sweepAngle, points, brush, pen, rightPosition, sameBackFront, pointIndex)) + return; + } + + // Pie slice pass throw 180 degree. Curve has to be spited. + if (startAngle < 180 && endAngle > 180) + { + if (area.Area3DStyle.Inclination > 0) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTopStart], + points[(int)PiePoints.DoughnutTop180], + points[(int)PiePoints.DoughnutBottomStart], + points[(int)PiePoints.DoughnutBottom180], + startAngle, + 180 - startAngle, + pointIndex + ); + + } + else + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTop180], + points[(int)PiePoints.DoughnutTopEnd], + points[(int)PiePoints.DoughnutBottom180], + points[(int)PiePoints.DoughnutBottomEnd], + 180, + startAngle + sweepAngle - 180, + pointIndex + ); + + } + } + + // Pie slice pass throw 0 degree. Curve has to be spited. + else if (startAngle < 0 && endAngle > 0) + { + if (area.Area3DStyle.Inclination < 0) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTopStart], + points[(int)PiePoints.DoughnutTop0], + points[(int)PiePoints.DoughnutBottomStart], + points[(int)PiePoints.DoughnutBottom0], + startAngle, + -startAngle, + pointIndex + ); + + } + else + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTop0], + points[(int)PiePoints.DoughnutTopEnd], + points[(int)PiePoints.DoughnutBottom0], + points[(int)PiePoints.DoughnutBottomEnd], + 0, + sweepAngle + startAngle, + pointIndex + ); + + } + } + // Pie slice pass throw 360 degree. Curve has to be spited. + else if (startAngle < 360 && endAngle > 360) + { + if (area.Area3DStyle.Inclination < 0) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTopStart], + points[(int)PiePoints.DoughnutTop0], + points[(int)PiePoints.DoughnutBottomStart], + points[(int)PiePoints.DoughnutBottom0], + startAngle, + 360 - startAngle, + pointIndex + ); + + } + else + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTop0], + points[(int)PiePoints.DoughnutTopEnd], + points[(int)PiePoints.DoughnutBottom0], + points[(int)PiePoints.DoughnutBottomEnd], + 0, + endAngle - 360, + pointIndex + ); + } + } + else + { + // *************************************************** + // REGULAR CASE: The curve is not split. + // *************************************************** + if (startAngle < 180 && startAngle >= 0 && area.Area3DStyle.Inclination > 0 + || startAngle < 540 && startAngle >= 360 && area.Area3DStyle.Inclination > 0 + || startAngle >= 180 && startAngle < 360 && area.Area3DStyle.Inclination < 0 + || startAngle >= -180 && startAngle < 0 && area.Area3DStyle.Inclination < 0 + ) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTopStart], + points[(int)PiePoints.DoughnutTopEnd], + points[(int)PiePoints.DoughnutBottomStart], + points[(int)PiePoints.DoughnutBottomEnd], + startAngle, + sweepAngle, + pointIndex + ); + } + } + + } + + } + + + /// + /// This method is used for special case when big doughnut slice has to be drawn. + /// + /// Chart Grahics. + /// Chart Area. + /// Data Point used for pie slice. + /// Start angle of a pie slice. + /// Sweep angle of a pie slice. + /// Important 3d points of a pie slice. + /// Brush without lithing efects. + /// Pen used for border. + /// Position of the curve of big pie slice. Big pie slice coud have to visible curves - left and right + /// This is big pie slice which is in same time back and front slice. + /// Data Point Index + /// True if slice is special case and it is drawn as a special case. + private bool DrawDoughnutCurvesBigSlice + ( + ChartGraphics graph, + ChartArea area, + DataPoint dataPoint, + float startAngle, + float sweepAngle, + PointF [] points, + Brush brush, + Pen pen, + bool rightPosition, + bool sameBackFront, + int pointIndex + ) + { + float endAngle = startAngle + sweepAngle; + + // Two different cases connected with X angle. + // ***************************************************** + // X angle is positive + // ***************************************************** + if( area.Area3DStyle.Inclination < 0 ) + { + // Show curve from 0 to 180. + if( startAngle < 180 && endAngle > 360 ) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTop0], + points[(int)PiePoints.DoughnutTop180], + points[(int)PiePoints.DoughnutBottom0], + points[(int)PiePoints.DoughnutBottom180], + 0, + -180, + pointIndex + ); + } + else if( startAngle < 0 && endAngle > 180 ) + { + // There is big data point which is back and + // front point in same time. + if( sameBackFront ) + { + // The big pie slice has to be split. This part makes + // decision which part of this big slice will be + // drawn first. + if( rightPosition ) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTop180], + points[(int)PiePoints.DoughnutTopEnd], + points[(int)PiePoints.DoughnutBottom180], + points[(int)PiePoints.DoughnutBottomEnd], + 180, + endAngle - 180, + pointIndex + ); + } + else + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTopStart], + points[(int)PiePoints.DoughnutTop0], + points[(int)PiePoints.DoughnutBottomStart], + points[(int)PiePoints.DoughnutBottom0], + startAngle, + -startAngle, + pointIndex + ); + } + } + else + { + // There is big pie slice (>180), but that pie slice + // is not back and front point in same time. + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTopStart], + points[(int)PiePoints.DoughnutTop0], + points[(int)PiePoints.DoughnutBottomStart], + points[(int)PiePoints.DoughnutBottom0], + startAngle, + -startAngle, + pointIndex + ); + + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTop180], + points[(int)PiePoints.DoughnutTopEnd], + points[(int)PiePoints.DoughnutBottom180], + points[(int)PiePoints.DoughnutBottomEnd], + 180, + endAngle - 180, + pointIndex + ); + } + + } + else + { + // Big pie slice behaves as normal pie slice. Continue + // Non special case alghoritham + return false; + } + } + // ********************************************* + // X angle negative + // ********************************************* + else + { + // Show curve from 0 to 180. + if( startAngle < 0 && endAngle > 180 ) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTop0], + points[(int)PiePoints.DoughnutTop180], + points[(int)PiePoints.DoughnutBottom0], + points[(int)PiePoints.DoughnutBottom180], + 0, + 180, + pointIndex + ); + } + else if( startAngle < 180 && endAngle > 360 ) + { + // There is big data point which is back and + // front point in same time. + if( sameBackFront ) + { + // The big pie slice has to be split. This part makes + // decision which part of this big slice will be + // drawn first. + if( rightPosition ) + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTopStart], + points[(int)PiePoints.DoughnutTop180], + points[(int)PiePoints.DoughnutBottomStart], + points[(int)PiePoints.DoughnutBottom180], + startAngle, + 180 - startAngle, + pointIndex + ); + } + else + { + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTop0], + points[(int)PiePoints.DoughnutTopEnd], + points[(int)PiePoints.DoughnutBottom0], + points[(int)PiePoints.DoughnutBottomEnd], + 0, + endAngle - 360, + pointIndex + ); + } + } + else + { + // There is big pie slice (>180), but that pie slice + // is not back and front point in same time. + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTop0], + points[(int)PiePoints.DoughnutTopEnd], + points[(int)PiePoints.DoughnutBottom0], + points[(int)PiePoints.DoughnutBottomEnd], + 0, + endAngle - 360, + pointIndex + ); + + graph.FillPieCurve( + area, + dataPoint, + brush, + pen, + points[(int)PiePoints.DoughnutTopRectTopLeftPoint], + points[(int)PiePoints.DoughnutTopRectBottomRightPoint], + points[(int)PiePoints.DoughnutBottomRectTopLeftPoint], + points[(int)PiePoints.DoughnutBottomRectBottomRightPoint], + points[(int)PiePoints.DoughnutTopStart], + points[(int)PiePoints.DoughnutTop180], + points[(int)PiePoints.DoughnutBottomStart], + points[(int)PiePoints.DoughnutBottom180], + startAngle, + 180 - startAngle, + pointIndex + ); + } + + } + else + { + // Big pie slice behaves as normal pie slice. Continue + // Non special case alghoritham + return false; + } + } + + return true; + } + + + + #endregion + + #region 3D Order of points Methods + + /// + /// This method sort data points on specific way. Because + /// of order of drawing in 3D space, the back data point + /// (point which pass throw 270 degree has to be drawn first. + /// After that side data points have to be drawn. At the end + /// front data point (data point which pass throw 0 degree) + /// has to be drawn. There is special case if there is big + /// data point, which is back and front point in same time. + /// + /// Data series + /// Chart area + /// Unsorted List of Start angles. + /// Unsorted List of Sweep angles. + /// Data Point index list + /// Beck and Fron Points are same - There is a big pie slice. + /// Sorted data point list. + private DataPoint [] PointOrder( Series series, ChartArea area, out float [] newStartAngleList, out float [] newSweepAngleList, out int [] newPointIndexList, out bool sameBackFrontPoint ) + { + + double startAngle; + double sweepAngle; + double endAngle; + int backPoint = -1; + int frontPoint = -1; + sameBackFrontPoint = false; + + // The data points loop. Find Sum of data points. + double sum = 0; + int numOfEmpty = 0; + foreach( DataPoint point in series.Points ) + { + if( point.IsEmpty ) + numOfEmpty++; + + if( !point.IsEmpty ) + { + sum += Math.Abs(point.YValues[0]); + } + } + + // Find number of data points + int numOfPoints = series.Points.Count - numOfEmpty; + + DataPoint [] points = new DataPoint[ numOfPoints ]; + float [] startAngleList = new float[ numOfPoints ]; + float [] sweepAngleList = new float[ numOfPoints ]; + int [] pointIndexList = new int[ numOfPoints ]; + newStartAngleList = new float[ numOfPoints ]; + newSweepAngleList = new float[ numOfPoints ]; + newPointIndexList = new int[ numOfPoints ]; + + // If sum is less then 0 do not draw pie chart + if( sum <= 0 ) + { + return null; + } + // ***************************************************** + // Find Back and Front Points. Back point is a point + // which pass throw 270 degree. Front point pass + // throw 90 degree. + // There are two points in the data point list which will be + // placed at the end and at the beginning on the sorted list: Back + // point (beginning) and Front point (the end). Back point could + // be only after Front point at the unsorted list. + // ***************************************************** + int pointIndx = 0; + startAngle = area.Area3DStyle.Rotation; + foreach( DataPoint point in series.Points ) + { + // Do not process empty points + if( point.IsEmpty ) + { + continue; + } + + // Find angles + sweepAngle = (float)( Math.Abs(point.YValues[0]) * 360 / sum ); + endAngle = startAngle + sweepAngle; + + startAngleList[ pointIndx ] = (float)startAngle; + sweepAngleList[ pointIndx ] = (float)sweepAngle; + pointIndexList[ pointIndx ] = pointIndx; + + // *************************************************************** + // Find Back point. + // Because angle could be between -180 and 540 ( Y axis + // rotation from -180 to 180 ), Back point could be at -90 and 270 + // *************************************************************** + if( startAngle <= -90 && endAngle > -90 || startAngle <= 270 && endAngle > 270 && points[0] == null ) + { + /*if( points[0] != null ) + throw new InvalidOperationException(SR.ExceptionPiePointOrderInvalid); + */ + backPoint = pointIndx; + points[0] = point; + newStartAngleList[0] = startAngleList[pointIndx]; + newSweepAngleList[0] = sweepAngleList[pointIndx]; + newPointIndexList[0] = pointIndexList[pointIndx]; + } + + // *************************************************************** + // Find Front point. + // Because angle could be between -180 and 540 ( Y axis + // rotation from -180 to 180 ), Front point could be at 90 and 450 + // Case frontPoint == -1 is set because of rounding error. + // *************************************************************** + if( startAngle <= 90 && endAngle > 90 || startAngle <= 450 && endAngle > 450 && frontPoint == -1 && ( points[points.Length-1] == null || points.Length == 1 ) ) + { + /* + if( points[points.Length-1] != null && points.Length != 1) + throw new InvalidOperationException(SR.ExceptionPiePointOrderInvalid); + */ + frontPoint = pointIndx; + points[points.Length-1] = point; + newStartAngleList[points.Length-1] = startAngleList[pointIndx]; + newSweepAngleList[points.Length-1] = sweepAngleList[pointIndx]; + newPointIndexList[points.Length-1] = pointIndexList[pointIndx]; + } + + pointIndx++; + startAngle += sweepAngle; + } + + if( frontPoint == -1 || backPoint == -1 ) + { + throw new InvalidOperationException(SR.ExceptionPieUnassignedFrontBackPoints); + } + + // If front point and back point are same do not + // put same point in two fields. + if( frontPoint == backPoint && points.Length != 1 ) + { + points[points.Length-1] = null; + newStartAngleList[points.Length-1] = 0; + newSweepAngleList[points.Length-1] = 0; + newPointIndexList[points.Length-1] = 0; + sameBackFrontPoint = true; + } + + // ******************************************** + // Special case. Front Point and Back points + // are same. + // ******************************************** + if( frontPoint == backPoint ) + { + // Find middle angle of a data point + float midAngle = startAngleList[backPoint] + sweepAngleList[backPoint] / 2F; + + int listIndx; + bool rightSidePoints = false; + + // If big pie slice is on the right and all other + // pie slices are on the left. + if( midAngle > -90 && midAngle < 90 || midAngle > 270 && midAngle < 450 ) + { + rightSidePoints = true; + } + + listIndx = numOfPoints - frontPoint; + pointIndx = 0; + foreach( DataPoint point in series.Points ) + { + // Do not process empty points + if( point.IsEmpty ) + { + continue; + } + + // If Front and back points continue with loop + if( pointIndx == frontPoint ) + { + pointIndx++; + continue; + } + + if( pointIndx < frontPoint ) + { + if( points[listIndx] != null ) + throw new InvalidOperationException(SR.ExceptionPiePointOrderInvalid); + points[listIndx] = point; + newStartAngleList[listIndx] = startAngleList[pointIndx]; + newSweepAngleList[listIndx] = sweepAngleList[pointIndx]; + newPointIndexList[listIndx] = pointIndexList[pointIndx]; + + listIndx++; + } + pointIndx++; + } + + pointIndx = 0; + listIndx = 1; + foreach( DataPoint point in series.Points ) + { + // Do not process empty points + if( point.IsEmpty ) + { + continue; + } + + // If Front and back points continue with loop + if( pointIndx == frontPoint ) + { + pointIndx++; + continue; + } + + if( pointIndx > frontPoint ) + { + if( points[listIndx] != null ) + throw new InvalidOperationException(SR.ExceptionPiePointOrderInvalid); + points[listIndx] = point; + newStartAngleList[listIndx] = startAngleList[pointIndx]; + newSweepAngleList[listIndx] = sweepAngleList[pointIndx]; + newPointIndexList[listIndx] = pointIndexList[pointIndx]; + listIndx++; + } + pointIndx++; + } + if( rightSidePoints ) + { + SwitchPoints( numOfPoints, ref points, ref newStartAngleList, ref newSweepAngleList, ref newPointIndexList, backPoint == frontPoint ); + } + } + else if( frontPoint < backPoint ) + { + + // ************************************************ + // Fill From Back Point to the end of unsorted list + // ************************************************ + pointIndx = 0; + int listIndx = 1; + foreach( DataPoint point in series.Points ) + { + // Do not process empty points + if( point.IsEmpty ) + { + continue; + } + + // If Front and back points continue with loop + if( pointIndx == frontPoint || pointIndx == backPoint ) + { + pointIndx++; + continue; + } + + // If curent point is after front point. + else if( pointIndx > backPoint ) + { + if( points[listIndx] != null ) + throw new InvalidOperationException(SR.ExceptionPiePointOrderInvalid); + points[listIndx] = point; + newStartAngleList[listIndx] = startAngleList[pointIndx]; + newSweepAngleList[listIndx] = sweepAngleList[pointIndx]; + newPointIndexList[listIndx] = pointIndexList[pointIndx]; + listIndx++; + } + + pointIndx++; + } + + // ****************************************************** + // Fill from the begining of unsorted list to Front Point + // ****************************************************** + pointIndx = 0; + foreach( DataPoint point in series.Points ) + { + // Do not process empty points + if( point.IsEmpty ) + { + continue; + } + + // If Front and back points continue with loop + if( pointIndx == frontPoint || pointIndx == backPoint ) + { + pointIndx++; + continue; + } + + // If curent point is before front point. + else if( pointIndx < frontPoint ) + { + if( points[listIndx] != null ) + throw new InvalidOperationException(SR.ExceptionPiePointOrderInvalid); + points[listIndx] = point; + newStartAngleList[listIndx] = startAngleList[pointIndx]; + newSweepAngleList[listIndx] = sweepAngleList[pointIndx]; + newPointIndexList[listIndx] = pointIndexList[pointIndx]; + listIndx++; + } + + pointIndx++; + } + + + // ********************************************************* + // This code run only if special case is not active. + // Special case: FrontPoint and back point are same. This is + // happening because pie slice is bigger then 180 degree. + // ********************************************************* + + + // ********************************** + // Fill from Front Point to Back Point + // ********************************** + listIndx = points.Length - 2; + pointIndx = 0; + foreach( DataPoint point in series.Points ) + { + // Do not process empty points + if( point.IsEmpty ) + { + continue; + } + + // If Front and back points continue with loop + if( pointIndx == frontPoint || pointIndx == backPoint ) + { + pointIndx++; + continue; + } + + // If curent point is between front point and back point. + else if( pointIndx > frontPoint && pointIndx < backPoint ) + { + if (points[listIndx] != null) throw new InvalidOperationException(SR.ExceptionPiePointOrderInvalid); + points[listIndx] = point; + newStartAngleList[listIndx] = startAngleList[pointIndx]; + newSweepAngleList[listIndx] = sweepAngleList[pointIndx]; + newPointIndexList[listIndx] = pointIndexList[pointIndx]; + listIndx--; + } + + pointIndx++; + } + } + else + { + // ********************************** + // Fill from Back Point to Front Point + // ********************************** + int listIndx = 1; + pointIndx = 0; + foreach( DataPoint point in series.Points ) + { + // Do not process empty points + if( point.IsEmpty ) + { + continue; + } + + // If Front and back points continue with loop + if( pointIndx == frontPoint || pointIndx == backPoint ) + { + pointIndx++; + continue; + } + + // If curent point is between front back and front points. + else if( pointIndx > backPoint && pointIndx < frontPoint ) + { + if (points[listIndx] != null) throw new InvalidOperationException(SR.ExceptionPiePointOrderInvalid); + points[listIndx] = point; + newStartAngleList[listIndx] = startAngleList[pointIndx]; + newSweepAngleList[listIndx] = sweepAngleList[pointIndx]; + newPointIndexList[listIndx] = pointIndexList[pointIndx]; + listIndx++; + } + + pointIndx++; + } + + // ************************************************ + // Fill From Front Point to the end of unsorted list + // ************************************************ + listIndx = points.Length - 2; + pointIndx = 0; + foreach( DataPoint point in series.Points ) + { + // Do not process empty points + if( point.IsEmpty ) + { + continue; + } + + // If Front and back points continue with loop + if( pointIndx == frontPoint || pointIndx == backPoint ) + { + pointIndx++; + continue; + } + // If curent point is after front point. + else if( pointIndx > frontPoint ) + { + if( points[listIndx] != null ) + throw new InvalidOperationException(SR.ExceptionPiePointOrderInvalid); + points[listIndx] = point; + newStartAngleList[listIndx] = startAngleList[pointIndx]; + newSweepAngleList[listIndx] = sweepAngleList[pointIndx]; + newPointIndexList[listIndx] = pointIndexList[pointIndx]; + listIndx--; + } + + pointIndx++; + } + + // ****************************************************** + // Fill from the begining of unsorted list to Back Point + // ****************************************************** + pointIndx = 0; + foreach( DataPoint point in series.Points ) + { + // Do not process empty points + if( point.IsEmpty ) + { + continue; + } + + // If Front and back points continue with loop + if( pointIndx == frontPoint || pointIndx == backPoint ) + { + pointIndx++; + continue; + } + + // If curent point is before front point. + else if( pointIndx < backPoint ) + { + if( points[listIndx] != null ) + throw new InvalidOperationException(SR.ExceptionPiePointOrderInvalid); + points[listIndx] = point; + newStartAngleList[listIndx] = startAngleList[pointIndx]; + newSweepAngleList[listIndx] = sweepAngleList[pointIndx]; + newPointIndexList[listIndx] = pointIndexList[pointIndx]; + listIndx--; + } + + pointIndx++; + } + + + // ********************************************************* + // This code run only if special case is not active. + // Special case: FrontPoint and back point are same. This is + // happening because pie slice is bigger then 180 degree. + // ********************************************************* + + + + } + + + // ******************************************************* + // If X angle is positive direction of drawing data points + // should be opposite. This part of code switch order of + // data points. + // ******************************************************* + if( area.Area3DStyle.Inclination > 0 ) + { + SwitchPoints( numOfPoints, ref points, ref newStartAngleList, ref newSweepAngleList, ref newPointIndexList, backPoint == frontPoint ); + } + + return points; + } + + /// + /// This method switches order of data points in the array of points. + /// + /// Number of data points + /// Array of Data points + /// List of start angles which has to be switched together with data points + /// List of sweep angles which has to be switched together with data points + /// Indexes (position) of data points in the series + /// There is big pie slice which has same back and front pie slice + private void SwitchPoints( int numOfPoints, ref DataPoint [] points, ref float [] newStartAngleList, ref float [] newSweepAngleList, ref int [] newPointIndexList, bool sameBackFront ) + { + float [] tempStartAngles = new float[ numOfPoints ]; + float [] tempSweepAngles = new float[ numOfPoints ]; + int [] tempPointIndexList = new int[ numOfPoints ]; + DataPoint [] tempPoints = new DataPoint[ numOfPoints ]; + int start = 0;; + + // The big pie slice (special case) is always on the beginning. + if( sameBackFront ) + { + start = 1; + + // Switch order. + tempPoints[0] = points[0]; + tempStartAngles[0] = newStartAngleList[0]; + tempSweepAngles[0] = newSweepAngleList[0]; + tempPointIndexList[0] = newPointIndexList[0]; + } + + for( int index = start; index < numOfPoints; index++ ) + { + if( points[ index ] == null ) + { + throw new InvalidOperationException(SR.ExceptionPieOrderOperationInvalid); + } + + // Switch order. + tempPoints[ numOfPoints - index - 1 + start] = points[ index ]; + tempStartAngles[ numOfPoints - index - 1 + start] = newStartAngleList[ index ]; + tempSweepAngles[ numOfPoints - index - 1 + start] = newSweepAngleList[ index ]; + tempPointIndexList[ numOfPoints - index - 1 + start] = newPointIndexList[ index ]; + + } + + points = tempPoints; + newStartAngleList = tempStartAngles; + newSweepAngleList = tempSweepAngles; + newPointIndexList = tempPointIndexList; + + } + + #endregion + + #region 3D Label column class + + /// + /// LabelColumn class is used for labels manipulation - outside label style + /// + internal class LabelColumn + { + // Fields of Label Column class + private RectangleF _chartAreaPosition; + private RectangleF _innerPlotPosition; + internal float columnHeight; + internal int numOfItems = 0; + private int _numOfInsertedLabels = 0; + private DataPoint [] _points; + private float [] _yPositions; + private bool _rightPosition = true; + private float _labelLineSize; + + /// + /// Constructor + /// + /// Chart Area position. + public LabelColumn( RectangleF position ) + { + _chartAreaPosition = position; + } + + /// + /// Return index of label position in the column. + /// + /// y coordinate + /// Index of column + internal int GetLabelIndex( float y ) + { + // y coordinate is out of chart area. + if( y < _chartAreaPosition.Y ) + { + y = _chartAreaPosition.Y; + } + else if( y > _chartAreaPosition.Bottom ) + { + y = _chartAreaPosition.Bottom - columnHeight; + } + + return (int) (( y - _chartAreaPosition.Y ) / columnHeight ) ; + } + + /// + /// This method sorts labels by y Position + /// + internal void Sort() + { + for( int indexA = 0; indexA < _points.Length; indexA++ ) + { + for( int indexB = 0; indexB < indexA; indexB++ ) + { + if( _yPositions[indexA] < _yPositions[indexB] && _points[indexA] != null && _points[indexB] != null ) + { + float tempYPos; + DataPoint tempPoint; + tempYPos = _yPositions[indexA]; + tempPoint = _points[indexA]; + _yPositions[indexA] = _yPositions[indexB]; + _points[indexA] = _points[indexB]; + _yPositions[indexB] = tempYPos; + _points[indexB] = tempPoint; + } + } + } + } + + /// + /// Returns label position y coordinate from index position + /// + /// Index position of the row + /// Y coordinate row position + internal float GetLabelPosition( int index ) + { + if( index < 0 || index > numOfItems - 1 ) + throw new InvalidOperationException(SR.Exception3DPieLabelsIndexInvalid); + + return (float) _chartAreaPosition.Y + columnHeight * index + columnHeight / 2; + } + + /// + /// This method finds X and Y position for outside + /// labels. There is discrete number of cells and + /// Y position depends on cell position. X position + /// is connected with angle between invisible + /// line (which connects center of a pie and label) + /// and any horizontal line. + /// + /// Data Point + /// Position of a label + internal PointF GetLabelPosition( DataPoint dataPoint ) + { + PointF position = PointF.Empty; + int pointIndex = 0; + + // Find Y position of Data Point + // Loop is necessary to find index of data point in the array list. + foreach( DataPoint point in _points ) + { + if( point == dataPoint ) + { + position.Y = GetLabelPosition( pointIndex ); + break; + } + pointIndex++; + } + + // Find initial X position for labels ( All labels are aligne ). + if( _rightPosition ) + { + position.X = _innerPlotPosition.Right + _chartAreaPosition.Width * this._labelLineSize; + } + else + { + position.X = _innerPlotPosition.Left - _chartAreaPosition.Width * this._labelLineSize; + } + + // Find angle between invisible line (which connects center of a pie and label) + // and any horizontal line. + float angle; + angle = (float)Math.Atan( ( position.Y - _innerPlotPosition.Top - _innerPlotPosition.Height / 2) / ( position.X - _innerPlotPosition.Left - _innerPlotPosition.Width / 2 )); + + // Make Angle correction for X Position + float correct; + if( Math.Cos( angle ) == 0 ) + { + correct = 0; + } + else + { + correct = (float)(_innerPlotPosition.Width * 0.4 - _innerPlotPosition.Width * 0.4 / Math.Cos( angle )); + } + + // Set Corrected X Position + if( _rightPosition ) + { + position.X += correct; + } + else + { + position.X -= correct; + } + + return position; + } + + /// + /// This method inserts outside labels in Column label list. Column label + /// list has defined number of cells. This method has to put labels on + /// the best position in the list. If two labels according to their + /// positions belong to same cell of the list, this method should + /// assign to them different positions. + /// + /// Data Point which label has to be inserted + /// Y coordinate which is the best position for this label + /// Point index of this data point in the series + internal void InsertLabel( DataPoint point, float yCoordinate, int pointIndx ) + { + + // Find index of label list by Y value + int indexYValue = GetLabelIndex( yCoordinate ); + + // This position is already used. + if( _points[indexYValue] != null ) + { + // All even elements go up and other + // Down (If there are many labels which use this position). + if( pointIndx % 2 == 0 ) + { + // Check if there is space Down + if( CheckFreeSpace( indexYValue, false ) ) + { + // Move labels Down + MoveLabels( indexYValue, false ); + } + else + { + // Move labels Up + MoveLabels( indexYValue, true ); + } + } + else + { + // Check if there is space Up + if( CheckFreeSpace( indexYValue, true ) ) + { + // Move labels Up + MoveLabels( indexYValue, true ); + } + else + { + // Move labels Down + MoveLabels( indexYValue, false ); + } + } + } + + // Set label position + _points[indexYValue] = point; + _yPositions[indexYValue] = yCoordinate; + _numOfInsertedLabels++; + } + + /// + /// This method is used for inserting labels. When label is inserted + /// and that position was previously used, labels have to be + /// moved on proper way. + /// + /// Position which has to be free + /// Direction for moving labels + private void MoveLabels( int position, bool upDirection ) + { + if( upDirection ) + { + DataPoint point = _points[position]; + float yValue = _yPositions[position]; + _points[position] = null; + _yPositions[position] = 0; + + for( int index = position; index > 0; index-- ) + { + // IsEmpty position found. Stop moving cells UP + if( _points[index-1] == null ) + { + _points[index-1] = point; + _yPositions[index-1] = yValue; + break; + } + else + { + DataPoint tempPoint; + float tempYValue; + + tempPoint = _points[index-1]; + tempYValue = _yPositions[index-1]; + _points[index-1] = point; + _yPositions[index-1] = yValue; + point = tempPoint; + yValue = tempYValue; + } + } + } + else + { + DataPoint point = _points[position]; + float yValue = _yPositions[position]; + _points[position] = null; + _yPositions[position] = 0; + + for( int index = position; index < numOfItems-1; index++ ) + { + // IsEmpty position found. Stop moving cells UP + if( _points[index+1] == null ) + { + _points[index+1] = point; + _yPositions[index+1] = yValue; + break; + } + else + { + DataPoint tempPoint; + float tempYValue; + + tempPoint = _points[index+1]; + tempYValue = _yPositions[index+1]; + _points[index+1] = point; + _yPositions[index+1] = yValue; + point = tempPoint; + yValue = tempYValue; + } + } + } + } + + /// + /// This method is used to center labels in + /// the middle of chart area (vertically). + /// + internal void AdjustPositions() + { + int numEmptyUp = 0; + int numEmptyDown = 0; + + // Adjust position only if there are many labels + if( _numOfInsertedLabels < _points.Length / 2 ) + return; + + // Find the number of empty label positions on the top. + for( int point = 0; point < _points.Length && _points[point] == null; point++ ) + { + numEmptyUp++; + } + + // Find the number of empty label positions on the bottom. + for( int point = _points.Length - 1; point >= 0 && _points[point] == null; point-- ) + { + numEmptyDown++; + } + + // Find where are more empty spaces – on the top or on the bottom. + bool moreEmptyUp = numEmptyUp > numEmptyDown ? true : false; + + // Find average number of empty spaces for top and bottom. + int numMove = ( numEmptyUp + numEmptyDown ) / 2; + + // If difference between empty spaces on the top and + // the bottom is not bigger then 2 do not adjust labels. + if( Math.Abs( numEmptyUp - numEmptyDown ) < 2 ) + return; + + if( moreEmptyUp ) + { + // Move labels UP + int indexPoint = 0; + for( int point = numMove; point < _points.Length; point++ ) + { + if(numEmptyUp+indexPoint > _points.Length - 1) + break; + + _points[point] = _points[numEmptyUp+indexPoint]; + _points[numEmptyUp+indexPoint] = null; + indexPoint++; + } + } + else + { + // Move labels DOWN + int indexPoint = _points.Length - 1; + for( int point = _points.Length - 1 - numMove; point >= 0; point-- ) + { + if(indexPoint - numEmptyDown < 0) + break; + + _points[point] = _points[indexPoint - numEmptyDown]; + _points[indexPoint - numEmptyDown] = null; + indexPoint--; + } + } + } + + + /// + /// Check if there is empty cell Labels column in + /// specified direction from specified position + /// + /// Start Position for testing + /// True if direction is upward, false if downward + /// True if there is empty cell + private bool CheckFreeSpace( int position, bool upDirection ) + { + if( upDirection ) + { + // Position is on the beginning. There is no empty space. + if( position == 0 ) + { + return false; + } + + for( int index = position - 1; index >= 0; index-- ) + { + // There is empty space + if( _points[index] == null ) + { + return true; + } + } + } + else + { + // Position is on the end. There is no empty space. + if( position == numOfItems - 1 ) + { + return false; + } + + for( int index = position + 1; index < numOfItems; index++ ) + { + // There is empty space + if( _points[index] == null ) + { + return true; + } + } + } + + // There is no empty space + return false; + } + + + /// + /// This method initialize label column. + /// + /// Rectangle used for labels + /// True if labels are on the right side of chart area. + /// Maximum nuber of rows. + /// Value for label line size from custom attribute. + internal void Initialize( RectangleF rectangle, bool rightPosition, int maxNumOfRows, float labelLineSize ) + { + + // Minimum number of rows. + numOfItems = Math.Max( numOfItems, maxNumOfRows ); + + // Find height of rows + columnHeight = _chartAreaPosition.Height / numOfItems; + + // Set inner plot position + _innerPlotPosition = rectangle; + + // Init data column + _points = new DataPoint[numOfItems]; + + // Init y position column + _yPositions = new float[numOfItems]; + + // Label column position + this._rightPosition = rightPosition; + + // 3D Label line size + this._labelLineSize = labelLineSize; + + } + + } + + #endregion // 3D Label column class + + #region 3D Labels + + /// + /// This method calculates initial pie size if outside 3D labels is active. + /// + /// Chart Graphics object. + /// Chart Area. + /// Rectangle which is used for drawing pie. + /// Width of pie slice. + /// List of data points. + /// List of start angles. + /// List of sweep angles. + /// Data series used for drawing pie chart. + /// Custom Attribute for label line size. + private void InitPieSize( + ChartGraphics graph, + ChartArea area, + ref RectangleF pieRectangle, + ref float pieWidth, + DataPoint [] dataPoints, + float [] startAngleList, + float [] sweepAngleList, + Series series, + float labelLineSize + ) + { + labelColumnLeft = new LabelColumn(area.Position.ToRectangleF()); + labelColumnRight = new LabelColumn(area.Position.ToRectangleF()); + float maxSize = float.MinValue; + float maxSizeVertical = float.MinValue; + + int pointIndx = 0; + // Loop which finds max label size and number of label rows. + foreach( DataPoint point in dataPoints ) + { + // Do not process empty points + if( point.IsEmpty ) + { + continue; + } + + float midAngle = startAngleList[pointIndx] + sweepAngleList[pointIndx] / 2F; + + if( midAngle >= -90 && midAngle < 90 || midAngle >= 270 && midAngle < 450 ) + { + labelColumnRight.numOfItems++; + } + else + { + labelColumnLeft.numOfItems++; + } + + // Find size of the maximum label string. + SizeF size = graph.MeasureStringRel( GetLabelText( point ).Replace("\\n", "\n"), point.Font ); + + maxSize = Math.Max( size.Width, maxSize ); + maxSizeVertical = Math.Max( size.Height, maxSizeVertical ); + + pointIndx++; + } + + float oldWidth = pieRectangle.Width; + float oldHeight = pieRectangle.Height; + + // Find size of inner plot are + pieRectangle.Width = pieRectangle.Width - 2F * maxSize - 2 * pieRectangle.Width * labelLineSize; + + pieRectangle.Height = pieRectangle.Height - pieRectangle.Height * 0.3F; + + // Size of pie chart can not be less then MinimumRelativePieSize of chart area. + if( pieRectangle.Width < oldWidth * (float)this.MinimumRelativePieSize( area ) ) + { + pieRectangle.Width = oldWidth * (float)this.MinimumRelativePieSize( area ); + } + + // Size of pie chart can not be less then MinimumRelativePieSize of chart area. + if( pieRectangle.Height < oldHeight * (float)this.MinimumRelativePieSize( area ) ) + { + pieRectangle.Height = oldHeight * (float)this.MinimumRelativePieSize( area ); + } + + // Size has to be reduce always because of label lines. + if( oldWidth * 0.8F < pieRectangle.Width ) + { + pieRectangle.Width *= 0.8F; + } + + pieRectangle.X = pieRectangle.X + ( oldWidth - pieRectangle.Width ) / 2F; + pieWidth = pieRectangle.Width / oldWidth * pieWidth; + + pieRectangle.Y = pieRectangle.Y + ( oldHeight - pieRectangle.Height ) / 2F; + + // Find maximum number of rows. Number of rows will be changed + // but this is only recommendation, which depends on font size + // and Height of chart area. + SizeF fontSize = new SizeF(1.4F * series.Font.Size,1.4F * series.Font.Size); + fontSize = graph.GetRelativeSize( fontSize ); + int maxNumOfRows = (int)( pieRectangle.Height / maxSizeVertical/*fontSize.Height*/ ); + + // Initialize label column + labelColumnRight.Initialize( pieRectangle, true, maxNumOfRows, labelLineSize ); + labelColumnLeft.Initialize( pieRectangle, false, maxNumOfRows, labelLineSize ); + + } + + /// + /// This method inserts outside 3D labels into array of Label column class. + /// + /// Chart Graphics object. + /// Chart Area. + /// Rectangle used for drawing pie slices. + /// Width of a pie slice. + /// Data Point. + /// Start angle of a pie slice. + /// Sweep angle of a pie slice. + /// Data point index. + /// Inner Radius of the doughnut. + /// true if pie slice is exploded. + private void FillPieLabelOutside( + ChartGraphics graph, + ChartArea area, + RectangleF pieRectangle, + float pieWidth, + DataPoint point, + float startAngle, + float sweepAngle, + int pointIndx, + float doughnutRadius, + bool exploded + ) + { + float midAngle = startAngle + sweepAngle / 2F; + + PointF [] piePoints = GetPiePoints( graph, area, pieWidth, pieRectangle, startAngle, sweepAngle, false, doughnutRadius, exploded ); + + float y = piePoints[(int)PiePoints.TopLabelLineout].Y; + if( midAngle >= -90 && midAngle < 90 || midAngle >= 270 && midAngle < 450 ) + { + labelColumnRight.InsertLabel( point, y, pointIndx ); + } + else + { + labelColumnLeft.InsertLabel( point, y, pointIndx ); + } + } + + /// + /// This method draws outside labels with lines, which + /// connect labels with pie slices. + /// + /// Chart Graphics object + /// Chart Area + /// Pen object + /// Important pie points + /// Data point + /// Middle Angle for pie slice + /// Point Index. + private void Draw3DOutsideLabels( + ChartGraphics graph, + ChartArea area, + Pen pen, + PointF [] points, + DataPoint point, + float midAngle, + int pointIndex) + { + // Take label text + string text = GetLabelText( point ); + if(text.Length == 0) + { + return; + } + + graph.DrawLine( pen, points[(int)PiePoints.TopLabelLine], points[(int)PiePoints.TopLabelLineout] ); + LabelColumn columnLabel; + + using (StringFormat format = new StringFormat()) + { + format.LineAlignment = StringAlignment.Center; + + RectangleF chartAreaPosition = graph.GetAbsoluteRectangle(area.Position.ToRectangleF()); + RectangleF labelPosition = RectangleF.Empty; + + PointF labelPoint; + + if (midAngle >= -90 && midAngle < 90 || midAngle >= 270 && midAngle < 450) + { + columnLabel = labelColumnRight; + format.Alignment = StringAlignment.Near; + + float labelVertSize = graph.GetAbsoluteSize(new SizeF(0f, this.labelColumnRight.columnHeight)).Height; + labelPoint = graph.GetAbsolutePoint(columnLabel.GetLabelPosition(point)); + + // Label has to be right from TopLabelLineOut + if (points[(int)PiePoints.TopLabelLineout].X > labelPoint.X) + { + labelPoint.X = points[(int)PiePoints.TopLabelLineout].X + 10; + } + + labelPosition.X = labelPoint.X; + labelPosition.Width = chartAreaPosition.Right - labelPosition.X; + labelPosition.Y = labelPoint.Y - labelVertSize / 2; + labelPosition.Height = labelVertSize; + + } + else + { + columnLabel = labelColumnLeft; + format.Alignment = StringAlignment.Far; + + float labelVertSize = graph.GetAbsoluteSize(new SizeF(0f, this.labelColumnLeft.columnHeight)).Height; + labelPoint = graph.GetAbsolutePoint(columnLabel.GetLabelPosition(point)); + + // Label has to be left from TopLabelLineOut + if (points[(int)PiePoints.TopLabelLineout].X < labelPoint.X) + { + labelPoint.X = points[(int)PiePoints.TopLabelLineout].X - 10; + } + + labelPosition.X = chartAreaPosition.X; + labelPosition.Width = labelPoint.X - labelPosition.X; + labelPosition.Y = labelPoint.Y - labelVertSize / 2; + labelPosition.Height = labelVertSize; + } + format.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit; + format.Trimming = StringTrimming.EllipsisWord; + + graph.DrawLine(pen, points[(int)PiePoints.TopLabelLineout], labelPoint); + + // Get label relative position + labelPosition = graph.GetRelativeRectangle(labelPosition); + + // Get label background position + SizeF valueTextSize = graph.MeasureStringRel(text.Replace("\\n", "\n"), point.Font); + valueTextSize.Height += valueTextSize.Height / 8; + float spacing = valueTextSize.Width / text.Length / 2; + valueTextSize.Width += spacing; + RectangleF labelBackPosition = new RectangleF( + labelPosition.X, + labelPosition.Y + labelPosition.Height / 2f - valueTextSize.Height / 2f, + valueTextSize.Width, + valueTextSize.Height); + + // Adjust position based on alignment + if (format.Alignment == StringAlignment.Near) + { + labelBackPosition.X -= spacing / 2f; + } + else if (format.Alignment == StringAlignment.Center) + { + labelBackPosition.X = labelPosition.X + (labelPosition.Width - valueTextSize.Width) / 2f; + } + else if (format.Alignment == StringAlignment.Far) + { + labelBackPosition.X = labelPosition.Right - valueTextSize.Width - spacing / 2f; + } + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + graph.Common, + text, + point.Font, + brush, + labelPosition, + format, + 0, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + point.series, + point, + pointIndex); + } + } + } + + /// + /// This method draws inside labels. + /// + /// Chart Graphics object + /// Important pie points + /// Data point + /// Data point index + private void Draw3DInsideLabels( ChartGraphics graph, PointF [] points, DataPoint point, int pointIndex ) + { + // Set String Alignment + StringFormat format = new StringFormat(); + format.LineAlignment = StringAlignment.Center; + format.Alignment = StringAlignment.Center; + + // Take label text + string text = GetLabelText( point ); + + // Get label relative position + PointF labelPosition = graph.GetRelativePoint(points[(int)PiePoints.TopLabelCenter]); + + // Measure string + SizeF sizeFont = graph.GetRelativeSize( + graph.MeasureString( + text.Replace("\\n", "\n"), + point.Font, + new SizeF(1000f, 1000f), + new StringFormat(StringFormat.GenericTypographic))); + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeFont.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = new RectangleF( + labelPosition.X - sizeLabel.Width/2, + labelPosition.Y - sizeLabel.Height/2 - sizeFont.Height / 10, + sizeLabel.Width, + sizeLabel.Height); + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + graph.Common, + text, + point.Font, + brush, + labelPosition, + format, + 0, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + point.series, + point, + pointIndex); + } + } + + /// + /// Gets the point label. + /// + /// The point. + /// + private String GetPointLabel(DataPoint point) + { + String pointLabel = String.Empty; + + // If There is no Label take axis Label + if( point.Label.Length == 0 ) + { + pointLabel = point.AxisLabel; + // remove axis label if is set the CustomPropertyName.PieAutoAxisLabels and is set to false + if (point.series != null && + point.series.IsCustomPropertySet(CustomPropertyName.PieAutoAxisLabels) && + String.Equals(point.series.GetCustomProperty(CustomPropertyName.PieAutoAxisLabels), "false", StringComparison.OrdinalIgnoreCase)) + { + pointLabel = String.Empty; + } + } + else + pointLabel = point.Label; + + return point.ReplaceKeywords(pointLabel); + } + + /// + /// Take formated text from label or axis label + /// + /// Data point which is used. + /// Formated text + private string GetLabelText( DataPoint point ) + { + string pointLabel = this.GetPointLabel(point); + // Get label text + string text; + if( point.Label.Length == 0 && point.IsValueShownAsLabel ) + { + text = ValueConverter.FormatValue( + point.series.Chart, + point, + point.Tag, + point.YValues[0], + point.LabelFormat, + point.series.YValueType, + ChartElementType.DataPoint); + } + else + { + text = pointLabel; + } + + // Retuen formated label or axis label text + return text; + } + + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} + diff --git a/System.Web.DataVisualization/Common/ChartTypes/PointAndFigureChart.cs b/System.Web.DataVisualization/Common/ChartTypes/PointAndFigureChart.cs new file mode 100644 index 000000000..751db7552 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/PointAndFigureChart.cs @@ -0,0 +1,913 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: PointAndFigureChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: PointAndFigureChart +// +// Purpose: Point and Figure chart type do not plot series data +// point directly as most of the other chart types. +// Instead it uses different calculation to create a +// new RangeColumn type series based on its data in +// the PrepareData method. All the changes in this +// method are reversed back in the UnPrepareData +// method. RangeColumn chart type is extended to +// display a column of Os or Xs. +// +// Point and Figure Charts Overview: +// --------------------------------- +// +// Point and Figure charts differ from traditional price charts in +// that they completely disregard the passage of time, and only +// display changes in prices. Rather than having price on the y-axis, +// and time on the x-axis, Point and Figure charts display price +// changes on both axes. This is similar to the Kagi, Renko, and +// Three Line Break charts. +// +// The Point and Figure chart displays the underlying supply and +// demand as reflected in the price values. A column of Xs shows +// that demand is exceeding supply, which is known as a rally, +// a column of Os shows that supply is exceeding demand, which is +// known as a decline, and a series of short columns shows that +// supply and demand are relatively equal, which of course, +// represents a market equilibrium. +// +// The following should be taken into account when working with +// this type of chart: +// +// - The X values of data points are automatically indexed. For +// more information see the topic on Indexing Data Point X Values. +// +// - There is a formula applied to the original data before it gets +// plotted. This formula changes the number of points, as well as +// their X/Y values. +// +// - Due to the data being recalculated, we do not recommend setting +// the minimum, or maximum values for the X axis. This is because it +// cannot be determined how many data points will actually be plotted. +// However, if the axis' Maximum, or Minimum is set, then the Maximum, +// and Minimum properties will use data point index values. +// +// - Data point anchoring, used for annotations, is not supported +// with this type of chart. +// +// Reviewed: AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel.Design; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else +using System.Web.UI.DataVisualization.Charting; + +using System.Web.UI.DataVisualization.Charting.ChartTypes; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else +namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// PointAndFigureChart class contains all the code necessary for calculation + /// and drawing Point and Figure chart. + /// + internal class PointAndFigureChart : RangeColumnChart + { + #region Fields + + /// + /// Indicates that class subscribed fro the customize event. + /// + static private bool _customizeSubscribed = false; + + #endregion // Fields + + #region Methods + + /// + /// Prepares PointAndFigure chart type for rendering. We hide original series + /// during rendering and only using the data for calculations. New RangeColumn + /// type series is added wich displayes the columns of Os or Xs. + /// All the changes in this method are reversed back in the UnPrepareData method. + /// + /// Series to be prepared. + internal static void PrepareData(Series series) + { + // Check series chart type + if(String.Compare( series.ChartTypeName, ChartTypeNames.PointAndFigure, StringComparison.OrdinalIgnoreCase ) != 0 || !series.IsVisible()) + { + return; + } + + // Get reference to the chart control + Chart chart = series.Chart; + if(chart == null) + { + throw (new InvalidOperationException(SR.ExceptionPointAndFigureNullReference)); + } + + // PointAndFigure chart may not be combined with any other chart types + ChartArea area = chart.ChartAreas[series.ChartArea]; + foreach (Series currentSeries in chart.Series) + { + if (currentSeries.IsVisible() && currentSeries != series && area == chart.ChartAreas[currentSeries.ChartArea]) + { + throw (new InvalidOperationException(SR.ExceptionPointAndFigureCanNotCombine)); + } + } + + // Subscribe for customize event + if(!_customizeSubscribed) + { + _customizeSubscribed = true; + chart.Customize += new EventHandler(OnCustomize); + } + + // Create a temp series which will hold original series data points + string tempSeriesName = "POINTANDFIGURE_ORIGINAL_DATA_" + series.Name; + if (chart.Series.IndexOf(tempSeriesName) != -1) + { + return; // the temp series has already been added + } + Series seriesOriginalData = new Series(tempSeriesName, series.YValuesPerPoint); + seriesOriginalData.Enabled = false; + seriesOriginalData.IsVisibleInLegend = false; + seriesOriginalData.YValuesPerPoint = series.YValuesPerPoint; + chart.Series.Add(seriesOriginalData); + foreach(DataPoint dp in series.Points) + { + seriesOriginalData.Points.Add(dp); + } + series.Points.Clear(); + if(series.IsCustomPropertySet("TempDesignData")) + { + seriesOriginalData["TempDesignData"] = "true"; + } + + + // Remember prev. series parameters + series["OldXValueIndexed"] = series.IsXValueIndexed.ToString(CultureInfo.InvariantCulture); + series["OldYValuesPerPoint"] = series.YValuesPerPoint.ToString(CultureInfo.InvariantCulture); + series.IsXValueIndexed = true; + + // Calculate date-time interval for indexed series + if(series.ChartArea.Length > 0 && + series.IsXValueDateTime()) + { + // Get X axis connected to the series + Axis xAxis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName); + + // Change interval for auto-calculated interval only + if(xAxis.Interval == 0 && xAxis.IntervalType == DateTimeIntervalType.Auto) + { + // Check if original data has X values set to date-time values and + // calculate min/max X values. + bool nonZeroXValues = false; + double minX = double.MaxValue; + double maxX = double.MinValue; + foreach(DataPoint dp in seriesOriginalData.Points) + { + if(!dp.IsEmpty) + { + if(dp.XValue != 0.0) + { + nonZeroXValues = true; + } + if(dp.XValue > maxX) + { + maxX = dp.XValue; + } + if(dp.XValue < minX) + { + minX = dp.XValue; + } + } + } + + if(nonZeroXValues) + { + // Save flag that axis interval is automatic + series["OldAutomaticXAxisInterval"] = "true"; + + // Calculate and set axis date-time interval + DateTimeIntervalType intervalType = DateTimeIntervalType.Auto; + xAxis.interval = xAxis.CalcInterval(minX, maxX, true, out intervalType, series.XValueType); + xAxis.intervalType = intervalType; + } + } + } + + // Calculate PointAndFigure bricks data points values + FillPointAndFigureData(series, seriesOriginalData); + } + + /// + /// Remove any changes done while preparing PointAndFigure chart type for rendering. + /// + /// Series to be un-prepared. + /// True if series was removed from collection. + internal static bool UnPrepareData(Series series) + { + if(series.Name.StartsWith("POINTANDFIGURE_ORIGINAL_DATA_", StringComparison.Ordinal)) + { + // Get reference to the chart control + Chart chart = series.Chart; + if(chart == null) + { + throw (new InvalidOperationException(SR.ExceptionPointAndFigureNullReference)); + } + + // Unsubscribe for customize event + if(_customizeSubscribed) + { + _customizeSubscribed = false; + chart.Customize -= new EventHandler(OnCustomize); + } + + // Get original PointAndFigure series + Series pointAndFigureSeries = chart.Series[series.Name.Substring(29)]; + Series.MovePositionMarkers(pointAndFigureSeries, series); + + // Copy data back to original PointAndFigure series + pointAndFigureSeries.Points.Clear(); + if(!series.IsCustomPropertySet("TempDesignData")) + { + foreach(DataPoint dp in series.Points) + { + pointAndFigureSeries.Points.Add(dp); + } + } + + // Restore series properties + bool xValIndexed; + bool parseSucceed = bool.TryParse(pointAndFigureSeries["OldXValueIndexed"], out xValIndexed); + + pointAndFigureSeries.IsXValueIndexed = parseSucceed && xValIndexed; + + int yVals; + parseSucceed = int.TryParse(pointAndFigureSeries["OldYValuesPerPoint"], NumberStyles.Any, CultureInfo.InvariantCulture, out yVals); + + if (parseSucceed) + { + pointAndFigureSeries.YValuesPerPoint = yVals; + } + + pointAndFigureSeries.DeleteCustomProperty("OldXValueIndexed"); + pointAndFigureSeries.DeleteCustomProperty("OldYValuesPerPoint"); + pointAndFigureSeries.DeleteCustomProperty(CustomPropertyName.EmptyPointValue); + + series["OldAutomaticXAxisInterval"] = "true"; + if(pointAndFigureSeries.IsCustomPropertySet("OldAutomaticXAxisInterval")) + { + pointAndFigureSeries.DeleteCustomProperty("OldAutomaticXAxisInterval"); + + // Reset automatic interval for X axis + if(pointAndFigureSeries.ChartArea.Length > 0) + { + // Get X axis connected to the series + ChartArea area = chart.ChartAreas[pointAndFigureSeries.ChartArea]; + Axis xAxis = area.GetAxis(AxisName.X, pointAndFigureSeries.XAxisType, pointAndFigureSeries.XSubAxisName); + + xAxis.interval = 0.0; + xAxis.intervalType = DateTimeIntervalType.Auto; + } + } + + // Remove series from the collection + chart.Series.Remove(series); + return true; + } + + return false; + } + + /// + /// Gets price range in the point and figure chart. + /// + /// Series with original data. + /// Index of the Y value to use as High price. + /// Index of the Y value to use as Low price. + /// Returns max price. + /// Returns min price. + private static void GetPriceRange( + Series originalData, + int yValueHighIndex, + int yValueLowIndex, + out double minPrice, + out double maxPrice) + { + // Calculate percent of the highest and lowest price difference. + maxPrice = double.MinValue; + minPrice = double.MaxValue; + foreach(DataPoint dp in originalData.Points) + { + if(!dp.IsEmpty) + { + // Check required Y values number + if(dp.YValues.Length < 2) + { + throw(new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(ChartTypeNames.PointAndFigure, ((int)(2)).ToString(CultureInfo.CurrentCulture)))); + } + + if(dp.YValues[yValueHighIndex] > maxPrice) + { + maxPrice = dp.YValues[yValueHighIndex]; + } + else if(dp.YValues[yValueLowIndex] > maxPrice) + { + maxPrice = dp.YValues[yValueLowIndex]; + } + + if(dp.YValues[yValueHighIndex] < minPrice) + { + minPrice = dp.YValues[yValueHighIndex]; + } + else if(dp.YValues[yValueLowIndex] < minPrice) + { + minPrice = dp.YValues[yValueLowIndex]; + } + } + } + } + + /// + /// Gets box size of the renko chart. + /// + /// Range column chart series used to dispaly the renko chart. + /// Max price. + /// Min price. + private static double GetBoxSize( + Series series, + double minPrice, + double maxPrice) + { + // Check "BoxSize" custom attribute + double boxSize = 1.0; + double percentOfPriceRange = 4.0; + bool roundBoxSize = true; + if (series.IsCustomPropertySet(CustomPropertyName.BoxSize)) + { + string attrValue = series[CustomPropertyName.BoxSize].Trim(); + bool usePercentage = attrValue.EndsWith("%", StringComparison.Ordinal); + if (usePercentage) + { + attrValue = attrValue.Substring(0, attrValue.Length - 1); + } + + bool parseSucceed = false; + if (usePercentage) + { + double percent; + parseSucceed = double.TryParse(attrValue, NumberStyles.Any, CultureInfo.InvariantCulture, out percent); + if (parseSucceed) + { + percentOfPriceRange = percent; + roundBoxSize = false; + } + } + else + { + double b = 0; + parseSucceed = double.TryParse(attrValue, NumberStyles.Any, CultureInfo.InvariantCulture, out b); + if (parseSucceed) + { + boxSize = b; + percentOfPriceRange = 0.0; + } + } + if (!parseSucceed) + { + throw (new InvalidOperationException(SR.ExceptionRenkoBoxSizeFormatInvalid)); + } + } + + // Calculate box size using the percentage of price range + if(percentOfPriceRange > 0.0) + { + // Set default box size + boxSize = 1.0; + + // Calculate box size as percentage of price difference + if(minPrice == maxPrice) + { + boxSize = 1.0; + } + else if( (maxPrice - minPrice) < 0.000001) + { + boxSize = 0.000001; + } + else + { + boxSize = (maxPrice - minPrice) * (percentOfPriceRange / 100.0); + } + + + // Round calculated value + if(roundBoxSize) + { + + double[] availableBoxSizes = new double[] + { 0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 1.0, 2.0, 2.5, 3.0, 4.0, 5.0, 7.5, 10.0, 15.0, 20.0, 25.0, 50.0, 100.0, 200.0, 500.0, 1000.0, 5000.0, 10000.0, 50000.0, 100000.0, 1000000.0, 1000000.0}; + + for(int index = 1; index < availableBoxSizes.Length; index ++) + { + if(boxSize > availableBoxSizes[index - 1] && + boxSize < availableBoxSizes[index]) + { + boxSize = availableBoxSizes[index]; + } + } + } + } + + // Save current box size as a custom attribute of the original series + series["CurrentBoxSize"] = boxSize.ToString(CultureInfo.InvariantCulture); + + return boxSize; + } + + /// + /// Gets reversal amount of the pointAndFigure chart. + /// + /// Step line chart series used to dispaly the pointAndFigure chart. + private static double GetReversalAmount( + Series series) + { + // Check "ReversalAmount" custom attribute + double reversalAmount = 3.0; + if (series.IsCustomPropertySet(CustomPropertyName.ReversalAmount)) + { + string attrValue = series[CustomPropertyName.ReversalAmount].Trim(); + + double amount; + bool parseSucceed = double.TryParse(attrValue, NumberStyles.Any, CultureInfo.InvariantCulture, out amount); + if (parseSucceed) + { + reversalAmount = amount; + } + else + { + throw (new InvalidOperationException(SR.ExceptionPointAndFigureReversalAmountInvalidFormat)); + } + } + + return reversalAmount; + } + + + /// + /// Fills step line series with data to draw the PointAndFigure chart. + /// + /// Step line chart series used to dispaly the PointAndFigure chart. + /// Series with original data. + private static void FillPointAndFigureData(Series series, Series originalData) + { + // Get index of the Y values used for High/Low + int yValueHighIndex = 0; + if(series.IsCustomPropertySet(CustomPropertyName.UsedYValueHigh)) + { + try + { + + yValueHighIndex = int.Parse(series[CustomPropertyName.UsedYValueHigh], CultureInfo.InvariantCulture); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionPointAndFigureUsedYValueHighInvalidFormat)); + } + + if(yValueHighIndex >= series.YValuesPerPoint) + { + throw (new InvalidOperationException(SR.ExceptionPointAndFigureUsedYValueHighOutOfRange)); + } + } + int yValueLowIndex = 1; + if(series.IsCustomPropertySet(CustomPropertyName.UsedYValueLow)) + { + try + { + yValueLowIndex = int.Parse(series[CustomPropertyName.UsedYValueLow], CultureInfo.InvariantCulture); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionPointAndFigureUsedYValueLowInvalidFormat)); + } + + if(yValueLowIndex >= series.YValuesPerPoint) + { + throw (new InvalidOperationException(SR.ExceptionPointAndFigureUsedYValueLowOutOfrange)); + } + } + + // Get Up Brick color + Color upPriceColor = ChartGraphics.GetGradientColor(series.Color, Color.Black, 0.5); + string upPriceColorString = series[CustomPropertyName.PriceUpColor]; + if(upPriceColorString != null) + { + try + { + ColorConverter colorConverter = new ColorConverter(); + upPriceColor = (Color)colorConverter.ConvertFromString(null, CultureInfo.InvariantCulture, upPriceColorString); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionPointAndFigureUpBrickColorInvalidFormat)); + } + } + + // Get price range + double priceHigh, priceLow; + GetPriceRange(originalData, yValueHighIndex, yValueLowIndex, out priceHigh, out priceLow); + + // Calculate box size + double boxSize = GetBoxSize(series, priceHigh, priceLow); + + // Calculate reversal amount + double reversalAmount = GetReversalAmount(series); + + // Fill points + double prevHigh = double.NaN; + double prevLow = double.NaN; + int prevDirection = 0; // 1 up; -1 down; 0 none + int pointIndex = 0; + foreach(DataPoint dataPoint in originalData.Points) + { + if(!dataPoint.IsEmpty) + { + // Indicates that all updates are already performed and no further processing required + bool doNotUpdate = false; + + // Number of brciks total or added to the curent column + int numberOfBricks = 0; + + // Check if previus values exists + if(double.IsNaN(prevHigh)) + { + prevHigh = dataPoint.YValues[yValueHighIndex]; + prevLow = dataPoint.YValues[yValueLowIndex]; + ++pointIndex; + continue; + } + + // Check direction of the price change + int direction = 0; + if(prevDirection == 1 || prevDirection == 0) + { + if(dataPoint.YValues[yValueHighIndex] >= (prevHigh + boxSize)) + { + direction = 1; + numberOfBricks = (int)Math.Floor( + (dataPoint.YValues[yValueHighIndex] - prevHigh) / boxSize); + } + else if(dataPoint.YValues[yValueLowIndex] <= (prevHigh - boxSize * reversalAmount)) + { + direction = -1; + numberOfBricks = (int)Math.Floor( + (prevHigh - dataPoint.YValues[yValueLowIndex]) / boxSize); + } + // Adjust the lower part of the column while going up + else if (dataPoint.YValues[yValueHighIndex] <= (prevLow - boxSize)) + { + doNotUpdate = true; + numberOfBricks = (int)Math.Floor( + (prevLow - dataPoint.YValues[yValueHighIndex]) / boxSize); + + if (series.Points.Count > 0) + { + series.Points[series.Points.Count - 1].YValues[0] -= numberOfBricks * boxSize; + } + prevLow -= numberOfBricks * boxSize; + } + + } + if(direction == 0 && + (prevDirection == -1 || prevDirection == 0) ) + { + if(dataPoint.YValues[yValueLowIndex] <= (prevLow - boxSize)) + { + direction = -1; + numberOfBricks = (int)Math.Floor( + (prevLow - dataPoint.YValues[yValueLowIndex]) / boxSize); + } + else if(dataPoint.YValues[yValueHighIndex] >= (prevLow + boxSize * reversalAmount)) + { + direction = 1; + numberOfBricks = (int)Math.Floor( + (dataPoint.YValues[yValueHighIndex] - prevLow) / boxSize); + } + // Adjust the upper part of the column while going down + else if (dataPoint.YValues[yValueLowIndex] >= (prevHigh + boxSize)) + { + doNotUpdate = true; + numberOfBricks = (int)Math.Floor( + (prevHigh - dataPoint.YValues[yValueLowIndex]) / boxSize); + + if (series.Points.Count > 0) + { + series.Points[series.Points.Count - 1].YValues[1] += numberOfBricks * boxSize; + } + prevHigh += numberOfBricks * boxSize; + } + + } + + // Check if value was changed - otherwise do nothing + if (direction != 0 && !doNotUpdate) + { + // Extend line in same direction + if(direction == prevDirection) + { + if (direction == 1) + { + series.Points[series.Points.Count - 1].YValues[1] += numberOfBricks * boxSize; + prevHigh += numberOfBricks * boxSize; + series.Points[series.Points.Count - 1]["OriginalPointIndex"] = pointIndex.ToString(CultureInfo.InvariantCulture); + } + else + { + series.Points[series.Points.Count - 1].YValues[0] -= numberOfBricks * boxSize; + prevLow -= numberOfBricks * boxSize; + series.Points[series.Points.Count - 1]["OriginalPointIndex"] = pointIndex.ToString(CultureInfo.InvariantCulture); + } + } + else + { + // Opposite direction by more than reversal amount + DataPoint newDataPoint = (DataPoint)dataPoint.Clone(); + newDataPoint["OriginalPointIndex"] = pointIndex.ToString(CultureInfo.InvariantCulture); + newDataPoint.series = series; + newDataPoint.XValue = dataPoint.XValue; + if(direction == 1) + { + newDataPoint.Color = upPriceColor; + newDataPoint["PriceUpPoint"] = "true"; + newDataPoint.YValues[0] = prevLow + ((prevDirection != 0) ? boxSize : 0.0); + newDataPoint.YValues[1] = newDataPoint.YValues[0] + numberOfBricks * boxSize - ((prevDirection != 0) ? boxSize : 0.0); + } + else + { + newDataPoint.YValues[1] = prevHigh - ((prevDirection != 0) ? boxSize : 0.0); + newDataPoint.YValues[0] = newDataPoint.YValues[1] - numberOfBricks * boxSize; + } + + prevHigh = newDataPoint.YValues[1]; + prevLow = newDataPoint.YValues[0]; + + // Add PointAndFigure to the range step line series + series.Points.Add(newDataPoint); + } + + // Save previous close value and direction + prevDirection = direction; + } + } + ++pointIndex; + } + + } + + /// + /// Customize chart event, used to add empty points to make point and + /// figure chart symbols look proportional. + /// + /// The source Chart object of this event. + /// The EventArgs object that contains the event data. + static private void OnCustomize(Object sender, EventArgs e) + { + bool chartResized = false; + Chart chart = (Chart)sender; + // Loop through all series + foreach(Series series in chart.Series) + { + // Check for the PointAndFigure chart type + if(series.Name.StartsWith("POINTANDFIGURE_ORIGINAL_DATA_", StringComparison.Ordinal)) + { + // Get original series + Series pointAndFigureSeries = chart.Series[series.Name.Substring(29)]; + + // Check if proportional symbol custom attribute is set + bool proportionalSymbols = true; + string attrValue = pointAndFigureSeries[CustomPropertyName.ProportionalSymbols]; + if(attrValue != null && String.Compare( attrValue, "True", StringComparison.OrdinalIgnoreCase ) != 0 ) + { + proportionalSymbols = false; + } + + if(proportionalSymbols && + pointAndFigureSeries.Enabled && + pointAndFigureSeries.ChartArea.Length > 0) + { + // Resize chart + if(!chartResized) + { + chartResized = true; + chart.chartPicture.Resize(chart.chartPicture.ChartGraph, false); + } + + // Find series chart area, X & Y axes + ChartArea chartArea = chart.ChartAreas[pointAndFigureSeries.ChartArea]; + Axis axisX = chartArea.GetAxis(AxisName.X, pointAndFigureSeries.XAxisType, pointAndFigureSeries.XSubAxisName); + Axis axisY = chartArea.GetAxis(AxisName.Y, pointAndFigureSeries.YAxisType, pointAndFigureSeries.YSubAxisName); + + // Symbols are drawn only in 2D mode + if(!chartArea.Area3DStyle.Enable3D) + { + // Get current box size + double boxSize = double.Parse( + pointAndFigureSeries["CurrentBoxSize"], + CultureInfo.InvariantCulture); + + // Calculate symbol width and height + double boxYSize = Math.Abs( + axisY.GetPosition(axisY.Minimum) - + axisY.GetPosition(axisY.Minimum + boxSize) ); + double boxXSize = Math.Abs( + axisX.GetPosition(1.0) - + axisX.GetPosition(0.0) ); + boxXSize *= 0.8; + + // Get absolute size in pixels + SizeF markSize = chart.chartPicture.ChartGraph.GetAbsoluteSize( + new SizeF((float)boxXSize, (float)boxYSize)); + + // Calculate number of empty points that should be added + int pointCount = 0; + if(markSize.Width > markSize.Height) + { + pointCount = (int)(pointAndFigureSeries.Points.Count * (markSize.Width / markSize.Height)); + } + + // Add empty points + DataPoint emptyPoint = new DataPoint(pointAndFigureSeries); + emptyPoint.IsEmpty = true; + emptyPoint.AxisLabel = " "; + while(pointAndFigureSeries.Points.Count < pointCount) + { + pointAndFigureSeries.Points.Add(emptyPoint); + } + + // Always use zeros for Y values of empty points + pointAndFigureSeries[CustomPropertyName.EmptyPointValue] = "Zero"; + + // RecalculateAxesScale chart are data + chartArea.ReCalcInternal(); + } + } + } + } + } + + #endregion // Methods + + #region Drawing methods + + /// + /// Draws 2D column using 'X' or 'O' symbols. + /// + /// Chart graphics. + /// Vertical axis. + /// Column position and size. + /// Column data point. + /// Column series. + protected override void DrawColumn2D( + ChartGraphics graph, + Axis vAxis, + RectangleF rectSize, + DataPoint point, + Series ser) + { + // Get box size + double boxSize = double.Parse(ser["CurrentBoxSize"], CultureInfo.InvariantCulture); + double boxSizeRel = vAxis.GetLogValue(vAxis.ViewMinimum); + boxSizeRel = vAxis.GetLinearPosition(boxSizeRel); + boxSizeRel = Math.Abs(boxSizeRel - + vAxis.GetLinearPosition(vAxis.GetLogValue(vAxis.ViewMinimum + boxSize))); + + // Draw a series of Xs or Os + for(float positionY = rectSize.Y; positionY < rectSize.Bottom - (float)(boxSizeRel - boxSizeRel/4.0); positionY += (float)boxSizeRel) + { + // Get position of symbol + RectangleF position = RectangleF.Empty; + position.X = rectSize.X; + position.Y = positionY; + position.Width = rectSize.Width; + position.Height = (float)boxSizeRel; + + // Get absolute position and add 1 pixel spacing + position = graph.GetAbsoluteRectangle(position); + int spacing = 1 + point.BorderWidth / 2; + position.Y += spacing; + position.Height -= 2 * spacing; + + // Calculate shadow position + RectangleF shadowPosition = new RectangleF(position.Location, position.Size); + shadowPosition.Offset(ser.ShadowOffset, ser.ShadowOffset); + + if(point.IsCustomPropertySet("PriceUpPoint")) + { + // Draw shadow + if(ser.ShadowOffset != 0) + { + graph.DrawLineAbs( + ser.ShadowColor, + point.BorderWidth, + ChartDashStyle.Solid, + new PointF(shadowPosition.Left, shadowPosition.Top), + new PointF(shadowPosition.Right, shadowPosition.Bottom)); + graph.DrawLineAbs( + ser.ShadowColor, + point.BorderWidth, + ChartDashStyle.Solid, + new PointF(shadowPosition.Left, shadowPosition.Bottom), + new PointF(shadowPosition.Right, shadowPosition.Top)); + } + + // Draw 'X' symbol + graph.DrawLineAbs( + point.Color, + point.BorderWidth, + ChartDashStyle.Solid, + new PointF(position.Left, position.Top), + new PointF(position.Right, position.Bottom)); + graph.DrawLineAbs( + point.Color, + point.BorderWidth, + ChartDashStyle.Solid, + new PointF(position.Left, position.Bottom), + new PointF(position.Right, position.Top)); + } + else + { + // Draw circles when price is dropping + if(ser.ShadowOffset != 0) + { + graph.DrawCircleAbs( + new Pen(ser.ShadowColor, point.BorderWidth), + null, + shadowPosition, + 1, + false); + } + + // Draw 'O' symbol + graph.DrawCircleAbs( + new Pen(point.Color, point.BorderWidth), + null, + position, + 1, + false); + } + } + + + } + + #endregion // Drawing methods + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.PointAndFigure;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + #endregion + } +} + diff --git a/System.Web.DataVisualization/Common/ChartTypes/PointChart.cs b/System.Web.DataVisualization/Common/ChartTypes/PointChart.cs new file mode 100644 index 000000000..468256fc0 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/PointChart.cs @@ -0,0 +1,1822 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: PointChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: PointChart +// +// Purpose: Provides 2D/3D drawing and hit testing functionality +// for the Point chart. +// +// Reviewed: AG - Aug 6, 2002 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// PointChart class provides 2D/3D drawing and hit testing + /// functionality for the Point chart. + /// + internal class PointChart : IChartType + { + #region Fields + + /// + /// Indicates that markers will be always drawn + /// + internal bool alwaysDrawMarkers = true; + + /// + /// Index of the Y value used to draw chart + /// + internal int YValueIndex { get; set; } + + /// + /// Index of the Y value used to be shown as point value label + /// + internal int labelYValueIndex = -1; + + /// + /// Auto label position flag + /// + internal bool autoLabelPosition = true; + + /// + /// Label position + /// + internal LabelAlignmentStyles labelPosition = LabelAlignmentStyles.Top; + + /// + /// Vertical axes + /// + internal Axis VAxis { get; set; } + + /// + /// Horizontal axes + /// + internal Axis HAxis { get; set; } + + /// + /// Indexed series flag + /// + internal bool indexedSeries = false; + + /// + /// Common elements object + /// + internal CommonElements Common { get; set; } + + /// + /// Chart area object + /// + internal ChartArea Area { get; set; } + + /// + /// Indicates that marker and label are drawn in the middle of 3D depth + /// + internal bool middleMarker = true; + + /// + /// Stores information about 3D labels. Used to draw 3D labels in layers. + /// + internal ArrayList label3DInfoList = null; + + #endregion + + #region Constructors + + /// + /// Class public constructor. + /// + public PointChart() + { + } + + /// + /// Class public constructor. + /// + /// Indicates if markers should be always painted. + public PointChart(bool alwaysDrawMarkers) + { + this.alwaysDrawMarkers = alwaysDrawMarkers; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.Point;}} + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + virtual public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + virtual public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + virtual public bool SideBySideSeries { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return false; } } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Marker; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint { get { return 1; } } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Painting and Selection + + /// + /// Paint Point Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + this.Common = common; + this.Area = area; + ProcessChartType( false, graph, common, area, seriesToDraw); + } + + /// + /// This method recalculates size of the bars. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual protected void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + + this.Common = common; + // Prosess 3D chart type + if(area.Area3DStyle.Enable3D) + { + ProcessChartType3D( selection, graph, common, area, seriesToDraw ); + return; + } + + // Check if series is indexed + if( ShiftedSerName.Length == 0) + { + indexedSeries = ChartHelper.IndexedSeries(this.Common, area.GetSeriesFromChartType(this.Name).ToArray()); + } + else + { + indexedSeries = ChartHelper.IndexedSeries( common.DataManager.Series[ShiftedSerName] ); + } + + //************************************************************ + //** Loop through all series + //************************************************************ + foreach( Series ser in common.DataManager.Series ) + { + // Labels and markers have to be shifted if there + // is more than one series for column chart. This property + // will give a name of the series, which is used, for + // labels and markers. + bool breakSeriesLoop = false; + if( ShiftedSerName.Length > 0) + { + if( ShiftedSerName != ser.Name ) + { + continue; + } + breakSeriesLoop = true; + } + + // Process only point chart series in this chart area + if( String.Compare( ser.ChartTypeName, this.Name, true, System.Globalization.CultureInfo.CurrentCulture ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Check if only 1 specified series must be processed + if (seriesToDraw != null && seriesToDraw.Name != ser.Name) + { + continue; + } + + //************************************************************ + //** Set active horizontal/vertical axis + //************************************************************ + HAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + VAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + double horizontalViewMax = HAxis.ViewMaximum; + double horizontalViewMin = HAxis.ViewMinimum; + double verticalViewMax = VAxis.ViewMaximum; + double verticalViewMin = VAxis.ViewMinimum; + + //************************************************************ + //** Call Back Paint event + //************************************************************ + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + //************************************************************ + //** Loop through all data points in the series + //************************************************************ + int markerIndex = 0; // Marker index + int index = 1; // Data points loop + foreach( DataPoint point in ser.Points ) + { + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + //************************************************************ + //** Check if point values are in the chart area + //************************************************************ + + // Check for min/max X values + double xValue = (indexedSeries) ? (double)index : point.XValue; + xValue = HAxis.GetLogValue(xValue); + if(xValue > horizontalViewMax || xValue < horizontalViewMin) + { + index++; + continue; + } + + // Check for min/max Y values + double yValue = GetYValue(common, area, ser, point, index - 1, YValueIndex); + + // Axis is logarithmic + yValue = VAxis.GetLogValue( yValue ); + + if( yValue > verticalViewMax || yValue < verticalViewMin) + { + index++; + continue; + } + + + // Check if point should be drawn on the edge of the data scaleView. + bool skipMarker = false; + if(!ShouldDrawMarkerOnViewEdgeX()) + { + // Check for min/max X values + if(xValue == horizontalViewMax && ShiftedX >= 0) + { + skipMarker = true; + } + + // Check for min/max X values + if(xValue == horizontalViewMin && ShiftedX <= 0) + { + skipMarker = true; + } + } + + //************************************************************ + //** Get marker position and size + //************************************************************ + int pointMarkerSize = point.MarkerSize; + string pointMarkerImage = point.MarkerImage; + MarkerStyle pointMarkerStyle = point.MarkerStyle; + + + // Get marker position + PointF markerPosition = PointF.Empty; + markerPosition.Y = (float)VAxis.GetLinearPosition(yValue); + if( indexedSeries ) + { + // The formula for position is based on a distance + // from the grid line or nPoints position. + markerPosition.X = (float)HAxis.GetPosition( (double)index ); + } + else + { + markerPosition.X = (float)HAxis.GetPosition( point.XValue ); + } + + // Labels and markers have to be shifted if there + // is more than one series for column chart. + markerPosition.X += (float)ShiftedX; + + // Remeber pre-calculated point position + point.positionRel = new PointF(markerPosition.X, markerPosition.Y); + + // Get marker size + SizeF markerSize = GetMarkerSize( + graph, + common, + area, + point, + pointMarkerSize, + pointMarkerImage); + + //************************************************************ + //** Skip marker drawing + //************************************************************ + if( skipMarker ) + { + index++; + continue; + } + + //************************************************************ + //** Draw point chart + //************************************************************ + if(alwaysDrawMarkers || + pointMarkerStyle != MarkerStyle.None || + pointMarkerImage.Length > 0) + { + if( common.ProcessModePaint ) + { + // Check marker index + if(markerIndex == 0) + { + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw the marker + this.DrawPointMarker( + graph, + point.series, + point, + markerPosition, + (pointMarkerStyle == MarkerStyle.None) ? MarkerStyle.Circle : pointMarkerStyle, + (int)markerSize.Height, + (point.MarkerColor == Color.Empty) ? point.Color : point.MarkerColor, + (point.MarkerBorderColor == Color.Empty) ? point.BorderColor : point.MarkerBorderColor, + GetMarkerBorderSize(point), + pointMarkerImage, + point.MarkerImageTransparentColor, + (point.series != null) ? point.series.ShadowOffset : 0, + (point.series != null) ? point.series.ShadowColor : Color.Empty, + new RectangleF(markerPosition.X, markerPosition.Y, markerSize.Width, markerSize.Height)); + + // End Svg Selection mode + graph.EndHotRegion( ); + } + + if( common.ProcessModeRegions ) + { + SetHotRegions( + common, + graph, + point, + markerSize, + point.series.Name, + index - 1, + pointMarkerStyle, + markerPosition ); + } + } + + // Increase the markers counter + ++markerIndex; + if(ser.MarkerStep == markerIndex) + { + markerIndex = 0; + } + } + + // Start Svg Selection mode + graph.StartHotRegion( point, true ); + + // Draw labels + DrawLabels( + area, + graph, + common, + markerPosition, + (int)markerSize.Height, + point, + ser, + index - 1); + + // End Svg Selection mode + graph.EndHotRegion( ); + + + ++index; + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + // Break series loop. + if( breakSeriesLoop ) + { + break; + } + } + } + + /// + /// Draw series point marker. + /// + /// Chart Graphics used for drawing. + /// Series. + /// Series data point. + /// Coordinates of the center. + /// Marker style. + /// Marker size. + /// Marker color. + /// Marker border color. + /// Marker border size. + /// Marker image name. + /// Color of the marker image transparent. + /// Marker shadow size. + /// Marker shadow color. + /// Rectangle to which marker image should be scaled. + protected virtual void DrawPointMarker( + ChartGraphics graph, + Series series, + DataPoint dataPoint, + PointF point, + MarkerStyle markerStyle, + int markerSize, + Color markerColor, + Color markerBorderColor, + int markerBorderSize, + string markerImage, + Color markerImageTransparentColor, + int shadowSize, + Color shadowColor, + RectangleF imageScaleRect + ) + { + // Draw marker using relative coordinates + graph.DrawMarkerRel( + point, + markerStyle, + markerSize, + markerColor, + markerBorderColor, + markerBorderSize, + markerImage, + markerImageTransparentColor, + shadowSize, + shadowColor, + imageScaleRect); + } + + /// + /// Inserts Hot Regions used for image maps, tool tips and + /// hit test function + /// + /// Common elements object + /// Chart Graphics object + /// Data point used for hot region + /// Size of the marker + /// Name of the series + /// Data point index + /// Marker Style + /// Marker Position + private void SetHotRegions( CommonElements common, ChartGraphics graph, DataPoint point, SizeF markerSize, string seriesName, int pointIndex, MarkerStyle pointMarkerStyle, PointF markerPosition ) + { + + // Get relative marker size + SizeF relativeMarkerSize = graph.GetRelativeSize(markerSize); + + int insertIndex = common.HotRegionsList.FindInsertIndex(); + + // Insert circle area + if( pointMarkerStyle == MarkerStyle.Circle ) + { + common.HotRegionsList.AddHotRegion( insertIndex, graph, markerPosition.X, markerPosition.Y, relativeMarkerSize.Width/2f, point, seriesName, pointIndex ); + } + // All other markers represented as rectangles + else + { + // Insert area + common.HotRegionsList.AddHotRegion( + new RectangleF(markerPosition.X - relativeMarkerSize.Width/2f, markerPosition.Y - relativeMarkerSize.Height/2f, relativeMarkerSize.Width, relativeMarkerSize.Height), + point, + seriesName, + pointIndex ); + } + + } + + /// + /// This method draws labels in point chart. + /// + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Marker position + /// Marker size + /// Data point + /// Data series + /// Data point index. + private void DrawLabels( + ChartArea area, + ChartGraphics graph, + CommonElements common, + PointF markerPosition, + int markerSize, + DataPoint point, + Series ser, + int pointIndex) + { + // Get some properties for performance + string pointLabel = point.Label; + bool pointShowLabelAsValue = point.IsValueShownAsLabel; + + // **************************** + // Draw data point value label + // **************************** + if((!point.IsEmpty && (ser.IsValueShownAsLabel || pointShowLabelAsValue || pointLabel.Length > 0)) || + (pointShowLabelAsValue || pointLabel.Length > 0)) + { + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + + // Get label text + string text; + if (pointLabel.Length == 0) + { + text = ValueConverter.FormatValue( + ser.Chart, + point, + point.Tag, + point.YValues[(labelYValueIndex == -1) ? YValueIndex : labelYValueIndex], + point.LabelFormat, + ser.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(pointLabel); + } + + // Get point label style attribute + SizeF sizeMarker = graph.GetRelativeSize(new SizeF(markerSize, markerSize)); + SizeF sizeFont = graph.GetRelativeSize( + graph.MeasureString(text, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic)); + + SizeF sizeSingleCharacter = graph.GetRelativeSize( + graph.MeasureString("W", point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic)); + + // Increase label size when background is drawn + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + float horizontalSpacing = sizeLabel.Width / text.Length; + sizeLabel.Height += sizeSingleCharacter.Height / 2; + sizeLabel.Width += horizontalSpacing; + + // Get attribute from point or series + string attrib = point[CustomPropertyName.LabelStyle]; + if (attrib == null || attrib.Length == 0) + { + attrib = ser[CustomPropertyName.LabelStyle]; + } + this.autoLabelPosition = true; + if (attrib != null && attrib.Length > 0) + { + this.autoLabelPosition = false; + + // Get label position from attribute + if (String.Compare(attrib, "Auto", StringComparison.OrdinalIgnoreCase) == 0) + { + this.autoLabelPosition = true; + } + else if (String.Compare(attrib, "Center", StringComparison.OrdinalIgnoreCase) == 0) + { + this.labelPosition = LabelAlignmentStyles.Center; + } + else if (String.Compare(attrib, "Bottom", StringComparison.OrdinalIgnoreCase) == 0) + { + this.labelPosition = LabelAlignmentStyles.Bottom; + } + else if (String.Compare(attrib, "TopLeft", StringComparison.OrdinalIgnoreCase) == 0) + { + this.labelPosition = LabelAlignmentStyles.TopLeft; + } + else if (String.Compare(attrib, "TopRight", StringComparison.OrdinalIgnoreCase) == 0) + { + this.labelPosition = LabelAlignmentStyles.TopRight; + } + else if (String.Compare(attrib, "BottomLeft", StringComparison.OrdinalIgnoreCase) == 0) + { + this.labelPosition = LabelAlignmentStyles.BottomLeft; + } + else if (String.Compare(attrib, "BottomRight", StringComparison.OrdinalIgnoreCase) == 0) + { + this.labelPosition = LabelAlignmentStyles.BottomRight; + } + else if (String.Compare(attrib, "Left", StringComparison.OrdinalIgnoreCase) == 0) + { + this.labelPosition = LabelAlignmentStyles.Left; + } + else if (String.Compare(attrib, "Right", StringComparison.OrdinalIgnoreCase) == 0) + { + this.labelPosition = LabelAlignmentStyles.Right; + } + else if (String.Compare(attrib, "Top", StringComparison.OrdinalIgnoreCase) == 0) + { + this.labelPosition = LabelAlignmentStyles.Top; + } + else + { + throw (new ArgumentException(SR.ExceptionCustomAttributeValueInvalid(attrib, "LabelStyle"))); + } + } + + // Try to get automatic label position + if (this.autoLabelPosition) + { + this.labelPosition = GetAutoLabelPosition(ser, pointIndex); + } + + // Calculate label position + PointF position = new PointF(markerPosition.X, markerPosition.Y); + switch (this.labelPosition) + { + case LabelAlignmentStyles.Center: + format.Alignment = StringAlignment.Center; + break; + case LabelAlignmentStyles.Bottom: + format.Alignment = StringAlignment.Center; + position.Y += sizeMarker.Height / 1.75F; + position.Y += sizeLabel.Height / 2F; + break; + case LabelAlignmentStyles.Top: + format.Alignment = StringAlignment.Center; + position.Y -= sizeMarker.Height / 1.75F; + position.Y -= sizeLabel.Height / 2F; + break; + case LabelAlignmentStyles.Left: + format.Alignment = StringAlignment.Far; + position.X -= sizeMarker.Height / 1.75F + horizontalSpacing / 2f; + break; + case LabelAlignmentStyles.TopLeft: + format.Alignment = StringAlignment.Far; + position.X -= sizeMarker.Height / 1.75F + horizontalSpacing / 2f; + position.Y -= sizeMarker.Height / 1.75F; + position.Y -= sizeLabel.Height / 2F; + break; + case LabelAlignmentStyles.BottomLeft: + format.Alignment = StringAlignment.Far; + position.X -= sizeMarker.Height / 1.75F + horizontalSpacing / 2f; + position.Y += sizeMarker.Height / 1.75F; + position.Y += sizeLabel.Height / 2F; + break; + case LabelAlignmentStyles.Right: + //format.Alignment = StringAlignment.Near; + position.X += sizeMarker.Height / 1.75F + horizontalSpacing / 2f; + break; + case LabelAlignmentStyles.TopRight: + //format.Alignment = StringAlignment.Near; + position.X += sizeMarker.Height / 1.75F + horizontalSpacing / 2f; + position.Y -= sizeMarker.Height / 1.75F; + position.Y -= sizeLabel.Height / 2F; + break; + case LabelAlignmentStyles.BottomRight: + //format.Alignment = StringAlignment.Near; + position.X += sizeMarker.Height / 1.75F + horizontalSpacing / 2f; + position.Y += sizeMarker.Height / 1.75F; + position.Y += sizeLabel.Height / 2F; + break; + } + + // Get text angle + int textAngle = point.LabelAngle; + + // Check if text contains white space only + if (text.Trim().Length != 0) + { + + + // Check if Smart Labels are enabled + if (ser.SmartLabelStyle.Enabled) + { + // Adjust label position using SmartLabelStyle algorithm + position = area.smartLabels.AdjustSmartLabelPosition( + common, + graph, + area, + ser.SmartLabelStyle, + position, + sizeFont, + format, + markerPosition, + sizeMarker, + this.labelPosition); + + // Smart labels always use 0 degrees text angle + textAngle = 0; + } + + + + // Adjust alignment of vertical labels + // NOTE: Fixes issue #4560 + if (textAngle == 90 || textAngle == -90) + { + switch (this.labelPosition) + { + case LabelAlignmentStyles.Top: + format.Alignment = StringAlignment.Near; + position.Y += sizeLabel.Height / 2F; + break; + case LabelAlignmentStyles.Bottom: + format.Alignment = StringAlignment.Far; + position.Y -= sizeLabel.Height / 2F; + break; + case LabelAlignmentStyles.Right: + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Near; + break; + case LabelAlignmentStyles.Left: + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + break; + case LabelAlignmentStyles.TopLeft: + format.Alignment = StringAlignment.Near; + break; + case LabelAlignmentStyles.TopRight: + break; + case LabelAlignmentStyles.BottomLeft: + break; + case LabelAlignmentStyles.BottomRight: + format.Alignment = StringAlignment.Far; + break; + } + } + + // Draw label + if (!position.IsEmpty) + { + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + sizeLabel.Height -= sizeFont.Height / 2; + sizeLabel.Height += sizeFont.Height / 8; + labelBackPosition = GetLabelPosition( + graph, + position, + sizeLabel, + format, + true); + + // Adjust rectangle position due to horizontal spacing + switch (this.labelPosition) + { + case LabelAlignmentStyles.Left: + labelBackPosition.X += horizontalSpacing / 2f; + break; + case LabelAlignmentStyles.TopLeft: + labelBackPosition.X += horizontalSpacing / 2f; + break; + case LabelAlignmentStyles.BottomLeft: + labelBackPosition.X += horizontalSpacing / 2f; + break; + case LabelAlignmentStyles.Right: + labelBackPosition.X -= horizontalSpacing / 2f; + break; + case LabelAlignmentStyles.TopRight: + labelBackPosition.X -= horizontalSpacing / 2f; + break; + case LabelAlignmentStyles.BottomRight: + labelBackPosition.X -= horizontalSpacing / 2f; + break; + } + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + position, + format, + textAngle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + ser, + point, + pointIndex); + } + } + } + } + } + } + + + /// + /// Gets rectangle position of the label. + /// + /// Chart graphics object. + /// Original label position. + /// Label text size. + /// Label string format. + /// Result position is adjusted for drawing. + /// Label rectangle position. + internal static RectangleF GetLabelPosition( + ChartGraphics graph, + PointF position, + SizeF size, + StringFormat format, + bool adjustForDrawing) + { + // Calculate label position rectangle + RectangleF labelPosition = RectangleF.Empty; + labelPosition.Width = size.Width; + labelPosition.Height = size.Height; + + // Calculate pixel size in relative coordiantes + SizeF pixelSize = SizeF.Empty; + if(graph != null) + { + pixelSize = graph.GetRelativeSize(new SizeF(1f, 1f)); + } + + if(format.Alignment == StringAlignment.Far) + { + labelPosition.X = position.X - size.Width; + if(adjustForDrawing && !pixelSize.IsEmpty) + { + labelPosition.X -= 4f*pixelSize.Width; + labelPosition.Width += 4f*pixelSize.Width; + } + } + else if(format.Alignment == StringAlignment.Near) + { + labelPosition.X = position.X; + if(adjustForDrawing && !pixelSize.IsEmpty) + { + labelPosition.Width += 4f*pixelSize.Width; + } + } + else if(format.Alignment == StringAlignment.Center) + { + labelPosition.X = position.X - size.Width/2F; + if(adjustForDrawing && !pixelSize.IsEmpty) + { + labelPosition.X -= 2f*pixelSize.Width; + labelPosition.Width += 4f*pixelSize.Width; + } + } + + if(format.LineAlignment == StringAlignment.Far) + { + labelPosition.Y = position.Y - size.Height; + } + else if(format.LineAlignment == StringAlignment.Near) + { + labelPosition.Y = position.Y; + } + else if(format.LineAlignment == StringAlignment.Center) + { + labelPosition.Y = position.Y - size.Height/2F; + } + + labelPosition.Y -= 1f * pixelSize.Height; + + return labelPosition; + } + + #endregion + + #region 3D painting and Selection + + /// + /// This method recalculates size of the point marker. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual protected void ProcessChartType3D( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + + // Get list of series to draw + List typeSeries = null; + if( (area.Area3DStyle.IsClustered && this.SideBySideSeries) || + this.Stacked) + { + // Draw all series of the same chart type + typeSeries = area.GetSeriesFromChartType(Name); + } + else + { + // Draw just one chart series + typeSeries = new List(); + typeSeries.Add(seriesToDraw.Name); + } + + + //************************************************************ + //** Get order of data points drawing + //************************************************************ + ArrayList dataPointDrawingOrder = area.GetDataPointDrawingOrder(typeSeries, this, selection, COPCoordinates.X, null, this.YValueIndex, false); + + //************************************************************ + //** Loop through all data poins + //************************************************************ + foreach(object obj in dataPointDrawingOrder) + { + // Process single point + ProcessSinglePoint3D( + (DataPoint3D) obj, + graph, + common, + area + ); + } + + // Finish processing 3D labels + this.DrawAccumulated3DLabels(graph, common, area); + + } + + + /// + /// Draws\Hit tests single 3D point. + /// + /// 3D point information. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + internal void ProcessSinglePoint3D( + DataPoint3D pointEx, + ChartGraphics graph, + CommonElements common, + ChartArea area + ) + { + // Get point & series + DataPoint point = pointEx.dataPoint; + Series ser = point.series; + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + //************************************************************ + //** Set active horizontal/vertical axis + //************************************************************ + HAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + VAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + //************************************************************ + //** Check if point values are in the chart area + //************************************************************ + + // Check for min/max Y values + double yValue = GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, YValueIndex); + + // Axis is logarithmic + yValue = VAxis.GetLogValue( yValue ); + + if( yValue > VAxis.ViewMaximum || yValue < VAxis.ViewMinimum) + { + return; + } + + // Check for min/max X values + double xValue = (pointEx.indexedSeries) ? (double)pointEx.index : point.XValue; + xValue = HAxis.GetLogValue(xValue); + if(xValue > HAxis.ViewMaximum || xValue < HAxis.ViewMinimum) + { + return; + } + + // Check if point should be drawn on the edge of the data scaleView. + if(!ShouldDrawMarkerOnViewEdgeX()) + { + // Check for min/max X values + if(xValue == HAxis.ViewMaximum && ShiftedX >= 0) + { + return; + } + + // Check for min/max X values + if(xValue == HAxis.ViewMinimum && ShiftedX <= 0) + { + return; + } + } + + //************************************************************ + //** Get marker position and size + //************************************************************ + + // Get marker position + PointF markerPosition = PointF.Empty; + markerPosition.Y = (float)pointEx.yPosition; + markerPosition.X = (float)HAxis.GetLinearPosition(xValue); // No Log transformation required. Done above! + + // Labels and markers have to be shifted if there + // is more than one series for column chart. + markerPosition.X += (float)ShiftedX; + + // Remeber pre-calculated point position + point.positionRel = new PointF(markerPosition.X, markerPosition.Y); + + // Get point some point properties and save them in variables + int pointMarkerSize = point.MarkerSize; + string pointMarkerImage = point.MarkerImage; + MarkerStyle pointMarkerStyle = point.MarkerStyle; + + // Get marker size + SizeF markerSize = GetMarkerSize( + graph, + common, + area, + point, + pointMarkerSize, + pointMarkerImage); + + //************************************************************ + //** Transform marker position in 3D space + //************************************************************ + // Get projection coordinates + Point3D[] marker3DPosition = new Point3D[1]; + marker3DPosition[0] = new Point3D(markerPosition.X, markerPosition.Y, (float)(pointEx.zPosition + ((this.middleMarker) ? pointEx.depth/2f : pointEx.depth))); + + // Transform coordinates of text size + area.matrix3D.TransformPoints(marker3DPosition); + PointF markerRotatedPosition = marker3DPosition[0].PointF; + + //************************************************************ + //** Draw point chart + //************************************************************ + GraphicsPath rectPath = null; + + if(alwaysDrawMarkers || + pointMarkerStyle != MarkerStyle.None || + pointMarkerImage.Length > 0) + { + // Check marker index + if((pointEx.index % ser.MarkerStep) == 0) + { + // Detect if we need to get graphical path of drawn object + DrawingOperationTypes drawingOperationType = DrawingOperationTypes.DrawElement; + + if( common.ProcessModeRegions ) + { + drawingOperationType |= DrawingOperationTypes.CalcElementPath; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw the marker + rectPath = graph.DrawMarker3D(area.matrix3D, + area.Area3DStyle.LightStyle, + pointEx.zPosition + ((this.middleMarker) ? pointEx.depth/2f : pointEx.depth), + markerPosition, + (pointMarkerStyle == MarkerStyle.None) ? MarkerStyle.Circle : pointMarkerStyle, + (int)markerSize.Height, + (point.MarkerColor == Color.Empty) ? point.Color : point.MarkerColor, + (point.MarkerBorderColor == Color.Empty) ? point.BorderColor : point.MarkerBorderColor, + GetMarkerBorderSize(point), + pointMarkerImage, + point.MarkerImageTransparentColor, + (point.series != null) ? point.series.ShadowOffset : 0, + (point.series != null) ? point.series.ShadowColor : Color.Empty, + new RectangleF(markerRotatedPosition.X, markerRotatedPosition.Y, markerSize.Width, markerSize.Height), + drawingOperationType); + + // End Svg Selection mode + graph.EndHotRegion( ); + } + } + + + //********************************************************************** + //** Data point label is not drawn with the data point. Instead the + //** information about label is collected and drawn when all points + //** with current Z position are drawn. + //** This is done to achieve correct Z order layering of labels. + //********************************************************************** + if(this.label3DInfoList != null && + this.label3DInfoList.Count > 0 && + ((Label3DInfo)this.label3DInfoList[this.label3DInfoList.Count-1]).PointEx.zPosition != pointEx.zPosition) + { + // Draw labels with information previously collected + this.DrawAccumulated3DLabels(graph, common, area); + } + + // Check if labels info list was created + if(this.label3DInfoList == null) + { + this.label3DInfoList = new ArrayList(); + } + + // Store information about the label for future drawing + Label3DInfo label3DInfo = new Label3DInfo(); + label3DInfo.PointEx = pointEx; + label3DInfo.MarkerPosition = markerRotatedPosition; + label3DInfo.MarkerSize = markerSize; + this.label3DInfoList.Add(label3DInfo); + + if( common.ProcessModeRegions ) + { + // Get relative marker size + SizeF relativeMarkerSize = graph.GetRelativeSize(markerSize); + + // Insert area just after the last custom area + int insertIndex = common.HotRegionsList.FindInsertIndex(); + + // Insert circle area + if(pointMarkerStyle == MarkerStyle.Circle) + { + float[] circCoord = new float[3]; + circCoord[0] = markerRotatedPosition.X; + circCoord[1] = markerRotatedPosition.Y; + circCoord[2] = relativeMarkerSize.Width/2f; + + common.HotRegionsList.AddHotRegion( + insertIndex, + graph, + circCoord[0], + circCoord[1], + circCoord[2], + point, + ser.Name, + pointEx.index - 1 + ); + } + + // Insert path for 3D bar + if(pointMarkerStyle == MarkerStyle.Square) + { + common.HotRegionsList.AddHotRegion( + rectPath, + false, + graph, + point, + ser.Name, + pointEx.index - 1 + ); + } + + // All other markers represented as rectangles + else + { + common.HotRegionsList.AddHotRegion( + new RectangleF(markerRotatedPosition.X - relativeMarkerSize.Width/2f, markerRotatedPosition.Y - relativeMarkerSize.Height/2f, relativeMarkerSize.Width, relativeMarkerSize.Height), + point, + ser.Name, + pointEx.index - 1 + ); + } + } + if (rectPath != null) + { + rectPath.Dispose(); + } + } + + /// + /// Draws labels which are srored in the collection. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + internal void DrawAccumulated3DLabels( + ChartGraphics graph, + CommonElements common, + ChartArea area) + { + if(this.label3DInfoList != null) + { + foreach(Label3DInfo labelInfo in this.label3DInfoList) + { + // Draw labels + DrawLabels( + area, + graph, + common, + labelInfo.MarkerPosition, + (int)labelInfo.MarkerSize.Height, + labelInfo.PointEx.dataPoint, + labelInfo.PointEx.dataPoint.series, + labelInfo.PointEx.index - 1); + + } + + // Clear labels info list + this.label3DInfoList.Clear(); + } + } + + #endregion + + #region Marker and Labels related methods + + /// + /// Indicates that markers are drawnd on the X edge of the data scaleView. + /// + /// True. Point chart always draws markers on the edge. + virtual protected bool ShouldDrawMarkerOnViewEdgeX() + { + return true; + } + + /// + /// Gets marker border size. + /// + /// Data point. + /// Marker border size. + virtual protected int GetMarkerBorderSize(DataPointCustomProperties point) + { + return point.MarkerBorderWidth; + } + + /// + /// Gets label position. For point chart this function always returns 'Top'. + /// + /// Series. + /// Data point index in series. + /// Return automaticly detected label position. + virtual protected LabelAlignmentStyles GetAutoLabelPosition(Series series, int pointIndex) + { + return LabelAlignmentStyles.Top; + } + + /// + /// Returns marker size. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Data point. + /// Marker size. + /// Marker image. + /// Marker width and height. + virtual protected SizeF GetMarkerSize( + ChartGraphics graph, + CommonElements common, + ChartArea area, + DataPoint point, + int markerSize, + string markerImage) + { + SizeF size = new SizeF(markerSize, markerSize); + if (graph != null && graph.Graphics != null) + { + // Marker size is in pixels and we do the mapping for higher DPIs + size.Width = markerSize * graph.Graphics.DpiX / 96; + size.Height = markerSize * graph.Graphics.DpiY / 96; + } + + if (markerImage.Length > 0) // Get image size + common.ImageLoader.GetAdjustedImageSize(markerImage, graph.Graphics, ref size); + + return size; + } + + #endregion + + #region Labels shifting properties + + /// + /// Labels and markers have to be shifted if there + /// is more than one series for column chart. + /// NOT USED IN POINT CHART. + /// + virtual public double ShiftedX + { + get + { + return 0; + } + set + { + } + } + + /// + /// Labels and markers have to be shifted if there + /// is more than one series for column chart. This property + /// will give a name of the series, which is used, for + /// labels and markers. + /// NOT USED IN POINT CHART. + /// + virtual public string ShiftedSerName + { + get + { + return ""; + } + set + { + } + } + + #endregion + + #region Y values related methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + + // Point chart do not have height + if(yValueIndex == -1) + { + return 0.0; + } + + // Check required Y values number + if (point.YValues.Length <= yValueIndex) + { + throw (new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)))); + } + + // Check empty point + if (point.IsEmpty || double.IsNaN(point.YValues[yValueIndex])) + { + double result = GetEmptyPointValue( point, pointIndex ); + + // NOTE: Fixes issue #6921 + // If empty point Y value is zero then check if the scale of + // the Y axis and if it is not containing zero adjust the Y value + // of the empty point, so it will be visible + if (result == 0.0) + { + Axis yAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName); + double yViewMax = yAxis.maximum; + double yViewMin = yAxis.minimum; + if (result < yViewMin) + { + result = yViewMin; + } + else if (result > yViewMax) + { + result = yViewMax; + } + } + + return result; + } + + return point.YValues[yValueIndex]; + } + + /// + /// This method will find previous and next data point, which is not + /// empty and recalculate a new value for current empty data point. + /// New value depends on custom attribute “EmptyPointValue” and + /// it could be zero or average. + /// + /// IsEmpty data point. + /// IsEmpty data point index. + /// A Value for empty data point. + internal double GetEmptyPointValue( DataPoint point, int pointIndex ) + { + Series series = point.series; // Data series + double previousPoint = 0; // Previous data point value (not empty) + double nextPoint = 0; // Next data point value (not empty) + int prevIndx = 0; // Previous data point index + int nextIndx = series.Points.Count - 1; // Next data point index + + //************************************************************ + //** Check custom attribute "EmptyPointValue" + //************************************************************ + string emptyPointValue = ""; + if( series.EmptyPointStyle.IsCustomPropertySet(CustomPropertyName.EmptyPointValue) ) + { + emptyPointValue = series.EmptyPointStyle[CustomPropertyName.EmptyPointValue]; + } + else if( series.IsCustomPropertySet(CustomPropertyName.EmptyPointValue) ) + { + emptyPointValue = series[CustomPropertyName.EmptyPointValue]; + } + + // Take attribute value + if( String.Compare(emptyPointValue, "Zero", StringComparison.OrdinalIgnoreCase) == 0 ) + { + // IsEmpty points represented with zero values + return 0.0; + } + + //************************************************************ + //** IsEmpty point value is an average of neighbour points + //************************************************************ + + // Find previous non-empty point value + for( int indx = pointIndex; indx >= 0; indx-- ) + { + if( !series.Points[indx].IsEmpty ) + { + previousPoint = series.Points[indx].YValues[YValueIndex]; + prevIndx = indx; + break; + } + previousPoint = Double.NaN; + } + + // Find next non-empty point value + for( int indx = pointIndex; indx < series.Points.Count; indx++ ) + { + if( !series.Points[indx].IsEmpty ) + { + nextPoint = series.Points[indx].YValues[YValueIndex]; + nextIndx = indx; + break; + } + nextPoint = Double.NaN; + } + + // All Previous points are empty + if( Double.IsNaN( previousPoint ) ) + { + // All points are empty + if( Double.IsNaN( nextPoint ) ) + { + previousPoint = 0; + } + else // Next point is equal to previous point + { + previousPoint = nextPoint; + } + } + + // All next points are empty + if( Double.IsNaN( nextPoint ) ) + { + // Previous point is equal to next point + nextPoint = previousPoint; + } + + // If points value are the same use average + if( series.Points[nextIndx].XValue == series.Points[prevIndx].XValue ) + { + return ( previousPoint + nextPoint ) / 2; + } + + // Calculate and return average value + double aCoeff = (previousPoint - nextPoint) / (series.Points[nextIndx].XValue - series.Points[prevIndx].XValue); + return -aCoeff * (point.XValue - series.Points[prevIndx].XValue) + previousPoint; + } + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + this.Common = common; + // Check if series is indexed + indexedSeries = ChartHelper.IndexedSeries(this.Common, area.GetSeriesFromChartType(this.Name).ToArray()); + + //************************************************************ + //** Set active horizontal/vertical axis + //************************************************************ + Axis hAxis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName); + Axis vAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName); + + //************************************************************ + //** Loop through all data points in the series + //************************************************************ + int markerIndex = 0; // Marker index + int index = 1; // Data points loop + foreach( DataPoint point in series.Points ) + { + //************************************************************ + //** Check if point values are in the chart area + //************************************************************ + + // Check for min/max Y values + double yValue = GetYValue(common, area, series, point, index - 1, YValueIndex); + + // Axis is logarithmic + yValue = vAxis.GetLogValue( yValue ); + + if( yValue > vAxis.ViewMaximum || yValue < vAxis.ViewMinimum) + { + index++; + continue; + } + + // Check for min/max X values + double xValue = (indexedSeries) ? (double)index : point.XValue; + xValue = hAxis.GetLogValue(xValue); + if(xValue > hAxis.ViewMaximum || xValue < hAxis.ViewMinimum) + { + index++; + continue; + } + + // Check if point should be drawn on the edge of the data scaleView. + if(!ShouldDrawMarkerOnViewEdgeX()) + { + // Check for min/max X values + if(xValue == hAxis.ViewMaximum && ShiftedX >= 0) + { + index++; + continue; + } + + // Check for min/max X values + if(xValue == hAxis.ViewMinimum && ShiftedX <= 0) + { + index++; + continue; + } + } + + //************************************************************ + //** Get marker position and size + //************************************************************ + + // Get marker position + PointF markerPosition = PointF.Empty; + markerPosition.Y = (float)vAxis.GetLinearPosition(yValue); + if( indexedSeries ) + { + // The formula for position is based on a distance + // from the grid line or nPoints position. + markerPosition.X = (float)hAxis.GetPosition( (double)index ); + } + else + { + markerPosition.X = (float)hAxis.GetPosition( point.XValue ); + } + + // Labels and markers have to be shifted if there + // is more than one series for column chart. + markerPosition.X += (float)ShiftedX; + + // Get point some point properties and save them in variables + int pointMarkerSize = point.MarkerSize; + string pointMarkerImage = point.MarkerImage; + MarkerStyle pointMarkerStyle = point.MarkerStyle; + + // Get marker size + SizeF markerSize = GetMarkerSize( + common.graph, + common, + area, + point, + pointMarkerSize, + pointMarkerImage); + + // Transform marker position in 3D space + if(area.Area3DStyle.Enable3D) + { + // Get series depth and Z position + float seriesDepth, seriesZPosition; + area.GetSeriesZPositionAndDepth(series, out seriesDepth, out seriesZPosition); + + Point3D[] marker3DPosition = new Point3D[1]; + marker3DPosition[0] = new Point3D( + markerPosition.X, + markerPosition.Y, + (float)(seriesZPosition + ((this.middleMarker) ? seriesDepth/2f : seriesDepth))); + + // Transform coordinates + area.matrix3D.TransformPoints(marker3DPosition); + markerPosition = marker3DPosition[0].PointF; + } + + // Check if marker visible + if(alwaysDrawMarkers || + pointMarkerStyle != MarkerStyle.None || + pointMarkerImage.Length > 0) + { + // Check marker index + if(markerIndex == 0) + { + markerSize = common.graph.GetRelativeSize(markerSize); + + // Add marker position into the list + RectangleF markerRect = new RectangleF( + markerPosition.X - markerSize.Width / 2f, + markerPosition.Y - markerSize.Height / 2f, + markerSize.Width, + markerSize.Height); + list.Add(markerRect); + } + + // Increase the markers counter + ++markerIndex; + if(series.MarkerStep == markerIndex) + { + markerIndex = 0; + } + } + + ++index; + } + } + + #endregion + + #region 3D Label Info class + + /// + /// 3D LabelStyle info. + /// + internal class Label3DInfo + { + internal DataPoint3D PointEx = null; + internal PointF MarkerPosition = PointF.Empty; + internal SizeF MarkerSize = SizeF.Empty; + } + + #endregion // 3D Label Info class + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/PolarChart.cs b/System.Web.DataVisualization/Common/ChartTypes/PolarChart.cs new file mode 100644 index 000000000..15837fb22 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/PolarChart.cs @@ -0,0 +1,271 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: PolarChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: PolarChart +// +// Purpose: Polar chart type is similar to the Radar chart. +// All the drawing functionality is located in the +// RadarChart class and PolarChart class provides +// positionning and style methods required only in +// Polar chart. +// +// Polar Chart Overview: +// --------------------- +// +// The polar chart type is a circular graph on which data points +// are displayed using the angle, and the distance from the center +// point. The X axis is located on the boundaries of the circle and +// the Y axis connects the center of the circle with the X axis. +// +// By default, the angle scale ranges from 0 to 360 degrees. However, +// the X Axis Minimum and Maximum properties may be used to specify +// a different angular scale. The Minimum angle value starts at the +// top (12 O'Clock position) of the chart but can be changed to +// another angle using the Crossing property. For example, setting +// the Crossing property to 90 will move the "zero" value to the +// 3 O'Clock position. +// +// Reviewed: AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; + +#if Microsoft_CONTROL +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web.UI.DataVisualization.Charting; + + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// PolarChart class uses its base class RadarChart to perform most of the + /// drawing and calculation operations. + /// + internal class PolarChart : RadarChart + { + #region Constructors + + /// + /// Class public constructor. + /// + public PolarChart() + { + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.Polar;}} + + #endregion + + #region ICircularChartType interface implementation + + /// + /// Checks if closed figure should be drawn even in Line drawing mode. + /// + /// True if closed figure should be drawn even in Line drawing mode. + public override bool RequireClosedFigure() + { + return false; + } + + /// + /// Checks if Y axis position may be changed using X axis Crossing property. + /// + /// True if Y axis position may be changed using X axis Crossing property. + public override bool XAxisCrossingSupported() + { + return true; + } + + /// + /// Checks if automatic X axis labels are supported. + /// + /// True if automatic X axis labels are supported. + public override bool XAxisLabelsSupported() + { + return true; + } + + /// + /// Checks if radial grid lines (X axis) are supported by the chart type. + /// + /// True if radial grid lines are supported. + public override bool RadialGridLinesSupported() + { + return true; + } + + /// + /// Gets number of sectors in the circular chart area. + /// + /// Chart area to get number of sectors for. + /// Collection of series. + /// Returns number of sectors in circular chart. + public override int GetNumerOfSectors(ChartArea area, SeriesCollection seriesCollection) + { + // By default we split polar chart into 12 sectors (30 degrees in case of 360 degrees scale) + int sectorNumber = 12; + + // Custom interval is set on the X axis + double interval = area.AxisX.Interval; + if(area.AxisX.LabelStyle.GetInterval() > 0) + { + interval = area.AxisX.LabelStyle.GetInterval(); + } + if(interval != 0) + { + // Get X axis scale size + double max = (area.AxisX.AutoMaximum) ? 360.0 : area.AxisX.Maximum; + double min = (area.AxisX.AutoMinimum) ? 0.0 : area.AxisX.Minimum; + + // Calculate number of sectors + sectorNumber = (int)(Math.Abs(max - min) / interval); + } + + return sectorNumber; + } + + /// + /// Get a location of Y axis in degrees. + /// + /// Chart area to get Y axes locations for. + /// Returns an array of one or more locations of Y axis. + public override float[] GetYAxisLocations(ChartArea area) + { + float[] axesLocation = new float[1]; + axesLocation[0] = 0f; + + // Check if X axis crossing is set to change location of Y axis + if( !double.IsNaN(area.AxisX.Crossing) ) + { + axesLocation[0] = (float)area.AxisX.Crossing; + while(axesLocation[0] < 0) + { + axesLocation[0] = 360f + axesLocation[0]; + } + + } + + return axesLocation; + } + + #endregion // ICircularChartType interface implementation + + #region Helper Methods + + /// + /// Gets polar chart drawing style. + /// + /// Chart series. + /// Series point. + /// Returns polar drawing style. + override protected RadarDrawingStyle GetDrawingStyle(Series ser, DataPoint point) + { + RadarDrawingStyle drawingStyle = RadarDrawingStyle.Line; + if (point.IsCustomPropertySet(CustomPropertyName.PolarDrawingStyle) || + ser.IsCustomPropertySet(CustomPropertyName.PolarDrawingStyle)) + { + string attributeValue = + (point.IsCustomPropertySet(CustomPropertyName.PolarDrawingStyle)) ? + point[CustomPropertyName.PolarDrawingStyle] : + ser[CustomPropertyName.PolarDrawingStyle]; + if(String.Compare(attributeValue, "Line", StringComparison.OrdinalIgnoreCase ) == 0) + { + drawingStyle = RadarDrawingStyle.Line; + } + else if(String.Compare(attributeValue, "Marker", StringComparison.OrdinalIgnoreCase ) == 0) + { + drawingStyle = RadarDrawingStyle.Marker; + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(attributeValue, "PolarDrawingStyle"))); + } + } + return drawingStyle; + } + + /// + /// Fills a PointF array of data points absolute pixel positions. + /// + /// Graphics object. + /// Chart area. + /// Point series. + /// Array of data points position. + override protected PointF[] GetPointsPosition(ChartGraphics graph, ChartArea area, Series series) + { + PointF[] pointPos = new PointF[series.Points.Count + 1]; + int index = 0; + foreach( DataPoint point in series.Points ) + { + // Change Y value if line is out of plot area + double yValue = GetYValue(Common, area, series, point, index, 0); + + // Recalculates y position + double yPosition = area.AxisY.GetPosition( yValue ); + + // Recalculates x position + double xPosition = area.circularCenter.X; + + // Add point position into array + pointPos[index] = graph.GetAbsolutePoint(new PointF((float)xPosition, (float)yPosition)); + + // Rotate position + float sectorAngle = area.CircularPositionToAngle(point.XValue); + Matrix matrix = new Matrix(); + matrix.RotateAt(sectorAngle, graph.GetAbsolutePoint(area.circularCenter)); + PointF[] rotatedPoint = new PointF[] { pointPos[index] }; + matrix.TransformPoints(rotatedPoint); + pointPos[index] = rotatedPoint[0]; + + index++; + } + + // Add last center point + pointPos[index] = graph.GetAbsolutePoint(area.circularCenter); + + return pointPos; + } + + #endregion // Helper Methods + } +} + diff --git a/System.Web.DataVisualization/Common/ChartTypes/RadarChart.cs b/System.Web.DataVisualization/Common/ChartTypes/RadarChart.cs new file mode 100644 index 000000000..bf94333c9 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/RadarChart.cs @@ -0,0 +1,1685 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: RadarChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: RadarChart, ICircularChartType +// +// Purpose: Provides 2D/3D drawing and hit testing functionality +// for the Radar chart. RadarChart class is used as a +// base class for the PolarChart. +// +// Reviewed: GS - Jul 15, 2003 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; + +#if Microsoft_CONTROL +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web.UI.DataVisualization.Charting; + + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else +namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + #region Enumerations + + /// + /// Circular chart drawing style. + /// + internal enum RadarDrawingStyle + { + /// + /// Series are drawn as filled areas. + /// + Area, + /// + /// Series are drawn as lines. + /// + Line, + /// + /// Series are drawn as markers. + /// + Marker + } + + #endregion // Enumerations + + /// + /// RadarChart class provides 2D/3D drawing and hit testing + /// functionality for the Radar chart. It is also used as a + /// base class for the PolarChart. + /// + internal class RadarChart : IChartType, ICircularChartType + { + #region Fields + + /// + /// Common elements object + /// + internal CommonElements Common { get; set; } + + /// + /// Chart area object + /// + internal ChartArea Area { get; set; } + + /// + /// Auto label position flag + /// + private bool _autoLabelPosition = true; + + /// + /// Label position + /// + private LabelAlignmentStyles _labelPosition = LabelAlignmentStyles.Top; + + #endregion + + #region Constructors + + /// + /// Class public constructor. + /// + public RadarChart() + { + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.Radar;}} + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axes + /// + virtual public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return true;} } + + /// + /// True if chart type supports logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return false;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + virtual public bool SideBySideSeries { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return false;} } + + /// + /// True if palette colors should be applied for each data point. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return false; } } + + /// + /// Indicates that this is a one hundred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that negative 100% stacked values are shown on + /// the other side of the X axis + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + if(series != null) + { + RadarDrawingStyle drawingStyle = GetDrawingStyle(series, new DataPoint(series)); + if(drawingStyle == RadarDrawingStyle.Line) + { + return LegendImageStyle.Line; + } + else if(drawingStyle == RadarDrawingStyle.Marker) + { + return LegendImageStyle.Marker; + } + } + return LegendImageStyle.Rectangle; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint { get { return 1; } } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region ICircularChartType interface implementation + + /// + /// Checks if closed figure should be drawn even in Line drawing mode. + /// + /// True if closed figure should be drawn even in Line drawing mode. + public virtual bool RequireClosedFigure() + { + return true; + } + + /// + /// Checks if Y axis position may be changed using X axis Crossing property. + /// + /// True if Y axis position may be changed using X axis Crossing property. + public virtual bool XAxisCrossingSupported() + { + return false; + } + + /// + /// Checks if automatic X axis labels are supported. + /// + /// True if automatic X axis labels are supported. + public virtual bool XAxisLabelsSupported() + { + return false; + } + + /// + /// Checks if radial grid lines (X axis) are supported by the chart type. + /// + /// True if radial grid lines are supported. + public virtual bool RadialGridLinesSupported() + { + return false; + } + + /// + /// Gets number of sectors in the circular chart area. + /// + /// Chart area to get number of sectors for. + /// Collection of series. + /// Returns number of sectors in circular chart. + public virtual int GetNumerOfSectors(ChartArea area, SeriesCollection seriesCollection) + { + int sectorNumber = 0; + + // Get maximum number of points in all series + foreach(Series series in seriesCollection) + { + if(series.IsVisible() && series.ChartArea == area.Name) + { + sectorNumber = (int)Math.Max(series.Points.Count, sectorNumber); + } + } + return sectorNumber; + } + + /// + /// Get a location of each Y axis in degrees. + /// + /// Chart area to get Y axes locations for. + /// Returns an array of one or more locations of Y axis. + public virtual float[] GetYAxisLocations(ChartArea area) + { + float[] axesLocation = new float[area.CircularSectorsNumber]; + float sectorSize = 360f / ((float)axesLocation.Length); + for(int index = 0; index < axesLocation.Length; index++) + { + axesLocation[index] = sectorSize * index; + } + return axesLocation; + } + + #endregion // ICircularChartType interface implementation + + #region Painting and Selection + + /// + /// Paint Radar Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + this.Common = common; + this.Area = area; + + // Draw chart + ProcessChartType( false, graph, common, area, seriesToDraw ); + } + + /// + /// This method recalculates size of the bars. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual protected void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + + //************************************************************ + //** Loop through all series + //************************************************************ + foreach( Series ser in common.DataManager.Series ) + { + // Process only series in this chart area + if( ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // All series attached to this chart area must have Radar chart type + if(String.Compare( ser.ChartTypeName, this.Name, true, System.Globalization.CultureInfo.CurrentCulture ) != 0 ) + { + throw(new InvalidOperationException(SR.ExceptionChartTypeCanNotCombine(ser.ChartTypeName, this.Name))); + } + + //************************************************************ + //** Call Back Paint event + //************************************************************ + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + // Chart type do not supprot secondary axes + //if (ser.YAxisType == AxisType.Secondary) + //{ + // throw (new InvalidOperationException(SR.ExceptionChartTypeSecondaryYAxisUnsupported(this.Name))); + //} + //if (ser.XAxisType == AxisType.Secondary) + //{ + // throw (new InvalidOperationException(SR.ExceptionChartTypeSecondaryXAxisUnsupported(this.Name))); + //} + + // Set active vertical axis and scaleView boundary + Axis vAxis = area.GetAxis(AxisName.Y, AxisType.Primary, ser.YSubAxisName); + double vAxisMin = vAxis.ViewMinimum; + double vAxisMax = vAxis.ViewMaximum; + + //************************************************************ + //** Fill the array of data points coordinates (absolute) + //************************************************************ + PointF[] dataPointPos = GetPointsPosition(graph, area, ser); + + //************************************************************ + //** Draw shadow of area first + //************************************************************ + int index = 0; // Data points loop + if(ser.ShadowOffset != 0 && !selection) + { + foreach( DataPoint point in ser.Points ) + { + // Calculate second point index + int secondPointIndex = index + 1; + if(secondPointIndex >= ser.Points.Count) + { + secondPointIndex = 0; + } + + // Get visual properties of the point + DataPointCustomProperties pointAttributes = point; + + if(ser.Points[secondPointIndex].IsEmpty) + { + pointAttributes = ser.Points[secondPointIndex]; + } + + + //************************************************************ + //** Check what is the main element of radar point. It can be + //** area (default), line or marker. + //************************************************************ + Color areaColor = pointAttributes.Color; + Color borderColor = pointAttributes.BorderColor; + int borderWidth = pointAttributes.BorderWidth; + ChartDashStyle borderDashStyle = pointAttributes.BorderDashStyle; + RadarDrawingStyle drawingStyle = GetDrawingStyle(ser, point); + + // Check if point Y value is in axis scaleView + if(vAxis.GetLogValue(point.YValues[0]) > vAxisMax || vAxis.GetLogValue(point.YValues[0]) < vAxisMin || + vAxis.GetLogValue(ser.Points[secondPointIndex].YValues[0]) > vAxisMax || vAxis.GetLogValue(ser.Points[secondPointIndex].YValues[0]) < vAxisMin) + { + ++index; + continue; + } + + if(drawingStyle == RadarDrawingStyle.Line) + { + // Use the main color for the border and make sure border is visible + borderColor = pointAttributes.Color; + borderWidth = (borderWidth < 1) ? 1 : borderWidth; + borderDashStyle = (borderDashStyle == ChartDashStyle.NotSet) ? ChartDashStyle.Solid : borderDashStyle; + + // Area is not visible + areaColor = Color.Transparent; + } + else if(drawingStyle == RadarDrawingStyle.Marker) + { + // Area is not visible + areaColor = Color.Transparent; + } + + // Check if line should be always closed + if(secondPointIndex == 0 && + !RequireClosedFigure() && + drawingStyle != RadarDrawingStyle.Area) + { + break; + } + + //************************************************************ + //** Fill area + //************************************************************ + if (areaColor != Color.Transparent && areaColor != Color.Empty && ser.ShadowOffset != 0) + { + // Create sector path + using (GraphicsPath fillPath = new GraphicsPath()) + { + fillPath.AddLine(graph.GetAbsolutePoint(area.circularCenter), dataPointPos[index]); + fillPath.AddLine(dataPointPos[index], dataPointPos[secondPointIndex]); + fillPath.AddLine(dataPointPos[secondPointIndex], graph.GetAbsolutePoint(area.circularCenter)); + + // Shift shadow position + Matrix shadowMatrix = new Matrix(); + shadowMatrix.Translate(ser.ShadowOffset, ser.ShadowOffset); + fillPath.Transform(shadowMatrix); + + // Fill shadow sector + using (Brush brush = new SolidBrush(ser.ShadowColor)) + { + graph.FillPath(brush, fillPath); + } + } + } + + // Increase index + ++index; + } + } + + + //************************************************************ + //** Loop through all data points in the series and fill areas + //** and draw border lines. + //************************************************************ + index = 0; // Data points loop + foreach( DataPoint point in ser.Points ) + { + // Set pre-calculated point position + point.positionRel = graph.GetRelativePoint(dataPointPos[index]); + + // Calculate second point index + int secondPointIndex = index + 1; + if(secondPointIndex >= ser.Points.Count) + { + secondPointIndex = 0; + } + + // Get visual properties of the point + DataPointCustomProperties pointAttributes = point; + + if(ser.Points[secondPointIndex].IsEmpty) + { + pointAttributes = ser.Points[secondPointIndex]; + } + + + //************************************************************ + //** Check what is the main element of radar point. It can be + //** area (default), line or marker. + //************************************************************ + Color areaColor = pointAttributes.Color; + Color borderColor = pointAttributes.BorderColor; + int borderWidth = pointAttributes.BorderWidth; + ChartDashStyle borderDashStyle = pointAttributes.BorderDashStyle; + RadarDrawingStyle drawingStyle = GetDrawingStyle(ser, point); + + // Check if point Y value is in axis scaleView + if(vAxis.GetLogValue(point.YValues[0]) > vAxisMax || vAxis.GetLogValue(point.YValues[0]) < vAxisMin || + vAxis.GetLogValue(ser.Points[secondPointIndex].YValues[0]) > vAxisMax || vAxis.GetLogValue(ser.Points[secondPointIndex].YValues[0]) < vAxisMin) + { + ++index; + continue; + } + + if(drawingStyle == RadarDrawingStyle.Line) + { + // Use the main color for the border and make sure border is visible + borderColor = pointAttributes.Color; + borderWidth = (borderWidth < 1) ? 1 : borderWidth; + borderDashStyle = (borderDashStyle == ChartDashStyle.NotSet) ? ChartDashStyle.Solid : borderDashStyle; + + // Area is not visible + areaColor = Color.Transparent; + } + else if(drawingStyle == RadarDrawingStyle.Marker) + { + // Area is not visible + areaColor = Color.Transparent; + } + + // Check if line should be always closed + using (GraphicsPath selectionPath = new GraphicsPath()) + { + if (secondPointIndex == 0 && + !RequireClosedFigure() && + drawingStyle != RadarDrawingStyle.Area) + { + // Process hot region for the last point + if (common.ProcessModeRegions) + { + // Add area to the selection path + AddSelectionPath(area, selectionPath, dataPointPos, index, secondPointIndex, graph.GetAbsolutePoint(area.circularCenter), 0); + + // Insert area just after the last custom area + int insertIndex = common.HotRegionsList.FindInsertIndex(); + + // Insert area + common.HotRegionsList.AddHotRegion( + insertIndex, + selectionPath, + false, + graph, + point, + ser.Name, + index); + } + break; + } + + //************************************************************ + //** Fill area + //************************************************************ + if (areaColor != Color.Transparent && areaColor != Color.Empty) + { + // Create sector path + using (GraphicsPath fillPath = new GraphicsPath()) + { + fillPath.AddLine(graph.GetAbsolutePoint(area.circularCenter), dataPointPos[index]); + fillPath.AddLine(dataPointPos[index], dataPointPos[secondPointIndex]); + fillPath.AddLine(dataPointPos[secondPointIndex], graph.GetAbsolutePoint(area.circularCenter)); + + if (common.ProcessModePaint) + { + // Create fill brush + using (Brush brush = graph.CreateBrush( + fillPath.GetBounds(), + areaColor, + pointAttributes.BackHatchStyle, + pointAttributes.BackImage, + pointAttributes.BackImageWrapMode, + pointAttributes.BackImageTransparentColor, + pointAttributes.BackGradientStyle, + pointAttributes.BackSecondaryColor)) + { + + // Start Svg Selection mode + graph.StartHotRegion(point); + + // Fill sector + graph.FillPath(brush, fillPath); + + // End Svg Selection mode + graph.EndHotRegion(); + } + } + } + + if (common.ProcessModeRegions) + { + // Add area to the selection path + AddSelectionPath(area, selectionPath, dataPointPos, index, secondPointIndex, graph.GetAbsolutePoint(area.circularCenter), 0); + } + + } + + //************************************************************ + //** Draw Line + //************************************************************ + if (borderColor != Color.Empty && borderWidth > 0 && borderDashStyle != ChartDashStyle.NotSet) + { + if (secondPointIndex < ser.Points.Count) + { + if (common.ProcessModePaint) + { + // Start Svg Selection mode + graph.StartHotRegion(point); + + graph.DrawLineAbs( + borderColor, + borderWidth, + borderDashStyle, + dataPointPos[index], + dataPointPos[secondPointIndex], + ser.ShadowColor, + (areaColor == Color.Transparent || areaColor == Color.Empty) ? ser.ShadowOffset : 0); + + // End Svg Selection mode + graph.EndHotRegion(); + } + + if (common.ProcessModeRegions) + { + // Add line to the selection path + AddSelectionPath(area, selectionPath, dataPointPos, index, secondPointIndex, PointF.Empty, borderWidth); + } + } + } + + //************************************************************ + //** Image map for the area and line + //************************************************************ + if (common.ProcessModeRegions) + { + // Insert area just after the last custom area + int insertIndex = common.HotRegionsList.FindInsertIndex(); + + // Insert area + common.HotRegionsList.AddHotRegion( + insertIndex, + selectionPath, + false, + graph, + point, + ser.Name, + index); + } + } + // Increase index + ++index; + } + + //************************************************************ + //** Loop through all data points in the series and draw + //** markers and points labels. + //************************************************************ + int markerIndex = 0; // Marker index + index = 0; // Data points loop + foreach( DataPoint point in ser.Points ) + { + //************************************************************ + //** Check what is the main element of radar point. It can be + //** area (default), line or marker. + //************************************************************ + Color markerColor = point.MarkerColor; + MarkerStyle markerStyle = point.MarkerStyle; + RadarDrawingStyle drawingStyle = GetDrawingStyle(ser, point); + + // Check if point Y value is in axis scaleView + if(vAxis.GetLogValue(point.YValues[0]) > vAxisMax || + vAxis.GetLogValue(point.YValues[0]) < vAxisMin) + { + ++index; + continue; + } + + if(drawingStyle == RadarDrawingStyle.Marker && + markerColor.IsEmpty) + { + // Set main color to marker + markerColor = point.Color; + } + + //************************************************************ + //** Get marker size + //************************************************************ + // Get marker size + SizeF markerSize = GetMarkerSize( + graph, + common, + area, + point, + point.MarkerSize, + point.MarkerImage); + + //************************************************************ + //** Draw point chart + //************************************************************ + if( common.ProcessModePaint ) + { + if(markerStyle != MarkerStyle.None || point.MarkerImage.Length > 0) + { + // If marker style is set and color is not - use main color of point + if(markerColor.IsEmpty) + { + markerColor = point.Color; + } + + // Check marker index + if(markerIndex == 0) + { + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw the marker + graph.DrawMarkerAbs(dataPointPos[index], + markerStyle, + (int)markerSize.Height, + markerColor, + point.MarkerBorderColor, + point.MarkerBorderWidth, + point.MarkerImage, + point.MarkerImageTransparentColor, + (point.series != null) ? point.series.ShadowOffset : 0, + (point.series != null) ? point.series.ShadowColor : Color.Empty, + new RectangleF(dataPointPos[index].X, dataPointPos[index].Y, markerSize.Width, markerSize.Height), + false); + + // End Svg Selection mode + graph.EndHotRegion( ); + } + + // Increase the markers counter + ++markerIndex; + if(ser.MarkerStep == markerIndex) + { + markerIndex = 0; + } + } + + // Draw labels + DrawLabels( + area, + graph, + common, + dataPointPos[index], + (int)markerSize.Height, + point, + ser, + index); + } + + if( common.ProcessModeRegions ) + { + // Get relative marker size + SizeF relativeMarkerSize = graph.GetRelativeSize(markerSize); + + // Get relative marker position + PointF relativeMarkerPosition = graph.GetRelativePoint(dataPointPos[index]); + + // Insert area just after the last custom area + int insertIndex = common.HotRegionsList.FindInsertIndex(); + + // Insert circle area + if(point.MarkerStyle == MarkerStyle.Circle) + { + float[] circCoord = new float[3]; + circCoord[0] = relativeMarkerPosition.X; + circCoord[1] = relativeMarkerPosition.Y; + circCoord[2] = relativeMarkerSize.Width/2f; + + common.HotRegionsList.AddHotRegion( + insertIndex, + graph, + circCoord[0], + circCoord[1], + circCoord[2], + point, + ser.Name, + index ); + } + + // All other markers represented as rectangles + else + { + common.HotRegionsList.AddHotRegion( + new RectangleF(relativeMarkerPosition.X - relativeMarkerSize.Width/2f, relativeMarkerPosition.Y - relativeMarkerSize.Height/2f, relativeMarkerSize.Width, relativeMarkerSize.Height), + point, + ser.Name, + index ); + } + } + + ++index; + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + } + } + + /// + /// Creates selection path for one data point. + /// + /// Chart area object. + /// Selection path used for data storing. + /// Array of points positions. + /// First point index. + /// Second point index. + /// Center point for segment area. + /// Border width + internal void AddSelectionPath( + ChartArea area, + GraphicsPath selectionPath, + PointF[] dataPointPos, + int firstPointIndex, + int secondPointIndex, + PointF centerPoint, + int borderWidth) + { + // Calculate "half" points on the left and right side of the point + PointF rightSidePoint = GetMiddlePoint(dataPointPos[firstPointIndex], dataPointPos[secondPointIndex]); + PointF leftSidePoint = PointF.Empty; + if(firstPointIndex > 0) + { + leftSidePoint = GetMiddlePoint(dataPointPos[firstPointIndex], dataPointPos[firstPointIndex - 1]); + } + else if(firstPointIndex == 0) + { + if(area.CircularSectorsNumber == dataPointPos.Length - 1) + { + leftSidePoint = GetMiddlePoint(dataPointPos[firstPointIndex], dataPointPos[dataPointPos.Length - 2]); + } + } + + // Add area segment + if(!centerPoint.IsEmpty) + { + selectionPath.AddLine(centerPoint, rightSidePoint); + selectionPath.AddLine(rightSidePoint, dataPointPos[firstPointIndex]); + if(leftSidePoint.IsEmpty) + { + selectionPath.AddLine(dataPointPos[firstPointIndex], centerPoint); + } + else + { + selectionPath.AddLine(dataPointPos[firstPointIndex], leftSidePoint); + selectionPath.AddLine(leftSidePoint, centerPoint); + } + } + else + { + // Add line + GraphicsPath linePath = new GraphicsPath(); + if(!leftSidePoint.IsEmpty) + { + linePath.AddLine(leftSidePoint, dataPointPos[firstPointIndex]); + } + linePath.AddLine(dataPointPos[firstPointIndex], rightSidePoint); + + // Widen path + try + { + linePath.Widen(new Pen(Color.Black, borderWidth + 2)); + linePath.Flatten(); + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + + // Add to the selection path + selectionPath.AddPath(linePath, false); + } + + } + + /// + /// Gets the middle point of the line. + /// + /// First line point. + /// Second line point. + /// + private PointF GetMiddlePoint(PointF p1, PointF p2) + { + PointF middlePoint = PointF.Empty; + middlePoint.X = (p1.X + p2.X) / 2f; + middlePoint.Y = (p1.Y + p2.Y) / 2f; + return middlePoint; + } + + /// + /// Returns marker size. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Data point. + /// Marker size. + /// Marker image. + /// Marker width and height. + virtual protected SizeF GetMarkerSize( + ChartGraphics graph, + CommonElements common, + ChartArea area, + DataPoint point, + int markerSize, + string markerImage) + { + SizeF size = new SizeF(markerSize, markerSize); + if (graph != null && graph.Graphics != null) + { + // Marker size is in pixels and we do the mapping for higher DPIs + size.Width = markerSize * graph.Graphics.DpiX / 96; + size.Height = markerSize * graph.Graphics.DpiY / 96; + } + + if(markerImage.Length > 0) + common.ImageLoader.GetAdjustedImageSize(markerImage, graph.Graphics, ref size); + + return size; + } + + /// + /// Fills a PointF array of data points absolute pixel positions. + /// + /// Graphics object. + /// Chart area. + /// Point series. + /// Array of data points position. + virtual protected PointF[] GetPointsPosition(ChartGraphics graph, ChartArea area, Series series) + { + PointF[] pointPos = new PointF[series.Points.Count + 1]; + int index = 0; + foreach( DataPoint point in series.Points ) + { + // Change Y value if line is out of plot area + double yValue = GetYValue(Common, area, series, point, index, 0); + + // Recalculates y position + double yPosition = area.AxisY.GetPosition( yValue ); + + // Recalculates x position + double xPosition = area.circularCenter.X; + + // Add point position into array + pointPos[index] = graph.GetAbsolutePoint(new PointF((float)xPosition, (float)yPosition)); + + // Rotate position + float sectorAngle = 360f / area.CircularSectorsNumber * index; + Matrix matrix = new Matrix(); + matrix.RotateAt(sectorAngle, graph.GetAbsolutePoint(area.circularCenter)); + PointF[] rotatedPoint = new PointF[] { pointPos[index] }; + matrix.TransformPoints(rotatedPoint); + pointPos[index] = rotatedPoint[0]; + + index++; + } + + // Add last center point + pointPos[index] = graph.GetAbsolutePoint(area.circularCenter); + + return pointPos; + } + + /// + /// This method draws labels in point chart. + /// + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Marker position + /// Marker size + /// Data point + /// Data series + /// Data point index. + internal void DrawLabels( + ChartArea area, + ChartGraphics graph, + CommonElements common, + PointF markerPosition, + int markerSize, + DataPoint point, + Series ser, + int pointIndex) + { + // Get some properties for performance + string pointLabel = point.Label; + bool pointShowLabelAsValue = point.IsValueShownAsLabel; + + // **************************** + // Draw data point value label + // **************************** + if((!point.IsEmpty && (ser.IsValueShownAsLabel || pointShowLabelAsValue || pointLabel.Length > 0)) || + (pointShowLabelAsValue || pointLabel.Length > 0)) + { + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + + // Get label text + string text; + if (pointLabel.Length == 0) + { + text = ValueConverter.FormatValue( + ser.Chart, + point, + point.Tag, + point.YValues[0], + point.LabelFormat, + ser.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(pointLabel); + } + + // Get point label style attribute + SizeF sizeMarker = new SizeF(markerSize, markerSize); + SizeF sizeFont = graph.MeasureString(text, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic); + + // Increase label size when background is drawn + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeLabel.Height / 2; + sizeLabel.Width += sizeLabel.Width / text.Length; + + // Get attribute from point or series + this._autoLabelPosition = true; + string attrib = point[CustomPropertyName.LabelStyle]; + if (attrib == null || attrib.Length == 0) + { + attrib = ser[CustomPropertyName.LabelStyle]; + } + if (attrib != null && attrib.Length > 0) + { + this._autoLabelPosition = false; + + // Get label position from attribute + if (String.Compare(attrib, "Auto", StringComparison.OrdinalIgnoreCase) == 0) + { + this._autoLabelPosition = true; + } + else if (String.Compare(attrib, "Center", StringComparison.OrdinalIgnoreCase) == 0) + { + this._labelPosition = LabelAlignmentStyles.Center; + } + else if (String.Compare(attrib, "Bottom", StringComparison.OrdinalIgnoreCase) == 0) + { + this._labelPosition = LabelAlignmentStyles.Bottom; + } + else if (String.Compare(attrib, "TopLeft", StringComparison.OrdinalIgnoreCase) == 0) + { + this._labelPosition = LabelAlignmentStyles.TopLeft; + } + else if (String.Compare(attrib, "TopRight", StringComparison.OrdinalIgnoreCase) == 0) + { + this._labelPosition = LabelAlignmentStyles.TopRight; + } + else if (String.Compare(attrib, "BottomLeft", StringComparison.OrdinalIgnoreCase) == 0) + { + this._labelPosition = LabelAlignmentStyles.BottomLeft; + } + else if (String.Compare(attrib, "BottomRight", StringComparison.OrdinalIgnoreCase) == 0) + { + this._labelPosition = LabelAlignmentStyles.BottomRight; + } + else if (String.Compare(attrib, "Left", StringComparison.OrdinalIgnoreCase) == 0) + { + this._labelPosition = LabelAlignmentStyles.Left; + } + else if (String.Compare(attrib, "Right", StringComparison.OrdinalIgnoreCase) == 0) + { + this._labelPosition = LabelAlignmentStyles.Right; + } + else if (String.Compare(attrib, "Top", StringComparison.OrdinalIgnoreCase) == 0) + { + this._labelPosition = LabelAlignmentStyles.Top; + } + else + { + throw (new ArgumentException(SR.ExceptionCustomAttributeValueInvalid(attrib, "LabelStyle"))); + } + } + + // Try to get automatic label position + if (this._autoLabelPosition) + { + this._labelPosition = GetAutoLabelPosition(area, ser, pointIndex); + } + + // Calculate label position + PointF position = new PointF(markerPosition.X, markerPosition.Y); + switch (this._labelPosition) + { + case LabelAlignmentStyles.Center: + format.Alignment = StringAlignment.Center; + break; + case LabelAlignmentStyles.Bottom: + format.Alignment = StringAlignment.Center; + position.Y += sizeMarker.Height / 1.75F; + position.Y += sizeLabel.Height / 2F; + break; + case LabelAlignmentStyles.Top: + format.Alignment = StringAlignment.Center; + position.Y -= sizeMarker.Height / 1.75F; + position.Y -= sizeLabel.Height / 2F; + break; + + case LabelAlignmentStyles.Left: + format.Alignment = StringAlignment.Far; + position.X -= sizeMarker.Height / 1.75F; + break; + case LabelAlignmentStyles.TopLeft: + format.Alignment = StringAlignment.Far; + position.X -= sizeMarker.Height / 1.75F; + position.Y -= sizeMarker.Height / 1.75F; + position.Y -= sizeLabel.Height / 2F; + break; + case LabelAlignmentStyles.BottomLeft: + format.Alignment = StringAlignment.Far; + position.X -= sizeMarker.Height / 1.75F; + position.Y += sizeMarker.Height / 1.75F; + position.Y += sizeLabel.Height / 2F; + break; + case LabelAlignmentStyles.Right: + //format.Alignment = StringAlignment.Near; + position.X += sizeMarker.Height / 1.75F; + break; + case LabelAlignmentStyles.TopRight: + //format.Alignment = StringAlignment.Near; + position.X += sizeMarker.Height / 1.75F; + position.Y -= sizeMarker.Height / 1.75F; + position.Y -= sizeLabel.Height / 2F; + break; + case LabelAlignmentStyles.BottomRight: + //format.Alignment = StringAlignment.Near; + position.X += sizeMarker.Height / 1.75F; + position.Y += sizeMarker.Height / 1.75F; + position.Y += sizeLabel.Height / 2F; + break; + } + + // Get text angle + int textAngle = point.LabelAngle; + + // Check if text contains white space only + if (text.Trim().Length != 0) + { + + + // Check if Smart Labels are enabled + if (ser.SmartLabelStyle.Enabled) + { + position = graph.GetRelativePoint(position); + markerPosition = graph.GetRelativePoint(markerPosition); + sizeFont = graph.GetRelativeSize(sizeFont); + sizeMarker = graph.GetRelativeSize(sizeMarker); + + // Adjust label position using SmartLabelStyle algorithm + position = area.smartLabels.AdjustSmartLabelPosition( + common, + graph, + area, + ser.SmartLabelStyle, + position, + sizeFont, + format, + markerPosition, + sizeMarker, + this._labelPosition); + + // Restore absolute coordinates + if (!position.IsEmpty) + { + position = graph.GetAbsolutePoint(position); + } + sizeFont = graph.GetAbsoluteSize(sizeFont); + + // Smart labels always use 0 degrees text angle + textAngle = 0; + } + + + // Draw label + if (!position.IsEmpty) + { + position = graph.GetRelativePoint(position); + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + sizeLabel = graph.GetRelativeSize(sizeFont); + sizeLabel.Height += sizeLabel.Height / 8; + labelBackPosition = PointChart.GetLabelPosition( + graph, + position, + sizeLabel, + format, + true); + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + position, + format, + textAngle, + labelBackPosition, + + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + ser, + point, + pointIndex); + } + } + } + } + } + } + + /// + /// Gets label position depending on the prev/next point values. + /// This method will reduce label overlapping with the chart itself (line). + /// + /// Chart area for this chart + /// Series. + /// Data point index in series. + /// Return automaticly detected label position. + virtual protected LabelAlignmentStyles GetAutoLabelPosition(ChartArea area, Series series, int pointIndex) + { + LabelAlignmentStyles labelAlignment = LabelAlignmentStyles.Top; + + // Calculate data point sector angle + float sectorAngle = 360f / area.CircularSectorsNumber * pointIndex; + + if(sectorAngle == 0f) + { + labelAlignment = LabelAlignmentStyles.TopRight; + } + else if(sectorAngle >= 0 && sectorAngle <= 45) + { + labelAlignment = LabelAlignmentStyles.Top; + } + else if(sectorAngle >= 45 && sectorAngle <= 90) + { + labelAlignment = LabelAlignmentStyles.TopRight; + } + else if(sectorAngle >= 90 && sectorAngle <= 135) + { + labelAlignment = LabelAlignmentStyles.BottomRight; + } + else if(sectorAngle >= 135 && sectorAngle <= 180) + { + labelAlignment = LabelAlignmentStyles.BottomRight; + } + else if(sectorAngle >= 180 && sectorAngle <= 225) + { + labelAlignment = LabelAlignmentStyles.BottomLeft; + } + else if(sectorAngle >= 225 && sectorAngle <= 270) + { + labelAlignment = LabelAlignmentStyles.BottomLeft; + } + else if(sectorAngle >= 270 && sectorAngle <= 315) + { + labelAlignment = LabelAlignmentStyles.TopLeft; + } + else if(sectorAngle >= 315 && sectorAngle <= 360) + { + labelAlignment = LabelAlignmentStyles.TopLeft; + } + + return labelAlignment; + } + + /// + /// Gets radar chart drawing style. + /// + /// Chart series. + /// Series point. + /// Returns radar drawing style. + virtual protected RadarDrawingStyle GetDrawingStyle(Series ser, DataPoint point) + { + RadarDrawingStyle drawingStyle = RadarDrawingStyle.Area; + if(point.IsCustomPropertySet(CustomPropertyName.RadarDrawingStyle) || + ser.IsCustomPropertySet(CustomPropertyName.RadarDrawingStyle)) + { + string attributeValue = + (point.IsCustomPropertySet(CustomPropertyName.RadarDrawingStyle)) ? + point[CustomPropertyName.RadarDrawingStyle] : + ser[CustomPropertyName.RadarDrawingStyle]; + if(String.Compare(attributeValue, "Area", StringComparison.OrdinalIgnoreCase) == 0 ) + { + drawingStyle = RadarDrawingStyle.Area; + } + else if (String.Compare(attributeValue, "Line", StringComparison.OrdinalIgnoreCase) == 0) + { + drawingStyle = RadarDrawingStyle.Line; + } + else if(String.Compare(attributeValue, "Marker", StringComparison.OrdinalIgnoreCase) == 0) + { + drawingStyle = RadarDrawingStyle.Marker; + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(attributeValue, "RadarDrawingStyle"))); + } + } + return drawingStyle; + } + + #endregion + + #region Y values related methods + + /// + /// Helper function that returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + + // Point chart do not have height + if(yValueIndex == -1) + { + return 0.0; + } + + if( point.IsEmpty ) + { + double result = GetEmptyPointValue(point, pointIndex); + + // NOTE: Fixes issue #6921 + // If empty point Y value is zero then check if the scale of + // the Y axis and if it is not containing zero adjust the Y value + // of the empty point, so it will be visible + if (result == 0.0) + { + Axis yAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName); + double yViewMax = yAxis.maximum; + double yViewMin = yAxis.minimum; + if (result < yViewMin) + { + result = yViewMin; + } + else if (result > yViewMax) + { + result = yViewMax; + } + } + + return result; + } + return point.YValues[yValueIndex]; + } + + /// + /// This method will find previous and next data point, which is not + /// empty and recalculate a new value for current empty data point. + /// New value depends on custom attribute “EmptyPointValue” and + /// it could be zero or average. + /// + /// IsEmpty data point. + /// IsEmpty data point index. + /// A Value for empty data point. + internal double GetEmptyPointValue( DataPoint point, int pointIndex ) + { + Series series = point.series; // Data series + double previousPoint = 0; // Previous data point value (not empty) + double nextPoint = 0; // Next data point value (not empty) + int prevIndx = 0; // Previous data point index + int nextIndx = series.Points.Count - 1; // Next data point index + + //************************************************************ + //** Check custom attribute "EmptyPointValue" + //************************************************************ + string emptyPointValue = ""; + if( series.EmptyPointStyle.IsCustomPropertySet(CustomPropertyName.EmptyPointValue) ) + { + emptyPointValue = series.EmptyPointStyle[CustomPropertyName.EmptyPointValue]; + } + else if( series.IsCustomPropertySet(CustomPropertyName.EmptyPointValue) ) + { + emptyPointValue = series[CustomPropertyName.EmptyPointValue]; + } + + // Take attribute value + if( String.Compare(emptyPointValue, "Zero", StringComparison.OrdinalIgnoreCase) == 0 ) + { + // IsEmpty points represented with zero values + return 0; + } + + //************************************************************ + //** IsEmpty point value is an average of neighbour points + //************************************************************ + + // Find previous non-empty point value + for( int indx = pointIndex; indx >= 0; indx-- ) + { + if( !series.Points[indx].IsEmpty ) + { + previousPoint = series.Points[indx].YValues[0]; + prevIndx = indx; + break; + } + previousPoint = Double.NaN; + } + + // Find next non-empty point value + for( int indx = pointIndex; indx < series.Points.Count; indx++ ) + { + if( !series.Points[indx].IsEmpty ) + { + nextPoint = series.Points[indx].YValues[0]; + nextIndx = indx; + break; + } + nextPoint = Double.NaN; + } + + // All Previous points are empty + if( Double.IsNaN( previousPoint ) ) + { + // All points are empty + if( Double.IsNaN( nextPoint ) ) + { + previousPoint = 0; + } + else // Next point is equal to previous point + { + previousPoint = nextPoint; + } + } + + // All next points are empty + if( Double.IsNaN( nextPoint ) ) + { + // Previous point is equal to next point + nextPoint = previousPoint; + } + + // If points value are the same use average + if( series.Points[nextIndx].XValue == series.Points[prevIndx].XValue ) + { + return ( previousPoint + nextPoint ) / 2; + } + + // Calculate and return average value + double aCoeff = (previousPoint - nextPoint) / (series.Points[nextIndx].XValue - series.Points[prevIndx].XValue); + return -aCoeff * (point.XValue - series.Points[prevIndx].XValue) + previousPoint; + } + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + //************************************************************ + //** Fill the array of data points coordinates (absolute) + //************************************************************ + PointF[] dataPointPos = GetPointsPosition(common.graph, area, series); + + //************************************************************ + //** Loop through all data points in the series and draw + //** markers and points labels. + //************************************************************ + int markerIndex = 0; // Marker index + int index = 0; // Data points loop + foreach( DataPoint point in series.Points ) + { + //************************************************************ + //** Check what is the main element of radar point. It can be + //** area (default), line or marker. + //************************************************************ + Color markerColor = point.MarkerColor; + MarkerStyle markerStyle = point.MarkerStyle; + RadarDrawingStyle drawingStyle = GetDrawingStyle(series, point); + if(drawingStyle == RadarDrawingStyle.Marker) + { + // Set main color to marker + markerColor = point.Color; + } + + //************************************************************ + //** Get marker size + //************************************************************ + // Get marker size + SizeF markerSize = GetMarkerSize( + common.graph, + common, + area, + point, + point.MarkerSize, + point.MarkerImage); + + //************************************************************ + //** Draw point chart + //************************************************************ + if(markerStyle != MarkerStyle.None || point.MarkerImage.Length > 0) + { + // If marker style is set and color is not - use main color of point + if(markerColor.IsEmpty) + { + markerColor = point.Color; + } + + // Check marker index + if(markerIndex == 0) + { + PointF markerPosition = common.graph.GetRelativePoint(dataPointPos[index]); + markerSize = common.graph.GetRelativeSize(markerSize); + RectangleF markerRect = new RectangleF( + markerPosition.X - markerSize.Width/2f, + markerPosition.Y - markerSize.Height/2f, + markerSize.Width, + markerSize.Height); + list.Add(markerRect); + } + + // Increase the markers counter + ++markerIndex; + if(series.MarkerStep == markerIndex) + { + markerIndex = 0; + } + } + + ++index; + } + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } + + /// + /// ICircularChartType interface provides behaviuour information for circular + /// chart types like Radar or Polar. This interface is similar to IChartType + /// interface. + /// + internal interface ICircularChartType + { + #region Methods + + /// + /// Checks if closed figure should be drawn even in Line drawing mode. + /// + /// True if closed figure should be drawn even in Line drawing mode. + bool RequireClosedFigure(); + + /// + /// Checks if Y axis position may be changed using X axis Crossing property. + /// + /// True if Y axis position may be changed using X axis Crossing property. + bool XAxisCrossingSupported(); + + /// + /// Checks if automatic X axis labels are supported. + /// + /// True if automatic X axis labels are supported. + bool XAxisLabelsSupported(); + + /// + /// Checks if radial grid lines (X axis) are supported by the chart type. + /// + /// True if radial grid lines are supported. + bool RadialGridLinesSupported(); + + /// + /// Gets number of sectors in the circular chart area. + /// + /// Chart area to get number of sectors for. + /// Collection of series. + /// Returns number of sectors in circular chart. + int GetNumerOfSectors(ChartArea area, SeriesCollection seriesCollection); + + /// + /// Get a location of each Y axis in degrees. + /// + /// Chart area to get Y axes locations for. + /// Returns an array of one or more locations of Y axis. + float[] GetYAxisLocations(ChartArea area); + + #endregion // Methods + } + +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/RangeChart.cs b/System.Web.DataVisualization/Common/ChartTypes/RangeChart.cs new file mode 100644 index 000000000..e61b4027e --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/RangeChart.cs @@ -0,0 +1,1820 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: RangeChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: RangeChart, SplineRangeChart +// +// Purpose: Provides 2D/3D drawing and hit testing functionality +// for the Range and SplineRange charts. The Range chart +// displays a range of data by plotting two Y values per +// data point, with each Y value being drawn as a line +// chart. The range between the Y values can then be +// filled with color. Spline Range chart changes the +// default tension of the lines between data points. +// +// Reviewed: AG - Aug 6, 2002 +// AG - Microsoft 6, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web.UI.DataVisualization.Charting; + + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// SplineRangeChart class extends the RangeChart class by + /// providing a different initial tension for the lines. + /// + internal class SplineRangeChart : RangeChart + { + #region Constructor + + /// + /// Default constructor. + /// + public SplineRangeChart() + { + // Set default line tension + base.lineTension = 0.5f; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + public override string Name { get{ return ChartTypeNames.SplineRange;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Default tension method + + /// + /// Gets default line tension. + /// + /// Default line tension. + override protected float GetDefaultTension() + { + return 0.5f; + } + + /// + /// Checks if line tension is supported by the chart type. + /// + /// True if line tension is supported. + protected override bool IsLineTensionSupported() + { + return true; + } + + #endregion + } + + /// + /// RangeChart class provides 2D/3D drawing and hit testing + /// functionality for the Range and SplineRange charts. The + /// only difference of the SplineRange chart is the default + /// tension of the line. + /// + /// SplineChart base class provides most of the functionality + /// like drawing lines, labels and markers. + /// + internal class RangeChart : SplineChart + { + #region Fields + + /// + /// Fields used to fill area with gradient + /// + internal bool gradientFill = false; + + /// + /// Shape of the low values + /// + internal GraphicsPath areaBottomPath = new GraphicsPath(); + + /// + /// Coordinates of the area path + /// + protected GraphicsPath areaPath = null; + + /// + /// Reference to the current series object + /// + private Series _series = null; + + /// + /// Array of low line values + /// + internal PointF[] lowPoints = null; + + /// + /// Check if series are indexed based + /// + internal bool indexedBasedX = false; + + /// + /// Secondary Y coordinate that should be used for bottom line of the range (left point) + /// + private float _thirdPointY2Value = float.NaN; + + /// + /// Secondary Y coordinate that should be used for bottom line of the range (right point) + /// + private float _fourthPointY2Value = float.NaN; + + #endregion + + #region Constructor + + /// + /// Default constructor. + /// + public RangeChart() + { + this.drawOutsideLines = true; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + public override string Name { get{ return ChartTypeNames.Range;}} + + /// + /// Number of supported Y value(s) per point + /// + override public int YValuesPerPoint { get { return 2; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + override public bool ExtraYValuesConnectedToYAxis{ get { return true; } } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + override public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Default tension method + + /// + /// Gets default line tension. + /// + /// Line tension. + override protected float GetDefaultTension() + { + return 0.0f; + } + + /// + /// Checks if line tension is supported by the chart type. + /// + /// True if line tension is supported. + protected override bool IsLineTensionSupported() + { + return false; + } + + #endregion + + #region Painting and Selection related methods + + /// + /// Fills last series area with gradient. + /// If gradient is used as a back color of the series it must be drawn + /// at the same time. + /// + /// The Chart Graphics object. + private void FillLastSeriesGradient(ChartGraphics graph) + { + // Add last line in the path + if(areaPath != null) + { + areaPath.AddLine( + areaPath.GetLastPoint().X, + areaPath.GetLastPoint().Y, + areaPath.GetLastPoint().X, + areaBottomPath.GetLastPoint().Y); + } + + // Fill whole area with gradient + if(gradientFill && areaPath != null) + { + // Set clip region + graph.SetClip( Area.PlotAreaPosition.ToRectangleF() ); + + // Create new path from high/low lines + using (GraphicsPath gradientPath = new GraphicsPath()) + { + gradientPath.AddPath(areaPath, true); + areaBottomPath.Reverse(); + gradientPath.AddPath(areaBottomPath, true); + + // Create brush + using (Brush areaGradientBrush = graph.GetGradientBrush(gradientPath.GetBounds(), this._series.Color, this._series.BackSecondaryColor, this._series.BackGradientStyle)) + { + // Fill area with gradient + graph.FillPath(areaGradientBrush, gradientPath); + gradientFill = false; + } + } + + // Reset clip region + graph.ResetClip(); + } + if(areaPath != null) + { + areaPath.Dispose(); + areaPath = null; + } + + // Reset bottom area path + areaBottomPath.Reset(); + } + + /// + /// This method recalculates position of the end points of lines. This method + /// is used from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + protected override void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + gradientFill = false; + lowPoints = null; + + // Check if series is indexed based + indexedBasedX = ChartHelper.IndexedSeries(common, area.GetSeriesFromChartType(this.Name).ToArray()); + + // Call base class + base.ProcessChartType(selection, graph, common, area, seriesToDraw); + + // Fill gradient fro the previous series + FillLastSeriesGradient(graph); + } + + /// + /// Override line drawing method to fill the range and draw lines. + /// + /// Graphics object. + /// The Common elements object. + /// Point to draw the line for. + /// Point series. + /// Array of oints coordinates. + /// Index of point to draw. + /// Line tension. + override protected void DrawLine( + ChartGraphics graph, + CommonElements common, + DataPoint point, + Series series, + PointF[] points, + int pointIndex, + float tension) + { + // Two Y values required + if(point.YValues.Length < 2) + { + throw(new InvalidOperationException( SR.ExceptionChartTypeRequiresYValues( this.Name, "2" ))); + } + + // Start drawing from the second point + if(pointIndex <= 0) + { + return; + } + + // Do nothing for the low values line + if(this.YValueIndex == 1) + { + return; + } + + // Check if its a beginning of a new series + if(this._series != null) + { + if(this._series.Name != series.Name) + { + // Fill gradient from the previous series + FillLastSeriesGradient(graph); + this._series = series; + lowPoints = null; + areaBottomPath.Reset(); + } + } + else + { + this._series = series; + } + + // Fill array of lower points of the range + if(lowPoints == null) + { + this.YValueIndex = 1; + lowPoints = GetPointsPosition(graph, series, indexedBasedX); + this.YValueIndex = 0; + } + + // Calculate points position + PointF highPoint1 = points[pointIndex-1]; + PointF highPoint2 = points[pointIndex]; + PointF lowPoint1 = lowPoints[pointIndex-1]; + PointF lowPoint2 = lowPoints[pointIndex]; + + // Create area brush + Brush areaBrush = null; + if( point.BackHatchStyle != ChartHatchStyle.None ) + { + areaBrush = graph.GetHatchBrush( point.BackHatchStyle, point.Color, point.BackSecondaryColor); + } + else if( point.BackGradientStyle != GradientStyle.None ) + { + this.gradientFill = true; + this._series = point.series; + } + else if( point.BackImage.Length > 0 && point.BackImageWrapMode != ChartImageWrapMode.Unscaled && point.BackImageWrapMode != ChartImageWrapMode.Scaled) + { + areaBrush = graph.GetTextureBrush(point.BackImage, point.BackImageTransparentColor, point.BackImageWrapMode, point.Color ); + } + else + { + areaBrush = new SolidBrush(point.Color); + } + + // Calculate data point area segment path + GraphicsPath path = new GraphicsPath(); + path.AddLine(highPoint1.X, lowPoint1.Y, highPoint1.X, highPoint1.Y); + if(this.lineTension == 0) + { + path.AddLine(points[pointIndex-1], points[pointIndex]); + } + else + { + path.AddCurve(points, pointIndex-1, 1, this.lineTension); + } + + path.AddLine(highPoint2.X, highPoint2.Y, highPoint2.X, lowPoint2.Y); + + // Because of SVG Rendering order of points in the close shape + // has to be respected. + if( graph.ActiveRenderingType == RenderingType.Svg ) + { + using (GraphicsPath pathReverse = new GraphicsPath()) + { + // Add curve to the new graphics path + if (this.lineTension == 0) + { + path.AddLine(lowPoints[pointIndex - 1], lowPoints[pointIndex]); + } + else + { + pathReverse.AddCurve(lowPoints, pointIndex - 1, 1, this.lineTension); + + // Convert to polygon + pathReverse.Flatten(); + + // Reversed points order in the aray + PointF[] pointsReversed = pathReverse.PathPoints; + PointF[] pointF = new PointF[pointsReversed.Length]; + int pntIndex = pointsReversed.Length - 1; + foreach (PointF pp in pointsReversed) + { + pointF[pntIndex] = pp; + pntIndex--; + } + + // Path can not have polygon width two points + if (pointF.Length == 2) + { + PointF[] newPointF = new PointF[3]; + newPointF[0] = pointF[0]; + newPointF[1] = pointF[1]; + newPointF[2] = pointF[1]; + pointF = newPointF; + } + + // Add Polygon to the path + path.AddPolygon(pointF); + } + } + } + else + { + if(this.lineTension == 0) + { + path.AddLine(lowPoints[pointIndex-1], lowPoints[pointIndex]); + } + else + { + path.AddCurve(lowPoints, pointIndex-1, 1, this.lineTension); + } + + } + + // Check if bottom line is partialy in the data scaleView + if(!clipRegionSet) + { + double xValue = (indexedSeries) ? pointIndex + 1 : series.Points[pointIndex].XValue; + double xPrevValue = (indexedSeries) ? pointIndex : series.Points[pointIndex - 1].XValue; + if(xPrevValue < hAxisMin || xPrevValue > hAxisMax || + xValue > hAxisMax || xValue < hAxisMin || + series.Points[pointIndex-1].YValues[1] < vAxisMin || series.Points[pointIndex-1].YValues[1] > vAxisMax || + series.Points[pointIndex].YValues[1] < vAxisMin || series.Points[pointIndex].YValues[1] > vAxisMax ) + { + // Set clipping region for bottom line drawing + graph.SetClip( Area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + } + + // Draw shadow + if(series.ShadowColor != Color.Empty && series.ShadowOffset != 0) + { + if(point.Color != Color.Empty && point.Color != Color.Transparent) + { + // Translate drawing matrix + Matrix translateMatrix = graph.Transform.Clone(); + translateMatrix.Translate(series.ShadowOffset, series.ShadowOffset); + Matrix oldMatrix = graph.Transform; + graph.Transform = translateMatrix; + + Region shadowRegion = new Region(path); + using (Brush shadowBrush = new SolidBrush((series.ShadowColor.A != 255) ? series.ShadowColor : Color.FromArgb(point.Color.A / 2, series.ShadowColor))) + { + Region clipRegion = null; + if (!graph.IsClipEmpty && !graph.Clip.IsInfinite(graph.Graphics)) + { + clipRegion = graph.Clip; + clipRegion.Translate(series.ShadowOffset + 1, series.ShadowOffset + 1); + graph.Clip = clipRegion; + + } + + // Fill region + graph.FillRegion(shadowBrush, shadowRegion); + + // Draw leftmost and rightmost vertical lines + using (Pen areaLinePen = new Pen(shadowBrush, 1)) + { + if (pointIndex == 0) + { + graph.DrawLine(areaLinePen, highPoint1.X, lowPoint1.Y, highPoint1.X, highPoint1.Y); + } + if (pointIndex == series.Points.Count - 1) + { + graph.DrawLine(areaLinePen, highPoint2.X, highPoint2.Y, highPoint2.X, lowPoint2.Y); + } + } + + // Restore graphics parameters + graph.Transform = oldMatrix; + + // Draw high and low line shadows + this.drawShadowOnly = true; + base.DrawLine(graph, common, point, series, points, pointIndex, tension); + this.YValueIndex = 1; + base.DrawLine(graph, common, point, series, lowPoints, pointIndex, tension); + this.YValueIndex = 0; + this.drawShadowOnly = false; + + // Restore clip region + if (clipRegion != null) + { + clipRegion = graph.Clip; + clipRegion.Translate(-(series.ShadowOffset + 1), -(series.ShadowOffset + 1)); + graph.Clip = clipRegion; + } + } + } + } + + // Draw area + if(!gradientFill) + { + // Turn off anti aliasing and fill area + SmoothingMode oldMode = graph.SmoothingMode; + graph.SmoothingMode = SmoothingMode.None; + path.CloseAllFigures(); + graph.FillPath(areaBrush, path); + graph.SmoothingMode = oldMode; + + // Draw top and bottom lines, because anti aliasing is not working for the FillPath method + if(graph.SmoothingMode != SmoothingMode.None) + { + Pen areaLinePen = new Pen(areaBrush, 1); + + // This code is introduce because of problem + // with Svg and Hatch Color + HatchBrush hatchBrush = areaBrush as HatchBrush; + if( hatchBrush != null ) + { + areaLinePen.Color = hatchBrush.ForegroundColor; + } + + if(pointIndex == 0) + { + graph.DrawLine(areaLinePen, highPoint1.X, lowPoint1.Y, highPoint1.X, highPoint1.Y); + } + if(pointIndex == series.Points.Count - 1) + { + graph.DrawLine(areaLinePen, highPoint2.X, highPoint2.Y, highPoint2.X, lowPoint2.Y); + } + + if(this.lineTension == 0) + { + graph.DrawLine(areaLinePen, points[pointIndex - 1], points[pointIndex]); + } + else + { + graph.DrawCurve(areaLinePen, points, pointIndex-1, 1, this.lineTension); + } + + if(this.lineTension == 0) + { + graph.DrawLine(areaLinePen, lowPoints[pointIndex - 1], lowPoints[pointIndex]); + } + else + { + graph.DrawCurve(areaLinePen, lowPoints, pointIndex-1, 1, this.lineTension); + } + } + } + + // Add first line + if(areaPath == null) + { + areaPath = new GraphicsPath(); + areaPath.AddLine(highPoint1.X, lowPoint1.Y, highPoint1.X, highPoint1.Y); + } + + // Add line to the gradient path + if(this.lineTension == 0) + { + areaPath.AddLine(points[pointIndex-1], points[pointIndex]); + } + else + { + areaPath.AddCurve(points, pointIndex-1, 1, this.lineTension); + } + + if(this.lineTension == 0) + { + areaBottomPath.AddLine(lowPoints[pointIndex-1], lowPoints[pointIndex]); + } + else + { + areaBottomPath.AddCurve(lowPoints, pointIndex-1, 1, this.lineTension); + } + + // Draw range High and Low border lines + if((point.BorderWidth > 0 && + point.BorderDashStyle != ChartDashStyle.NotSet && + point.BorderColor != Color.Empty) || + areaBrush is SolidBrush) + { + this.useBorderColor = true; + this.disableShadow = true; + base.DrawLine(graph, common, point, series, points, pointIndex, tension); + this.YValueIndex = 1; + base.DrawLine(graph, common, point, series, lowPoints, pointIndex, tension); + this.YValueIndex = 0; + this.useBorderColor = false; + this.disableShadow = false; + } + + if( common.ProcessModeRegions ) + { + //************************************************************** + //** Add area for the inside of the area + //************************************************************** + + path.AddLine(highPoint1.X, lowPoint1.Y, highPoint1.X, highPoint1.Y); + if(this.lineTension == 0) + { + path.AddLine(points[pointIndex-1], points[pointIndex]); + } + else + { + path.AddCurve(points, pointIndex-1, 1, this.lineTension); + } + path.AddLine(highPoint2.X, highPoint2.Y, highPoint2.X, lowPoint2.Y); + if(this.lineTension == 0) + { + path.AddLine(lowPoints[pointIndex-1], lowPoints[pointIndex]); + } + else + { + path.AddCurve(lowPoints, pointIndex-1, 1, this.lineTension); + } + + // Create grapics path object dor the curved area + GraphicsPath mapAreaPath = new GraphicsPath(); + mapAreaPath.AddLine(highPoint1.X, lowPoint1.Y, highPoint1.X, highPoint1.Y); + if(this.lineTension == 0) + { + mapAreaPath.AddLine(points[pointIndex - 1], points[pointIndex]); + } + else + { + mapAreaPath.AddCurve(points, pointIndex-1, 1, this.lineTension); + mapAreaPath.Flatten(); + } + mapAreaPath.AddLine(highPoint2.X, highPoint2.Y, highPoint2.X, lowPoint2.Y); + if(this.lineTension == 0) + { + mapAreaPath.AddLine(lowPoints[pointIndex - 1], lowPoints[pointIndex]); + } + else + { + mapAreaPath.AddCurve(lowPoints, pointIndex-1, 1, this.lineTension); + mapAreaPath.Flatten(); + } + + // Allocate array of floats + PointF pointNew = PointF.Empty; + float[] coord = new float[mapAreaPath.PointCount * 2]; + PointF[] pathPoints = mapAreaPath.PathPoints; + for( int i = 0; i < mapAreaPath.PointCount; i++ ) + { + pointNew = graph.GetRelativePoint( pathPoints[i] ); + coord[2*i] = pointNew.X; + coord[2*i + 1] = pointNew.Y; + } + + common.HotRegionsList.AddHotRegion( + mapAreaPath, + false, + coord, + point, + series.Name, + pointIndex ); + + } + //Clean up + if (areaBrush != null) + areaBrush.Dispose(); + if (path != null) + { + path.Dispose(); + path = null; + } + + } + + + #endregion + + #region 3D painting and selection methods + + /// + /// Draws a 3D surface connecting the two specified points in 2D space. + /// Used to draw Line based charts. + /// + /// Chart area reference. + /// Chart graphics. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Previous data point object. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Array of points. + /// Index of point to draw. + /// Index of points loop. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Darkenning scale for top surface. 0 - None. + /// Darkenning scale for bottom surface. 0 - None. + /// Position where the third point is actually located or float.NaN if same as in "firstPoint". + /// Position where the fourth point is actually located or float.NaN if same as in "secondPoint". + /// Indicates that drawn segment is 3D clipped. Only top/bottom should be drawn. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + protected override GraphicsPath Draw3DSurface( + ChartArea area, + ChartGraphics graph, + Matrix3D matrix, + LightStyle lightStyle, + DataPoint3D prevDataPointEx, + float positionZ, + float depth, + ArrayList points, + int pointIndex, + int pointLoopIndex, + float tension, + DrawingOperationTypes operationType, + float topDarkening, + float bottomDarkening, + PointF thirdPointPosition, + PointF fourthPointPosition, + bool clippedSegment) + { + // Create graphics path for selection + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + + //**************************************************************** + //** Find line first and second points. + //**************************************************************** + + // Check if points are drawn from sides to center (do only once) + if(centerPointIndex == int.MaxValue) + { + centerPointIndex = GetCenterPointIndex(points); + } + + //************************************************************ + //** Find line first & second points + //************************************************************ + DataPoint3D secondPoint = (DataPoint3D)points[pointIndex]; + int pointArrayIndex = pointIndex; + DataPoint3D firstPoint = ChartGraphics.FindPointByIndex( + points, + secondPoint.index - 1, + (this.multiSeries) ? secondPoint : null, + ref pointArrayIndex); + + //**************************************************************** + //** Switch first and second points. + //**************************************************************** + bool reversed = false; + if(firstPoint.index > secondPoint.index) + { + DataPoint3D tempPoint = firstPoint; + firstPoint = secondPoint; + secondPoint = tempPoint; + reversed = true; + } + + + // Points can be drawn from sides to the center. + // In this case can't use index in the list to find first point. + // Use point series and real point index to find the first point. + // Get required point index + if(matrix.Perspective != 0 && centerPointIndex != int.MaxValue) + { + pointArrayIndex = pointIndex; + if( pointIndex != (centerPointIndex + 1)) + { + firstPoint = ChartGraphics.FindPointByIndex(points, secondPoint.index - 1, (this.multiSeries) ? secondPoint : null, ref pointArrayIndex); + } + else + { + if (!area.ReverseSeriesOrder) + { + secondPoint = ChartGraphics.FindPointByIndex(points, firstPoint.index + 1, (this.multiSeries) ? secondPoint : null, ref pointArrayIndex); + } + else + { + firstPoint = secondPoint; + secondPoint = ChartGraphics.FindPointByIndex(points, secondPoint.index - 1, (this.multiSeries) ? secondPoint : null, ref pointArrayIndex); + } + } + } + + // Check if points are not null + if(firstPoint == null || secondPoint == null) + { + return resultPath; + } + + + // Area point is drawn as one segment + return Draw3DSurface( firstPoint, secondPoint, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, LineSegmentType.Single, + topDarkening, bottomDarkening, + thirdPointPosition, fourthPointPosition, + clippedSegment, + true, true); + } + + /// + /// Draws a 3D surface connecting the two specified points in 2D space. + /// Used to draw Line based charts. + /// + /// First data point. + /// Second data point. + /// Points are in reversed order. + /// Chart area reference. + /// Chart graphics. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Previous data point object. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Array of points. + /// Index of point to draw. + /// Index of points loop. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Define surface segment type if it consists of several segments. + /// Darkenning scale for top surface. 0 - None. + /// Darkenning scale for bottom surface. 0 - None. + /// Position where the third point is actually located or float.NaN if same as in "firstPoint". + /// Position where the fourth point is actually located or float.NaN if same as in "secondPoint". + /// Indicates that drawn segment is 3D clipped. Only top/bottom should be drawn. + /// Indicates that top segment line should be clipped to the pkot area. + /// Indicates that bottom segment line should be clipped to the pkot area. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + protected override GraphicsPath Draw3DSurface( + DataPoint3D firstPoint, + DataPoint3D secondPoint, + bool reversed, + ChartArea area, + ChartGraphics graph, + Matrix3D matrix, + LightStyle lightStyle, + DataPoint3D prevDataPointEx, + float positionZ, + float depth, + ArrayList points, + int pointIndex, + int pointLoopIndex, + float tension, + DrawingOperationTypes operationType, + LineSegmentType surfaceSegmentType, + float topDarkening, + float bottomDarkening, + PointF thirdPointPosition, + PointF fourthPointPosition, + bool clippedSegment, + bool clipOnTop, + bool clipOnBottom) + { + // Create graphics path for selection + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + // Fint point with line properties + DataPoint3D pointAttr = secondPoint; + if(prevDataPointEx.dataPoint.IsEmpty) + { + pointAttr = prevDataPointEx; + } + else if(firstPoint.index > secondPoint.index) + { + pointAttr = firstPoint; + } + + //**************************************************************** + //** Adjust point visual properties. + //**************************************************************** + Color color = (useBorderColor) ? pointAttr.dataPoint.BorderColor : pointAttr.dataPoint.Color; + ChartDashStyle dashStyle = pointAttr.dataPoint.BorderDashStyle; + if( pointAttr.dataPoint.IsEmpty && pointAttr.dataPoint.Color == Color.Empty) + { + color = Color.Gray; + } + if( pointAttr.dataPoint.IsEmpty && pointAttr.dataPoint.BorderDashStyle == ChartDashStyle.NotSet ) + { + dashStyle = ChartDashStyle.Solid; + } + + //**************************************************************** + //** Get axis position + //**************************************************************** + float axisPosition = (float)VAxis.GetPosition(this.VAxis.Crossing); + + + //**************************************************************** + //** Calculate position of top/bootom points. + //**************************************************************** + PointF thirdPoint, fourthPoint; + GetBottomPointsPosition( + Common, + area, + axisPosition, + ref firstPoint, + ref secondPoint, + out thirdPoint, + out fourthPoint); + + // Check if point's position provided as parameter + if(!float.IsNaN(thirdPointPosition.Y)) + { + thirdPoint.Y = thirdPointPosition.Y; + } + if(!float.IsNaN(fourthPointPosition.Y)) + { + fourthPoint.Y = fourthPointPosition.Y; + } + + + //**************************************************************** + //** Check if top/bottom lines of range segment intersect. + //**************************************************************** + double smallDouble = 0.0001; + if (Math.Abs(firstPoint.yPosition - (double)thirdPoint.Y) > smallDouble && + Math.Abs(secondPoint.yPosition - (double)fourthPoint.Y) > smallDouble && + ((firstPoint.yPosition > thirdPoint.Y && secondPoint.yPosition < fourthPoint.Y) || + (firstPoint.yPosition < thirdPoint.Y && secondPoint.yPosition > fourthPoint.Y))) + { + // This feature is not supported in 3D SplineRange chart type + if(tension != 0f) + { + throw (new InvalidOperationException(SR.Exception3DSplineY1ValueIsLessThenY2)); + } + + // Find intersection point + PointF intersectionCoordinates = ChartGraphics.GetLinesIntersection( + (float)firstPoint.xPosition, (float)firstPoint.yPosition, + (float)secondPoint.xPosition, (float)secondPoint.yPosition, + thirdPoint.X, thirdPoint.Y, + fourthPoint.X, fourthPoint.Y); + DataPoint3D intersectionPoint = new DataPoint3D(); + intersectionPoint.xPosition = intersectionCoordinates.X; + intersectionPoint.yPosition = intersectionCoordinates.Y; + + // Check if intersection point is valid + bool splitDraw = true; + if( double.IsNaN(intersectionCoordinates.X) || + double.IsNaN(intersectionCoordinates.Y) ) + { + splitDraw = false; + } + else + { + if( (decimal)intersectionCoordinates.X == (decimal)firstPoint.xPosition && + (decimal)intersectionCoordinates.Y == (decimal)firstPoint.yPosition ) + { + splitDraw = false; + } + if( (decimal)intersectionCoordinates.X == (decimal)secondPoint.xPosition && + (decimal)intersectionCoordinates.Y == (decimal)secondPoint.yPosition ) + { + splitDraw = false; + } + } + + if(splitDraw) + { + // Check if reversed drawing order required + reversed = false; + if((pointIndex + 1) < points.Count) + { + DataPoint3D p = (DataPoint3D)points[pointIndex + 1]; + if(p.index == firstPoint.index) + { + reversed = true; + } + } + + // Draw two segments + for(int segmentIndex = 0; segmentIndex <= 1; segmentIndex++) + { + GraphicsPath segmentPath = null; + if(segmentIndex == 0 && !reversed || + segmentIndex == 1 && reversed) + { + // Set coordinates of bottom points + _fourthPointY2Value = (float)intersectionPoint.yPosition; + + // Draw first segment + intersectionPoint.dataPoint = secondPoint.dataPoint; + intersectionPoint.index = secondPoint.index; + segmentPath = Draw3DSurface( firstPoint, intersectionPoint, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, surfaceSegmentType, + topDarkening, bottomDarkening, + new PointF(float.NaN, float.NaN), + new PointF(float.NaN, float.NaN), + clippedSegment, + true, true); + } + + if(segmentIndex == 1 && !reversed || + segmentIndex == 0 && reversed) + { + // Set coordinates of bottom points + _thirdPointY2Value = (float)intersectionPoint.yPosition; + + // Draw second segment + intersectionPoint.dataPoint = firstPoint.dataPoint; + intersectionPoint.index = firstPoint.index; + segmentPath = Draw3DSurface( intersectionPoint, secondPoint, reversed, + area, graph, matrix, lightStyle, prevDataPointEx, + positionZ, depth, points, pointIndex, pointLoopIndex, + tension, operationType, surfaceSegmentType, + topDarkening, bottomDarkening, + new PointF(float.NaN, float.NaN), + new PointF(float.NaN, float.NaN), + clippedSegment, + true, true); + } + + // Add segment path + if(resultPath != null && segmentPath != null && segmentPath.PointCount > 0) + { + resultPath.AddPath(segmentPath, true); + } + + // Reset bottom line "forced" Y coordinates + _thirdPointY2Value = float.NaN; + _fourthPointY2Value = float.NaN; + + } + + return resultPath; + } + } + + + //**************************************************************** + //** Detect visibility of the bounding rectangle. + //**************************************************************** + float minX = (float)Math.Min(firstPoint.xPosition, secondPoint.xPosition); + float minY = (float)Math.Min(firstPoint.yPosition, secondPoint.yPosition); + minY = (float)Math.Min(minY, axisPosition); + float maxX = (float)Math.Max(firstPoint.xPosition, secondPoint.xPosition); + float maxY = (float)Math.Max(firstPoint.yPosition, secondPoint.yPosition); + maxY = (float)Math.Max(maxY, axisPosition); + RectangleF position = new RectangleF(minX, minY, maxX - minX, maxY - minY); + SurfaceNames visibleSurfaces = graph.GetVisibleSurfaces(position,positionZ,depth,matrix); + + // Check if area point is drawn upside down. + bool upSideDown = false; + if(firstPoint.yPosition >= thirdPoint.Y && secondPoint.yPosition >= fourthPoint.Y) + { + upSideDown = true; + + // Switch visibility between Top & Bottom surfaces + bool topVisible = ( (visibleSurfaces & SurfaceNames.Top) == SurfaceNames.Top ); + bool bottomVisible = ( (visibleSurfaces & SurfaceNames.Bottom) == SurfaceNames.Bottom ); + visibleSurfaces ^= SurfaceNames.Bottom; + visibleSurfaces ^= SurfaceNames.Top; + if(topVisible) + { + visibleSurfaces |= SurfaceNames.Bottom; + } + if(bottomVisible) + { + visibleSurfaces |= SurfaceNames.Top; + } + } + + // Check Top/Bottom surface visibility + GetTopSurfaceVisibility(area, firstPoint, secondPoint, upSideDown, positionZ, depth, matrix, ref visibleSurfaces); + + // Top and bottom surfaces are always visible for spline range + bool bottomFirst = true; + if(tension != 0f) + { + if( (visibleSurfaces & SurfaceNames.Bottom) == SurfaceNames.Bottom ) + { + bottomFirst = false; + } + if( (visibleSurfaces & SurfaceNames.Bottom) == 0 && + (visibleSurfaces & SurfaceNames.Top) == 0 ) + { + bottomFirst = false; + } + + + visibleSurfaces |= SurfaceNames.Bottom; + visibleSurfaces |= SurfaceNames.Top; + } + + // Round double values to 5 decimals + firstPoint.xPosition = Math.Round(firstPoint.xPosition, 5); + firstPoint.yPosition = Math.Round(firstPoint.yPosition, 5); + secondPoint.xPosition = Math.Round(secondPoint.xPosition, 5); + secondPoint.yPosition = Math.Round(secondPoint.yPosition, 5); + + //**************************************************************** + //** Clip area first and second data points inside + //** the plotting area. + //**************************************************************** + if(ClipTopPoints( + resultPath, + ref firstPoint, + ref secondPoint, + reversed, + area, + graph, + matrix, + lightStyle, + prevDataPointEx, + positionZ, + depth, + points, + pointIndex, + pointLoopIndex, + tension, + operationType, + surfaceSegmentType, + topDarkening, + bottomDarkening + ) == true) + { + return resultPath; + } + + //**************************************************************** + //** Clip area third and fourth data points inside + //** the plotting area. + //**************************************************************** + if(ClipBottomPoints( + resultPath, + ref firstPoint, + ref secondPoint, + ref thirdPoint, + ref fourthPoint, + reversed, + area, + graph, + matrix, + lightStyle, + prevDataPointEx, + positionZ, + depth, + points, + pointIndex, + pointLoopIndex, + tension, + operationType, + surfaceSegmentType, + topDarkening, + bottomDarkening + ) == true) + { + return resultPath; + } + + //**************************************************************** + //** Draw elements of area chart in 2 layers (back & front) + //**************************************************************** + for(int elemLayer = 1; elemLayer <= 2; elemLayer++) + { + // Loop through all surfaces + SurfaceNames[] surfacesOrder = null; + if(bottomFirst) + surfacesOrder = new SurfaceNames[] {SurfaceNames.Back, SurfaceNames.Bottom, SurfaceNames.Top, SurfaceNames.Left, SurfaceNames.Right, SurfaceNames.Front}; + else + surfacesOrder = new SurfaceNames[] {SurfaceNames.Back, SurfaceNames.Top, SurfaceNames.Bottom, SurfaceNames.Left, SurfaceNames.Right, SurfaceNames.Front}; + + LineSegmentType lineSegmentType = LineSegmentType.Middle; + foreach(SurfaceNames currentSurface in surfacesOrder) + { + // Check id surface should be drawn + if (ChartGraphics.ShouldDrawLineChartSurface(area, area.ReverseSeriesOrder, currentSurface, visibleSurfaces, color, + points, firstPoint, secondPoint, this.multiSeries, ref lineSegmentType) != elemLayer) + { + continue; + } + + // Draw only borders of the invisible elements on the back layer + Color surfaceColor = color; + Color surfaceBorderColor = pointAttr.dataPoint.BorderColor; + if(elemLayer == 1) + { + // Draw only if point color is semi-transparent + if(surfaceColor.A == 255) + { + continue; + } + + // Define drawing colors + surfaceColor = Color.Transparent; + if(surfaceBorderColor == Color.Empty) + { + // If border color is emty use color slightly darker than main back color + surfaceBorderColor = ChartGraphics.GetGradientColor( color, Color.Black, 0.2 ); + } + } + + // Draw surfaces + GraphicsPath surfacePath = null; + switch(currentSurface) + { + case(SurfaceNames.Top): + surfacePath = graph.Draw3DSurface( area, matrix, lightStyle, currentSurface, positionZ, depth, + surfaceColor, surfaceBorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + firstPoint, secondPoint, points, pointIndex, + tension, operationType, LineSegmentType.Middle, + (this.showPointLines) ? true : false, false, area.ReverseSeriesOrder, this.multiSeries, 0, true); + break; + case(SurfaceNames.Bottom): + { + // Calculate coordinates + DataPoint3D dp1 = new DataPoint3D(); + dp1.dataPoint = firstPoint.dataPoint; + dp1.index = firstPoint.index; + dp1.xPosition = firstPoint.xPosition; + dp1.yPosition = thirdPoint.Y; + DataPoint3D dp2 = new DataPoint3D(); + dp2.dataPoint = secondPoint.dataPoint; + dp2.index = secondPoint.index; + dp2.xPosition = secondPoint.xPosition; + dp2.yPosition = fourthPoint.Y; + + // Draw surface + surfacePath = graph.Draw3DSurface( area, matrix, lightStyle, currentSurface, positionZ, depth, + surfaceColor, surfaceBorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + dp1, dp2, points, pointIndex, + tension, operationType, LineSegmentType.Middle, + (this.showPointLines) ? true : false, false, area.ReverseSeriesOrder, this.multiSeries, 1, true); + break; + } + + case(SurfaceNames.Left): + { + if(surfaceSegmentType == LineSegmentType.Single || + (!area.ReverseSeriesOrder && surfaceSegmentType == LineSegmentType.First) || + (area.ReverseSeriesOrder && surfaceSegmentType == LineSegmentType.Last)) + { + + // Calculate coordinates + DataPoint3D leftMostPoint = (firstPoint.xPosition <= secondPoint.xPosition) ? firstPoint : secondPoint; + DataPoint3D dp1 = new DataPoint3D(); + dp1.xPosition = leftMostPoint.xPosition; + dp1.yPosition = (firstPoint.xPosition <= secondPoint.xPosition) ? thirdPoint.Y : fourthPoint.Y; + DataPoint3D dp2 = new DataPoint3D(); + dp2.xPosition = leftMostPoint.xPosition;; + dp2.yPosition = leftMostPoint.yPosition; + + // Draw surface + surfacePath = graph.Draw3DSurface( area, matrix, lightStyle, currentSurface, positionZ, depth, + surfaceColor, surfaceBorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + dp1, dp2, points, pointIndex, + 0f, operationType, LineSegmentType.Single, false, true, area.ReverseSeriesOrder, this.multiSeries, 0, true); + + } + break; + } + case(SurfaceNames.Right): + { + if(surfaceSegmentType == LineSegmentType.Single || + (!area.ReverseSeriesOrder && surfaceSegmentType == LineSegmentType.Last) || + (area.ReverseSeriesOrder && surfaceSegmentType == LineSegmentType.First)) + + { + // Calculate coordinates + DataPoint3D rightMostPoint = (secondPoint.xPosition >= firstPoint.xPosition) ? secondPoint : firstPoint; + DataPoint3D dp1 = new DataPoint3D(); + dp1.xPosition = rightMostPoint.xPosition; + dp1.yPosition = (secondPoint.xPosition >= firstPoint.xPosition) ? fourthPoint.Y : thirdPoint.Y; + DataPoint3D dp2 = new DataPoint3D(); + dp2.xPosition = rightMostPoint.xPosition; + dp2.yPosition = rightMostPoint.yPosition; + + // Draw surface + surfacePath = graph.Draw3DSurface( area, matrix, lightStyle, currentSurface, positionZ, depth, + surfaceColor, surfaceBorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + dp1, dp2, points, pointIndex, + 0f, operationType, LineSegmentType.Single, false, true, area.ReverseSeriesOrder, this.multiSeries, 0, true); + } + + break; + } + case(SurfaceNames.Back): + { + // Calculate coordinates + DataPoint3D dp1 = new DataPoint3D(); + dp1.dataPoint = firstPoint.dataPoint; + dp1.index = firstPoint.index; + dp1.xPosition = firstPoint.xPosition; + dp1.yPosition = thirdPoint.Y; + DataPoint3D dp2 = new DataPoint3D(); + dp2.dataPoint = secondPoint.dataPoint; + dp2.index = secondPoint.index; + dp2.xPosition = secondPoint.xPosition; + dp2.yPosition = fourthPoint.Y; + + // Draw surface + surfacePath = Draw3DSplinePolygon( graph, area, positionZ, + surfaceColor, surfaceBorderColor, pointAttr.dataPoint.BorderWidth, + firstPoint, secondPoint, dp2, dp1, points, + tension, operationType, lineSegmentType, + (this.showPointLines) ? true : false); + + break; + } + case(SurfaceNames.Front): + { + + // Calculate coordinates + DataPoint3D dp1 = new DataPoint3D(); + dp1.dataPoint = firstPoint.dataPoint; + dp1.index = firstPoint.index; + dp1.xPosition = firstPoint.xPosition; + dp1.yPosition = thirdPoint.Y; + DataPoint3D dp2 = new DataPoint3D(); + dp2.dataPoint = secondPoint.dataPoint; + dp2.index = secondPoint.index; + dp2.xPosition = secondPoint.xPosition; + dp2.yPosition = fourthPoint.Y; + + // Change segment type for the reversed series order + if (area.ReverseSeriesOrder) + { + if(lineSegmentType == LineSegmentType.First) + { + lineSegmentType = LineSegmentType.Last; + } + else if(lineSegmentType == LineSegmentType.Last) + { + lineSegmentType = LineSegmentType.First; + } + } + + if(surfaceSegmentType != LineSegmentType.Single) + { + if( surfaceSegmentType == LineSegmentType.Middle || + ( surfaceSegmentType == LineSegmentType.First && lineSegmentType != LineSegmentType.First) || + ( surfaceSegmentType == LineSegmentType.Last && lineSegmentType != LineSegmentType.Last) ) + { + lineSegmentType = LineSegmentType.Middle; + } + if(reversed) + { + if(lineSegmentType == LineSegmentType.First) + { + lineSegmentType = LineSegmentType.Last; + } + else if(lineSegmentType == LineSegmentType.Last) + { + lineSegmentType = LineSegmentType.First; + } + } + } + + // Draw surface + surfacePath = Draw3DSplinePolygon( graph, area, positionZ + depth, + surfaceColor, surfaceBorderColor, pointAttr.dataPoint.BorderWidth, + firstPoint, secondPoint, dp2, dp1, points, + tension, operationType, lineSegmentType, + (this.showPointLines) ? true : false); + + break; + } + } + + // Add path of the fully visible surfaces to the result surface + if(elemLayer == 2 && resultPath != null && surfacePath != null && surfacePath.PointCount > 0) + { + resultPath.CloseFigure(); + resultPath.AddPath(surfacePath, true); + } + + } + } + + return resultPath; + } + + /// + /// Gets visibility of the top surface. + /// + /// Chart area object. + /// First data point of the line. + /// Second data point of the line. + /// Indicates that Y values of the data points are below axis line. + /// Z coordinate of the back side of the cube. + /// Cube depth. + /// Coordinate transformation matrix. + /// Surface visibility reference. Initialized with bounary cube visibility. + protected virtual void GetTopSurfaceVisibility( + ChartArea area, + DataPoint3D firstPoint, + DataPoint3D secondPoint, + bool upSideDown, + float positionZ, + float depth, + Matrix3D matrix, + ref SurfaceNames visibleSurfaces) + { + //*********************************************************************** + //** Check Top surface visibility + //*********************************************************************** + // If Top surface visibility in bounding rectangle - do not gurantee angled linde visibility + if( (visibleSurfaces & SurfaceNames.Top) == SurfaceNames.Top) + { + visibleSurfaces ^= SurfaceNames.Top; + } + + // Create top surface coordinates in 3D space + Point3D[] cubePoints = new Point3D[3]; + if (!area.ReverseSeriesOrder) + { + if(!upSideDown && firstPoint.xPosition < secondPoint.xPosition || + upSideDown && firstPoint.xPosition > secondPoint.xPosition) + { + cubePoints[0] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ + depth ); + cubePoints[1] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ ); + cubePoints[2] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ ); + } + else + { + cubePoints[0] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ + depth ); + cubePoints[1] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ ); + cubePoints[2] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ ); + } + } + else + { + if(!upSideDown && secondPoint.xPosition < firstPoint.xPosition || + upSideDown && secondPoint.xPosition > firstPoint.xPosition) + { + cubePoints[0] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ + depth ); + cubePoints[1] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ ); + cubePoints[2] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ ); + } + else + { + cubePoints[0] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ + depth ); + cubePoints[1] = new Point3D( (float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ ); + cubePoints[2] = new Point3D( (float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ ); + } + } + + // Tranform coordinates + matrix.TransformPoints( cubePoints ); + + // Check the top side visibility + if(ChartGraphics.IsSurfaceVisible(cubePoints[0],cubePoints[1],cubePoints[2])) + { + visibleSurfaces |= SurfaceNames.Top; + } + + + //*********************************************************************** + //** Check Bottom surface visibility + //*********************************************************************** + + // Get bottom surface points + PointF thirdPoint, fourthPoint; + GetBottomPointsPosition(area.Common, area, 0, ref firstPoint, ref secondPoint, out thirdPoint, out fourthPoint); + + + // If Bottom surface visibility in bounding rectangle - do not gurantee angled linde visibility + if( (visibleSurfaces & SurfaceNames.Bottom) == SurfaceNames.Bottom) + { + visibleSurfaces ^= SurfaceNames.Bottom; + } + + // Create top surface coordinates in 3D space + cubePoints = new Point3D[3]; + if (!area.ReverseSeriesOrder) + { + if(!upSideDown && firstPoint.xPosition < secondPoint.xPosition || + upSideDown && firstPoint.xPosition > secondPoint.xPosition) + { + cubePoints[0] = new Point3D( (float)firstPoint.xPosition, (float)thirdPoint.Y, positionZ + depth ); + cubePoints[1] = new Point3D( (float)firstPoint.xPosition, (float)thirdPoint.Y, positionZ ); + cubePoints[2] = new Point3D( (float)secondPoint.xPosition, (float)fourthPoint.Y, positionZ ); + } + else + { + cubePoints[0] = new Point3D( (float)secondPoint.xPosition, (float)fourthPoint.Y, positionZ + depth ); + cubePoints[1] = new Point3D( (float)secondPoint.xPosition, (float)fourthPoint.Y, positionZ ); + cubePoints[2] = new Point3D( (float)firstPoint.xPosition, (float)thirdPoint.Y, positionZ ); + } + } + else + { + if(!upSideDown && secondPoint.xPosition < firstPoint.xPosition || + upSideDown && secondPoint.xPosition > firstPoint.xPosition) + { + cubePoints[0] = new Point3D( (float)secondPoint.xPosition, (float)fourthPoint.Y, positionZ + depth ); + cubePoints[1] = new Point3D( (float)secondPoint.xPosition, (float)fourthPoint.Y, positionZ ); + cubePoints[2] = new Point3D( (float)firstPoint.xPosition, (float)thirdPoint.Y, positionZ ); + } + else + { + cubePoints[0] = new Point3D( (float)firstPoint.xPosition, (float)thirdPoint.Y, positionZ + depth ); + cubePoints[1] = new Point3D( (float)firstPoint.xPosition, (float)thirdPoint.Y, positionZ ); + cubePoints[2] = new Point3D( (float)secondPoint.xPosition, (float)fourthPoint.Y, positionZ ); + } + } + + // Tranform coordinates + matrix.TransformPoints( cubePoints ); + + // Check the top side visibility + if(ChartGraphics.IsSurfaceVisible(cubePoints[2],cubePoints[1],cubePoints[0])) + { + visibleSurfaces |= SurfaceNames.Bottom; + } + + } + + /// + /// Gets position ob the bottom points in area chart. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Axis position. + /// First top point coordinates. + /// Second top point coordinates. + /// Returns third bottom point coordinates. + /// Returns fourth bottom point coordinates. + protected virtual void GetBottomPointsPosition( + CommonElements common, + ChartArea area, + float axisPosition, + ref DataPoint3D firstPoint, + ref DataPoint3D secondPoint, + out PointF thirdPoint, + out PointF fourthPoint) + { + // Set active vertical axis + Axis vAxis = area.GetAxis(AxisName.Y, firstPoint.dataPoint.series.YAxisType, firstPoint.dataPoint.series.YSubAxisName); + + // Initialize points using second Y value + float secondYValue = (float)vAxis.GetPosition(firstPoint.dataPoint.YValues[1]); + thirdPoint = new PointF((float)firstPoint.xPosition, secondYValue); + secondYValue = (float)vAxis.GetPosition(secondPoint.dataPoint.YValues[1]); + fourthPoint = new PointF((float)secondPoint.xPosition, secondYValue); + + // Check if "forced" Y values where set + if(!float.IsNaN(_thirdPointY2Value)) + { + thirdPoint.Y = _thirdPointY2Value; + + } + if(!float.IsNaN(_fourthPointY2Value)) + { + fourthPoint.Y = _fourthPointY2Value; + } + } + + /// + /// Draws a 3D polygon defined by 4 points in 2D space. + /// Top and Bottom lines are drawn as splines of specified tension. + /// + /// Chart area reference. + /// Chart graphics. + /// Z position of the back side of the 3D surface. + /// Color of rectangle + /// Border Color + /// Border Width + /// First point. + /// Second point. + /// Third point. + /// Fourth point. + /// Array of points. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// AxisName of line segment. Used for step lines and splines. + /// Thin border will be drawn on all segments. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + internal GraphicsPath Draw3DSplinePolygon( + ChartGraphics graph, + ChartArea area, + float positionZ, + Color backColor, + Color borderColor, + int borderWidth, + DataPoint3D firstPoint, + DataPoint3D secondPoint, + DataPoint3D thirdPoint, + DataPoint3D fourthPoint, + ArrayList points, + float tension, + DrawingOperationTypes operationType, + LineSegmentType lineSegmentType, + bool forceThinBorder) + { + // Check tension parameter + if(tension == 0f) + { + SurfaceNames thinBorderSides = 0; + if(forceThinBorder) + { + thinBorderSides = SurfaceNames.Left | SurfaceNames.Right; + } + + return graph.Draw3DPolygon( area, area.matrix3D, SurfaceNames.Front, positionZ, + backColor, borderColor, borderWidth, + firstPoint, secondPoint, thirdPoint, fourthPoint, + operationType, lineSegmentType, thinBorderSides); + } + + // Create graphics path for selection + bool drawElements = ((operationType & DrawingOperationTypes.DrawElement) == DrawingOperationTypes.DrawElement); + GraphicsPath resultPath = new GraphicsPath(); + + //********************************************************************** + //** Prepare, transform polygon coordinates + //********************************************************************** + + // Get top line path + GraphicsPath topLine = graph.GetSplineFlattenPath( + area, positionZ, + firstPoint, secondPoint, points, tension, false, true, 0); + + // Get bottom line path + GraphicsPath bottomLine = graph.GetSplineFlattenPath( + area, positionZ, + thirdPoint, fourthPoint, points, tension, false, true, 1); + + // Add paths to the result path + resultPath.AddPath(topLine, true); + resultPath.AddPath(bottomLine, true); + resultPath.CloseAllFigures(); + + + //********************************************************************** + //** Define drawing colors + //********************************************************************** + + // Define 3 points polygon + Point3D [] points3D = new Point3D[3]; + points3D[0] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ); + points3D[1] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ); + points3D[2] = new Point3D((float)thirdPoint.xPosition, (float)thirdPoint.yPosition, positionZ); + + // Transform coordinates + area.matrix3D.TransformPoints( points3D ); + + // Get colors + bool topIsVisible = ChartGraphics.IsSurfaceVisible( points3D[0], points3D[1], points3D[2]); + Color polygonColor = area.matrix3D.GetPolygonLight(points3D, backColor, topIsVisible, area.Area3DStyle.Rotation, SurfaceNames.Front, area.ReverseSeriesOrder); + Color surfaceBorderColor = borderColor; + if(surfaceBorderColor == Color.Empty) + { + // If border color is emty use color slightly darker than main back color + surfaceBorderColor = ChartGraphics.GetGradientColor( backColor, Color.Black, 0.2 ); + } + + //********************************************************************** + //** Draw elements if required. + //********************************************************************** + Pen thickBorderPen = null; + if(drawElements) + { + // Remember SmoothingMode and turn off anti aliasing + SmoothingMode oldSmoothingMode = graph.SmoothingMode; + graph.SmoothingMode = SmoothingMode.Default; + + // Draw the polygon + using (Brush brush = new SolidBrush(polygonColor)) + { + graph.FillPath(brush, resultPath); + } + + // Return old smoothing mode + graph.SmoothingMode = oldSmoothingMode; + + // Draw thin polygon border of darker color around the whole polygon + if(forceThinBorder) + { + graph.DrawPath(new Pen(surfaceBorderColor, 1), resultPath); + } + else if(polygonColor.A == 255) + { + graph.DrawPath(new Pen(polygonColor, 1), resultPath); + } + + // Create thick border line pen + thickBorderPen = new Pen(surfaceBorderColor, borderWidth); + thickBorderPen.StartCap = LineCap.Round; + thickBorderPen.EndCap = LineCap.Round; + + // Draw thick Top & Bottom lines + graph.DrawPath(thickBorderPen, topLine); + graph.DrawPath(thickBorderPen, bottomLine); + + // Draw thick Right & Left lines on first & last segments of the line + if(lineSegmentType == LineSegmentType.First) + { + graph.DrawLine(thickBorderPen, topLine.PathPoints[0], bottomLine.GetLastPoint()); + + } + else if(lineSegmentType == LineSegmentType.Last) + { + graph.DrawLine(thickBorderPen, topLine.GetLastPoint(), bottomLine.PathPoints[0]); + } + } + + + // Calculate path for selection + if(resultPath != null && thickBorderPen != null) + { + // Widen result path + try + { + resultPath.Widen(thickBorderPen); + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + } + + return resultPath; + } + + #endregion + + #region IDisposable overrides + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Dispose managed resources + if (this.areaBottomPath != null) + { + this.areaBottomPath.Dispose(); + this.areaBottomPath = null; + } + if (this.areaPath != null) + { + this.areaPath.Dispose(); + this.areaPath = null; + } + } + base.Dispose(disposing); + } + #endregion + + } +} + diff --git a/System.Web.DataVisualization/Common/ChartTypes/RenkoChart.cs b/System.Web.DataVisualization/Common/ChartTypes/RenkoChart.cs new file mode 100644 index 000000000..2f3373814 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/RenkoChart.cs @@ -0,0 +1,722 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: RenkoChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: RenkoChart +// +// Purpose: Renko chart type provides methods for calculations and +// depends on the Range Column chart type to do all the +// drawing. PrepareData method is used to create temporary +// RangeColumn series and fill it with data. Changes are +// then reversed in the UnPrepareData method. +// +// Renko Chart Overview: +// --------------------- +// The Renko charting method is thought to have acquired its name +// from Renga, a Japanese word for bricks. Renko charts isolate the +// underlying price trends by filtering out minor price changes. +// These charts can be very useful for determining major trend lines, +// or support and resistance levels. +// +// Basic trend reversals are signaled with the emergence of a new +// color brick which depends on the choice of colors used in the +// series. Since the Renko chart is used as a trend following aid, +// there are times when Renko charts produce whip saws, giving +// signals near the end of short-lived trends. However, the +// expectation with any trend following technique is that it allows +// you to ride the major portion of any significant trends. +// +// Renko charts are normally based on closing price values. However, +// unless otherwise specified, the value reflected in the chart will +// be the first YValue. You can also specify a box size that +// determines the minimum price change to display in the chart. The +// default box size is calculated from the average share price over +// the charted period. + +// The following should be taken into account when working with Renko +// charts: +// +// - The X values of data points are automatically indexed. +// +// - There is a formula applied to the original data before that data +// gets plotted. This formula changes the number of points in the data, +// and also changes the X and Y values of the data points. +// +// - Due to data being recalculated, we do not recommend setting the +// minimum and/or maximum values for the X axis. This is because it +// cannot be determined how many data points will actually be plotted. +// However, if the axis' Maximum, or Minimum is set, then the Maximum, +// or Minimum properties should use data point index values. +// +// - Data point anchoring, used for annotations, is not supported in +// this type of chart. +// +// Reviewed: AG - Microsoft 7, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel.Design; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else +using System.Web.UI.DataVisualization.Charting; + +using System.Web.UI.DataVisualization.Charting.ChartTypes; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else +namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// RenkoChart class provides methods to perform all nessesary + /// calculations to display Renko chart with the help of the + /// temporary RangeColumn series. This series is created in the + /// PrepareData method and then removed in the UnPrepareData method. + /// + internal class RenkoChart : IChartType + { + #region Methods + + /// + /// Prepares renko chart type for rendering. + /// + /// Series to be prepared. + internal static void PrepareData(Series series) + { + // Check series chart type + if( String.Compare( series.ChartTypeName, ChartTypeNames.Renko, StringComparison.OrdinalIgnoreCase ) != 0 || !series.IsVisible()) + { + return; + } + + // Get reference to the chart control + Chart chart = series.Chart; + if(chart == null) + { + throw (new InvalidOperationException(SR.ExceptionRenkoNullReference)); + } + + // Renko chart may not be combined with any other chart types + ChartArea area = chart.ChartAreas[series.ChartArea]; + foreach (Series currentSeries in chart.Series) + { + if (currentSeries.IsVisible() && currentSeries != series && area == chart.ChartAreas[currentSeries.ChartArea]) + { + throw (new InvalidOperationException(SR.ExceptionRenkoCanNotCobine)); + } + } + + + // Create a temp series which will hold original series data points + Series seriesOriginalData = new Series("RENKO_ORIGINAL_DATA_" + series.Name, series.YValuesPerPoint); + seriesOriginalData.Enabled = false; + seriesOriginalData.IsVisibleInLegend = false; + chart.Series.Add(seriesOriginalData); + foreach(DataPoint dp in series.Points) + { + seriesOriginalData.Points.Add(dp); + } + series.Points.Clear(); + if(series.IsCustomPropertySet("TempDesignData")) + { + seriesOriginalData["TempDesignData"] = "true"; + } + + + // Change renko series type to range column + series["OldXValueIndexed"] = series.IsXValueIndexed.ToString(CultureInfo.InvariantCulture); + series["OldYValuesPerPoint"] = series.YValuesPerPoint.ToString(CultureInfo.InvariantCulture); + series.ChartType = SeriesChartType.RangeColumn; + series.IsXValueIndexed = true; + series.YValuesPerPoint = 2; + + // Calculate date-time interval for indexed series + if(series.ChartArea.Length > 0 && + series.IsXValueDateTime()) + { + // Get X axis connected to the series + Axis xAxis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName); + + // Change interval for auto-calculated interval only + if(xAxis.Interval == 0 && xAxis.IntervalType == DateTimeIntervalType.Auto) + { + // Check if original data has X values set to date-time values and + // calculate min/max X values. + bool nonZeroXValues = false; + double minX = double.MaxValue; + double maxX = double.MinValue; + foreach(DataPoint dp in seriesOriginalData.Points) + { + if(!dp.IsEmpty) + { + if(dp.XValue != 0.0) + { + nonZeroXValues = true; + } + if(dp.XValue > maxX) + { + maxX = dp.XValue; + } + if(dp.XValue < minX) + { + minX = dp.XValue; + } + } + } + + if(nonZeroXValues) + { + // Save flag that axis interval is automatic + series["OldAutomaticXAxisInterval"] = "true"; + + // Calculate and set axis date-time interval + DateTimeIntervalType intervalType = DateTimeIntervalType.Auto; + xAxis.interval = xAxis.CalcInterval(minX, maxX, true, out intervalType, series.XValueType); + xAxis.intervalType = intervalType; + } + } + } + + // Calculate renko bricks data points values + FillRenkoData(series, seriesOriginalData); + } + + /// + /// Remove any changes done while preparing renko chart type for rendering. + /// + /// Series to be un-prepared. + /// True if series was removed from collection. + internal static bool UnPrepareData(Series series) + { + if (series.Name.StartsWith("RENKO_ORIGINAL_DATA_", StringComparison.Ordinal)) + { + // Get reference to the chart control + Chart chart = series.Chart; + if (chart == null) + { + throw (new InvalidOperationException(SR.ExceptionRenkoNullReference)); + } + + // Get original Renko series + Series renkoSeries = chart.Series[series.Name.Substring(20)]; + Series.MovePositionMarkers(renkoSeries, series); + // Copy data back to original Renko series + renkoSeries.Points.Clear(); + if (!series.IsCustomPropertySet("TempDesignData")) + { + foreach (DataPoint dp in series.Points) + { + renkoSeries.Points.Add(dp); + } + } + + // Restore renko series properties + renkoSeries.ChartType = SeriesChartType.Renko; + + bool isXValIndexed; + bool parseSucceed = bool.TryParse(renkoSeries["OldXValueIndexed"], out isXValIndexed); + renkoSeries.IsXValueIndexed = parseSucceed && isXValIndexed; + + int yValsPerPoint; + parseSucceed = int.TryParse(renkoSeries["OldYValuesPerPoint"], NumberStyles.Any, CultureInfo.InvariantCulture, out yValsPerPoint); + + if (parseSucceed) + { + renkoSeries.YValuesPerPoint = yValsPerPoint; + } + + renkoSeries.DeleteCustomProperty("OldXValueIndexed"); + renkoSeries.DeleteCustomProperty("OldYValuesPerPoint"); + + series["OldAutomaticXAxisInterval"] = "true"; + if (renkoSeries.IsCustomPropertySet("OldAutomaticXAxisInterval")) + { + renkoSeries.DeleteCustomProperty("OldAutomaticXAxisInterval"); + + // Reset automatic interval for X axis + if (renkoSeries.ChartArea.Length > 0) + { + // Get X axis connected to the series + ChartArea area = chart.ChartAreas[renkoSeries.ChartArea]; + Axis xAxis = area.GetAxis(AxisName.X, renkoSeries.XAxisType, renkoSeries.XSubAxisName); + + xAxis.interval = 0.0; + xAxis.intervalType = DateTimeIntervalType.Auto; + } + } + + // Remove series from the collection + chart.Series.Remove(series); + return true; + } + + // Remove current box size attribute + if(series.IsCustomPropertySet("CurrentBoxSize")) + { + series.DeleteCustomProperty("CurrentBoxSize"); + } + + return false; + } + + /// + /// Gets box size of the renko chart. + /// + /// Range column chart series used to dispaly the renko chart. + /// Series with original data. + /// Index of the Y value to use. + private static double GetBoxSize(Series series, Series originalData, int yValueIndex) + { + // Check "BoxSize" custom attribute + double boxSize = 1.0; + double percentOfPriceRange = 4.0; + bool roundBoxSize = true; + if(series.IsCustomPropertySet(CustomPropertyName.BoxSize)) + { + string attrValue = series[CustomPropertyName.BoxSize].Trim(); + bool usePercentage = attrValue.EndsWith("%", StringComparison.Ordinal); + if(usePercentage) + { + attrValue = attrValue.Substring(0, attrValue.Length - 1); + } + + try + { + if(usePercentage) + { + percentOfPriceRange = double.Parse(attrValue, CultureInfo.InvariantCulture); + roundBoxSize = false; + } + else + { + boxSize = double.Parse(attrValue, CultureInfo.InvariantCulture); + percentOfPriceRange = 0.0; + } + } + catch + { + throw (new InvalidOperationException(SR.ExceptionRenkoBoxSizeFormatInvalid)); + } + } + + // Calculate box size using the percentage of price range + if(percentOfPriceRange > 0.0) + { + // Set default box size + boxSize = 1.0; + + // Calculate percent of the highest and lowest price difference. + double highest = double.MinValue; + double lowest = double.MaxValue; + foreach(DataPoint dp in originalData.Points) + { + if(!dp.IsEmpty) + { + if(dp.YValues[yValueIndex] > highest) + { + highest = dp.YValues[yValueIndex]; + } + if(dp.YValues[yValueIndex] < lowest) + { + lowest = dp.YValues[yValueIndex]; + } + } + } + + // Calculate box size as percentage of price difference + if(lowest == highest) + { + boxSize = 1.0; + } + else if( (highest - lowest) < 0.000001) + { + boxSize = 0.000001; + } + else + { + boxSize = (highest - lowest) * (percentOfPriceRange / 100.0); + } + + + // Round calculated value + if(roundBoxSize) + { + + double[] availableBoxSizes = new double[] + { 0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 1.0, 2.0, 2.5, 3.0, 4.0, 5.0, 7.5, 10.0, 15.0, 20.0, 25.0, 50.0, 100.0, 200.0, 500.0, 1000.0, 5000.0, 10000.0, 50000.0, 100000.0, 1000000.0, 1000000.0}; + + for(int index = 1; index < availableBoxSizes.Length; index ++) + { + if(boxSize > availableBoxSizes[index - 1] && + boxSize < availableBoxSizes[index]) + { + boxSize = availableBoxSizes[index]; + } + } + } + } + + // Save current box size as a custom attribute of the original series + series["CurrentBoxSize"] = boxSize.ToString(CultureInfo.InvariantCulture); + + return boxSize; + } + + /// + /// Fills range column series with data to draw the renko chart. + /// + /// Range column chart series used to dispaly the renko chart. + /// Series with original data. + private static void FillRenkoData(Series series, Series originalData) + { + // Get index of the Y values used + int yValueIndex = 0; + if(series.IsCustomPropertySet(CustomPropertyName.UsedYValue)) + { + try + { + yValueIndex = int.Parse(series[CustomPropertyName.UsedYValue], CultureInfo.InvariantCulture); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionRenkoUsedYValueFormatInvalid)); + } + + if(yValueIndex >= series.YValuesPerPoint) + { + throw (new InvalidOperationException(SR.ExceptionRenkoUsedYValueOutOfRange)); + } + } + + // Calculate box size + double boxSize = GetBoxSize(series, originalData, yValueIndex); + + // Fill points + double prevLow = double.NaN; + double prevHigh = double.NaN; + int pointIndex = 0; + foreach(DataPoint dataPoint in originalData.Points) + { + if(!dataPoint.IsEmpty) + { + int numberOfBricks = 0; + bool goingUp = true; + + // Check if previus values exists + if(double.IsNaN(prevLow) || double.IsNaN(prevHigh)) + { + prevHigh = dataPoint.YValues[yValueIndex]; + prevLow = dataPoint.YValues[yValueIndex]; + ++pointIndex; + continue; + } + + // Get Up Brick color + Color upBrickColor = Color.Transparent; + string upBrickColorString = dataPoint[CustomPropertyName.PriceUpColor]; + if(upBrickColorString == null) + { + upBrickColorString = series[CustomPropertyName.PriceUpColor]; + } + if(upBrickColorString != null) + { + try + { + ColorConverter colorConverter = new ColorConverter(); + upBrickColor = (Color)colorConverter.ConvertFromString(null, CultureInfo.InvariantCulture, upBrickColorString); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionRenkoUpBrickColorInvalid)); + } + } + + // Check if close value exceeds last brick position by box size + if(dataPoint.YValues[yValueIndex] >= (prevHigh + boxSize)) + { + goingUp = true; + numberOfBricks = (int)Math.Floor((dataPoint.YValues[yValueIndex] - prevHigh) / boxSize); + } + else if(dataPoint.YValues[yValueIndex] <= (prevLow - boxSize)) + { + goingUp = false; + numberOfBricks = (int)Math.Floor((prevLow - dataPoint.YValues[yValueIndex]) / boxSize); + } + + // Add points + while(numberOfBricks > 0) + { + // Create new point + DataPoint newDataPoint = (DataPoint)dataPoint.Clone(); + newDataPoint["OriginalPointIndex"] = pointIndex.ToString(CultureInfo.InvariantCulture); + newDataPoint.series = series; + newDataPoint.YValues = new double[2]; + newDataPoint.XValue = dataPoint.XValue; + newDataPoint.Tag = dataPoint; + if(goingUp) + { + newDataPoint.YValues[1] = prevHigh; + newDataPoint.YValues[0] = prevHigh + boxSize; + prevLow = prevHigh; + prevHigh = prevLow + boxSize; + + // Set renko up brick appearance + newDataPoint.Color = upBrickColor; + if(newDataPoint.BorderWidth < 1) + { + newDataPoint.BorderWidth = 1; + } + if(newDataPoint.BorderDashStyle == ChartDashStyle.NotSet) + { + newDataPoint.BorderDashStyle = ChartDashStyle.Solid; + } + if( (newDataPoint.BorderColor == Color.Empty || newDataPoint.BorderColor == Color.Transparent) && + (newDataPoint.Color == Color.Empty || newDataPoint.Color == Color.Transparent) ) + { + newDataPoint.BorderColor = series.Color; + } + } + else + { + newDataPoint.YValues[1] = prevLow; + newDataPoint.YValues[0] = prevLow - boxSize; + prevHigh = prevLow; + prevLow = prevHigh - boxSize; + } + + // Add renko brick to the range column series + series.Points.Add(newDataPoint); + --numberOfBricks; + } + } + ++pointIndex; + } + } + + #endregion // Methods + + #region Painting and Selection methods + + /// + /// Paint stock chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + // Renko series is never drawn directly. It is replaced with the range column chart. + // See PrepareData method. + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.Renko;}} + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + virtual public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + public bool SideBySideSeries { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return true; } } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint { get { return 1; } } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + #endregion + + #region Y values related methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + return point.YValues[yValueIndex]; + } + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + // NOTE: SmartLabelStyle feature is not supported by this chart type. + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} + diff --git a/System.Web.DataVisualization/Common/ChartTypes/StackedAreaChart.cs b/System.Web.DataVisualization/Common/ChartTypes/StackedAreaChart.cs new file mode 100644 index 000000000..a20586e67 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/StackedAreaChart.cs @@ -0,0 +1,1695 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: StackedAreaChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: StackedAreaChart, HundredPercentStackedAreaChart +// +// Purpose: Stacked area and hundred percent stacked area charts. +// +// Reviewed: AG - Aug 6, 2002 +// AG - Microsoft 7, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web.UI.DataVisualization.Charting; + + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// HundredPercentStackedAreaChart class extends StackedAreaChart class + /// by providing its own algorithm for calculating series data point + /// Y values. It makes sure that total Y value of all data points in a + /// single cluster from all series adds up to 100%. + /// + internal class HundredPercentStackedAreaChart : StackedAreaChart + { + #region Constructor + + /// + /// Default constructor. + /// + public HundredPercentStackedAreaChart() + { + hundredPercentStacked = true; + } + + #endregion + + #region Fields + + // Array of total points values + double[] _totalPerPoint = null; + int _seriesCount = -1; + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.OneHundredPercentStackedArea;}} + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + override public bool HundredPercent{ get{return true;} } + + #endregion + + #region Painting and Selection methods + + /// + /// Paint HundredPercentStackedAreaChart Chart + /// + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Chart series to draw. + override public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + this.Common = common; + // Reset total per point value + _totalPerPoint = null; + _seriesCount = -1; + // Call base class implementation + base.Paint( graph, common, area, seriesToDraw ); + } + + #endregion + + #region Y values related methods + /// + /// Returns series count of same type for given chart area. + /// + /// The common elements + /// The chart area to inspect + /// Series count of same type + private int GetSeriesCount(CommonElements common, ChartArea area) + { + if (_seriesCount == -1) + { + // Get number of series + int seriesCount = 0; + foreach (Series ser in common.DataManager.Series) + { + // Use series of the same type which belong to this area + if (String.Compare(ser.ChartTypeName, Name, true, System.Globalization.CultureInfo.CurrentCulture) == 0 + && ser.ChartArea == area.Name && ser.IsVisible()) + { + ++seriesCount; + } + } + _seriesCount = seriesCount; + } + return _seriesCount; + } + + /// + /// Helper function, which returns the Y value of the point + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + override public double GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex) + { + + // Calculate the totals of all Y values for all series + if(_totalPerPoint == null) + { + // Get number of series + int seriesCount = GetSeriesCount(common, area); + // Fill array of series with this type, which are drawn on this area + Series[] seriesArray = new Series[seriesCount]; + int seriesIndex = 0; + foreach( Series ser in common.DataManager.Series ) + { + // Use series of the same type which belong to this area + if( String.Compare( ser.ChartTypeName, Name, true, System.Globalization.CultureInfo.CurrentCulture ) == 0 + && ser.ChartArea == area.Name && ser.IsVisible()) + { + seriesArray[seriesIndex++] = ser; + } + } + + // Check if series are aligned + common.DataManipulator.CheckXValuesAlignment(seriesArray); + + // Allocate memory for the array + _totalPerPoint = new double[series.Points.Count]; + + // Calculate the total of Y value per point + for(int index = 0; index < series.Points.Count; index++) + { + _totalPerPoint[index] = 0; + foreach( Series ser in seriesArray ) + { + _totalPerPoint[index] += Math.Abs(ser.Points[index].YValues[0]); + } + } + } + + // NOTE: In stacked area chart we need to do processing even if Y value is not set +// if(point.YValues[0] == 0 || point.IsEmpty) +// { +// return 0; +// } + + // Calculate stacked area Y value for 2D chart + if(area.Area3DStyle.Enable3D == false) + { + if (_totalPerPoint[pointIndex] == 0) + { + // Get number of series + int seriesCount = GetSeriesCount(common, area); + return 100.0 / seriesCount; + } + return (point.YValues[0] / _totalPerPoint[pointIndex]) * 100.0; + } + + // Get point Height if pointIndex == -1 + double yValue = double.NaN; + if(yValueIndex == -1) + { + Axis vAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName); + double areaZeroValue = vAxis.Crossing; + yValue = GetYValue(common, area, series, point, pointIndex, 0); + if(area.Area3DStyle.Enable3D && yValue < 0.0) + { + // No negative values support in 3D stacked area chart + yValue = -yValue; + } + if( yValue >= 0 ) + { + if(!double.IsNaN(prevPosY)) + { + areaZeroValue = prevPosY; + } + } + else + { + if(!double.IsNaN(prevNegY)) + { + areaZeroValue = prevNegY; + } + } + + return yValue - areaZeroValue; + } + + + // Loop through all series + prevPosY = double.NaN; + prevNegY = double.NaN; + prevPositionX = double.NaN; + foreach(Series ser in common.DataManager.Series) + { + // Check series of the current chart type & area + if(String.Compare(series.ChartArea, ser.ChartArea, true, System.Globalization.CultureInfo.CurrentCulture) == 0 && + String.Compare(series.ChartTypeName, ser.ChartTypeName, true, System.Globalization.CultureInfo.CurrentCulture) == 0 && + series.IsVisible()) + { + yValue = (ser.Points[pointIndex].YValues[0] / _totalPerPoint[pointIndex]) * 100.0; + + // Fix of bug #677411 - Dev10 3D stacked area throws an exception when casting NaN to decimal + if (double.IsNaN(yValue) && _totalPerPoint[pointIndex] == 0) + { + yValue = 100.0 / GetSeriesCount(common, area); + } + + if(!double.IsNaN(yValue)) + if(area.Area3DStyle.Enable3D && yValue < 0.0) + { + // No negative values support in 3D stacked area chart + yValue = -yValue; + } + { + if(yValue >= 0.0 && !double.IsNaN(prevPosY)) + { + yValue += prevPosY; + } + if(yValue < 0.0 && !double.IsNaN(prevNegY)) + { + yValue += prevNegY; + } + } + + // Exit loop when current series was found + if (String.Compare(series.Name, ser.Name, StringComparison.Ordinal) == 0) + { + break; + } + + // Remenber privious position + if(yValue >= 0.0) + { + prevPosY = yValue; + } + else + { + prevNegY = yValue; + } + prevPositionX = ser.Points[pointIndex].XValue; + if(prevPositionX == 0.0 && ChartHelper.IndexedSeries(series)) + { + prevPositionX = pointIndex + 1; + } + } + } + + // Y value can't be more than a 100% + if(yValue > 100.0) + { + return 100.0; + } + + return yValue; + } + + #endregion + } + + /// + /// StackedAreaChart class extends AreaChart so that chart series are + /// positioned on top of each other. + /// + internal class StackedAreaChart : AreaChart + { + #region Fields + + /// + /// Shape of the previous series + /// + protected GraphicsPath areaBottomPath = new GraphicsPath(); + + /// + /// Previous stacked positive Y values. + /// + protected double prevPosY = double.NaN; + + /// + /// Previous stacked negative Y values. + /// + protected double prevNegY = double.NaN; + + /// + /// Previous X value. + /// + protected double prevPositionX = double.NaN; + + /// + /// Indicates if chart is 100% stacked + /// + protected bool hundredPercentStacked = false; + + #endregion + + #region Constructor + + /// + /// Public constructor. + /// + public StackedAreaChart() + { + multiSeries = true; + COPCoordinatesToCheck = COPCoordinates.X | COPCoordinates.Y; + } + + #endregion + + #region Default tension method + + /// + /// Gets default line tension. + /// + /// Line tension. + override protected float GetDefaultTension() + { + return 0f; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + public override string Name { get{ return ChartTypeNames.StackedArea;}} + + /// + /// True if chart type is stacked + /// + public override bool Stacked { get{ return true;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Painting and Selection methods + + /// + /// Paint Stacked Area Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + public override void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + this.Common = common; + // Set Clip Region + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + + // Draw chart + ProcessChartType( false, graph, common, area, seriesToDraw ); + + // Reset Clip Region + ((ChartGraphics)graph).ResetClip(); + } + + /// + /// This method calculates position of the area and either draws it or checks selection. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + override protected void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw) + { + this.Common = common; + ArrayList prevPointsArray = null; + ArrayList curentPointsArray = null; + + // Prosess 3D chart type + if(area.Area3DStyle.Enable3D) + { + base.ProcessChartType( + selection, + graph, + common, + area, + seriesToDraw); + return; + } + + // Zero X values mode. + bool indexedSeries = ChartHelper.IndexedSeries(this.Common, area.GetSeriesFromChartType(this.Name).ToArray() ); + + // Indicates that the second point loop for drawing lines or labels is required + bool requiresSecondPointLoop = false; + bool requiresThirdPointLoop = false; + + //************************************************************ + //** Loop through all series + //************************************************************ + int seriesPointsNumber = -1; + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with area chart type + if( String.Compare( ser.ChartTypeName, this.Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Reset area shape paths + if(areaPath != null) + { + areaPath.Dispose(); + areaPath = null; + } + areaBottomPath.Reset(); + + // Check that all seres has the same number of points + if(seriesPointsNumber == -1) + { + seriesPointsNumber = ser.Points.Count; + } + else if(seriesPointsNumber != ser.Points.Count) + { + throw (new ArgumentException(SR.ExceptionStackedAreaChartSeriesDataPointsNumberMismatch)); + } + + // Set active horizontal/vertical axis + HAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + VAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + hAxisMin = HAxis.ViewMinimum; + hAxisMax = HAxis.ViewMaximum; + vAxisMin = VAxis.ViewMinimum; + vAxisMax = VAxis.ViewMaximum; + + + // Get axis position + axisPos.X = (float)VAxis.GetPosition(this.VAxis.Crossing); + axisPos.Y = (float)VAxis.GetPosition(this.VAxis.Crossing); + axisPos = graph.GetAbsolutePoint(axisPos); + + // Fill previous series values array + if(curentPointsArray == null) + { + curentPointsArray = new ArrayList(ser.Points.Count); + } + else + { + prevPointsArray = curentPointsArray; + curentPointsArray = new ArrayList(ser.Points.Count); + } + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + // The data points loop + int index = 0; + float prevYValue1 = axisPos.Y; + float prevYValue2 = axisPos.Y; + PointF firstPoint = PointF.Empty; + PointF secondPoint = PointF.Empty; + foreach( DataPoint point in ser.Points ) + { + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Get point value + double yValue = (point.IsEmpty) ? 0.0 : GetYValue(common, area, ser, point, index, 0); + double xValue = (indexedSeries) ? (index + 1.0) : point.XValue; + + // Adjust point position with previous value + if(prevPointsArray != null && index < prevPointsArray.Count) + { + yValue += (double)prevPointsArray[index]; + } + curentPointsArray.Insert(index, yValue); + + // Get point position + float yPosition = (float)VAxis.GetPosition(yValue); + float xPosition = (float)HAxis.GetPosition(xValue); + + // Remeber pre-calculated point position + point.positionRel = new PointF(xPosition, yPosition); + + yValue = VAxis.GetLogValue(yValue); + xValue = HAxis.GetLogValue(xValue); + + // Calculate 2 points to draw area and line + if(firstPoint == PointF.Empty) + { + firstPoint.X = xPosition; + firstPoint.Y = yPosition; + if(prevPointsArray != null && index < prevPointsArray.Count) + { + prevYValue1 = (float)VAxis.GetPosition((double)prevPointsArray[index]); + prevYValue1 = graph.GetAbsolutePoint(new PointF(prevYValue1, prevYValue1)).Y; + } + firstPoint = graph.GetAbsolutePoint(firstPoint); + + ++index; + continue; + } + else + { + secondPoint.X = xPosition; + secondPoint.Y = yPosition; + if(prevPointsArray != null && index < prevPointsArray.Count) + { + prevYValue2 = (float)VAxis.GetPosition((double)prevPointsArray[index]); + prevYValue2 = graph.GetAbsolutePoint(new PointF(prevYValue2, prevYValue2)).Y; + } + secondPoint = graph.GetAbsolutePoint(secondPoint); + } + + // Round X coordinates + firstPoint.X = (float)Math.Round(firstPoint.X); + secondPoint.X = (float)Math.Round(secondPoint.X); + + + // Calculate data point area segment path + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLine(firstPoint.X, firstPoint.Y, secondPoint.X, secondPoint.Y); + path.AddLine(secondPoint.X, secondPoint.Y, secondPoint.X, prevYValue2); + path.AddLine(secondPoint.X, prevYValue2, firstPoint.X, prevYValue1); + path.AddLine(firstPoint.X, prevYValue1, firstPoint.X, firstPoint.Y); + + // Painting mode + if (common.ProcessModePaint) + { + // Get previous point value + double xPrevValue = (indexedSeries) ? (index) : ser.Points[index - 1].XValue; + + // Check if line is completly out of the data scaleView + if ((xValue <= hAxisMin && xPrevValue <= hAxisMin) || + (xValue >= hAxisMax && xPrevValue >= hAxisMax)) + { + // Save previous point + firstPoint = secondPoint; + prevYValue1 = prevYValue2; + + // Increase data point index + ++index; + + continue; + } + + // Create area brush + Brush areaBrush = null; + if (point.BackHatchStyle != ChartHatchStyle.None) + { + areaBrush = graph.GetHatchBrush(point.BackHatchStyle, point.Color, point.BackSecondaryColor); + } + else if (point.BackGradientStyle != GradientStyle.None) + { + this.gradientFill = true; + this.Series = point.series; + } + else if (point.BackImage.Length > 0 && point.BackImageWrapMode != ChartImageWrapMode.Unscaled && point.BackImageWrapMode != ChartImageWrapMode.Scaled) + { + areaBrush = graph.GetTextureBrush(point.BackImage, point.BackImageTransparentColor, point.BackImageWrapMode, point.Color); + } + else if (point.IsEmpty && point.Color == Color.Empty) + { + // Stacked area chart empty points should always use + // series color, otherwise chart will have empty 'holes'. + areaBrush = new SolidBrush(ser.Color); + } + else + { + areaBrush = new SolidBrush(point.Color); + } + + // Check if we need second loop to draw area border + if ((point.BorderColor != Color.Empty && point.BorderWidth > 0)) + { + requiresSecondPointLoop = true; + } + + // Check if we need third loop to draw labels + if (point.Label.Length > 0 || point.IsValueShownAsLabel) + { + requiresThirdPointLoop = true; + } + + // Draw area + if (!this.gradientFill) + { + // Start Svg Selection mode + graph.StartHotRegion(point); + + // Turn off anti aliasing and fill area + SmoothingMode oldMode = graph.SmoothingMode; + graph.SmoothingMode = SmoothingMode.None; + graph.FillPath(areaBrush, path); + graph.SmoothingMode = oldMode; + + // Draw top and bottom lines with antialiasing turned On. + // Process only if line is drawn by an angle + Pen areaLinePen = new Pen(areaBrush, 1); + if (!(firstPoint.X == secondPoint.X || firstPoint.Y == secondPoint.Y)) + { + graph.DrawLine(areaLinePen, firstPoint.X, firstPoint.Y, secondPoint.X, secondPoint.Y); + } + if (!(firstPoint.X == secondPoint.X || prevYValue2 == prevYValue1)) + { + graph.DrawLine(areaLinePen, secondPoint.X, prevYValue2, firstPoint.X, prevYValue1); + } + + // End Svg Selection mode + graph.EndHotRegion(); + } + + if (areaPath == null) + { + areaPath = new GraphicsPath(); + } + areaPath.AddLine(firstPoint.X, firstPoint.Y, secondPoint.X, secondPoint.Y); + areaBottomPath.AddLine(firstPoint.X, prevYValue1, secondPoint.X, prevYValue2); + + //Clean up + if (areaBrush != null) + areaBrush.Dispose(); + } + + if (common.ProcessModeRegions) + { + //************************************************************** + //** Add area for the inside of the area + //************************************************************** + + // Allocate array of floats + PointF pointNew = PointF.Empty; + float[] coord = new float[path.PointCount * 2]; + PointF[] pathPoints = path.PathPoints; + for (int i = 0; i < path.PointCount; i++) + { + pointNew = graph.GetRelativePoint(pathPoints[i]); + coord[2 * i] = pointNew.X; + coord[2 * i + 1] = pointNew.Y; + } + + common.HotRegionsList.AddHotRegion( + path, + false, + coord, + point, + ser.Name, + index); + + //************************************************************** + //** Add area for the top line (with thickness) + //************************************************************** + if (point.BorderWidth > 1 && point.BorderDashStyle != ChartDashStyle.NotSet && point.BorderColor != Color.Empty) + { + // Create grapics path object dor the curve + using (GraphicsPath linePath = new GraphicsPath()) + { + try + { + linePath.AddLine(firstPoint.X, firstPoint.Y, secondPoint.X, secondPoint.Y); + + // Widen the lines to the size of pen plus 2 + linePath.Widen(new Pen(point.Color, point.BorderWidth + 2)); + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + + // Allocate array of floats + pointNew = PointF.Empty; + coord = new float[linePath.PointCount * 2]; + for (int i = 0; i < linePath.PointCount; i++) + { + pointNew = graph.GetRelativePoint(linePath.PathPoints[i]); + coord[2 * i] = pointNew.X; + coord[2 * i + 1] = pointNew.Y; + } + + common.HotRegionsList.AddHotRegion( + linePath, + false, + coord, + point, + ser.Name, + index); + } + } + } + } + // Save previous point + firstPoint = secondPoint; + prevYValue1 = prevYValue2; + + // Increase data point index + ++index; + + } + + // Fill whole series area with gradient + if(gradientFill && areaPath != null) + { + // Create gradient path + using (GraphicsPath gradientPath = new GraphicsPath()) + { + gradientPath.AddPath(areaPath, true); + areaBottomPath.Reverse(); + gradientPath.AddPath(areaBottomPath, true); + + // Create brush + using (Brush areaBrush = graph.GetGradientBrush(gradientPath.GetBounds(), this.Series.Color, this.Series.BackSecondaryColor, this.Series.BackGradientStyle)) + { + // Fill area with gradient + graph.FillPath(areaBrush, gradientPath); + } + } + + areaPath.Dispose(); + areaPath = null; + gradientFill = false; + } + areaBottomPath.Reset(); + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + } + + //************************************************************ + //** Loop through all series/points for the second time + //** Draw border lines. + //************************************************************ + if(requiresSecondPointLoop) + { + prevPointsArray = null; + curentPointsArray = null; + foreach( Series ser in common.DataManager.Series ) + { + if( String.Compare( ser.ChartTypeName, this.Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Set active horizontal/vertical axis + HAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + VAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Get axis position + axisPos.X = (float)VAxis.GetPosition(this.VAxis.Crossing); + axisPos.Y = (float)VAxis.GetPosition(this.VAxis.Crossing); + axisPos = graph.GetAbsolutePoint(axisPos); + + // Fill previous series values array + if(curentPointsArray == null) + { + curentPointsArray = new ArrayList(ser.Points.Count); + } + else + { + prevPointsArray = curentPointsArray; + curentPointsArray = new ArrayList(ser.Points.Count); + } + + // The data points loop + int index = 0; + float prevYValue1 = axisPos.Y; + float prevYValue2 = axisPos.Y; + PointF firstPoint = PointF.Empty; + PointF secondPoint = PointF.Empty; + foreach( DataPoint point in ser.Points ) + { + // Get point value + double yValue = (point.IsEmpty) ? 0.0 : GetYValue(common, area, ser, point, index, 0); + double xValue = (indexedSeries) ? (index + 1.0) : point.XValue; + + // Adjust point position with previous value + if(prevPointsArray != null && index < prevPointsArray.Count) + { + yValue += (double)prevPointsArray[index]; + } + curentPointsArray.Insert(index, yValue); + + // Get point position + float yPosition = (float)VAxis.GetPosition(yValue); + float xPosition = (float)HAxis.GetPosition(xValue); + + + // Calculate 2 points to draw area and line + if(firstPoint == PointF.Empty) + { + firstPoint.X = xPosition; + firstPoint.Y = yPosition; + if(prevPointsArray != null && index < prevPointsArray.Count) + { + prevYValue1 = (float)VAxis.GetPosition((double)prevPointsArray[index]); + prevYValue1 = graph.GetAbsolutePoint(new PointF(prevYValue1, prevYValue1)).Y; + } + firstPoint = graph.GetAbsolutePoint(firstPoint); + secondPoint = firstPoint; + prevYValue2 = prevYValue1; + } + else + { + secondPoint.X = xPosition; + secondPoint.Y = yPosition; + if(prevPointsArray != null && index < prevPointsArray.Count) + { + prevYValue2 = (float)VAxis.GetPosition((double)prevPointsArray[index]); + prevYValue2 = graph.GetAbsolutePoint(new PointF(prevYValue2, prevYValue2)).Y; + } + secondPoint = graph.GetAbsolutePoint(secondPoint); + } + + if(index != 0) + { + // Round X coordinates + firstPoint.X = (float)Math.Round(firstPoint.X); + secondPoint.X = (float)Math.Round(secondPoint.X); + + // Draw border + graph.DrawLineRel(point.BorderColor, point.BorderWidth, point.BorderDashStyle, graph.GetRelativePoint(firstPoint), graph.GetRelativePoint(secondPoint), point.series.ShadowColor, point.series.ShadowOffset ); + } + + // Save previous point + firstPoint = secondPoint; + prevYValue1 = prevYValue2; + + // Increase data point index + ++index; + } + } + } + + //************************************************************ + //** Loop through all series/points for the second time + //** Draw labels. + //************************************************************ + if(requiresThirdPointLoop) + { + prevPointsArray = null; + curentPointsArray = null; + foreach( Series ser in common.DataManager.Series ) + { + if( String.Compare( ser.ChartTypeName, this.Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Set active horizontal/vertical axis + HAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + VAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Get axis position + axisPos.X = (float)VAxis.GetPosition(this.VAxis.Crossing); + axisPos.Y = (float)VAxis.GetPosition(this.VAxis.Crossing); + axisPos = graph.GetAbsolutePoint(axisPos); + + // Fill previous series values array + if(curentPointsArray == null) + { + curentPointsArray = new ArrayList(ser.Points.Count); + } + else + { + prevPointsArray = curentPointsArray; + curentPointsArray = new ArrayList(ser.Points.Count); + } + + // The data points loop + int index = 0; + float prevYValue1 = axisPos.Y; + float prevYValue2 = axisPos.Y; + PointF firstPoint = PointF.Empty; + PointF secondPoint = PointF.Empty; + foreach( DataPoint point in ser.Points ) + { + // Get point value + double yValue = (point.IsEmpty) ? 0.0 : GetYValue(common, area, ser, point, index, 0); + double xValue = (indexedSeries) ? (index + 1.0) : point.XValue; + + // Adjust point position with previous value + if(prevPointsArray != null && index < prevPointsArray.Count) + { + yValue += (double)prevPointsArray[index]; + } + curentPointsArray.Insert(index, yValue); + + // Get point position + float yPosition = (float)VAxis.GetPosition(yValue); + float xPosition = (float)HAxis.GetPosition(xValue); + + + // Calculate 2 points to draw area and line + if(firstPoint == PointF.Empty) + { + firstPoint.X = xPosition; + firstPoint.Y = yPosition; + if(prevPointsArray != null && index < prevPointsArray.Count) + { + prevYValue1 = (float)VAxis.GetPosition((double)prevPointsArray[index]); + prevYValue1 = graph.GetAbsolutePoint(new PointF(prevYValue1, prevYValue1)).Y; + } + firstPoint = graph.GetAbsolutePoint(firstPoint); + secondPoint = firstPoint; + prevYValue2 = prevYValue1; + } + else + { + secondPoint.X = xPosition; + secondPoint.Y = yPosition; + if(prevPointsArray != null && index < prevPointsArray.Count) + { + prevYValue2 = (float)VAxis.GetPosition((double)prevPointsArray[index]); + prevYValue2 = graph.GetAbsolutePoint(new PointF(prevYValue2, prevYValue2)).Y; + } + secondPoint = graph.GetAbsolutePoint(secondPoint); + } + + if(!point.IsEmpty && (ser.IsValueShownAsLabel || point.IsValueShownAsLabel || point.Label.Length > 0)) + { + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // Get label text + string text; + if (point.Label.Length == 0) + { + double pointLabelValue = GetYValue(common, area, ser, point, index, 0); + // Round Y values for 100% stacked area + if (this.hundredPercentStacked && point.LabelFormat.Length == 0) + { + pointLabelValue = Math.Round(pointLabelValue, 2); + } + text = ValueConverter.FormatValue( + ser.Chart, + point, + point.Tag, + pointLabelValue, + point.LabelFormat, + ser.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + } + + // Disable the clip region + Region oldClipRegion = graph.Clip; + graph.Clip = new Region(); + + // Draw label + PointF labelPosition = PointF.Empty; + labelPosition.X = secondPoint.X; + labelPosition.Y = secondPoint.Y - (secondPoint.Y - prevYValue2) / 2f; + labelPosition = graph.GetRelativePoint(labelPosition); + + // Measure string + SizeF sizeFont = graph.GetRelativeSize( + graph.MeasureString( + text, + point.Font, + new SizeF(1000f, 1000f), + StringFormat.GenericTypographic)); + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeFont.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = new RectangleF( + labelPosition.X - sizeLabel.Width / 2, + labelPosition.Y - sizeLabel.Height / 2 - sizeFont.Height / 10, + sizeLabel.Width, + sizeLabel.Height); + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + labelPosition, + format, + point.LabelAngle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + ser, + point, + index); + } + + // Restore old clip region + graph.Clip = oldClipRegion; + } + } + + + // Save previous point + firstPoint = secondPoint; + prevYValue1 = prevYValue2; + + // Increase data point index + ++index; + + } + } + } + } + + #endregion + + #region 3D Drawing and selection methods + + /// + /// Draws a 3D surface connecting the two specified points in 2D space. + /// Used to draw Line based charts. + /// + /// Chart area reference. + /// Chart graphics. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Previous data point object. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Array of points. + /// Index of point to draw. + /// Index of points loop. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Darkenning scale for top surface. 0 - None. + /// Darkenning scale for bottom surface. 0 - None. + /// Position where the third point is actually located or float.NaN if same as in "firstPoint". + /// Position where the fourth point is actually located or float.NaN if same as in "secondPoint". + /// Indicates that drawn segment is 3D clipped. Only top/bottom should be drawn. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + protected override GraphicsPath Draw3DSurface( + ChartArea area, + ChartGraphics graph, + Matrix3D matrix, + LightStyle lightStyle, + DataPoint3D prevDataPointEx, + float positionZ, + float depth, + ArrayList points, + int pointIndex, + int pointLoopIndex, + float tension, + DrawingOperationTypes operationType, + float topDarkening, + float bottomDarkening, + PointF thirdPointPosition, + PointF fourthPointPosition, + bool clippedSegment) + { + // Call base method + + if(pointLoopIndex != 2) + { + return base.Draw3DSurface( + area, + graph, + matrix, + lightStyle, + prevDataPointEx, + positionZ, + depth, + points, + pointIndex, + pointLoopIndex, + tension, + operationType, + topDarkening, + bottomDarkening, + thirdPointPosition, + fourthPointPosition, + clippedSegment); + } + + // Draw labels in the third loop + else + { + DataPoint3D pointEx = ((DataPoint3D)points[pointIndex]); + + // Draw label for the first point + if(pointEx.index == 2) + { + // Get point with prev index + int neighborPointIndex = 0; + DataPoint3D pointPrevEx = ChartGraphics.FindPointByIndex(points, pointEx.index - 1, pointEx, ref neighborPointIndex); + + // Draw labels in the third loop + DrawLabels3D( + area, + graph, + area.Common, + pointPrevEx, + positionZ, + depth); + } + + // Draw labels in the third loop + DrawLabels3D( + area, + graph, + area.Common, + pointEx, + positionZ, + depth); + } + + return new GraphicsPath(); + } + + /// + /// Gets visibility of the top surface. + /// + /// Chart area object. + /// First data point of the line. + /// Second data point of the line. + /// Indicates that Y values of the data points are below axis line. + /// Z coordinate of the back side of the cube. + /// Cube depth. + /// Coordinate transformation matrix. + /// Surface visibility reference. Initialized with bounary cube visibility. + protected override void GetTopSurfaceVisibility( + ChartArea area, + DataPoint3D firstPoint, + DataPoint3D secondPoint, + bool upSideDown, + float positionZ, + float depth, + Matrix3D matrix, + ref SurfaceNames visibleSurfaces) + { + // Call base class method first + base.GetTopSurfaceVisibility(area, firstPoint, secondPoint, upSideDown, + positionZ, depth, matrix, ref visibleSurfaces); + + // Check if the Top surface is overlapped with data point from other series + if( (visibleSurfaces & SurfaceNames.Top) == SurfaceNames.Top ) + { + // Try to find data point with same index from the series above + bool seriesFound = false; + foreach(Series ser in area.Common.DataManager.Series) + { + if(String.Compare(ser.ChartTypeName, secondPoint.dataPoint.series.ChartTypeName, true, System.Globalization.CultureInfo.CurrentCulture) == 0) + { + // If series on top of current was found - check point transparency + if(seriesFound) + { + DataPointCustomProperties pointProperties = ser.Points[secondPoint.index - 1]; + if(ser.Points[secondPoint.index - 1].IsEmpty) + { + pointProperties = ser.EmptyPointStyle; + } + if (pointProperties.Color.A == 255) + { + visibleSurfaces ^= SurfaceNames.Top; + } + break; + } + + // Check series name + if(String.Compare(ser.Name, secondPoint.dataPoint.series.Name, StringComparison.Ordinal) == 0) + { + seriesFound = true; + } + } + } + } + + // Check if the Bottom surface is on top of the transparent data point from other series + if( (visibleSurfaces & SurfaceNames.Bottom) != SurfaceNames.Bottom ) + { + // Try to find data point with same index from the series above + DataPointCustomProperties pointProperties = null; + foreach(Series ser in area.Common.DataManager.Series) + { + if(String.Compare(ser.ChartTypeName, secondPoint.dataPoint.series.ChartTypeName, StringComparison.OrdinalIgnoreCase) == 0) + { + // Check series name + if (pointProperties != null && String.Compare(ser.Name, secondPoint.dataPoint.series.Name, StringComparison.Ordinal) == 0) + { + if (pointProperties.Color.A != 255) + { + visibleSurfaces |= SurfaceNames.Bottom; + } + break; + } + + // Get properties + pointProperties = ser.Points[secondPoint.index - 1]; + if(ser.Points[secondPoint.index - 1].IsEmpty) + { + pointProperties = ser.EmptyPointStyle; + } + } + } + } + + } + + /// + /// Gets position ob the bottom points in area chart. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Axis position. + /// First top point coordinates. + /// Second top point coordinates. + /// Position where the third point is actually located or float.NaN if same as in "firstPoint". + /// Position where the fourth point is actually located or float.NaN if same as in "secondPoint". + /// Returns third bottom point coordinates. + /// Returns fourth bottom point coordinates. + protected override void GetBottomPointsPosition( + CommonElements common, + ChartArea area, + float axisPosition, + ref DataPoint3D firstPoint, + ref DataPoint3D secondPoint, + PointF thirdPointPosition, + PointF fourthPointPosition, + out PointF thirdPoint, + out PointF fourthPoint) + { + // Set active vertical/horizontal axis + Axis vAxis = area.GetAxis(AxisName.Y, firstPoint.dataPoint.series.YAxisType, firstPoint.dataPoint.series.YSubAxisName); + Axis hAxis = area.GetAxis(AxisName.X, firstPoint.dataPoint.series.XAxisType, firstPoint.dataPoint.series.XSubAxisName); + + // Find bottom points position + double yValue = GetYValue(area.Common, area, firstPoint.dataPoint.series, firstPoint.dataPoint, firstPoint.index - 1, 0); + double xValue = (float)firstPoint.xPosition; + if(yValue >= 0.0) + { + if(double.IsNaN(this.prevPosY)) + { + yValue = axisPosition; + } + else + { + yValue = vAxis.GetPosition(this.prevPosY); + xValue = hAxis.GetPosition(this.prevPositionX); + } + } + else + { + if(double.IsNaN(this.prevNegY)) + { + yValue = axisPosition; + } + else + { + yValue = vAxis.GetPosition(this.prevNegY); + xValue = hAxis.GetPosition(this.prevPositionX); + } + } + thirdPoint = new PointF((float)xValue, (float)yValue); + + + yValue = GetYValue(area.Common, area, secondPoint.dataPoint.series, secondPoint.dataPoint, secondPoint.index - 1, 0); + xValue = (float)secondPoint.xPosition; + if(yValue >= 0.0) + { + if(double.IsNaN(this.prevPosY)) + { + yValue = axisPosition; + } + else + { + yValue = vAxis.GetPosition(this.prevPosY); + xValue = hAxis.GetPosition(this.prevPositionX); + } + } + else + { + if(double.IsNaN(this.prevNegY)) + { + yValue = axisPosition; + } + else + { + yValue = vAxis.GetPosition(this.prevNegY); + xValue = hAxis.GetPosition(this.prevPositionX); + } + } + fourthPoint = new PointF((float)xValue, (float)yValue); + + // Check if position of the third and/or fourth point(s) should be adjusted + if(!float.IsNaN(thirdPointPosition.X)) + { + thirdPoint.X = (float)((firstPoint.xCenterVal == 0.0) ? firstPoint.xPosition : firstPoint.xCenterVal); + + // Calculate new Y value as an intersection point of two lines: + // line between current 3d & 4th points and vertical line with X value = thirdPointPositionX. + thirdPoint.Y = (thirdPointPosition.X - fourthPoint.X) / + (thirdPoint.X - fourthPoint.X) * + (thirdPoint.Y - fourthPoint.Y) + + fourthPoint.Y; + + // Set new X value + thirdPoint.X = thirdPointPosition.X; + } + if(!float.IsNaN(thirdPointPosition.Y)) + { + thirdPoint.Y = thirdPointPosition.Y; + } + + if(!float.IsNaN(fourthPointPosition.X)) + { + fourthPoint.X = (float)((secondPoint.xCenterVal == 0.0) ? secondPoint.xPosition : secondPoint.xCenterVal); + + // Calculate new Y value as an intersection point of two lines: + // line between current 3d & 4th points and vertical line with X value = thirdPointPositionX. + fourthPoint.Y = (fourthPointPosition.X - fourthPoint.X) / + (thirdPoint.X - fourthPoint.X) * + (thirdPoint.Y - fourthPoint.Y) + + fourthPoint.Y; + + // Set new X value + fourthPoint.X = fourthPointPosition.X; + } + if(!float.IsNaN(fourthPointPosition.Y)) + { + fourthPoint.Y = fourthPointPosition.Y; + } + + } + + /// + /// Returns how many loops through all data points is required (1 or 2) + /// + /// Selection indicator. + /// Points array list. + /// Number of loops (1 or 2). + override protected int GetPointLoopNumber(bool selection, ArrayList pointsArray) + { + // Always one loop for selection + if(selection) + { + return 1; + } + + // Second loop will be required for semi-transparent colors + int loopNumber = 1; + foreach(object obj in pointsArray) + { + // Get point & series + DataPoint3D pointEx = (DataPoint3D) obj; + + // Check properties + if(pointEx.dataPoint.Color.A != 255) + { + loopNumber = 2; + } + + // Check title + // VSTS fix #529011: 3-d stacked area and 100% stacked area charts do not show data labels. + if( pointEx.dataPoint.Label.Length > 0 || + pointEx.dataPoint.IsValueShownAsLabel || + pointEx.dataPoint.series.IsValueShownAsLabel) + { + // S loops through all data points required + loopNumber = 3; + break; + } + } + + return loopNumber; + } + + /// + /// This method draws labels in point chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Data point 3D. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + private void DrawLabels3D( + ChartArea area, + ChartGraphics graph, + CommonElements common, + DataPoint3D pointEx, + float positionZ, + float depth) + { + // Get some properties for performance + string pointLabel = pointEx.dataPoint.Label; + bool pointShowLabelAsValue = pointEx.dataPoint.IsValueShownAsLabel; + + // **************************** + // Draw data point value label + // **************************** + if((!pointEx.dataPoint.IsEmpty && (pointEx.dataPoint.series.IsValueShownAsLabel || pointShowLabelAsValue || pointLabel.Length > 0)) || + (pointShowLabelAsValue || pointLabel.Length > 0)) + { + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // Get label text + string text; + if (pointLabel.Length == 0) + { + // Round Y values for 100% stacked area + double pointLabelValue = pointEx.dataPoint.YValues[(labelYValueIndex == -1) ? YValueIndex : labelYValueIndex]; + if (this.hundredPercentStacked && pointEx.dataPoint.LabelFormat.Length == 0) + { + pointLabelValue = Math.Round(pointLabelValue, 2); + } + + text = ValueConverter.FormatValue( + pointEx.dataPoint.series.Chart, + pointEx.dataPoint, + pointEx.dataPoint.Tag, + pointLabelValue, + pointEx.dataPoint.LabelFormat, + pointEx.dataPoint.series.YValueType, + ChartElementType.DataPoint); + } + else + { + text = pointEx.dataPoint.ReplaceKeywords(pointLabel); + } + + // Get label position + Point3D[] points = new Point3D[1]; + points[0] = new Point3D((float)pointEx.xPosition, (float)(pointEx.yPosition + pointEx.height) / 2f, positionZ + depth); + area.matrix3D.TransformPoints(points); + + // Measure string + SizeF sizeFont = graph.GetRelativeSize( + graph.MeasureString( + text, + pointEx.dataPoint.Font, + new SizeF(1000f, 1000f), + StringFormat.GenericTypographic)); + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeFont.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = new RectangleF( + points[0].PointF.X - sizeLabel.Width / 2, + points[0].PointF.Y - sizeLabel.Height / 2 - sizeFont.Height / 10, + sizeLabel.Width, + sizeLabel.Height); + + // Draw label text + using (Brush brush = new SolidBrush(pointEx.dataPoint.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + pointEx.dataPoint.Font, + brush, + points[0].PointF, + format, + pointEx.dataPoint.LabelAngle, + labelBackPosition, + pointEx.dataPoint.LabelBackColor, + pointEx.dataPoint.LabelBorderColor, + pointEx.dataPoint.LabelBorderWidth, + pointEx.dataPoint.LabelBorderDashStyle, + pointEx.dataPoint.series, + pointEx.dataPoint, + pointEx.index - 1); + } + } + } + } + + #endregion + + #region Y values methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. Set to -1 to get the height. + /// Y value of the point. + override public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + double yValue = double.NaN; + + // Calculate stacked column Y value for 2D chart + if(area.Area3DStyle.Enable3D == false) + { + return point.YValues[0]; + } + + // Get point Height if pointIndex == -1 + if(yValueIndex == -1) + { + Axis vAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName); + double areaZeroValue = vAxis.Crossing; + yValue = GetYValue(common, area, series, point, pointIndex, 0); + if(area.Area3DStyle.Enable3D && yValue < 0.0) + { + // No negative values support in 3D stacked area chart + yValue = -yValue; + } + if( yValue >= 0 ) + { + if(!double.IsNaN(prevPosY)) + { + areaZeroValue = prevPosY; + } + } + else + { + if(!double.IsNaN(prevNegY)) + { + areaZeroValue = prevNegY; + } + } + + return yValue - areaZeroValue; + } + + + // Loop through all series + prevPosY = double.NaN; + prevNegY = double.NaN; + prevPositionX = double.NaN; + foreach(Series ser in common.DataManager.Series) + { + // Check series of the current chart type & area + if(String.Compare(series.ChartArea, ser.ChartArea, StringComparison.Ordinal) == 0 && + String.Compare(series.ChartTypeName, ser.ChartTypeName, StringComparison.OrdinalIgnoreCase) == 0 && + ser.IsVisible()) + { + yValue = ser.Points[pointIndex].YValues[0]; + if(area.Area3DStyle.Enable3D && yValue < 0.0) + { + // No negative values support in 3D stacked area chart + yValue = -yValue; + } + if(!double.IsNaN(yValue)) + { + if(yValue >= 0.0 && !double.IsNaN(prevPosY)) + { + yValue += prevPosY; + } + if(yValue < 0.0 && !double.IsNaN(prevNegY)) + { + yValue += prevNegY; + } + } + + // Exit loop when current series was found + if (String.Compare(series.Name, ser.Name, StringComparison.Ordinal) == 0) + { + break; + } + + // Remember privious position + if(yValue >= 0.0) + { + prevPosY = yValue; + } + if(yValue < 0.0) + { + prevNegY = yValue; + } + prevPositionX = ser.Points[pointIndex].XValue; + if(prevPositionX == 0.0 && ChartHelper.IndexedSeries(series)) + { + prevPositionX = pointIndex + 1; + } + } + } + + return yValue; + } + + #endregion + + #region IDisposable overrides + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Dispose managed resources + if (this.areaBottomPath != null) + { + this.areaBottomPath.Dispose(); + this.areaBottomPath = null; + } + } + base.Dispose(disposing); + } + #endregion + + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/StackedBarChart.cs b/System.Web.DataVisualization/Common/ChartTypes/StackedBarChart.cs new file mode 100644 index 000000000..097ab5077 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/StackedBarChart.cs @@ -0,0 +1,2156 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: StackedBarChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: StackedBarChart, HundredPercentStackedBarChart +// +// Purpose: This class contains all necessary methods and +// properties for drawing and selection of the stacked +// bar and hundred percent stacked bar charts. +// Every data point in the Stacked bar chart is +// represented with one rectangle. If there is +// more then one series with this chart type from +// same chart area, bars with same X values are +// Stacked. +// +// Reviewed: AG - Aug 6, 2002 +// AG - Microsoft 7, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// HundredPercentStackedBarChart class extends StackedBarChart class + /// by providing its own algorithm for calculating series data point + /// Y values. It makes sure that total Y value of all data points in a + /// single cluster from all series adds up to 100%. + /// + internal class HundredPercentStackedBarChart : StackedBarChart + { + #region Constructor + + /// + /// Default constructor. + /// + public HundredPercentStackedBarChart() + { + hundredPercentStacked = true; + } + + #endregion + + #region Fields + + + + // Total Y values from all series at specified index orgonized by stacked groups + // Hashtable will contain arrays of doubles stored by group name key. + Hashtable _stackedGroupsTotalPerPoint = null; + + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.OneHundredPercentStackedBar;}} + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + override public bool HundredPercent{ get{return true;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + override public bool HundredPercentSupportNegative{ get{return true;} } + + #endregion + + #region Painting and selection methods + + /// + /// Paint HundredPercentStackedBarChart Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + override public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + // Reset pre-calculated totals + + this._stackedGroupsTotalPerPoint = null; + + // Call base class painting + base.Paint( graph, common, area, seriesToDraw ); + } + + #endregion + + #region Y values related methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + override public double GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex) + { + // Array of Y totals for individual series index in the current stacked group + double[] currentGroupTotalPerPoint = null; + + + string currentStackedGroupName = HundredPercentStackedColumnChart.GetSeriesStackGroupName(series); + if(this._stackedGroupsTotalPerPoint == null) + { + // Create new hashtable + this._stackedGroupsTotalPerPoint = new Hashtable(); + + // Iterate through all stacked groups + foreach(string groupName in this.stackGroupNames) + { + // Get series that belong to the same group + Series[] seriesArray = HundredPercentStackedColumnChart.GetSeriesByStackedGroupName( + common, groupName, series.ChartTypeName, series.ChartArea); + + // Check if series are aligned + common.DataManipulator.CheckXValuesAlignment(seriesArray); + + // Allocate memory for the array of totals + double[] totals = new double[series.Points.Count]; + + // Calculate the total of Y value per point + for(int index = 0; index < series.Points.Count; index++) + { + totals[index] = 0; + foreach( Series ser in seriesArray ) + { + totals[index] += Math.Abs(ser.Points[index].YValues[0]); + } + } + + // Add totals array into the hashtable + this._stackedGroupsTotalPerPoint.Add(groupName, totals); + } + } + + // Find array of total Y values based on the current stacked group name + currentGroupTotalPerPoint = (double[])this._stackedGroupsTotalPerPoint[currentStackedGroupName]; + + + if(!area.Area3DStyle.Enable3D) + { + if(point.YValues[0] == 0 || point.IsEmpty) + { + return 0; + } + } + + // Calculate stacked column Y value for 2D chart + if(area.Area3DStyle.Enable3D == false || yValueIndex == -2) + { + if(currentGroupTotalPerPoint[pointIndex] == 0.0) + { + return 0.0; + } + return (point.YValues[0] / currentGroupTotalPerPoint[pointIndex]) * 100.0; + } + + // Get point Height if pointIndex == -1 + double yValue = double.NaN; + if(yValueIndex == -1) + { + Axis vAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName); + double barZeroValue = vAxis.Crossing; + yValue = GetYValue(common, area, series, point, pointIndex, 0); + if( yValue >= 0 ) + { + if(!double.IsNaN(prevPosY)) + { + barZeroValue = prevPosY; + } + } + else + { + if(!double.IsNaN(prevNegY)) + { + barZeroValue = prevNegY; + } + } + + return yValue - barZeroValue; + } + + + // Loop through all series to find point value + prevPosY = double.NaN; + prevNegY = double.NaN; + foreach(Series ser in common.DataManager.Series) + { + // Check series of the current chart type & area + if(String.Compare(series.ChartArea, ser.ChartArea, StringComparison.Ordinal) == 0 && + String.Compare(series.ChartTypeName, ser.ChartTypeName, StringComparison.OrdinalIgnoreCase) == 0 && + ser.IsVisible()) + { + + // Series must belong to the same stacked group + if(currentStackedGroupName != HundredPercentStackedColumnChart.GetSeriesStackGroupName(ser)) + { + continue; + } + + + if(double.IsNaN(yValue)) + { + if(currentGroupTotalPerPoint[pointIndex] == 0.0) + { + yValue = 0.0; + } + else + { + yValue = (ser.Points[pointIndex].YValues[0] / currentGroupTotalPerPoint[pointIndex]) * 100.0; + } + } + else + { + if(currentGroupTotalPerPoint[pointIndex] == 0.0) + { + yValue = 0.0; + } + else + { + yValue = (ser.Points[pointIndex].YValues[0] / currentGroupTotalPerPoint[pointIndex]) * 100.0; + } + if(yValue >= 0.0 && !double.IsNaN(prevPosY)) + { + yValue += prevPosY; + } + if(yValue < 0.0 && !double.IsNaN(prevNegY)) + { + yValue += prevNegY; + } + } + + // Exit loop when current series was found + if (String.Compare(series.Name, ser.Name, StringComparison.Ordinal) == 0) + { + break; + } + + // Save previous value + if(yValue >= 0.0) + { + prevPosY = yValue; + } + else + { + prevNegY = yValue; + } + } + } + + return (yValue > 100.0) ? 100.0 : yValue; + } + + #endregion + } + + /// + /// StackedBarChart class contains all the code necessary to draw + /// and hit test Stacked Bar chart. + /// + internal class StackedBarChart : IChartType + { + #region Fields + + /// + /// Previous stacked positive Y values. + /// + protected double prevPosY = double.NaN; + + /// + /// Previous stacked negative Y values. + /// + protected double prevNegY = double.NaN; + + /// + /// Indicates if chart is 100% stacked + /// + protected bool hundredPercentStacked = false; + + + + /// + /// True if stacke group name is applicable + /// + internal bool stackGroupNameUsed = false; + + /// + /// List of all stack group names + /// + internal ArrayList stackGroupNames = null; + + /// + /// Name of the current stack group. + /// + internal string currentStackGroup = string.Empty; + + + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.StackedBar;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + /// + /// True if chart type is stacked + /// + public bool Stacked { get{ return true;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return true; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return true;}} + + /// + /// True if chart type supports axeses + /// + public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + public bool SwitchValueAxes { get{ return true;} } + + /// + /// True if chart series can be placed side-by-side. + /// + public bool SideBySideSeries { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + public bool ZeroCrossing { get{ return true;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + public bool DataPointsInLegend { get{ return false;} } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return false; } } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Number of supported Y value(s) per point + /// + public int YValuesPerPoint{ get { return 1; } } + + #endregion + + #region Painting and selection methods + + /// + /// Paint Stacked Bar Chart. + /// + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Chart series to draw. + virtual public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + + // Reset stacked group names flag + this.stackGroupNameUsed = true; + + + // Set Clip Region in rounded to a pixel coordinates + RectangleF areaPosition = ((ChartGraphics)graph).GetAbsoluteRectangle( area.PlotAreaPosition.ToRectangleF()); + float right = (float)Math.Ceiling(areaPosition.Right); + float bottom = (float)Math.Ceiling(areaPosition.Bottom); + areaPosition.X = (float)Math.Floor(areaPosition.X); + areaPosition.Width = right - areaPosition.X; + areaPosition.Y = (float)Math.Floor(areaPosition.Y); + areaPosition.Height = bottom - areaPosition.Y; + ((ChartGraphics)graph).SetClipAbs( areaPosition ); + + // Draw shadow + ProcessChartType( false, graph, common, area, true, false, seriesToDraw ); + + // Draw stacked bars + ProcessChartType( false, graph, common, area, false, false, seriesToDraw ); + + // Draw labels + ProcessChartType( false, graph, common, area, false, true, seriesToDraw ); + + // Reset Clip Region + ((ChartGraphics)graph).ResetClip(); + } + + /// + /// This method recalculates size of the stacked bars. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// True if shadow mode is active. + /// Labels drawing mode. + /// Chart series to draw. + private void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + bool shadow, + bool labels, + Series seriesToDraw ) + { + + //************************************************************ + //** If stacked series is attached to diferent X and Y axis + //** they can not be processed. To solve this issue series + //** will be orgonized in groups based on the axes. + //************************************************************ + + // Loop through all series and check if different axes are used + bool differentAxesAreUsed = false; + AxisType xAxisType = AxisType.Primary; + AxisType yAxisType = AxisType.Primary; + string xSubAxisName = string.Empty; + string ySubAxisName = string.Empty; + for(int seriesIndex = 0; seriesIndex < common.DataManager.Series.Count; seriesIndex++) + { + // Process non empty series of the area with stacked column chart type + Series ser = common.DataManager.Series[seriesIndex]; + if( String.Compare( ser.ChartTypeName, Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + if(seriesIndex == 0) + { + xAxisType = ser.XAxisType; + yAxisType = ser.YAxisType; + xSubAxisName = ser.XSubAxisName; + ySubAxisName = ser.YSubAxisName; + } + else if(xAxisType != ser.XAxisType || + yAxisType != ser.YAxisType || + xSubAxisName != ser.XSubAxisName || + ySubAxisName != ser.YSubAxisName) + { + differentAxesAreUsed = true; + break; + } + } + + // Set stacked groups based on the axes used + if(differentAxesAreUsed) + { + for(int seriesIndex = 0; seriesIndex < common.DataManager.Series.Count; seriesIndex++) + { + // Process non empty series of the area with stacked column chart type + Series ser = common.DataManager.Series[seriesIndex]; + if( String.Compare( ser.ChartTypeName, Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Set new group name + string stackGroupName = StackedColumnChart.GetSeriesStackGroupName(ser); + stackGroupName = "_X_" + ser.XAxisType.ToString() + ser.XSubAxisName + "_Y_" + ser.YAxisType.ToString() + ser.YSubAxisName + "__"; + ser[CustomPropertyName.StackedGroupName] = stackGroupName; + } + } + + //************************************************************ + //** Check how many stack groups are available. + //************************************************************ + + // Loop through all series and get unique stack group names. + this.stackGroupNames = new ArrayList(); + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with stacked column chart type + if( String.Compare( ser.ChartTypeName, Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Get stack group name from the series + string stackGroupName = StackedColumnChart.GetSeriesStackGroupName(ser); + + // Add group name if it do not already exsist + if(!this.stackGroupNames.Contains(stackGroupName)) + { + this.stackGroupNames.Add(stackGroupName); + } + } + + + // Prosess 3D chart type + if(area.Area3DStyle.Enable3D) + { + if(!shadow) + { + ProcessChartType3D( + selection, + graph, + common, + area, + labels, + seriesToDraw ); + } + + return; + } + + // All data series from chart area which have Stacked Bar chart type + string[] seriesList = area.GetSeriesFromChartType(Name).ToArray(); + + // Get maximum number of data points for all series + int maxNumOfPoints = common.DataManager.GetNumberOfPoints(seriesList); + + // Zero X values mode. + bool indexedSeries = ChartHelper.IndexedSeries( common, seriesList); + + //************************************************************ + //** Loop through all data points + //************************************************************ + for( int pointIndx = 0; pointIndx < maxNumOfPoints; pointIndx++ ) + { + + //************************************************************ + //** Loop through all stack groups + //************************************************************ + for(int groupIndex = 0; groupIndex < this.stackGroupNames.Count; groupIndex++) + { + // Rememmber current stack group name + this.currentStackGroup = (string)this.stackGroupNames[groupIndex]; + + int seriesIndx = 0; // Data series index + double PreviousPosY = 0; // Previous positive Y value + double PreviousNegY = 0; // Previous negative Y value + + //************************************************************ + //** Loop through all series + //************************************************************ + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with stacked bar chart type + if( String.Compare( ser.ChartTypeName, Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Series point index is out of range + if( pointIndx >= ser.Points.Count ) + { + continue; + } + + + // Check if series belongs to the current group name + string seriesStackGroupName = StackedColumnChart.GetSeriesStackGroupName(ser); + if(seriesStackGroupName != this.currentStackGroup) + { + continue; + } + + + + // Get data point + DataPoint point = ser.Points[ pointIndx ]; + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Set active horizontal/vertical axis + Axis vAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + Axis hAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Interval between bars + double interval = 1; + if( !indexedSeries ) + { + if (ser.Points.Count == 1 && + (ser.XValueType == ChartValueType.Date || + ser.XValueType == ChartValueType.DateTime || + ser.XValueType == ChartValueType.Time || + ser.XValueType == ChartValueType.DateTimeOffset)) + { + // Check if interval is the same + bool sameInterval = false; + List typeSeries = area.GetSeriesFromChartType(Name); + area.GetPointsInterval(typeSeries, vAxis.IsLogarithmic, vAxis.logarithmBase, true, out sameInterval); + + // Special case when there is only one data point and date scale is used. + if (!double.IsNaN(vAxis.majorGrid.GetInterval()) && vAxis.majorGrid.GetIntervalType() != DateTimeIntervalType.NotSet) + { + interval = ChartHelper.GetIntervalSize(vAxis.minimum, vAxis.majorGrid.GetInterval(), vAxis.majorGrid.GetIntervalType()); + } + else + { + interval = ChartHelper.GetIntervalSize(vAxis.minimum, vAxis.Interval, vAxis.IntervalType); + } + } + else + { + interval = area.GetPointsInterval(vAxis.IsLogarithmic, vAxis.logarithmBase); + } + } + + // Calculates the width of bars. + double width = ser.GetPointWidth(graph, vAxis, interval, 0.8); + + + // Adjust width by number of stacked groups + width = width / (double)this.stackGroupNames.Count; + + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + // Change Y value if Bar is out of plot area + double yValue = GetYValue(common, area, ser, point, pointIndx, 0); + if( seriesIndx != 0 ) + { + if( yValue >= 0 ) + { + yValue = yValue + PreviousPosY; + } + else + { + yValue = yValue + PreviousNegY; + } + } + + // Check if scrolling/zooming frames cutting mode is enabled + bool ajaxScrollingEnabled = false; + + // Save original Y Value + double originalYValue = yValue; + + // Axis is logarithmic + if( hAxis.IsLogarithmic ) + { + yValue = Math.Log( yValue, hAxis.logarithmBase ); + } + + // Recalculates Height position and zero position of bars + double height = hAxis.GetLinearPosition( yValue ); + + // Set x position + double xValue = point.XValue; + if( indexedSeries ) + { + // The formula for position is based on a distance + //from the grid line or nPoints position. + xValue = (double)pointIndx + 1; + } + double xPosition = vAxis.GetPosition( xValue ); + + // Adjust X position of each stack group + if(this.stackGroupNames.Count > 1) + { + xPosition = xPosition - width * ((double) this.stackGroupNames.Count) / 2.0 + width / 2.0 + groupIndex * width; + } + + + xValue = vAxis.GetLogValue(xValue); + + + // Set Start position for a bar + double barZeroValue; + if( seriesIndx == 0 ) + { + if (ajaxScrollingEnabled && labels) + { + // If AJAX scrolling is used always use 0.0 as a starting point + barZeroValue = 0.0; + } + else + { + // Set Start position for a Column + barZeroValue = hAxis.Crossing; + } + } + else if( GetYValue(common, area, ser, point, pointIndx, 0) >= 0 ) + { + barZeroValue = PreviousPosY; + } + else + { + barZeroValue = PreviousNegY; + } + double zero = hAxis.GetPosition(barZeroValue); + + // Calculate bar position + RectangleF rectSize = RectangleF.Empty; + try + { + // Set the bar rectangle + rectSize.Y = (float)(xPosition - width/2); + rectSize.Height = (float)(width); + + // The left side of rectangle has always + // smaller value than a right value + if( zero < height ) + { + rectSize.X = (float)zero; + rectSize.Width = (float)height - rectSize.X; + } + else + { + rectSize.X = (float)height; + rectSize.Width = (float)zero - rectSize.X; + } + } + catch(OverflowException) + { + continue; + } + + // Remeber pre-calculated point position + point.positionRel = new PointF(rectSize.Right, (float)xPosition); + + + // if data point is not empty + if( point.IsEmpty ) + { + continue; + } + + // Axis is logarithmic + if( hAxis.IsLogarithmic ) + { + barZeroValue = Math.Log( barZeroValue, hAxis.logarithmBase ); + } + + // Check if column is completly out of the data scaleView + bool skipPoint = false; + if(xValue < vAxis.ViewMinimum || + xValue > vAxis.ViewMaximum || + (yValue < hAxis.ViewMinimum && barZeroValue < hAxis.ViewMinimum) || + (yValue > hAxis.ViewMaximum && barZeroValue > hAxis.ViewMaximum) ) + { + skipPoint = true; + } + + // *************************************************** + // Painting mode + // *************************************************** + if(!skipPoint) + { + if( common.ProcessModePaint ) + { + // Check if column is partialy in the data scaleView + bool clipRegionSet = false; + if(rectSize.Y < area.PlotAreaPosition.Y || + rectSize.Bottom > area.PlotAreaPosition.Bottom || + rectSize.X < area.PlotAreaPosition.X || + rectSize.Right > area.PlotAreaPosition.Right) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + // Set shadow + int shadowOffset = 0; + if( shadow ) + { + shadowOffset = ser.ShadowOffset; + } + + if( !labels ) + { + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw the bar rectangle + graph.FillRectangleRel( rectSize, + (!shadow)? point.Color : Color.Transparent, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + (!shadow)? point.BackSecondaryColor : Color.Transparent, + point.BorderColor, + point.BorderWidth, + point.BorderDashStyle, + ser.ShadowColor, + shadowOffset, + PenAlignment.Inset, + (shadow) ? BarDrawingStyle.Default : ChartGraphics.GetBarDrawingStyle(point), + false); + + // End Svg Selection mode + graph.EndHotRegion( ); + } + + // Draw labels + else + { + // Calculate label rectangle + RectangleF labelRect = new RectangleF(rectSize.Location, rectSize.Size); + if (clipRegionSet && !ajaxScrollingEnabled) + { + labelRect.Intersect(area.PlotAreaPosition.ToRectangleF()); + } + + // Draw Labels + DrawLabels( common, graph, area, point, pointIndx, ser, labelRect ); + } + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + } + + // *************************************************** + // Hot Regions Mode + // *************************************************** + if( common.ProcessModeRegions && !shadow && !labels) + { + common.HotRegionsList.AddHotRegion( rectSize, point, ser.Name, pointIndx ); + + // Process labels and markers regions only if it was not done while painting + if(labels && !common.ProcessModePaint) + { + DrawLabels( common, graph, area, point, pointIndx, ser, rectSize ); + } + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + } + + // Axis is logarithmic + if( hAxis.IsLogarithmic ) + { + yValue = Math.Pow( hAxis.logarithmBase, yValue ); + } + + // Data series index + seriesIndx++; + if( GetYValue(common, area, ser, point, pointIndx, 0) >= 0 ) + { + PreviousPosY = originalYValue; + } + else + { + PreviousNegY = originalYValue; + } + } + + } + + } + + + + //************************************************************ + //** Remove stacked groups created for series attached to different axis + //************************************************************ + + if(differentAxesAreUsed) + { + for(int seriesIndex = 0; seriesIndex < common.DataManager.Series.Count; seriesIndex++) + { + // Process non empty series of the area with stacked column chart type + Series ser = common.DataManager.Series[seriesIndex]; + if( String.Compare( ser.ChartTypeName, Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Set new group name + string stackGroupName = StackedColumnChart.GetSeriesStackGroupName(ser); + int index = stackGroupName.IndexOf("__", StringComparison.Ordinal); + if(index >= 0) + { + stackGroupName = stackGroupName.Substring(index + 2); + } + if(stackGroupName.Length > 0) + { + ser[CustomPropertyName.StackedGroupName] = stackGroupName; + } + else + { + ser.DeleteCustomProperty(CustomPropertyName.StackedGroupName); + } + } + } + + + + } + + /// + /// Draw Stacked Column labels. + /// + /// Chart common elements. + /// Chart Graphics. + /// Chart area the series belongs to. + /// Data point. + /// Data point index. + /// Data series. + /// Column rectangle. + public void DrawLabels( + CommonElements common, + ChartGraphics graph, + ChartArea area, + DataPoint point, + int pointIndex, + Series series, + RectangleF rectangle ) + { + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // Disable the clip region + Region oldClipRegion = graph.Clip; + graph.Clip = new Region(); + + if (point.IsValueShownAsLabel || point.Label.Length > 0) + { + // Round Y values for 100% stacked bar + double pointLabelValue = GetYValue(common, area, series, point, pointIndex, 0); + if (this.hundredPercentStacked && point.LabelFormat.Length == 0) + { + pointLabelValue = Math.Round(pointLabelValue, 2); + } + + // Get label text + string text; + if (point.Label.Length == 0) + { + text = ValueConverter.FormatValue( + series.Chart, + point, + point.Tag, + pointLabelValue, + point.LabelFormat, + series.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + } + + // Calculate position + PointF labelPosition = PointF.Empty; + labelPosition.X = rectangle.X + rectangle.Width / 2f; + labelPosition.Y = rectangle.Y + rectangle.Height / 2f; + + // Get text angle + int textAngle = point.LabelAngle; + + // Check if text contains white space only + if (text.Trim().Length != 0) + { + //************************************************************ + // Measure string + //************************************************************ + SizeF sizeFont = graph.GetRelativeSize( + graph.MeasureString( + text, + point.Font, + new SizeF(1000f, 1000f), + StringFormat.GenericTypographic)); + + //************************************************************ + // Check labels style custom properties + //************************************************************ + BarValueLabelDrawingStyle drawingStyle = BarValueLabelDrawingStyle.Center; + string valueLabelAttrib = ""; + if (point.IsCustomPropertySet(CustomPropertyName.BarLabelStyle)) + { + valueLabelAttrib = point[CustomPropertyName.BarLabelStyle]; + } + else if (series.IsCustomPropertySet(CustomPropertyName.BarLabelStyle)) + { + valueLabelAttrib = series[CustomPropertyName.BarLabelStyle]; + } + + if (valueLabelAttrib != null && valueLabelAttrib.Length > 0) + { + if (String.Compare(valueLabelAttrib, "Left", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Left; + else if (String.Compare(valueLabelAttrib, "Right", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Right; + else if (String.Compare(valueLabelAttrib, "Center", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Center; + else if (String.Compare(valueLabelAttrib, "Outside", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Outside; + } + + //************************************************************ + // Adjust label position based on the label drawing style + //************************************************************ + if (drawingStyle == BarValueLabelDrawingStyle.Left) + { + labelPosition.X = rectangle.X + sizeFont.Width / 2f; + } + else if (drawingStyle == BarValueLabelDrawingStyle.Right) + { + labelPosition.X = rectangle.Right - sizeFont.Width / 2f; + } + else if (drawingStyle == BarValueLabelDrawingStyle.Outside) + { + labelPosition.X = rectangle.Right + sizeFont.Width / 2f; + } + + + // Check if Smart Labels are enabled + if (series.SmartLabelStyle.Enabled) + { + // Force some SmartLabelStyle settings for column chart + bool oldMarkerOverlapping = series.SmartLabelStyle.IsMarkerOverlappingAllowed; + LabelAlignmentStyles oldMovingDirection = series.SmartLabelStyle.MovingDirection; + series.SmartLabelStyle.IsMarkerOverlappingAllowed = true; + if (series.SmartLabelStyle.MovingDirection == (LabelAlignmentStyles.Top | LabelAlignmentStyles.Bottom | LabelAlignmentStyles.Right | LabelAlignmentStyles.Left | LabelAlignmentStyles.TopLeft | LabelAlignmentStyles.TopRight | LabelAlignmentStyles.BottomLeft | LabelAlignmentStyles.BottomRight)) + { + series.SmartLabelStyle.MovingDirection = LabelAlignmentStyles.Left | LabelAlignmentStyles.Right; + } + + // Adjust label position using SmartLabelStyle algorithm + labelPosition = area.smartLabels.AdjustSmartLabelPosition( + common, + graph, + area, + series.SmartLabelStyle, + labelPosition, + sizeFont, + format, + labelPosition, + new SizeF(0f, 0f), + LabelAlignmentStyles.Center); + + // Restore forced values + series.SmartLabelStyle.IsMarkerOverlappingAllowed = oldMarkerOverlapping; + series.SmartLabelStyle.MovingDirection = oldMovingDirection; + + // Smart labels always use 0 degrees text angle + textAngle = 0; + } + + + + // Draw label + if (!labelPosition.IsEmpty) + { + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeFont.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = new RectangleF( + labelPosition.X - sizeLabel.Width / 2, + labelPosition.Y - sizeLabel.Height / 2 - sizeFont.Height / 10, + sizeLabel.Width, + sizeLabel.Height); + + + + // Adjust label background position that can be changed by the + // Smart Labels algorithm + // NOTE: Fixes issue #4688 + labelBackPosition = area.smartLabels.GetLabelPosition( + graph, + labelPosition, + sizeLabel, + format, + true); + + + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + labelPosition, + format, + textAngle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + series, + point, + pointIndex); + } + } + + } + } + + // Restore old clip region + graph.Clip = oldClipRegion; + } + } + + #endregion + + #region Y values related methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. Set to -1 to get the height. + /// Y value of the point. + virtual public double GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex) + { + double yValue = double.NaN; + + // Calculate stacked column Y value for 2D chart + if(area.Area3DStyle.Enable3D == false || yValueIndex == -2) + { + return point.YValues[0]; + } + + // Get point Height if pointIndex == -1 + if(yValueIndex == -1) + { + Axis vAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName); + double barZeroValue = vAxis.Crossing; + yValue = GetYValue(common, area, series, point, pointIndex, 0); + if( yValue >= 0 ) + { + if(!double.IsNaN(prevPosY)) + { + barZeroValue = prevPosY; + } + } + else + { + if(!double.IsNaN(prevNegY)) + { + barZeroValue = prevNegY; + } + } + + return yValue - barZeroValue; + } + + // Loop through all series + prevPosY = double.NaN; + prevNegY = double.NaN; + foreach(Series ser in common.DataManager.Series) + { + // Check series of the current chart type & area + if(String.Compare(series.ChartArea, ser.ChartArea, StringComparison.Ordinal) == 0 && + String.Compare(series.ChartTypeName, ser.ChartTypeName, StringComparison.OrdinalIgnoreCase) == 0 && + ser.IsVisible()) + { + + // Check if series belongs to the current group name + string seriesStackGroupName = StackedColumnChart.GetSeriesStackGroupName(ser); + if(this.stackGroupNameUsed && + seriesStackGroupName != this.currentStackGroup) + { + continue; + } + + + + if(double.IsNaN(yValue)) + { + yValue = ser.Points[pointIndex].YValues[0]; + } + else + { + yValue = ser.Points[pointIndex].YValues[0]; + if(yValue >= 0.0 && !double.IsNaN(prevPosY)) + { + yValue += prevPosY; + } + if(yValue < 0.0 && !double.IsNaN(prevNegY)) + { + yValue += prevNegY; + } + } + + // Exit loop when current series was found + if (String.Compare(series.Name, ser.Name, StringComparison.Ordinal) == 0) + { + break; + } + + // Save previous value + if(yValue >= 0.0) + { + prevPosY = yValue; + } + if(yValue < 0.0) + { + prevNegY = yValue; + } + } + } + + return yValue; + } + + #endregion + + #region 3D Painting and selection methods + + /// + /// This method recalculates size of the stacked bars in 3D space. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// True if labels must be drawn. + /// Chart series to draw. + private void ProcessChartType3D( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + bool drawLabels, + Series seriesToDraw ) + { + + // Get list of series to draw + List typeSeries = null; + + + // Get all series names that belong the same cluster + typeSeries = area.GetClusterSeriesNames(seriesToDraw.Name); + + + //************************************************************ + //** Get order of data points drawing + //************************************************************ + ArrayList dataPointDrawingOrder = area.GetDataPointDrawingOrder( + typeSeries, + this, + selection, + COPCoordinates.X | COPCoordinates.Y, + new BarPointsDrawingOrderComparer(area, selection, COPCoordinates.X | COPCoordinates.Y), + 0, + false); + + + //************************************************************ + //** Loop through all data poins and draw them + //************************************************************ + if(!drawLabels) + { + foreach(object obj in dataPointDrawingOrder) + { + // Get point & series + DataPoint3D pointEx = (DataPoint3D) obj; + DataPoint point = pointEx.dataPoint; + Series ser = point.series; + + + // Set current stack group name + this.currentStackGroup = StackedColumnChart.GetSeriesStackGroupName(ser); + + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Set active horizontal/vertical axis + Axis vAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + Axis hAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Get point bar drawing style + BarDrawingStyle barDrawingStyle = ChartGraphics.GetBarDrawingStyle(point); + + // All cut points are darkened except of the first and last series + float rightDarkening = 0.5f; + float leftDarkening = 0.5f; + + // NOTE: Following code was replaced with the code below to fix issue #5391 +// if((string)typeSeries[typeSeries.Count - 1] == ser.Name) +// { +// leftDarkening = 0f; +// } +// if((string)typeSeries[0] == ser.Name) +// { +// rightDarkening = 0f; +// } + bool firstVisibleSeries = true; + bool lastVisibleSeries = false; + for(int seriesIndex = 0; seriesIndex < typeSeries.Count; seriesIndex++) + { + // Get series object + Series currentSeries = common.DataManager.Series[seriesIndex]; + + // Check if it is a first series with non-zero Y value + if(firstVisibleSeries) + { + // Make series has non zero vallue + if(pointEx.index <= currentSeries.Points.Count && + currentSeries.Points[pointEx.index - 1].YValues[0] != 0.0) + { + firstVisibleSeries = false; + if(currentSeries.Name == ser.Name) + { + rightDarkening = 0f; + } + } + } + + // Check if it is a last series with non-zero Y value + if(currentSeries.Name == ser.Name) + { + lastVisibleSeries = true; + } + else if(pointEx.index <= currentSeries.Points.Count && + currentSeries.Points[pointEx.index - 1].YValues[0] != 0.0) + { + lastVisibleSeries = false; + } + } + + // Remove darkenning from the last series in the group + if(lastVisibleSeries) + { + leftDarkening = 0f; + } + + + // If stacked groups are used remove darkenning from the + // first/last series in the group + if (area.StackGroupNames != null && + area.StackGroupNames.Count > 1 && + area.Area3DStyle.IsClustered) + { + // Get series group name + string groupName = StackedColumnChart.GetSeriesStackGroupName(ser); + + // Iterate through all series in the group + bool firstSeries = true; + bool lastSeries = false; + foreach(string seriesName in typeSeries) + { + Series currentSeries = common.DataManager.Series[seriesName]; + if(StackedColumnChart.GetSeriesStackGroupName(currentSeries) == groupName) + { + // check if first seris + if(firstSeries) + { + // Make series has non zero vallue + if(pointEx.index < currentSeries.Points.Count && + currentSeries.Points[pointEx.index - 1].YValues[0] != 0.0) + { + firstSeries = false; + if(seriesName == ser.Name) + { + rightDarkening = 0f; + } + } + } + + // check if last series + if(seriesName == ser.Name) + { + lastSeries = true; + } + else if(pointEx.index < currentSeries.Points.Count && + currentSeries.Points[pointEx.index - 1].YValues[0] != 0.0) + { + lastSeries = false; + } + } + } + + // Remove darkenning from the last series in the group + if(lastSeries) + { + leftDarkening = 0f; + } + } + + + + // Change Y value if Bar is out of plot area + double yValue = GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, 0); + + // Set Start position for a bar + double barZeroValue = yValue - GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, -1); + + // Convert values if logarithmic axis is used + yValue = hAxis.GetLogValue(yValue); + barZeroValue = hAxis.GetLogValue(barZeroValue); + + if( barZeroValue > hAxis.ViewMaximum ) + { + leftDarkening = 0.5f; + barZeroValue = hAxis.ViewMaximum; + } + else if( barZeroValue < hAxis.ViewMinimum ) + { + rightDarkening = 0.5f; + barZeroValue = hAxis.ViewMinimum; + } + if( yValue > hAxis.ViewMaximum ) + { + leftDarkening = 0.5f; + yValue = hAxis.ViewMaximum; + } + else if( yValue < hAxis.ViewMinimum ) + { + rightDarkening = 0.5f; + yValue = hAxis.ViewMinimum; + } + + // Recalculates Height position and zero position of bars + double height = hAxis.GetLinearPosition(yValue); + double zero = hAxis.GetLinearPosition(barZeroValue); + + // Set x position + double xValue = (pointEx.indexedSeries) ? pointEx.index : point.XValue; + xValue = vAxis.GetLogValue(xValue); + + + // Calculate bar position + RectangleF rectSize = RectangleF.Empty; + try + { + // Set the bar rectangle + rectSize.Y = (float)(pointEx.xPosition - pointEx.width/2); + rectSize.Height = (float)(pointEx.width); + + // The left side of rectangle has always + // smaller value than a right value + if( zero < height ) + { + float temp = leftDarkening; + leftDarkening = rightDarkening; + rightDarkening = temp; + + rectSize.X = (float)zero; + rectSize.Width = (float)height - rectSize.X; + } + else + { + rectSize.X = (float)height; + rectSize.Width = (float)zero - rectSize.X; + } + } + catch(OverflowException) + { + continue; + } + + // Remeber pre-calculated point position + point.positionRel = new PointF(rectSize.Right, (float)pointEx.xPosition); + + // if data point is not empty + if( point.IsEmpty ) + { + continue; + } + + GraphicsPath rectPath = null; + + // Check if column is completly out of the data scaleView + if(xValue < vAxis.ViewMinimum || + xValue > vAxis.ViewMaximum || + (yValue < hAxis.ViewMinimum && barZeroValue < hAxis.ViewMinimum) || + (yValue > hAxis.ViewMaximum && barZeroValue > hAxis.ViewMaximum) ) + { + continue; + } + + // Check if column is partialy in the data scaleView + bool clipRegionSet = false; + if(rectSize.Bottom <= area.PlotAreaPosition.Y || rectSize.Y >= area.PlotAreaPosition.Bottom) + { + continue; + } + if(rectSize.Y < area.PlotAreaPosition.Y) + { + rectSize.Height -= area.PlotAreaPosition.Y - rectSize.Y; + rectSize.Y = area.PlotAreaPosition.Y; + } + if(rectSize.Bottom > area.PlotAreaPosition.Bottom) + { + rectSize.Height -= rectSize.Bottom - area.PlotAreaPosition.Bottom; + } + if(rectSize.Height < 0) + { + rectSize.Height = 0; + } + if(rectSize.Height == 0f || rectSize.Width == 0f) + { + continue; + } + + + // Detect if we need to get graphical path of drawn object + DrawingOperationTypes drawingOperationType = DrawingOperationTypes.DrawElement; + + if( common.ProcessModeRegions ) + { + drawingOperationType |= DrawingOperationTypes.CalcElementPath; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw the Bar rectangle + rectPath = graph.Fill3DRectangle( + rectSize, + pointEx.zPosition, + pointEx.depth, + area.matrix3D, + area.Area3DStyle.LightStyle, + point.Color, + rightDarkening, + leftDarkening, + point.BorderColor, + point.BorderWidth, + point.BorderDashStyle, + barDrawingStyle, + false, + drawingOperationType); + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + + if( common.ProcessModeRegions && !drawLabels) + { + common.HotRegionsList.AddHotRegion( + rectPath, + false, + graph, + point, + ser.Name, + pointEx.index - 1 + ); + } + if (rectPath != null) + { + rectPath.Dispose(); + } + } + } + + //************************************************************ + //** Loop through all data poins and draw labels + //************************************************************ + if(drawLabels) + { + foreach(object obj in dataPointDrawingOrder) + { + // Get point & series + DataPoint3D pointEx = (DataPoint3D) obj; + DataPoint point = pointEx.dataPoint; + Series ser = point.series; + + // Set active horizontal/vertical axis + Axis vAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + Axis hAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Change Y value if Bar is out of plot area + double yValue = GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, 0); + + // Axis is logarithmic + if( hAxis.IsLogarithmic ) + { + yValue = Math.Log( yValue, hAxis.logarithmBase ); + } + + // Recalculates Height position and zero position of bars + double height = pointEx.yPosition;; + + // Set x position + double xValue = (pointEx.indexedSeries) ? pointEx.index : point.XValue; + + // Set Start position for a bar + double barZeroValue = yValue - GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, -1); + double zero = pointEx.height; + + // Calculate bar position + RectangleF rectSize = RectangleF.Empty; + try + { + // Set the bar rectangle + rectSize.Y = (float)(pointEx.xPosition - pointEx.width/2); + rectSize.Height = (float)(pointEx.width); + + // The left side of rectangle has always + // smaller value than a right value + if( zero < height ) + { + rectSize.X = (float)zero; + rectSize.Width = (float)height - rectSize.X; + } + else + { + rectSize.X = (float)height; + rectSize.Width = (float)zero - rectSize.X; + } + } + catch(OverflowException) + { + continue; + } + + // if data point is not empty + if( point.IsEmpty ) + { + continue; + } + + // Axis is logarithmic + if( hAxis.IsLogarithmic ) + { + barZeroValue = Math.Log( barZeroValue, hAxis.logarithmBase ); + } + + // Check if column is completly out of the data scaleView + if(xValue < vAxis.ViewMinimum || + xValue > vAxis.ViewMaximum || + (yValue < hAxis.ViewMinimum && barZeroValue < hAxis.ViewMinimum) || + (yValue > hAxis.ViewMaximum && barZeroValue > hAxis.ViewMaximum) ) + { + continue; + } + + // Draw 3D labels + DrawLabels3D( area, graph, common, rectSize, pointEx, ser, barZeroValue, height, pointEx.width, pointEx.index - 1); + } + } + } + + /// + /// Draws labels in 3D. + /// + /// Chart area for this chart. + /// The Chart Graphics object. + /// The Common elements object. + /// Bar rectangle. + /// Data point. + /// Data series. + /// The zero position or the bottom of bars. + /// The Height of bars. + /// The width of bars. + /// Point index. + private void DrawLabels3D( + ChartArea area, + ChartGraphics graph, + CommonElements common, + RectangleF rectSize, + DataPoint3D pointEx, + Series ser, + double barStartPosition, + double barSize, + double width, + int pointIndex) + { + DataPoint point = pointEx.dataPoint; + + //************************************************************ + // Draw data point value label + //************************************************************ + if(ser.IsValueShownAsLabel || point.IsValueShownAsLabel || point.Label.Length > 0) + { + // Label rectangle + RectangleF rectLabel = RectangleF.Empty; + + // Label text format + using (StringFormat format = new StringFormat()) + { + + //************************************************************ + // Get label text + //************************************************************ + string text; + if (point.Label.Length == 0) + { + // Round Y values for 100% stacked bar + double pointLabelValue = GetYValue(common, area, ser, point, pointIndex, -2); + if (this.hundredPercentStacked && point.LabelFormat.Length == 0) + { + pointLabelValue = Math.Round(pointLabelValue, 2); + } + + text = ValueConverter.FormatValue( + ser.Chart, + point, + point.Tag, + pointLabelValue, + point.LabelFormat, + ser.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + } + + + //************************************************************ + // Check labels style custom properties + //************************************************************ + BarValueLabelDrawingStyle drawingStyle = BarValueLabelDrawingStyle.Center; + string valueLabelAttrib = ""; + if (point.IsCustomPropertySet(CustomPropertyName.BarLabelStyle)) + { + valueLabelAttrib = point[CustomPropertyName.BarLabelStyle]; + } + else if (ser.IsCustomPropertySet(CustomPropertyName.BarLabelStyle)) + { + valueLabelAttrib = ser[CustomPropertyName.BarLabelStyle]; + } + + if (valueLabelAttrib != null && valueLabelAttrib.Length > 0) + { + if (String.Compare(valueLabelAttrib, "Left", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Left; + else if (String.Compare(valueLabelAttrib, "Right", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Right; + else if (String.Compare(valueLabelAttrib, "Center", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Center; + else if (String.Compare(valueLabelAttrib, "Outside", StringComparison.OrdinalIgnoreCase) == 0) + drawingStyle = BarValueLabelDrawingStyle.Outside; + } + + //************************************************************ + // Make sure label fits. Otherwise change it style + //************************************************************ + bool labelFit = false; + while (!labelFit) + { + // Label text format + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + + // LabelStyle rectangle + if (barStartPosition < barSize) + { + rectLabel.X = rectSize.Right; + rectLabel.Width = area.PlotAreaPosition.Right - rectSize.Right; + } + else + { + rectLabel.X = area.PlotAreaPosition.X; + rectLabel.Width = rectSize.X - area.PlotAreaPosition.X; + } + + // Adjust label rectangle + rectLabel.Y = rectSize.Y - (float)width / 2F; + rectLabel.Height = rectSize.Height + (float)width; + + // Adjust label position depending on the drawing style + if (drawingStyle == BarValueLabelDrawingStyle.Left) + { + rectLabel = rectSize; + format.Alignment = StringAlignment.Near; + } + else if (drawingStyle == BarValueLabelDrawingStyle.Center) + { + rectLabel = rectSize; + format.Alignment = StringAlignment.Center; + } + else if (drawingStyle == BarValueLabelDrawingStyle.Right) + { + rectLabel = rectSize; + format.Alignment = StringAlignment.Far; + } + + // Reversed string alignment + if (barStartPosition >= barSize) + { + if (format.Alignment == StringAlignment.Far) + format.Alignment = StringAlignment.Near; + else if (format.Alignment == StringAlignment.Near) + format.Alignment = StringAlignment.Far; + } + + // Stacked bar chart can not change the BarValueLabelDrawingStyle trying to + // fit data point labels because it will cause label overlapping. + // NOTE: Code below is commented. Fixes issue #4687 - AG + labelFit = true; + + // // Make sure value label fits rectangle. + // SizeF valueTextSize = graph.MeasureStringRel(text, point.Font); + // if(!labelSwitched && valueTextSize.Width > rectLabel.Width) + // { + // // Switch label style only once + // labelSwitched = true; + // + // // If text do not fit - try to switch between Outside/Inside drawing styles + // if(drawingStyle == BarValueLabelDrawingStyle.Outside) + // { + // drawingStyle = BarValueLabelDrawingStyle.Right; + // } + // else + // { + // drawingStyle = BarValueLabelDrawingStyle.Outside; + // } + // } + // else + // { + // labelFit = true; + // } + } + + //************************************************************ + // Find text rotation center point + //************************************************************ + + // Measure string size + SizeF size = graph.MeasureStringRel(text, point.Font, new SizeF(rectLabel.Width, rectLabel.Height), format); + + PointF rotationCenter = PointF.Empty; + if (format.Alignment == StringAlignment.Near) + { // Near + rotationCenter.X = rectLabel.X + size.Width / 2; + } + else if (format.Alignment == StringAlignment.Far) + { // Far + rotationCenter.X = rectLabel.Right - size.Width / 2; + } + else + { // Center + rotationCenter.X = (rectLabel.Left + rectLabel.Right) / 2; + } + + if (format.LineAlignment == StringAlignment.Near) + { // Near + rotationCenter.Y = rectLabel.Top + size.Height / 2; + } + else if (format.LineAlignment == StringAlignment.Far) + { // Far + rotationCenter.Y = rectLabel.Bottom - size.Height / 2; + } + else + { // Center + rotationCenter.Y = (rectLabel.Bottom + rectLabel.Top) / 2; + } + + // Reset string alignment to center point + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + + //************************************************************ + // Adjust label rotation angle + //************************************************************ + int angle = point.LabelAngle; + + // Get projection coordinates + Point3D[] rotationCenterProjection = new Point3D[] { + new Point3D(rotationCenter.X, rotationCenter.Y, pointEx.zPosition + pointEx.depth), + new Point3D(rotationCenter.X - 20f, rotationCenter.Y, pointEx.zPosition + pointEx.depth) }; + // Transform coordinates of text rotation point + area.matrix3D.TransformPoints(rotationCenterProjection); + + // Adjust rotation point + rotationCenter = rotationCenterProjection[0].PointF; + + // Adjust angle of the horisontal text + if (angle == 0 || angle == 180) + { + // Convert coordinates to absolute + rotationCenterProjection[0].PointF = graph.GetAbsolutePoint(rotationCenterProjection[0].PointF); + rotationCenterProjection[1].PointF = graph.GetAbsolutePoint(rotationCenterProjection[1].PointF); + + // Calcuate axis angle + float angleXAxis = (float)Math.Atan( + (rotationCenterProjection[1].Y - rotationCenterProjection[0].Y) / + (rotationCenterProjection[1].X - rotationCenterProjection[0].X)); + angleXAxis = (float)Math.Round(angleXAxis * 180f / (float)Math.PI); + angle += (int)angleXAxis; + } + + SizeF sizeFont = SizeF.Empty; + + + // Check if Smart Labels are enabled + if (ser.SmartLabelStyle.Enabled) + { + sizeFont = graph.GetRelativeSize( + graph.MeasureString( + text, + point.Font, + new SizeF(1000f, 1000f), + StringFormat.GenericTypographic)); + + // Force some SmartLabelStyle settings for column chart + bool oldMarkerOverlapping = ser.SmartLabelStyle.IsMarkerOverlappingAllowed; + LabelAlignmentStyles oldMovingDirection = ser.SmartLabelStyle.MovingDirection; + ser.SmartLabelStyle.IsMarkerOverlappingAllowed = true; + if(ser.SmartLabelStyle.MovingDirection == (LabelAlignmentStyles.Top | LabelAlignmentStyles.Bottom | LabelAlignmentStyles.Right | LabelAlignmentStyles.Left | LabelAlignmentStyles.TopLeft | LabelAlignmentStyles.TopRight | LabelAlignmentStyles.BottomLeft | LabelAlignmentStyles.BottomRight) ) + { + ser.SmartLabelStyle.MovingDirection = LabelAlignmentStyles.Left | LabelAlignmentStyles.Right; + } + + // Adjust label position using SmartLabelStyle algorithm + rotationCenter = area.smartLabels.AdjustSmartLabelPosition( + common, + graph, + area, + ser.SmartLabelStyle, + rotationCenter, + sizeFont, + format, + rotationCenter, + new SizeF(0f, 0f), + LabelAlignmentStyles.Center); + + // Restore forced values + ser.SmartLabelStyle.IsMarkerOverlappingAllowed = oldMarkerOverlapping; + ser.SmartLabelStyle.MovingDirection = oldMovingDirection; + + // Smart labels always use 0 degrees text angle + angle = 0; + } + + + + + + //************************************************************ + // Draw label + //************************************************************ + if (!rotationCenter.IsEmpty) + { + // Measure string + if (sizeFont.IsEmpty) + { + sizeFont = graph.GetRelativeSize( + graph.MeasureString( + text, + point.Font, + new SizeF(1000f, 1000f), + new StringFormat(StringFormat.GenericTypographic))); + } + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeFont.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = new RectangleF( + rotationCenter.X - sizeLabel.Width / 2, + rotationCenter.Y - sizeLabel.Height / 2 - sizeFont.Height / 10, + sizeLabel.Width, + sizeLabel.Height); + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + rotationCenter, + format, + angle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + ser, + point, + pointIndex); + } + } + } + } + } + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + // NOTE: Stacked Bar chart type do not support SmartLabelStyle feature + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/StackedColumnChart.cs b/System.Web.DataVisualization/Common/ChartTypes/StackedColumnChart.cs new file mode 100644 index 000000000..cd0a1e4a0 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/StackedColumnChart.cs @@ -0,0 +1,2023 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: StackedColumnChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: StackedColumnChart, HundredPercentStackedColumnChart +// +// Purpose: This class contains all necessary methods and +// properties for drawing and selection of the stacked +// Column chart. Every data point in the Stacked Column +// chart is represented with one rectangle. If there is +// more then one series with this chart type from +// same chart area, Column with same X values are +// Stacked. +// +// Reviewed: AG - Aug 6, 2002 +// AG - Microsoft 7, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Utilities; +#else + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// HundredPercentStackedColumnChart class extends StackedColumnChart class + /// by providing its own algorithm for calculating series data point + /// Y values. It makes sure that total Y value of all data points in a + /// single cluster from all series adds up to 100%. + /// + internal class HundredPercentStackedColumnChart : StackedColumnChart + { + #region Constructor + + /// + /// Default constructor. + /// + public HundredPercentStackedColumnChart() + { + hundredPercentStacked = true; + } + + #endregion + + #region Fields + + + // Total Y values from all series at specified index orgonized by stacked groups + // Hashtable will contain arrays of doubles stored by group name key. + Hashtable _stackedGroupsTotalPerPoint = null; + + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.OneHundredPercentStackedColumn;}} + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + override public bool HundredPercent{ get{return true;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + override public bool HundredPercentSupportNegative{ get{return true;} } + + #endregion + + #region Painting and Selection methods + + /// + /// Paint HundredPercentStackedColumnChart Chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + override public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + // Reset pre-calculated totals + + this._stackedGroupsTotalPerPoint = null; + + base.Paint( graph, common, area, seriesToDraw ); + } + + #endregion + + #region Y values methods + + /// + /// Helper function, which returns the Y value of the point + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + override public double GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex) + { + // Array of Y totals for individual series index in the current stacked group + double[] currentGroupTotalPerPoint = null; + + + + string currentStackedGroupName = HundredPercentStackedColumnChart.GetSeriesStackGroupName(series); + if(this._stackedGroupsTotalPerPoint == null) + { + // Create new hashtable + this._stackedGroupsTotalPerPoint = new Hashtable(); + + // Iterate through all stacked groups + foreach(string groupName in this.stackGroupNames) + { + // Get series that belong to the same group + Series[] seriesArray = HundredPercentStackedColumnChart.GetSeriesByStackedGroupName( + common, groupName, series.ChartTypeName, series.ChartArea); + + // Check if series are aligned + common.DataManipulator.CheckXValuesAlignment(seriesArray); + + // Allocate memory for the array of totals + double[] totals = new double[series.Points.Count]; + + // Calculate the total of Y value per point + for(int index = 0; index < series.Points.Count; index++) + { + totals[index] = 0; + foreach( Series ser in seriesArray ) + { + totals[index] += Math.Abs(ser.Points[index].YValues[0]); + } + } + + // Add totals array into the hashtable + this._stackedGroupsTotalPerPoint.Add(groupName, totals); + } + } + + // Find array of total Y values based on the current stacked group name + currentGroupTotalPerPoint = (double[])this._stackedGroupsTotalPerPoint[currentStackedGroupName]; + + + // IsEmpty point + if(!area.Area3DStyle.Enable3D) + { + if(point.YValues[0] == 0 || point.IsEmpty) + { + return 0; + } + } + + // Calculate stacked column Y value for 2D chart + if(area.Area3DStyle.Enable3D == false || yValueIndex == -2) + { + if(currentGroupTotalPerPoint[pointIndex] == 0.0) + { + return 0.0; + } + return (point.YValues[0] / currentGroupTotalPerPoint[pointIndex]) * 100.0; + } + + + // Get point Height if pointIndex == -1 + double yValue = double.NaN; + if(yValueIndex == -1) + { + Axis vAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName); + double barZeroValue = vAxis.Crossing; + yValue = GetYValue(common, area, series, point, pointIndex, 0); + if( yValue >= 0 ) + { + if(!double.IsNaN(prevPosY)) + { + barZeroValue = prevPosY; + } + } + else + { + if(!double.IsNaN(prevNegY)) + { + barZeroValue = prevNegY; + } + } + + return yValue - barZeroValue; + } + + + // Loop through all series to find point value + prevPosY = double.NaN; + prevNegY = double.NaN; + foreach(Series ser in common.DataManager.Series) + { + // Check series of the current chart type & area + if(String.Compare(series.ChartArea, ser.ChartArea, StringComparison.Ordinal) == 0 && + String.Compare(series.ChartTypeName, ser.ChartTypeName, StringComparison.OrdinalIgnoreCase) == 0 && + ser.IsVisible()) + { + + // Series must belong to the same stacked group + if(currentStackedGroupName != HundredPercentStackedColumnChart.GetSeriesStackGroupName(ser)) + { + continue; + } + + + if(double.IsNaN(yValue)) + { + if(currentGroupTotalPerPoint[pointIndex] == 0.0) + { + yValue = 0.0; + } + else + { + yValue = (ser.Points[pointIndex].YValues[0] / currentGroupTotalPerPoint[pointIndex]) * 100.0; + } + } + else + { + if(currentGroupTotalPerPoint[pointIndex] == 0.0) + { + yValue = 0.0; + } + else + { + yValue = (ser.Points[pointIndex].YValues[0] / currentGroupTotalPerPoint[pointIndex]) * 100.0; + } + if(yValue >= 0.0 && !double.IsNaN(prevPosY)) + { + yValue += prevPosY; + } + if(yValue < 0.0 && !double.IsNaN(prevNegY)) + { + yValue += prevNegY; + } + } + + // Exit loop when current series was found + if (String.Compare(series.Name, ser.Name, StringComparison.Ordinal) == 0) + { + break; + } + + // Save previous value + if(yValue >= 0.0) + { + prevPosY = yValue; + } + else + { + prevNegY = yValue; + } + } + } + + return (yValue > 100.0) ? 100.0 : yValue; + } + + #endregion + } + + /// + /// StackedColumnChart class contains all the code necessary to draw + /// and hit test Stacked Column chart. + /// + internal class StackedColumnChart : IChartType + { + #region Fields + + /// + /// Previous stacked positive Y values. + /// + protected double prevPosY = double.NaN; + + /// + /// Previous stacked negative Y values. + /// + protected double prevNegY = double.NaN; + + /// + /// Indicates if chart is 100% stacked + /// + protected bool hundredPercentStacked = false; + + + + /// + /// True if stacke group name is applicable + /// + internal bool stackGroupNameUsed = false; + + /// + /// List of all stack group names + /// + internal ArrayList stackGroupNames = null; + + /// + /// Name of the current stack group. + /// + internal string currentStackGroup = string.Empty; + + + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.StackedColumn;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return true;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return true; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return true;}} + + /// + /// True if chart type supports axeses + /// + virtual public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + virtual public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + public bool SideBySideSeries { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return false;} } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return false; } } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint{ get { return 1; } } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return true;} } + + #endregion + + #region Constructor + + /// + /// Default constructor. + /// + public StackedColumnChart() + { + } + + #endregion + + #region Painting and Selection methods + + /// + /// Paint StackedColumnChart Chart + /// + /// The Chart Graphics object + /// The Common elements object + /// Chart area for this chart + /// Chart series to draw. + virtual public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + + // Reset stacked group names flag + stackGroupNameUsed = true; + + + // Set Clip Region in rounded to a pixel coordinates + RectangleF areaPosition = ((ChartGraphics)graph).GetAbsoluteRectangle( area.PlotAreaPosition.ToRectangleF()); + float right = (float)Math.Ceiling(areaPosition.Right); + float bottom = (float)Math.Ceiling(areaPosition.Bottom); + areaPosition.X = (float)Math.Floor(areaPosition.X); + areaPosition.Width = right - areaPosition.X; + areaPosition.Y = (float)Math.Floor(areaPosition.Y); + areaPosition.Height = bottom - areaPosition.Y; + ((ChartGraphics)graph).SetClipAbs( areaPosition ); + + // Draw shadow first + ProcessChartType( false, graph, common, area, true, false, seriesToDraw ); + + // Draw stacked bars + ProcessChartType( false, graph, common, area, false, false, seriesToDraw ); + + // Draw labels + ProcessChartType( false, graph, common, area, false, true, seriesToDraw ); + + // Reset Clip Region + ((ChartGraphics)graph).ResetClip(); + } + + /// + /// This method recalculates size of the Columns. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics objec.t + /// The Common elements object. + /// Chart area for this chart. + /// True if shadow mode is active. + /// Labels drawing mode. + /// Chart series to draw. + private void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + bool shadow, + bool labels, + Series seriesToDraw ) + { + + + //************************************************************ + //** If stacked series is attached to diferent X and Y axis + //** they can not be processed. To solve this issue series + //** will be orgonized in groups based on the axes. + //************************************************************ + + // Loop through all series and check if different axes are used + bool differentAxesAreUsed = false; + AxisType xAxisType = AxisType.Primary; + AxisType yAxisType = AxisType.Primary; + string xSubAxisName = string.Empty; + string ySubAxisName = string.Empty; + for(int seriesIndex = 0; seriesIndex < common.DataManager.Series.Count; seriesIndex++) + { + // Process non empty series of the area with stacked column chart type + Series ser = common.DataManager.Series[seriesIndex]; + if( String.Compare( ser.ChartTypeName, Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + if(seriesIndex == 0) + { + xAxisType = ser.XAxisType; + yAxisType = ser.YAxisType; + xSubAxisName = ser.XSubAxisName; + ySubAxisName = ser.YSubAxisName; + } + else if(xAxisType != ser.XAxisType || + yAxisType != ser.YAxisType || + xSubAxisName != ser.XSubAxisName || + ySubAxisName != ser.YSubAxisName) + { + differentAxesAreUsed = true; + break; + } + } + + // Set stacked groups based on the axes used + if(differentAxesAreUsed) + { + for(int seriesIndex = 0; seriesIndex < common.DataManager.Series.Count; seriesIndex++) + { + // Process non empty series of the area with stacked column chart type + Series ser = common.DataManager.Series[seriesIndex]; + if( String.Compare( ser.ChartTypeName, Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Set new group name + string stackGroupName = StackedColumnChart.GetSeriesStackGroupName(ser); + stackGroupName = "_X_" + ser.XAxisType.ToString() + ser.XSubAxisName + "_Y_" + ser.YAxisType.ToString() + ser.YSubAxisName + "__"; + ser[CustomPropertyName.StackedGroupName] = stackGroupName; + } + } + + //************************************************************ + //** Check how many stack groups are available. + //************************************************************ + + // Loop through all series and get unique stack group names. + this.stackGroupNames = new ArrayList(); + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with stacked column chart type + if( String.Compare( ser.ChartTypeName, Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Get stack group name from the series + string stackGroupName = StackedColumnChart.GetSeriesStackGroupName(ser); + + // Add group name if it do not already exsist + if(!this.stackGroupNames.Contains(stackGroupName)) + { + this.stackGroupNames.Add(stackGroupName); + } + } + + + //************************************************************ + //** Prosess 3D chart type. + //************************************************************ + if(area.Area3DStyle.Enable3D) + { + if(!shadow) + { + ProcessChartType3D( + selection, + graph, + common, + area, + labels, + seriesToDraw ); + } + + return; + } + + + // All data series from chart area which have Column chart type + string[] seriesList = area.GetSeriesFromChartType(Name).ToArray(); + + // Get maximum number of data points for all series + int maxNumOfPoints = common.DataManager.GetNumberOfPoints(seriesList); + + // Zero X values mode. + bool indexedSeries = ChartHelper.IndexedSeries(common, seriesList); + + //************************************************************ + //** Loop through all data points + //************************************************************ + for( int pointIndx = 0; pointIndx < maxNumOfPoints; pointIndx++ ) + { + + //************************************************************ + //** Loop through all stack groups + //************************************************************ + for(int groupIndex = 0; groupIndex < this.stackGroupNames.Count; groupIndex++) + { + // Rememmber current stack group name + this.currentStackGroup = (string)this.stackGroupNames[groupIndex]; + + int seriesIndx = 0; // Data series index + double PreviousPosY = 0; // Previous positive Y value + double PreviousNegY = 0; // Previous negative Y value + + //************************************************************ + //** Loop through all series + //************************************************************ + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with stacked column chart type + if( String.Compare( ser.ChartTypeName, Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Series point index is out of range + if( pointIndx >= ser.Points.Count ) + { + continue; + } + + + // Check if series belongs to the current group name + string seriesStackGroupName = StackedColumnChart.GetSeriesStackGroupName(ser); + if(seriesStackGroupName != this.currentStackGroup) + { + continue; + } + + + // Get data point + DataPoint point = ser.Points[ pointIndx ]; + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Set active horizontal/vertical axis + Axis vAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + Axis hAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + + // Interval between Columns + bool sameInterval = false; + double interval = 1; + if( !indexedSeries ) + { + if (ser.Points.Count == 1 && + (ser.XValueType == ChartValueType.Date || + ser.XValueType == ChartValueType.DateTime || + ser.XValueType == ChartValueType.Time || + ser.XValueType == ChartValueType.DateTimeOffset)) + { + // Check if interval is the same + List typeSeries = area.GetSeriesFromChartType(Name); + area.GetPointsInterval(typeSeries, hAxis.IsLogarithmic, hAxis.logarithmBase, true, out sameInterval); + + // Special case when there is only one data point and date scale is used. + if (!double.IsNaN(hAxis.majorGrid.GetInterval()) && hAxis.majorGrid.GetIntervalType() != DateTimeIntervalType.NotSet) + { + interval = ChartHelper.GetIntervalSize(hAxis.minimum, hAxis.majorGrid.GetInterval(), hAxis.majorGrid.GetIntervalType()); + } + else + { + interval = ChartHelper.GetIntervalSize(hAxis.minimum, hAxis.Interval, hAxis.IntervalType); + } + } + else + { + interval = area.GetPointsInterval(hAxis.IsLogarithmic, hAxis.logarithmBase); + } + } + + // Calculates the width of Columns. + double width = ser.GetPointWidth(graph, hAxis, interval, 0.8); + + + // Adjust width by number of stacked groups + width = width / (double)this.stackGroupNames.Count; + + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + // Change Y value if Column is out of plot area + double yValue = GetYValue(common, area, ser, point, pointIndx, 0); + if( seriesIndx != 0 ) + { + if( yValue >= 0 ) + { + yValue = yValue + PreviousPosY; + } + else + { + yValue = yValue + PreviousNegY; + } + } + + // Check if scrolling/zooming frames cutting mode is enabled + bool ajaxScrollingEnabled = false; + + // Save original Y Value + double originalYValue = yValue; + + // Get IsLogarithmic value + yValue = vAxis.GetLogValue(yValue); + + // Check if value is inside plotting area + if ( !( ajaxScrollingEnabled && labels) ) + { + if (yValue > vAxis.ViewMaximum) + { + yValue = vAxis.ViewMaximum; + } + if (yValue < vAxis.ViewMinimum) + { + yValue = vAxis.ViewMinimum; + } + } + + // Recalculates Height position and zero position of Columns + double height = vAxis.GetLinearPosition( yValue ); + + // Set Start position for a column + double barZeroValue = 0.0; + if( seriesIndx == 0 ) + { + if (ajaxScrollingEnabled && labels) + { + // If AJAX scrolling is used always use 0.0 as a starting point + barZeroValue = 0.0; + } + else + { + // Set Start position for a Column + barZeroValue = vAxis.Crossing; + } + + } + else if( GetYValue(common, area, ser, point, pointIndx, 0) >= 0 ) + { + barZeroValue = PreviousPosY; + } + else + { + barZeroValue = PreviousNegY; + } + double zero = vAxis.GetPosition(barZeroValue); + + // Set x position + double xValue = point.XValue; + if( indexedSeries ) + { + // The formula for position is based on a distance + //from the grid line or nPoints position. + xValue = (double)pointIndx + 1; + } + + double xPosition = hAxis.GetPosition( xValue ); + + // Adjust X position of each stack group + if(this.stackGroupNames.Count > 1) + { + xPosition = xPosition - width * ((double) this.stackGroupNames.Count) / 2.0 + width / 2.0 + groupIndex * width; + } + + + xValue = hAxis.GetLogValue(xValue); + + // Calculate column position + RectangleF rectSize = RectangleF.Empty; + try + { + // Set the Column rectangle + rectSize.X = (float)(xPosition - width/2); + rectSize.Width = (float)(width); + + // The top side of rectangle has always + // smaller value than a bottom value + if( zero < height ) + { + rectSize.Y = (float)zero; + rectSize.Height = (float)height - rectSize.Y; + } + else + { + rectSize.Y = (float)height; + rectSize.Height = (float)zero - rectSize.Y; + } + } + catch(OverflowException) + { + seriesIndx++; + continue; + } + + // Remeber pre-calculated point position + point.positionRel = new PointF((float)xPosition, rectSize.Top); + + // if data point is not empty + if( point.IsEmpty ) + { + seriesIndx++; + continue; + } + + // ************************************************** + // Painting mode + // ************************************************** + if( common.ProcessModePaint ) + { + // Check if column is completly out of the data scaleView + bool skipPoint = false; + if(xValue < hAxis.ViewMinimum || + xValue > hAxis.ViewMaximum || + (yValue < vAxis.ViewMinimum && barZeroValue < vAxis.ViewMinimum) || + (yValue > vAxis.ViewMaximum && barZeroValue > vAxis.ViewMaximum) ) + { + skipPoint = true; + } + + if(!skipPoint) + { + + // Ser shadow + int shadowOffset = 0; + if( shadow ) + { + shadowOffset = ser.ShadowOffset; + } + + if( !labels ) + { + // Check if column is partialy in the data scaleView + bool clipRegionSet = false; + if(rectSize.X < area.PlotAreaPosition.X || + rectSize.Right > area.PlotAreaPosition.Right || + rectSize.Y < area.PlotAreaPosition.Y || + rectSize.Bottom > area.PlotAreaPosition.Bottom) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + if(!shadow || shadowOffset != 0) + { + // Draw the Column rectangle + graph.FillRectangleRel( rectSize, + (!shadow)? point.Color : Color.Transparent, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + (!shadow)? point.BackSecondaryColor : Color.Transparent, + point.BorderColor, + point.BorderWidth, + point.BorderDashStyle, + ser.ShadowColor, + shadowOffset, + PenAlignment.Inset, + (shadow) ? BarDrawingStyle.Default : ChartGraphics.GetBarDrawingStyle(point), + true); + } + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + } + else + { + // Draw labels + DrawLabels( common, graph, area, point, pointIndx, ser, rectSize ); + } + } + } + + // ************************************************** + // Create Hot Regions + // ************************************************** + if( common.ProcessModeRegions && !shadow && !labels) + { + common.HotRegionsList.AddHotRegion( rectSize, point, ser.Name, pointIndx ); + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + + // Axis is logarithmic + if( vAxis.IsLogarithmic ) + { + yValue = Math.Pow( vAxis.logarithmBase, yValue ); + } + + // Data series index + seriesIndx++; + if( GetYValue(common, area, ser, point, pointIndx, 0) >= 0 ) + { + PreviousPosY = originalYValue; + } + else + { + PreviousNegY = originalYValue; + } + } + + } + + } + + + + + //************************************************************ + //** Remove stacked groups created for series attached to different axis + //************************************************************ + + if(differentAxesAreUsed) + { + for(int seriesIndex = 0; seriesIndex < common.DataManager.Series.Count; seriesIndex++) + { + // Process non empty series of the area with stacked column chart type + Series ser = common.DataManager.Series[seriesIndex]; + if( String.Compare( ser.ChartTypeName, Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Set new group name + string stackGroupName = StackedColumnChart.GetSeriesStackGroupName(ser); + int index = stackGroupName.IndexOf("__", StringComparison.Ordinal); + if(index >= 0) + { + stackGroupName = stackGroupName.Substring(index + 2); + } + if(stackGroupName.Length > 0) + { + ser[CustomPropertyName.StackedGroupName] = stackGroupName; + } + else + { + ser.DeleteCustomProperty(CustomPropertyName.StackedGroupName); + } + } + } + + + + } + + + + /// + /// Helper method that gets an array of series that belong to the specified + /// stacked group. + /// + /// Chart common elements. + /// Group name to get the list of series for. + /// Series chart type name to include in the result list. + /// Series chart are name where series should belong to. + /// Array of series that belong to the specified group. + static internal Series[] GetSeriesByStackedGroupName(CommonElements common, string groupName, string chartTypeName, string chartAreaName) + { + // Get a list of series with specified group name + ArrayList list = new ArrayList(); + foreach(Series series in common.DataManager.Series) + { + if (String.Compare(series.ChartTypeName, chartTypeName, StringComparison.OrdinalIgnoreCase) == 0 && + chartAreaName == series.ChartArea && + series.IsVisible()) + { + if (GetSeriesStackGroupName(series) == groupName) + { + list.Add(series); + } + } + } + + // Convert array list to array of series + int index = 0; + Series[] arrayOfSeries = new Series[list.Count]; + foreach(Series series in list) + { + arrayOfSeries[index++] = series; + } + + return arrayOfSeries; + } + + /// + /// Helper method that gets stacked group name from specified series. + /// + /// Series to get the group name from. + /// Series stacked group name. + static internal string GetSeriesStackGroupName(Series series) + { + // Get stack group name from the series + string stackGroupName = string.Empty; + if(series.IsCustomPropertySet(CustomPropertyName.StackedGroupName)) + { + stackGroupName = series[CustomPropertyName.StackedGroupName]; + } + return stackGroupName; + } + + /// + /// Checks if series supports stacked group names. + /// + /// Series to check. + /// True if feature supported. + static internal bool IsSeriesStackGroupNameSupported(Series series) + { + if( series.ChartType == SeriesChartType.StackedColumn || + series.ChartType == SeriesChartType.StackedColumn100 || + series.ChartType == SeriesChartType.StackedBar || + series.ChartType == SeriesChartType.StackedBar100) + { + return true; + } + return false; + } + + + + /// + /// Draw Stacked Column labels. + /// + /// Chart common elements. + /// Chart Graphics. + /// Chart area the series belongs to. + /// Data point. + /// Data point index. + /// Data series. + /// Column rectangle. + public void DrawLabels( + CommonElements common, + ChartGraphics graph, + ChartArea area, + DataPoint point, + int pointIndex, + Series series, + RectangleF rectangle ) + { + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // Disable the clip region + Region oldClipRegion = graph.Clip; + graph.Clip = new Region(); + + if (point.IsValueShownAsLabel || point.Label.Length > 0) + { + // Get label text + string text; + if (point.Label.Length == 0) + { + // Round Y values for 100% stacked area + double pointLabelValue = GetYValue(common, area, series, point, pointIndex, 0); + if (this.hundredPercentStacked && point.LabelFormat.Length == 0) + { + pointLabelValue = Math.Round(pointLabelValue, 2); + } + + text = ValueConverter.FormatValue( + series.Chart, + point, + point.Tag, + pointLabelValue, + point.LabelFormat, + series.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + } + + // Calculate label position + PointF labelPosition = PointF.Empty; + labelPosition.X = rectangle.X + rectangle.Width / 2f; + labelPosition.Y = rectangle.Y + rectangle.Height / 2f; + + // Get text angle + int textAngle = point.LabelAngle; + + // Check if text contains white space only + if (text.Trim().Length != 0) + { + SizeF sizeFont = SizeF.Empty; + + + // Check if Smart Labels are enabled + if (series.SmartLabelStyle.Enabled) + { + sizeFont = graph.GetRelativeSize( + graph.MeasureString( + text, + point.Font, + new SizeF(1000f, 1000f), + StringFormat.GenericTypographic)); + // Force some SmartLabelStyle settings for column chart + bool oldMarkerOverlapping = series.SmartLabelStyle.IsMarkerOverlappingAllowed; + LabelAlignmentStyles oldMovingDirection = series.SmartLabelStyle.MovingDirection; + series.SmartLabelStyle.IsMarkerOverlappingAllowed = true; + + // Change default moving direction + if (series.SmartLabelStyle.MovingDirection == (LabelAlignmentStyles.Top | LabelAlignmentStyles.Bottom | LabelAlignmentStyles.Right | LabelAlignmentStyles.Left | LabelAlignmentStyles.TopLeft | LabelAlignmentStyles.TopRight | LabelAlignmentStyles.BottomLeft | LabelAlignmentStyles.BottomRight)) + { + series.SmartLabelStyle.MovingDirection = LabelAlignmentStyles.Bottom | LabelAlignmentStyles.Top; + } + + // Adjust label position using SmartLabelStyle algorithm + labelPosition = area.smartLabels.AdjustSmartLabelPosition( + common, + graph, + area, + series.SmartLabelStyle, + labelPosition, + sizeFont, + format, + labelPosition, + new SizeF(0f, 0f), + LabelAlignmentStyles.Center); + + // Restore forced values + series.SmartLabelStyle.IsMarkerOverlappingAllowed = oldMarkerOverlapping; + series.SmartLabelStyle.MovingDirection = oldMovingDirection; + + // Smart labels always use 0 degrees text angle + textAngle = 0; + } + + + + // Draw label + if (!labelPosition.IsEmpty) + { + // Fix the .Net issue that text looks shifted to the left. + PointF absPosition = graph.GetAbsolutePoint(labelPosition); + if (graph.TextRenderingHint != TextRenderingHint.AntiAlias) + { + absPosition.X = (float)Math.Ceiling(absPosition.X) + 1f; + labelPosition = graph.GetRelativePoint(absPosition); + } + + // Measure string + if (sizeFont.IsEmpty) + { + sizeFont = graph.GetRelativeSize( + graph.MeasureString( + text, + point.Font, + new SizeF(1000f, 1000f), + StringFormat.GenericTypographic)); + } + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeFont.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = new RectangleF( + labelPosition.X - sizeLabel.Width / 2, + labelPosition.Y - sizeLabel.Height / 2 - sizeFont.Height / 10, + sizeLabel.Width, + sizeLabel.Height); + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + labelPosition, + format, + textAngle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + series, + point, + pointIndex); + } + } + } + } + + // Restore old clip region + graph.Clip = oldClipRegion; + } + } + + #endregion + + #region Y values methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. Set to -1 to get the height. + /// Y value of the point. + virtual public double GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex) + { + double yValue = double.NaN; + + // Calculate stacked column Y value for 2D chart + if(area.Area3DStyle.Enable3D == false || yValueIndex == -2) + { + return point.YValues[0]; + } + + // Get point Height if pointIndex == -1 + if(yValueIndex == -1) + { + Axis vAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName); + double barZeroValue = vAxis.Crossing; + yValue = GetYValue(common, area, series, point, pointIndex, 0); + if( yValue >= 0 ) + { + if(!double.IsNaN(prevPosY)) + { + barZeroValue = prevPosY; + } + } + else + { + if(!double.IsNaN(prevNegY)) + { + barZeroValue = prevNegY; + } + } + + return yValue - barZeroValue; + } + + // Loop through all series + prevPosY = double.NaN; + prevNegY = double.NaN; + foreach(Series ser in common.DataManager.Series) + { + // Check series of the current chart type & area + if(String.Compare(series.ChartArea, ser.ChartArea, StringComparison.Ordinal) == 0 && + String.Compare(series.ChartTypeName, ser.ChartTypeName, StringComparison.OrdinalIgnoreCase) == 0 && + ser.IsVisible()) + { + + // Check if series belongs to the current group name + string seriesStackGroupName = StackedColumnChart.GetSeriesStackGroupName(ser); + if(this.stackGroupNameUsed && + seriesStackGroupName != this.currentStackGroup) + { + continue; + } + + + + if(double.IsNaN(yValue)) + { + yValue = ser.Points[pointIndex].YValues[0]; + } + else + { + yValue = ser.Points[pointIndex].YValues[0]; + if(yValue >= 0.0 && !double.IsNaN(prevPosY)) + { + yValue += prevPosY; + } + if(yValue < 0.0 && !double.IsNaN(prevNegY)) + { + yValue += prevNegY; + } + } + + // Exit loop when current series was found + if (String.Compare(series.Name, ser.Name, StringComparison.Ordinal) == 0) + { + break; + } + + // Save previous value + if(yValue >= 0.0) + { + prevPosY = yValue; + } + + if(yValue < 0.0) + { + prevNegY = yValue; + } + } + } + + return yValue; + } + + #endregion + + #region 3D Painting and Selection method + + /// + /// This method recalculates size of the Columns. This method is used + /// from Paint or Select method in 3D space. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics objec.t + /// The Common elements object. + /// Chart area for this chart. + /// Labels drawing mode. + /// Chart series to draw. + private void ProcessChartType3D( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + bool labels, + Series seriesToDraw ) + { + // Labels & markers are drawn with the data points in the first iteration + if(labels && !selection) + { + return; + } + + // Get list of series to draw + List typeSeries = null; + + + // Get all series names that belong the same cluster + typeSeries = area.GetClusterSeriesNames(seriesToDraw.Name); + + + //************************************************************ + //** Get order of data points drawing + //************************************************************ + ArrayList dataPointDrawingOrder = area.GetDataPointDrawingOrder(typeSeries, this, selection, COPCoordinates.X | COPCoordinates.Y, null, 0, false); + + + //************************************************************ + //** Loop through all data poins and draw them + //************************************************************ + bool drawLabels = false; + foreach(object obj in dataPointDrawingOrder) + { + // Get point & series + DataPoint3D pointEx = (DataPoint3D) obj; + DataPoint point = pointEx.dataPoint; + Series ser = point.series; + + + // Set current stack group name + this.currentStackGroup = StackedColumnChart.GetSeriesStackGroupName(ser); + + + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Set active vertical/horizontal axis + Axis vAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + Axis hAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + + // Get point bar drawing style + BarDrawingStyle barDrawingStyle = ChartGraphics.GetBarDrawingStyle(point); + + // All cut points are darkened except of the first and last series + float topDarkening = 0.5f; + float bottomDarkening = 0.5f; + + // NOTE: Following code was replaced with the code below to fix issue #5391 +// if((string)typeSeries[typeSeries.Count - 1] == ser.Name) +// { +// topDarkening = 0f; +// } +// if((string)typeSeries[0] == ser.Name) +// { +// bottomDarkening = 0f; +// } + + bool firstVisibleSeries = true; + bool lastVisibleSeries = false; + for(int seriesIndex = 0; seriesIndex < typeSeries.Count; seriesIndex++) + { + // Get series object + Series currentSeries = common.DataManager.Series[seriesIndex]; + + // Check if it is a first series with non-zero Y value + if(firstVisibleSeries) + { + // Make series has non zero vallue + if(pointEx.index <= currentSeries.Points.Count && + currentSeries.Points[pointEx.index - 1].YValues[0] != 0.0) + { + firstVisibleSeries = false; + if(currentSeries.Name == ser.Name) + { + bottomDarkening = 0f; + } + } + } + + // Check if it is a last series with non-zero Y value + if(currentSeries.Name == ser.Name) + { + lastVisibleSeries = true; + } + else if(pointEx.index <= currentSeries.Points.Count && + currentSeries.Points[pointEx.index - 1].YValues[0] != 0.0) + { + lastVisibleSeries = false; + } + } + + // Remove darkenning from the last series in the group + if(lastVisibleSeries) + { + topDarkening = 0f; + } + + + + // If stacked groups are used remove darkenning from the + // first/last series in the group + if(area.StackGroupNames != null && + area.StackGroupNames.Count > 1 && + area.Area3DStyle.IsClustered) + { + // Get series group name + string groupName = StackedColumnChart.GetSeriesStackGroupName(ser); + + // Iterate through all series in the group + bool firstSeries = true; + bool lastSeries = false; + foreach(string seriesName in typeSeries) + { + Series currentSeries = common.DataManager.Series[seriesName]; + if(StackedColumnChart.GetSeriesStackGroupName(currentSeries) == groupName) + { + // check if first seris + if(firstSeries) + { + if(pointEx.index < currentSeries.Points.Count && + currentSeries.Points[pointEx.index - 1].YValues[0] != 0.0) + { + firstSeries = false; + if(seriesName == ser.Name) + { + bottomDarkening = 0f; + } + + } + } + + // check if last series + if(seriesName == ser.Name) + { + lastSeries = true; + } + else if(pointEx.index < currentSeries.Points.Count && + currentSeries.Points[pointEx.index - 1].YValues[0] != 0.0) + { + lastSeries = false; + } + } + } + + // Remove darkenning from the last series in the group + if(lastSeries) + { + topDarkening = 0f; + } + } + + + + // Check if value is inside plotting area + double yValue = GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, 0); + + // Set Start position for a column + double barZeroValue = yValue - GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, -1); + + // Convert values if logarithmic axis is used + yValue = vAxis.GetLogValue(yValue); + barZeroValue = vAxis.GetLogValue(barZeroValue); + + if( barZeroValue > vAxis.ViewMaximum ) + { + topDarkening = 0.5f; + barZeroValue = vAxis.ViewMaximum; + } + else if( barZeroValue < vAxis.ViewMinimum ) + { + bottomDarkening = 0.5f; + barZeroValue = vAxis.ViewMinimum; + } + if( yValue > vAxis.ViewMaximum ) + { + topDarkening = 0.5f; + yValue = vAxis.ViewMaximum; + } + else if( yValue < vAxis.ViewMinimum ) + { + bottomDarkening = 0.5f; + yValue = vAxis.ViewMinimum; + } + + // Recalculates Height position and zero position of Columns + double height = vAxis.GetLinearPosition(yValue); + double zero = vAxis.GetLinearPosition(barZeroValue); + + // Calculate column position + RectangleF rectSize = RectangleF.Empty; + try + { + // Set the Column rectangle + rectSize.X = (float)(pointEx.xPosition - pointEx.width/2); + rectSize.Width = (float)(pointEx.width); + + // The top side of rectangle has always + // smaller value than a bottom value + if( zero < height ) + { + float temp = bottomDarkening; + bottomDarkening = topDarkening; + topDarkening = temp; + + rectSize.Y = (float)zero; + rectSize.Height = (float)height - rectSize.Y; + } + else + { + rectSize.Y = (float)height; + rectSize.Height = (float)zero - rectSize.Y; + } + } + catch(OverflowException) + { + continue; + } + + // Remeber pre-calculated point position + point.positionRel = new PointF((float)pointEx.xPosition, rectSize.Top); + + // if data point is not empty + if( point.IsEmpty ) + { + continue; + } + + // Painting mode + // Check if column is completly out of the data scaleView + double xValue = (pointEx.indexedSeries) ? pointEx.index : point.XValue; + xValue = hAxis.GetLogValue(xValue); + if(xValue < hAxis.ViewMinimum || + xValue > hAxis.ViewMaximum || + (yValue < vAxis.ViewMinimum && barZeroValue < vAxis.ViewMinimum) || + (yValue > vAxis.ViewMaximum && barZeroValue > vAxis.ViewMaximum) ) + { + continue; + } + + // Check if column is partialy in the data scaleView + bool clipRegionSet = false; + if(rectSize.Right <= area.PlotAreaPosition.X || rectSize.X >= area.PlotAreaPosition.Right) + { + continue; + } + + if(rectSize.X < area.PlotAreaPosition.X) + { + rectSize.Width -= area.PlotAreaPosition.X - rectSize.X; + rectSize.X = area.PlotAreaPosition.X; + } + if(rectSize.Right > area.PlotAreaPosition.Right) + { + rectSize.Width -= rectSize.Right - area.PlotAreaPosition.Right; + } + if(rectSize.Width < 0) + { + rectSize.Width = 0; + } + if(rectSize.Height == 0f || rectSize.Width == 0f) + { + continue; + } + + // Detect if we need to get graphical path of drawn object + DrawingOperationTypes drawingOperationType = DrawingOperationTypes.DrawElement; + + if( common.ProcessModeRegions ) + { + drawingOperationType |= DrawingOperationTypes.CalcElementPath; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw the Column rectangle + using ( GraphicsPath rectPath = graph.Fill3DRectangle( + rectSize, + pointEx.zPosition, + pointEx.depth, + area.matrix3D, + area.Area3DStyle.LightStyle, + point.Color, + topDarkening, + bottomDarkening, + point.BorderColor, + point.BorderWidth, + point.BorderDashStyle, + barDrawingStyle, + true, + drawingOperationType)) + { + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + + if( common.ProcessModeRegions && !labels) + { + common.HotRegionsList.AddHotRegion( rectPath, false, graph, point, ser.Name, pointEx.index - 1 ); + } + + // Check if labels should be drawn + if( point.IsValueShownAsLabel || point.Label.Length > 0 ) + { + drawLabels = true; + } + } + } + + + + //************************************************************ + //** Loop through all data poins and draw labels + //************************************************************ + if(drawLabels) + { + foreach(object obj in dataPointDrawingOrder) + { + // Get point & series + DataPoint3D pointEx = (DataPoint3D) obj; + DataPoint point = pointEx.dataPoint; + Series ser = point.series; + + // Set active vertical/horizontal axis + Axis vAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + Axis hAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + + // Check if value is inside plotting area + double yValue = GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, 0); + if( yValue > vAxis.ViewMaximum ) + { + yValue = vAxis.ViewMaximum; + } + if( yValue < vAxis.ViewMinimum ) + { + yValue = vAxis.ViewMinimum; + } + yValue = vAxis.GetLogValue(yValue); + + // Recalculates Height position and zero position of Columns + double height = pointEx.yPosition; + + // Set Start position for a column + double barZeroValue = yValue - vAxis.GetLogValue(GetYValue(common, area, ser, pointEx.dataPoint, pointEx.index - 1, -1)); + double zero = pointEx.height; + + // Calculate column position + RectangleF rectSize = RectangleF.Empty; + try + { + // Set the Column rectangle + rectSize.X = (float)(pointEx.xPosition - pointEx.width/2); + rectSize.Width = (float)(pointEx.width); + + // The top side of rectangle has always + // smaller value than a bottom value + if( zero < height ) + { + rectSize.Y = (float)zero; + rectSize.Height = (float)height - rectSize.Y; + } + else + { + rectSize.Y = (float)height; + rectSize.Height = (float)zero - rectSize.Y; + } + } + catch(OverflowException) + { + continue; + } + + // if data point is not empty + if( point.IsEmpty ) + { + continue; + } + + // Painting mode + if( !selection ) + { + // Check if column is completly out of the data scaleView + double xValue = (pointEx.indexedSeries) ? pointEx.index : point.XValue; + xValue = hAxis.GetLogValue(xValue); + if(xValue < hAxis.ViewMinimum || + xValue > hAxis.ViewMaximum || + (yValue < vAxis.ViewMinimum && barZeroValue < vAxis.ViewMinimum) || + (yValue > vAxis.ViewMaximum && barZeroValue > vAxis.ViewMaximum) ) + { + continue; + } + + // Draw labels + DrawLabels3D( common, graph, area, pointEx, pointEx.index - 1, ser, rectSize ); + + } + } + } + } + + /// + /// Draw Stacked Column labels. + /// + /// Chart common elements. + /// Chart Graphics. + /// Chart area the series belongs to. + /// Data point. + /// Data point index. + /// Data series. + /// Column rectangle. + internal void DrawLabels3D( + CommonElements common, + ChartGraphics graph, + ChartArea area, + DataPoint3D pointEx, + int pointIndex, + Series series, + RectangleF rectangle ) + { + DataPoint point = pointEx.dataPoint; + + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // Disable the clip region + Region oldClipRegion = graph.Clip; + graph.Clip = new Region(); + + if (point.IsValueShownAsLabel || point.Label.Length > 0) + { + // Get label text + string text; + if (point.Label.Length == 0) + { + // Round Y values for 100% stacked area + double pointLabelValue = GetYValue(common, area, series, point, pointIndex, -2); + if (this.hundredPercentStacked && point.LabelFormat.Length == 0) + { + pointLabelValue = Math.Round(pointLabelValue, 2); + } + + text = ValueConverter.FormatValue( + series.Chart, + point, + point.Tag, + pointLabelValue, + point.LabelFormat, + series.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + } + + // Calculate label position + PointF labelPosition = PointF.Empty; + labelPosition.X = rectangle.X + rectangle.Width / 2f; + labelPosition.Y = rectangle.Y + rectangle.Height / 2f; + + // Transform coordinates + Point3D[] marker3DPosition = new Point3D[1]; + marker3DPosition[0] = new Point3D(labelPosition.X, labelPosition.Y, (float)(pointEx.zPosition + pointEx.depth)); + area.matrix3D.TransformPoints(marker3DPosition); + + labelPosition.X = marker3DPosition[0].X; + labelPosition.Y = marker3DPosition[0].Y; + + int textAngle = point.LabelAngle; + + SizeF sizeFont = SizeF.Empty; + + + // Check if Smart Labels are enabled + if (series.SmartLabelStyle.Enabled) + { + sizeFont = graph.GetRelativeSize( + graph.MeasureString( + text, + point.Font, + new SizeF(1000f, 1000f), + StringFormat.GenericTypographic)); + + // Force some SmartLabelStyle settings for column chart + bool oldMarkerOverlapping = series.SmartLabelStyle.IsMarkerOverlappingAllowed; + LabelAlignmentStyles oldMovingDirection = series.SmartLabelStyle.MovingDirection; + series.SmartLabelStyle.IsMarkerOverlappingAllowed = true; + + // Change default moving direction + if (series.SmartLabelStyle.MovingDirection == (LabelAlignmentStyles.Top | LabelAlignmentStyles.Bottom | LabelAlignmentStyles.Right | LabelAlignmentStyles.Left | LabelAlignmentStyles.TopLeft | LabelAlignmentStyles.TopRight | LabelAlignmentStyles.BottomLeft | LabelAlignmentStyles.BottomRight)) + { + series.SmartLabelStyle.MovingDirection = LabelAlignmentStyles.Bottom | LabelAlignmentStyles.Top; + } + + // Adjust label position using SmartLabelStyle algorithm + labelPosition = area.smartLabels.AdjustSmartLabelPosition( + common, + graph, + area, + series.SmartLabelStyle, + labelPosition, + sizeFont, + format, + labelPosition, + new SizeF(0f, 0f), + LabelAlignmentStyles.Center); + + // Restore forced values + series.SmartLabelStyle.IsMarkerOverlappingAllowed = oldMarkerOverlapping; + series.SmartLabelStyle.MovingDirection = oldMovingDirection; + + // Smart labels always use 0 degrees text angle + textAngle = 0; + } + + + + if (!labelPosition.IsEmpty) + { + // Measure string + if (sizeFont.IsEmpty) + { + sizeFont = graph.GetRelativeSize( + graph.MeasureString( + text, + point.Font, + new SizeF(1000f, 1000f), + StringFormat.GenericTypographic)); + } + + // Get label background position + RectangleF labelBackPosition = RectangleF.Empty; + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeFont.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = new RectangleF( + labelPosition.X - sizeLabel.Width / 2, + labelPosition.Y - sizeLabel.Height / 2 - sizeFont.Height / 10, + sizeLabel.Width, + sizeLabel.Height); + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + labelPosition, + format, + textAngle, + labelBackPosition, + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + series, + point, + pointIndex); + } + } + } + + // Restore old clip region + graph.Clip = oldClipRegion; + } + } + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/StepLineChart.cs b/System.Web.DataVisualization/Common/ChartTypes/StepLineChart.cs new file mode 100644 index 000000000..c2a5caac6 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/StepLineChart.cs @@ -0,0 +1,409 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: StepLineChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: StepLineChart +// +// Purpose: Step Line chart uses two line segments (horizontal +// and vertical) to connect data points. Markers and +// labels drawing code is inherited from the Line chart. +// +// Reviewed: AG - Aug 6, 2002 +// AG - Microsoft 7, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; +#else +using System.Web.UI.DataVisualization.Charting; + + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// StepLine class extends its base class LineChart by changing how two + /// neighbouring data points are connected with a line. Step Line chart + /// uses two line segments (horizontal and vertical) to connect data + /// points. Markers and labels drawing code is inherited from the Line chart. + /// + internal class StepLineChart : LineChart + { + #region Constructor + + /// + /// StepLineChart class constructor. + /// + public StepLineChart() + { + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + public override string Name { get{ return ChartTypeNames.StepLine;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + + #region Line drawing and selecting methods + + /// + /// Draw chart line using horisontal and vertical lines. + /// + /// Graphics object. + /// The Common elements object + /// Point to draw the line for. + /// Point series. + /// Array of points coordinates. + /// Index of point to draw. + /// Line tension + override protected void DrawLine( + ChartGraphics graph, + CommonElements common, + DataPoint point, + Series series, + PointF[] points, + int pointIndex, + float tension) + { + // Start drawing from the second point + if(pointIndex <= 0) + { + return; + } + + // Darw two lines + PointF point1 = points[pointIndex - 1]; + PointF point2 = new PointF(points[pointIndex].X, points[pointIndex - 1].Y); + PointF point3 = points[pointIndex]; + graph.DrawLineRel( point.Color, point.BorderWidth, point.BorderDashStyle, graph.GetRelativePoint(point1), graph.GetRelativePoint(point2), series.ShadowColor, series.ShadowOffset ); + graph.DrawLineRel( point.Color, point.BorderWidth, point.BorderDashStyle, graph.GetRelativePoint(point2), graph.GetRelativePoint(point3), series.ShadowColor, series.ShadowOffset ); + + if( common.ProcessModeRegions ) + { + // Create grapics path object for the line + // Split line into 2 segments. + GraphicsPath path = new GraphicsPath(); + try + { + path.AddLine(point2, point3); + if (!point2.Equals(point3)) + { + path.Widen(new Pen(point.Color, point.BorderWidth + 2)); + } + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + + // Allocate array of floats + PointF pointNew = PointF.Empty; + float[] coord = new float[path.PointCount * 2]; + PointF[] pathPoints = path.PathPoints; + for( int i = 0; i < path.PointCount; i++ ) + { + pointNew = graph.GetRelativePoint( pathPoints[i] ); + coord[2*i] = pointNew.X; + coord[2*i + 1] = pointNew.Y; + } + + common.HotRegionsList.AddHotRegion( + path, + false, + coord, + point, + series.Name, + pointIndex ); + path.Dispose(); + // Create grapics path object for the line + path = new GraphicsPath(); + try + { + path.AddLine(point1, point2); + path.Widen(new Pen(point.Color, point.BorderWidth + 2)); + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + + // Allocate array of floats + coord = new float[path.PointCount * 2]; + pathPoints = path.PathPoints; + for( int i = 0; i < path.PointCount; i++ ) + { + pointNew = graph.GetRelativePoint( pathPoints[i] ); + coord[2*i] = pointNew.X; + coord[2*i + 1] = pointNew.Y; + } + + common.HotRegionsList.AddHotRegion( + path, + false, + coord, + series.Points[pointIndex - 1], + series.Name, + pointIndex - 1); + path.Dispose(); + } + } + + #endregion + + #region 3D Line drawing and selection + + /// + /// Draws a 3D surface connecting the two specified points in 2D space. + /// Used to draw Line based charts. + /// + /// Chart area reference. + /// Chart graphics. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Previous data point object. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Array of points. + /// Index of point to draw. + /// Index of points loop. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Darkenning scale for top surface. 0 - None. + /// Darkenning scale for bottom surface. 0 - None. + /// Position where the third point is actually located or float.NaN if same as in "firstPoint". + /// Position where the fourth point is actually located or float.NaN if same as in "secondPoint". + /// Indicates that drawn segment is 3D clipped. Only top/bottom should be drawn. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + protected override GraphicsPath Draw3DSurface( + ChartArea area, + ChartGraphics graph, + Matrix3D matrix, + LightStyle lightStyle, + DataPoint3D prevDataPointEx, + float positionZ, + float depth, + ArrayList points, + int pointIndex, + int pointLoopIndex, + float tension, + DrawingOperationTypes operationType, + float topDarkening, + float bottomDarkening, + PointF thirdPointPosition, + PointF fourthPointPosition, + bool clippedSegment) + { + // Create graphics path for selection + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + // Check if points are drawn from sides to center (do only once) + if(centerPointIndex == int.MaxValue) + { + centerPointIndex = GetCenterPointIndex(points); + } + + //************************************************************ + //** Find line first & second points + //************************************************************ + DataPoint3D secondPoint = (DataPoint3D)points[pointIndex]; + int pointArrayIndex = pointIndex; + DataPoint3D firstPoint = ChartGraphics.FindPointByIndex( + points, + secondPoint.index - 1, + (this.multiSeries) ? secondPoint : null, + ref pointArrayIndex); + + // Fint point with line properties + DataPoint3D pointAttr = secondPoint; + if(prevDataPointEx.dataPoint.IsEmpty) + { + pointAttr = prevDataPointEx; + } + else if(firstPoint.index > secondPoint.index) + { + pointAttr = firstPoint; + } + + // Adjust point visual properties + Color color = (useBorderColor) ? pointAttr.dataPoint.BorderColor : pointAttr.dataPoint.Color; + ChartDashStyle dashStyle = pointAttr.dataPoint.BorderDashStyle; + if( pointAttr.dataPoint.IsEmpty && pointAttr.dataPoint.Color == Color.Empty) + { + color = Color.Gray; + } + if( pointAttr.dataPoint.IsEmpty && pointAttr.dataPoint.BorderDashStyle == ChartDashStyle.NotSet ) + { + dashStyle = ChartDashStyle.Solid; + } + + //************************************************************ + //** Create "middle" point + //************************************************************ + DataPoint3D middlePoint = new DataPoint3D(); + middlePoint.xPosition = secondPoint.xPosition; + middlePoint.yPosition = firstPoint.yPosition; + + // Check if reversed drawing order required + bool originalDrawOrder = true; + if((pointIndex + 1) < points.Count) + { + DataPoint3D p = (DataPoint3D)points[pointIndex + 1]; + if(p.index == firstPoint.index) + { + originalDrawOrder = false; + } + } + + // Check in which order vertical & horizontal lines segments should be drawn + if(centerPointIndex != int.MaxValue) + { + if(pointIndex >= centerPointIndex) + { + originalDrawOrder = false; + } + } + + // Draw two segments of the step line + GraphicsPath resultPathLine1, resultPathLine2; + if(originalDrawOrder) + { + // Draw first line + middlePoint.dataPoint = secondPoint.dataPoint; + resultPathLine1 = graph.Draw3DSurface( + area, matrix, lightStyle, SurfaceNames.Top, positionZ, depth, color, + pointAttr.dataPoint.BorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + firstPoint, middlePoint, + points, pointIndex, 0f, operationType, LineSegmentType.First, + (this.showPointLines) ? true : false, false, + area.ReverseSeriesOrder, + this.multiSeries, 0, true); + + // No second draw of the prev. front line required + graph.frontLinePen = null; + + // Draw second line + middlePoint.dataPoint = firstPoint.dataPoint; + resultPathLine2 = graph.Draw3DSurface( + area, matrix, lightStyle, SurfaceNames.Top, positionZ, depth, color, + pointAttr.dataPoint.BorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + middlePoint, secondPoint, + points, pointIndex, 0f, operationType, LineSegmentType.Last, + (this.showPointLines) ? true : false, false, + area.ReverseSeriesOrder, + this.multiSeries, 0, true); + + // No second draw of the prev. front line required + graph.frontLinePen = null; + } + else + { + // Draw second line + middlePoint.dataPoint = firstPoint.dataPoint; + resultPathLine2 = graph.Draw3DSurface( + area, matrix, lightStyle, SurfaceNames.Top, positionZ, depth, color, + pointAttr.dataPoint.BorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + middlePoint, secondPoint, + points, pointIndex, 0f, operationType, LineSegmentType.Last, + (this.showPointLines) ? true : false, false, + area.ReverseSeriesOrder, + this.multiSeries, 0, true); + + // No second draw of the prev. front line required + graph.frontLinePen = null; + + // Draw first line + middlePoint.dataPoint = secondPoint.dataPoint; + resultPathLine1 = graph.Draw3DSurface( + area, matrix, lightStyle, SurfaceNames.Top, positionZ, depth, color, + pointAttr.dataPoint.BorderColor, pointAttr.dataPoint.BorderWidth, dashStyle, + firstPoint, middlePoint, + points, pointIndex, 0f, operationType, LineSegmentType.First, + (this.showPointLines) ? true : false, false, + area.ReverseSeriesOrder, + this.multiSeries, 0, true); + + // No second draw of the prev. front line required + graph.frontLinePen = null; + } + + if(resultPath != null) + { + if( area.Common.ProcessModeRegions) + { + if(resultPathLine1 != null && resultPathLine1.PointCount > 0) + { + area.Common.HotRegionsList.AddHotRegion( + resultPathLine1, + false, + graph, + prevDataPointEx.dataPoint, + prevDataPointEx.dataPoint.series.Name, + prevDataPointEx.index - 1 ); + } + } + + if(resultPathLine2 != null && resultPathLine2.PointCount > 0) + { + resultPath.AddPath(resultPathLine2, true); + } + } + return resultPath; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/StockChart.cs b/System.Web.DataVisualization/Common/ChartTypes/StockChart.cs new file mode 100644 index 000000000..ca1b33de8 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/StockChart.cs @@ -0,0 +1,1957 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: StockChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Classes: StockChart, CandleStickChart +// +// Purpose: Stock chart requires 4 Y values High, Low, Open and Close. +// +// The Stock chart displays opening and closing values by using +// markers, which are typically lines or triangles. “OpenCloseStyle” +// custom attribute may be used to control the style of the markers. +// The opening values are shown by the markers on the left, and the +// closing values are shown by the markers on the right. +// +// A stock chart is typically used to illustrate significant stock +// price points including a stock's open, close, high, and low price +// points. However, this type of chart can also be used to analyze +// scientific data, because each series of data displays a high, low, +// open, and close value. +// +// Reviewed: AG - Aug 6, 2002 +// AG - Microsoft 7, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Collections.Generic; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Utilities; +#else + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else + namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + #region Open/close marks style enumeration + + /// + /// Style of the Open-Close marks in the stock chart + /// + internal enum StockOpenCloseMarkStyle + { + /// + /// Line + /// + Line, + + /// + /// Triangle + /// + Triangle, + + /// + /// CandleStick. Color of the bar depends if Open value was bigger than Close value. + /// + Candlestick + } + + #endregion + + /// + /// CandleStick class provides chart unique name and changes the marking + /// style in the StockChart class to StockOpenCloseMarkStyle.CandleStick. + /// + internal class CandleStickChart : StockChart + { + #region Constructor + + /// + /// CandleStick chart constructor. + /// + public CandleStickChart() : base(StockOpenCloseMarkStyle.Candlestick) + { + forceCandleStick = true; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + override public string Name { get{ return ChartTypeNames.Candlestick;}} + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + override public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + + #endregion + } + + /// + /// StockChart class provides 2D/3D drawing and hit testing + /// functionality for the Stock and CandleStick charts. + /// + internal class StockChart : IChartType + { + #region Fields + + /// + /// Vertical axis + /// + internal Axis VAxis { get; set; } + + /// + /// Horizontal axis + /// + internal Axis HAxis { get; set; } + + /// + /// Default open-close style + /// + protected StockOpenCloseMarkStyle openCloseStyle = StockOpenCloseMarkStyle.Line; + + /// + /// Indicates that only candle-stick type of the open-close marks should be used + /// + protected bool forceCandleStick = false; + + #endregion + + #region Constructor + + /// + /// Stock chart constructor. + /// + public StockChart() + { + } + + /// + /// Stock chart constructor. + /// + /// Open-close marks default style. + public StockChart(StockOpenCloseMarkStyle style) + { + this.openCloseStyle = style; + } + + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.Stock;}} + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + virtual public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports Logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + public bool SideBySideSeries { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return true; } } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Line; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint { get { return 4; } } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + #endregion + + #region Painting and Selection methods + + /// + /// Paint stock chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + ProcessChartType( false, graph, common, area, seriesToDraw ); + } + + /// + /// This method recalculates size of the bars. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual protected void ProcessChartType( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + + // Prosess 3D chart type + if(area.Area3DStyle.Enable3D) + { + ProcessChartType3D( selection, graph, common, area, seriesToDraw ); + return; + } + + + // All data series from chart area which have Stock chart type + List typeSeries = area.GetSeriesFromChartType(this.Name); + + // Zero X values mode. + bool indexedSeries = ChartHelper.IndexedSeries(common, typeSeries.ToArray() ); + + //************************************************************ + //** Loop through all series + //************************************************************ + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with stock chart type + if( String.Compare( ser.ChartTypeName, this.Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Check that we have at least 4 Y values + if(ser.YValuesPerPoint < 4) + { + throw(new ArgumentException(SR.ExceptionChartTypeRequiresYValues("StockChart", "4"))); + } + + // Set active horizontal/vertical axis + HAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + VAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Get interval between points + double interval = (indexedSeries) ? 1 : area.GetPointsInterval( HAxis.IsLogarithmic, HAxis.logarithmBase ); + + // Calculates the width of the candles. + float width = (float)(ser.GetPointWidth(graph, HAxis, interval, 0.8)); + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + + //************************************************************ + //** Series data points loop + //************************************************************ + int index = 1; + foreach( DataPoint point in ser.Points ) + { + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Get point X position + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + } + float xPosition = (float)HAxis.GetPosition( xValue ); + + double yValue0 = VAxis.GetLogValue( point.YValues[0] ); + double yValue1 = VAxis.GetLogValue( point.YValues[1] ); + xValue = HAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < HAxis.ViewMinimum || + xValue > HAxis.ViewMaximum || + (yValue0 < VAxis.ViewMinimum && yValue1 < VAxis.ViewMinimum) || + (yValue0 > VAxis.ViewMaximum && yValue1 > VAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Make sure High/Low values are in data scaleView range + double high = VAxis.GetLogValue( point.YValues[0] ); + double low = VAxis.GetLogValue( point.YValues[1] ); + + if( high > VAxis.ViewMaximum ) + { + high = VAxis.ViewMaximum; + } + if( high < VAxis.ViewMinimum ) + { + high = VAxis.ViewMinimum; + } + high = (float)VAxis.GetLinearPosition(high); + + if( low > VAxis.ViewMaximum ) + { + low = VAxis.ViewMaximum; + } + if( low < VAxis.ViewMinimum ) + { + low = VAxis.ViewMinimum; + } + low = VAxis.GetLinearPosition(low); + + // Remeber pre-calculated point position + point.positionRel = new PointF((float)xPosition, (float)high); + + if( common.ProcessModePaint ) + { + + // Check if chart is partialy in the data scaleView + bool clipRegionSet = false; + if(xValue == HAxis.ViewMinimum || xValue == HAxis.ViewMaximum ) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw Hi-Low line + graph.DrawLineRel( + point.Color, + point.BorderWidth, + point.BorderDashStyle, + new PointF(xPosition, (float)high), + new PointF(xPosition, (float)low), + ser.ShadowColor, + ser.ShadowOffset ); + + // Draw Open-Close marks + DrawOpenCloseMarks(graph, area, ser, point, xPosition, width); + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + } + + if( common.ProcessModeRegions ) + { + // Calculate rect around the hi-lo line and open-close marks + RectangleF areaRect = RectangleF.Empty; + areaRect.X = xPosition - width / 2f; + areaRect.Y = (float)Math.Min(high, low); + areaRect.Width = width; + areaRect.Height = (float)Math.Max(high, low) - areaRect.Y; + + common.HotRegionsList.AddHotRegion( + areaRect, + point, + ser.Name, + index - 1 ); + + } + ++index; + } + + //************************************************************ + //** Second series data points loop, when markers and labels + //** are drawn. + //************************************************************ + + int markerIndex = 0; + index = 1; + foreach( DataPoint point in ser.Points ) + { + // Get point X position + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + } + float xPosition = (float)HAxis.GetPosition( xValue ); + + double yValue0 = VAxis.GetLogValue( point.YValues[0] ); + double yValue1 = VAxis.GetLogValue( point.YValues[1] ); + xValue = HAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < HAxis.ViewMinimum || + xValue > HAxis.ViewMaximum || + (yValue0 < VAxis.ViewMinimum && yValue1 < VAxis.ViewMinimum) || + (yValue0 > VAxis.ViewMaximum && yValue1 > VAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Make sure High/Low values are in data scaleView range + double high = VAxis.GetLogValue( point.YValues[0] ); + double low = VAxis.GetLogValue( point.YValues[1] ); + + if( high > VAxis.ViewMaximum ) + { + high = VAxis.ViewMaximum; + } + if( high < VAxis.ViewMinimum ) + { + high = VAxis.ViewMinimum; + } + high = (float)VAxis.GetLinearPosition(high); + + if( low > VAxis.ViewMaximum ) + { + low = VAxis.ViewMaximum; + } + if( low < VAxis.ViewMinimum ) + { + low = VAxis.ViewMinimum; + } + low = VAxis.GetLinearPosition(low); + + // Draw marker + if(point.MarkerStyle != MarkerStyle.None || point.MarkerImage.Length > 0) + { + // Get marker size + SizeF markerSize = SizeF.Empty; + markerSize.Width = point.MarkerSize; + markerSize.Height = point.MarkerSize; + if (graph != null && graph.Graphics != null) + { + // Marker size is in pixels and we do the mapping for higher DPIs + markerSize.Width = point.MarkerSize * graph.Graphics.DpiX / 96; + markerSize.Height = point.MarkerSize * graph.Graphics.DpiY / 96; + } + + if (point.MarkerImage.Length > 0) + common.ImageLoader.GetAdjustedImageSize(point.MarkerImage, graph.Graphics, ref markerSize); + + // Get marker position + PointF markerPosition = PointF.Empty; + markerPosition.X = xPosition; + markerPosition.Y = (float)high - graph.GetRelativeSize(markerSize).Height/2f; + + // Draw marker + if(markerIndex == 0) + { + // Draw the marker + graph.DrawMarkerRel(markerPosition, + point.MarkerStyle, + (int)markerSize.Height, + (point.MarkerColor == Color.Empty) ? point.Color : point.MarkerColor, + (point.MarkerBorderColor == Color.Empty) ? point.BorderColor : point.MarkerBorderColor, + point.MarkerBorderWidth, + point.MarkerImage, + point.MarkerImageTransparentColor, + (point.series != null) ? point.series.ShadowOffset : 0, + (point.series != null) ? point.series.ShadowColor : Color.Empty, + new RectangleF(markerPosition.X, markerPosition.Y, markerSize.Width, markerSize.Height)); + + if( common.ProcessModeRegions ) + { + // Get relative marker size + SizeF relativeMarkerSize = graph.GetRelativeSize(markerSize); + + // Insert area just after the last custom area + int insertIndex = common.HotRegionsList.FindInsertIndex(); + common.HotRegionsList.FindInsertIndex(); + + // Insert circle area + if(point.MarkerStyle == MarkerStyle.Circle) + { + float[] circCoord = new float[3]; + circCoord[0] = markerPosition.X; + circCoord[1] = markerPosition.Y; + circCoord[2] = relativeMarkerSize.Width/2f; + + common.HotRegionsList.AddHotRegion( + insertIndex, + graph, + circCoord[0], + circCoord[1], + circCoord[2], + point, + ser.Name, + index - 1 ); + } + // All other markers represented as rectangles + else + { + common.HotRegionsList.AddHotRegion( + new RectangleF(markerPosition.X - relativeMarkerSize.Width/2f, markerPosition.Y - relativeMarkerSize.Height/2f, relativeMarkerSize.Width, relativeMarkerSize.Height), + point, + ser.Name, + index - 1 ); + } + } + + } + + // Increase the markers counter + ++markerIndex; + if(ser.MarkerStep == markerIndex) + { + markerIndex = 0; + } + } + + // Draw label + DrawLabel(common, area, graph, ser, point, new PointF(xPosition, (float)Math.Min(high, low)), index); + + // Increase point counter + ++index; + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + } + } + + /// + /// Draws stock chart open-close marks depending on selected style. + /// + /// Chart graphics object. + /// Chart area. + /// Data point series. + /// Data point to draw. + /// X position. + /// Point width. + virtual protected void DrawOpenCloseMarks( + ChartGraphics graph, + ChartArea area, + Series ser, + DataPoint point, + float xPosition, + float width) + { + double openY = VAxis.GetLogValue( point.YValues[2] ); + double closeY = VAxis.GetLogValue( point.YValues[3] ); + + // Check if mark is inside data scaleView + if( (openY > VAxis.ViewMaximum || + openY < VAxis.ViewMinimum) && + (closeY > VAxis.ViewMaximum || + closeY < VAxis.ViewMinimum) ) + { + //return; + } + + // Calculate open-close position + float open = (float)VAxis.GetLinearPosition(openY); + float close = (float)VAxis.GetLinearPosition(closeY); + SizeF absSize = graph.GetAbsoluteSize(new SizeF(width, width)); + float height = graph.GetRelativeSize(absSize).Height; + + // Detect style + StockOpenCloseMarkStyle style = openCloseStyle; + string styleType = ""; + if(point.IsCustomPropertySet(CustomPropertyName.OpenCloseStyle)) + { + styleType = point[CustomPropertyName.OpenCloseStyle]; + } + else if(ser.IsCustomPropertySet(CustomPropertyName.OpenCloseStyle)) + { + styleType = ser[CustomPropertyName.OpenCloseStyle]; + } + + if(styleType != null && styleType.Length > 0) + { + if(String.Compare(styleType, "Candlestick", StringComparison.OrdinalIgnoreCase) == 0) + { + style = StockOpenCloseMarkStyle.Candlestick; + } + else if (String.Compare(styleType, "Triangle", StringComparison.OrdinalIgnoreCase) == 0) + { + style = StockOpenCloseMarkStyle.Triangle; + } + else if (String.Compare(styleType, "Line", StringComparison.OrdinalIgnoreCase) == 0) + { + style = StockOpenCloseMarkStyle.Line; + } + } + + // Get attribute which controls if open/close marks are shown + bool showOpen = true; + bool showClose = true; + string showOpenClose = ""; + if(point.IsCustomPropertySet(CustomPropertyName.ShowOpenClose)) + { + showOpenClose = point[CustomPropertyName.ShowOpenClose]; + } + else if(ser.IsCustomPropertySet(CustomPropertyName.ShowOpenClose)) + { + showOpenClose = ser[CustomPropertyName.ShowOpenClose]; + } + + if(showOpenClose != null && showOpenClose.Length > 0) + { + if(String.Compare(showOpenClose, "Both", StringComparison.OrdinalIgnoreCase) == 0) + { + showOpen = true; + showClose = true; + } + else if (String.Compare(showOpenClose, "Open", StringComparison.OrdinalIgnoreCase) == 0) + { + showOpen = true; + showClose = false; + } + else if (String.Compare(showOpenClose, "Close", StringComparison.OrdinalIgnoreCase) == 0) + { + showOpen = false; + showClose = true; + } + } + + // Check if chart is partialy in the data scaleView + bool clipRegionSet = false; + if( style == StockOpenCloseMarkStyle.Candlestick || (xPosition - width / 2f) < area.PlotAreaPosition.X || (xPosition + width / 2f) > area.PlotAreaPosition.Right) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + + // Draw open-close marks as bar + if(forceCandleStick || style == StockOpenCloseMarkStyle.Candlestick) + { + // Colors used to draw bar of the open-close style + ColorConverter colorConverter = new ColorConverter(); + Color priceUpColor = point.Color; + Color priceDownColor = point.BackSecondaryColor; + + // Check if special color properties are set + string attrValue = point[CustomPropertyName.PriceUpColor]; + if(attrValue != null && attrValue.Length > 0) + { + bool failed = false; + try + { + priceUpColor = (Color)colorConverter.ConvertFromString(attrValue); + } + catch (ArgumentException) + { + failed = true; + } + catch (NotSupportedException) + { + failed = true; + } + + if (failed) + { + priceUpColor = (Color)colorConverter.ConvertFromInvariantString(attrValue); + } + } + + attrValue = point[CustomPropertyName.PriceDownColor]; + if(attrValue != null && attrValue.Length > 0) + { + bool failed = false; + try + { + priceDownColor = (Color)colorConverter.ConvertFromString(attrValue); + } + catch (ArgumentException) + { + failed = true; + } + catch (NotSupportedException) + { + failed = true; + } + + if (failed) + { + priceDownColor = (Color)colorConverter.ConvertFromInvariantString(attrValue); + } + } + + // Calculate bar rectangle + RectangleF rect = RectangleF.Empty; + rect.Y = (float)Math.Min(open, close); + rect.X = xPosition - width / 2f; + rect.Height = (float)Math.Max(open, close) - rect.Y; + rect.Width = width; + + // Bar and border color + Color barColor = (open > close) ? priceUpColor : priceDownColor; + Color barBorderColor = (point.BorderColor == Color.Empty) ? (barColor == Color.Empty) ? point.Color : barColor : point.BorderColor; + + // Get absolute height + SizeF sizeOfHeight = new SizeF( rect.Height, rect.Height ); + sizeOfHeight = graph.GetAbsoluteSize( sizeOfHeight ); + + // Draw open-close bar + if( sizeOfHeight.Height > 1 ) + { + graph.FillRectangleRel( + rect, + barColor, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + point.BackSecondaryColor, + barBorderColor, + point.BorderWidth, + point.BorderDashStyle, + ser.ShadowColor, + ser.ShadowOffset, + PenAlignment.Inset ); + } + else + { + graph.DrawLineRel(barBorderColor, point.BorderWidth, point.BorderDashStyle, + new PointF(rect.X, rect.Y), + new PointF(rect.Right, rect.Y), + ser.ShadowColor, ser.ShadowOffset ); + } + } + + // Draw open-close marks as triangals + else if(style == StockOpenCloseMarkStyle.Triangle) + { + using (GraphicsPath path = new GraphicsPath()) + { + PointF point1 = graph.GetAbsolutePoint(new PointF(xPosition, open)); + PointF point2 = graph.GetAbsolutePoint(new PointF(xPosition - width / 2f, open + height / 2f)); + PointF point3 = graph.GetAbsolutePoint(new PointF(xPosition - width / 2f, open - height / 2f)); + + using (Brush brush = new SolidBrush(point.Color)) + { + // Draw Open mark line + if (showOpen) + { + if (openY <= VAxis.ViewMaximum && openY >= VAxis.ViewMinimum) + { + path.AddLine(point2, point1); + path.AddLine(point1, point3); + path.AddLine(point3, point3); + graph.FillPath(brush, path); + } + } + + // Draw close mark line + if (showClose) + { + if (closeY <= VAxis.ViewMaximum && closeY >= VAxis.ViewMinimum) + { + path.Reset(); + point1 = graph.GetAbsolutePoint(new PointF(xPosition, close)); + point2 = graph.GetAbsolutePoint(new PointF(xPosition + width / 2f, close + height / 2f)); + point3 = graph.GetAbsolutePoint(new PointF(xPosition + width / 2f, close - height / 2f)); + path.AddLine(point2, point1); + path.AddLine(point1, point3); + path.AddLine(point3, point3); + graph.FillPath(brush, path); + } + } + } + } + + } + + // Draw ope-close marks as lines + else + { + // Draw Open mark line + if(showOpen) + { + if(openY <= VAxis.ViewMaximum && openY >= VAxis.ViewMinimum) + { + graph.DrawLineRel(point.Color, point.BorderWidth, point.BorderDashStyle, + new PointF(xPosition - width/2f, open), + new PointF(xPosition, open), + ser.ShadowColor, ser.ShadowOffset ); + } + } + + // Draw Close mark line + if(showClose) + { + if(closeY <= VAxis.ViewMaximum && closeY >= VAxis.ViewMinimum) + { + graph.DrawLineRel(point.Color, point.BorderWidth, point.BorderDashStyle, + new PointF(xPosition, close), + new PointF(xPosition + width/2f, close), + ser.ShadowColor, ser.ShadowOffset ); + } + } + } + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + } + + /// + /// Draws stock chart data point label. + /// + /// The Common elements object + /// Chart area for this chart + /// Chart graphics object. + /// Data point series. + /// Data point to draw. + /// Label position. + /// Data point index in the series. + virtual protected void DrawLabel( + CommonElements common, + ChartArea area, + ChartGraphics graph, + Series ser, + DataPoint point, + PointF position, + int pointIndex) + { + if(ser.IsValueShownAsLabel || point.IsValueShownAsLabel || point.Label.Length > 0) + { + // Label text format + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + if (point.LabelAngle == 0) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Far; + } + + // Get label text + string text; + if (point.Label.Length == 0) + { + // Check what value to show (High, Low, Open, Close) + int valueIndex = 3; + string valueType = ""; + if (point.IsCustomPropertySet(CustomPropertyName.LabelValueType)) + { + valueType = point[CustomPropertyName.LabelValueType]; + } + else if (ser.IsCustomPropertySet(CustomPropertyName.LabelValueType)) + { + valueType = ser[CustomPropertyName.LabelValueType]; + } + + if (String.Compare(valueType, "High", StringComparison.OrdinalIgnoreCase) == 0) + { + valueIndex = 0; + } + else if (String.Compare(valueType, "Low", StringComparison.OrdinalIgnoreCase) == 0) + { + valueIndex = 1; + } + else if (String.Compare(valueType, "Open", StringComparison.OrdinalIgnoreCase) == 0) + { + valueIndex = 2; + } + + text = ValueConverter.FormatValue( + ser.Chart, + point, + point.Tag, + point.YValues[valueIndex], + point.LabelFormat, + ser.YValueType, + ChartElementType.DataPoint); + } + else + { + text = point.ReplaceKeywords(point.Label); + } + + // Get text angle + int textAngle = point.LabelAngle; + + // Check if text contains white space only + if (text.Trim().Length != 0) + { + SizeF sizeFont = SizeF.Empty; + + + // Check if Smart Labels are enabled + if (ser.SmartLabelStyle.Enabled) + { + // Get marker size + SizeF markerSize = SizeF.Empty; + markerSize.Width = point.MarkerSize; + markerSize.Height = point.MarkerSize; + if (graph != null && graph.Graphics != null) + { + // Marker size is in pixels and we do the mapping for higher DPIs + markerSize.Width = point.MarkerSize * graph.Graphics.DpiX / 96; + markerSize.Height = point.MarkerSize * graph.Graphics.DpiY / 96; + } + + if (point.MarkerImage.Length > 0) + common.ImageLoader.GetAdjustedImageSize(point.MarkerImage, graph.Graphics, ref markerSize); + + // Get point label style attribute + markerSize = graph.GetRelativeSize(markerSize); + sizeFont = graph.GetRelativeSize(graph.MeasureString(text, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic)); + + // Adjust label position using SmartLabelStyle algorithm + position = area.smartLabels.AdjustSmartLabelPosition( + common, + graph, + area, + ser.SmartLabelStyle, + position, + sizeFont, + format, + position, + markerSize, + LabelAlignmentStyles.Top); + + // Smart labels always use 0 degrees text angle + textAngle = 0; + + } + + + + // Draw label + if (!position.IsEmpty) + { + RectangleF labelBackPosition = RectangleF.Empty; + + if (!point.LabelBackColor.IsEmpty || + point.LabelBorderWidth > 0 || + !point.LabelBorderColor.IsEmpty) + { + // Get text size + if (sizeFont.IsEmpty) + { + sizeFont = graph.GetRelativeSize(graph.MeasureString(text, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic)); + } + + // Adjust label y coordinate + position.Y -= sizeFont.Height / 8; + + // Get label background position + SizeF sizeLabel = new SizeF(sizeFont.Width, sizeFont.Height); + sizeLabel.Height += sizeFont.Height / 8; + sizeLabel.Width += sizeLabel.Width / text.Length; + labelBackPosition = PointChart.GetLabelPosition( + graph, + position, + sizeLabel, + format, + true); + } + + + // Draw label text + using (Brush brush = new SolidBrush(point.LabelForeColor)) + { + graph.DrawPointLabelStringRel( + common, + text, + point.Font, + brush, + position, + format, + textAngle, + labelBackPosition, + + point.LabelBackColor, + point.LabelBorderColor, + point.LabelBorderWidth, + point.LabelBorderDashStyle, + ser, + point, + pointIndex - 1); + } + } + } + } + } + } + + #endregion + + #region 3D Drawing and Selection methods + + /// + /// This method recalculates size of the bars. This method is used + /// from Paint or Select method. + /// + /// If True selection mode is active, otherwise paint mode is active. + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual protected void ProcessChartType3D( + bool selection, + ChartGraphics graph, + CommonElements common, + ChartArea area, + Series seriesToDraw ) + { + + // All data series from chart area which have Stock chart type + List typeSeries = area.GetSeriesFromChartType(this.Name); + + // Zero X values mode. + bool indexedSeries = ChartHelper.IndexedSeries(common, typeSeries.ToArray() ); + + //************************************************************ + //** Loop through all series + //************************************************************ + foreach( Series ser in common.DataManager.Series ) + { + // Process non empty series of the area with stock chart type + if( String.Compare( ser.ChartTypeName, this.Name, StringComparison.OrdinalIgnoreCase ) != 0 + || ser.ChartArea != area.Name || !ser.IsVisible()) + { + continue; + } + + // Check if drawn series is specified + if(seriesToDraw != null && seriesToDraw.Name != ser.Name) + { + continue; + } + + // Check that we have at least 4 Y values + if(ser.YValuesPerPoint < 4) + { + throw(new ArgumentException(SR.ExceptionChartTypeRequiresYValues("StockChart", "4" ))); + } + + // Set active horizontal/vertical axis + HAxis = area.GetAxis(AxisName.X, ser.XAxisType, ser.XSubAxisName); + VAxis = area.GetAxis(AxisName.Y, ser.YAxisType, ser.YSubAxisName); + + // Get interval between points + double interval = (indexedSeries) ? 1 : area.GetPointsInterval( HAxis.IsLogarithmic, HAxis.logarithmBase ); + + // Calculates the width of the candles. + float width = (float)(ser.GetPointWidth(graph, HAxis, interval, 0.8)); + + // Call Back Paint event + if( !selection ) + { + common.Chart.CallOnPrePaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + + //************************************************************ + //** Get series depth and Z position + //************************************************************ + float seriesDepth, seriesZPosition; + area.GetSeriesZPositionAndDepth(ser, out seriesDepth, out seriesZPosition); + + //************************************************************ + //** Series data points loop + //************************************************************ + int index = 1; + foreach( DataPoint point in ser.Points ) + { + // Reset pre-calculated point position + point.positionRel = new PointF(float.NaN, float.NaN); + + // Get point X position + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + } + float xPosition = (float)HAxis.GetPosition( xValue ); + + double yValue0 = VAxis.GetLogValue( point.YValues[0] ); + double yValue1 = VAxis.GetLogValue( point.YValues[1] ); + xValue = HAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < HAxis.ViewMinimum || + xValue > HAxis.ViewMaximum || + (yValue0 < VAxis.ViewMinimum && yValue1 < VAxis.ViewMinimum) || + (yValue0 > VAxis.ViewMaximum && yValue1 > VAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Check if chart is partialy in the data scaleView + bool clipRegionSet = false; + if(xValue == HAxis.ViewMinimum || xValue == HAxis.ViewMaximum ) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + // Make sure High/Low values are in data scaleView range + double high = VAxis.GetLogValue( point.YValues[0] ); + double low = VAxis.GetLogValue( point.YValues[1] ); + + if( high > VAxis.ViewMaximum ) + { + high = VAxis.ViewMaximum; + } + if( high < VAxis.ViewMinimum ) + { + high = VAxis.ViewMinimum; + } + high = (float)VAxis.GetLinearPosition(high); + + if( low > VAxis.ViewMaximum ) + { + low = VAxis.ViewMaximum; + } + if( low < VAxis.ViewMinimum ) + { + low = VAxis.ViewMinimum; + } + low = VAxis.GetLinearPosition(low); + + // Remeber pre-calculated point position + point.positionRel = new PointF((float)xPosition, (float)high); + + // 3D Transform coordinates + Point3D[] points = new Point3D[2]; + points[0] = new Point3D(xPosition, (float)high, seriesZPosition+seriesDepth/2f); + points[1] = new Point3D(xPosition, (float)low, seriesZPosition+seriesDepth/2f); + area.matrix3D.TransformPoints(points); + + // Start Svg Selection mode + graph.StartHotRegion( point ); + + // Draw Hi-Low line + graph.DrawLineRel( + point.Color, + point.BorderWidth, + point.BorderDashStyle, + points[0].PointF, + points[1].PointF, + ser.ShadowColor, + ser.ShadowOffset ); + + // Draw Open-Close marks + DrawOpenCloseMarks3D(graph, area, ser, point, xPosition, width, seriesZPosition, seriesDepth); + xPosition = points[0].X; + high = points[0].Y; + low = points[1].Y; + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + + if( common.ProcessModeRegions ) + { + // Calculate rect around the hi-lo line and open-close marks + RectangleF areaRect = RectangleF.Empty; + areaRect.X = xPosition - width / 2f; + areaRect.Y = (float)Math.Min(high, low); + areaRect.Width = width; + areaRect.Height = (float)Math.Max(high, low) - areaRect.Y; + + common.HotRegionsList.AddHotRegion( + areaRect, + point, + ser.Name, + index - 1 ); + + } + + ++index; + } + + //************************************************************ + //** Second series data points loop, when markers and labels + //** are drawn. + //************************************************************ + int markerIndex = 0; + index = 1; + foreach( DataPoint point in ser.Points ) + { + // Get point X position + double xValue = point.XValue; + if( indexedSeries ) + { + xValue = (double)index; + } + float xPosition = (float)HAxis.GetPosition( xValue ); + + double yValue0 = VAxis.GetLogValue( point.YValues[0] ); + double yValue1 = VAxis.GetLogValue( point.YValues[1] ); + xValue = HAxis.GetLogValue(xValue); + + // Check if chart is completly out of the data scaleView + if(xValue < HAxis.ViewMinimum || + xValue > HAxis.ViewMaximum || + (yValue0 < VAxis.ViewMinimum && yValue1 < VAxis.ViewMinimum) || + (yValue0 > VAxis.ViewMaximum && yValue1 > VAxis.ViewMaximum) ) + { + ++index; + continue; + } + + // Make sure High/Low values are in data scaleView range + double high = VAxis.GetLogValue( point.YValues[0] ); + double low = VAxis.GetLogValue( point.YValues[1] ); + + if( high > VAxis.ViewMaximum ) + { + high = VAxis.ViewMaximum; + } + if( high < VAxis.ViewMinimum ) + { + high = VAxis.ViewMinimum; + } + high = (float)VAxis.GetLinearPosition(high); + + if( low > VAxis.ViewMaximum ) + { + low = VAxis.ViewMaximum; + } + if( low < VAxis.ViewMinimum ) + { + low = VAxis.ViewMinimum; + } + low = VAxis.GetLinearPosition(low); + + + // 3D Transform coordinates + Point3D[] points = new Point3D[2]; + points[0] = new Point3D(xPosition, (float)high, seriesZPosition+seriesDepth/2f); + points[1] = new Point3D(xPosition, (float)low, seriesZPosition+seriesDepth/2f); + area.matrix3D.TransformPoints(points); + xPosition = points[0].X; + high = points[0].Y; + low = points[1].Y; + + // Draw label + DrawLabel(common, area, graph, ser, point, new PointF(xPosition, (float)Math.Min(high, low)), index); + + // Draw marker + if(point.MarkerStyle != MarkerStyle.None || point.MarkerImage.Length > 0) + { + // Get marker size + SizeF markerSize = SizeF.Empty; + markerSize.Width = point.MarkerSize; + markerSize.Height = point.MarkerSize; + if (graph != null && graph.Graphics != null) + { + // Marker size is in pixels and we do the mapping for higher DPIs + markerSize.Width = point.MarkerSize * graph.Graphics.DpiX / 96; + markerSize.Height = point.MarkerSize * graph.Graphics.DpiY / 96; + } + + if (point.MarkerImage.Length > 0) + common.ImageLoader.GetAdjustedImageSize(point.MarkerImage, graph.Graphics, ref markerSize); + + // Get marker position + PointF markerPosition = PointF.Empty; + markerPosition.X = xPosition; + markerPosition.Y = (float)high - graph.GetRelativeSize(markerSize).Height/2f; + + // Draw marker + if(markerIndex == 0) + { + // Draw the marker + graph.DrawMarkerRel(markerPosition, + point.MarkerStyle, + (int)markerSize.Height, + (point.MarkerColor == Color.Empty) ? point.Color : point.MarkerColor, + (point.MarkerBorderColor == Color.Empty) ? point.BorderColor : point.MarkerBorderColor, + point.MarkerBorderWidth, + point.MarkerImage, + point.MarkerImageTransparentColor, + (point.series != null) ? point.series.ShadowOffset : 0, + (point.series != null) ? point.series.ShadowColor : Color.Empty, + new RectangleF(markerPosition.X, markerPosition.Y, markerSize.Width, markerSize.Height)); + + if( common.ProcessModeRegions ) + { + // Get relative marker size + SizeF relativeMarkerSize = graph.GetRelativeSize(markerSize); + + // Insert area just after the last custom area + int insertIndex = common.HotRegionsList.FindInsertIndex(); + common.HotRegionsList.FindInsertIndex(); + + // Insert circle area + if(point.MarkerStyle == MarkerStyle.Circle) + { + float[] circCoord = new float[3]; + circCoord[0] = markerPosition.X; + circCoord[1] = markerPosition.Y; + circCoord[2] = relativeMarkerSize.Width/2f; + + common.HotRegionsList.AddHotRegion( + insertIndex, + graph, + circCoord[0], + circCoord[1], + circCoord[2], + point, + ser.Name, + index - 1 ); + } + // All other markers represented as rectangles + else + { + common.HotRegionsList.AddHotRegion( + new RectangleF(markerPosition.X - relativeMarkerSize.Width/2f, markerPosition.Y - relativeMarkerSize.Height/2f, relativeMarkerSize.Width, relativeMarkerSize.Height), + point, + ser.Name, + index - 1 ); + } + } + } + + // Increase the markers counter + ++markerIndex; + if(ser.MarkerStep == markerIndex) + { + markerIndex = 0; + } + } + ++index; + } + + // Call Paint event + if( !selection ) + { + common.Chart.CallOnPostPaint(new ChartPaintEventArgs(ser, graph, common, area.PlotAreaPosition)); + } + } + } + + /// + /// Draws stock chart open-close marks depending on selected style. + /// + /// Chart graphics object. + /// Chart area. + /// Data point series. + /// Data point to draw. + /// X position. + /// Point width. + /// Series Z position. + /// Series depth. + virtual protected void DrawOpenCloseMarks3D( + ChartGraphics graph, + ChartArea area, + Series ser, + DataPoint point, + float xPosition, + float width, + float zPosition, + float depth) + { + double openY = VAxis.GetLogValue( point.YValues[2] ); + double closeY = VAxis.GetLogValue( point.YValues[3] ); + + // Check if mark is inside data scaleView + if( (openY > VAxis.ViewMaximum || + openY < VAxis.ViewMinimum) && + (closeY > VAxis.ViewMaximum || + closeY < VAxis.ViewMinimum) ) + { + //return; + } + + // Calculate open-close position + float open = (float)VAxis.GetLinearPosition(openY); + float close = (float)VAxis.GetLinearPosition(closeY); + SizeF absSize = graph.GetAbsoluteSize(new SizeF(width, width)); + float height = graph.GetRelativeSize(absSize).Height; + + // Detect style + StockOpenCloseMarkStyle style = openCloseStyle; + string styleType = ""; + if(point.IsCustomPropertySet(CustomPropertyName.OpenCloseStyle)) + { + styleType = point[CustomPropertyName.OpenCloseStyle]; + } + else if(ser.IsCustomPropertySet(CustomPropertyName.OpenCloseStyle)) + { + styleType = ser[CustomPropertyName.OpenCloseStyle]; + } + + if(styleType != null && styleType.Length > 0) + { + if(String.Compare(styleType, "Candlestick", StringComparison.OrdinalIgnoreCase) == 0) + { + style = StockOpenCloseMarkStyle.Candlestick; + } + else if (String.Compare(styleType, "Triangle", StringComparison.OrdinalIgnoreCase) == 0) + { + style = StockOpenCloseMarkStyle.Triangle; + } + else if (String.Compare(styleType, "Line", StringComparison.OrdinalIgnoreCase) == 0) + { + style = StockOpenCloseMarkStyle.Line; + } + } + + // Get attribute which controls if open/close marks are shown + bool showOpen = true; + bool showClose = true; + string showOpenClose = ""; + if(point.IsCustomPropertySet(CustomPropertyName.ShowOpenClose)) + { + showOpenClose = point[CustomPropertyName.ShowOpenClose]; + } + else if(ser.IsCustomPropertySet(CustomPropertyName.ShowOpenClose)) + { + showOpenClose = ser[CustomPropertyName.ShowOpenClose]; + } + + if(showOpenClose != null && showOpenClose.Length > 0) + { + if(String.Compare(showOpenClose, "Both", StringComparison.OrdinalIgnoreCase) == 0) + { + showOpen = true; + showClose = true; + } + else if (String.Compare(showOpenClose, "Open", StringComparison.OrdinalIgnoreCase) == 0) + { + showOpen = true; + showClose = false; + } + else if (String.Compare(showOpenClose, "Close", StringComparison.OrdinalIgnoreCase) == 0) + { + showOpen = false; + showClose = true; + } + } + + // Check if chart is partialy in the data scaleView + bool clipRegionSet = false; + if((xPosition - width / 2f) < area.PlotAreaPosition.X || (xPosition + width / 2f) > area.PlotAreaPosition.Right) + { + // Set clipping region for line drawing + graph.SetClip( area.PlotAreaPosition.ToRectangleF() ); + clipRegionSet = true; + } + + + // Draw open-close marks as bar + if(forceCandleStick || style == StockOpenCloseMarkStyle.Candlestick) + { + // Colors used to draw bar of the open-close style + ColorConverter colorConverter = new ColorConverter(); + Color priceUpColor = point.Color; + Color priceDownColor = point.BackSecondaryColor; + + // Check if special color properties are set + string attrValue = point[CustomPropertyName.PriceUpColor]; + if(attrValue != null && attrValue.Length > 0) + { + bool failed = false; + try + { + priceUpColor = (Color)colorConverter.ConvertFromString(attrValue); + } + catch (NotSupportedException) + { + failed = true; + } + catch (ArgumentException) + { + failed = true; + } + + if (failed) + { + priceUpColor = (Color)colorConverter.ConvertFromInvariantString(attrValue); + } + } + + attrValue = point[CustomPropertyName.PriceDownColor]; + if(attrValue != null && attrValue.Length > 0) + { + bool failed = false; + try + { + priceDownColor = (Color)colorConverter.ConvertFromString(attrValue); + } + catch (ArgumentException) + { + failed = true; + } + catch (NotSupportedException) + { + failed = true; + } + + if (failed) + { + priceDownColor = (Color)colorConverter.ConvertFromInvariantString(attrValue); + } + } + + // Calculate bar rectangle + RectangleF rect = RectangleF.Empty; + rect.Y = (float)Math.Min(open, close); + rect.X = xPosition - width / 2f; + rect.Height = (float)Math.Max(open, close) - rect.Y; + rect.Width = width; + + // Bar and border color + Color barColor = (open > close) ? priceUpColor : priceDownColor; + Color barBorderColor = (point.BorderColor == Color.Empty) ? (barColor == Color.Empty) ? point.Color : barColor : point.BorderColor; + + // Translate coordinates + Point3D[] points = new Point3D[2]; + points[0] = new Point3D(rect.X, rect.Y, zPosition + depth/2f); + points[1] = new Point3D(rect.Right, rect.Bottom, zPosition + depth/2f); + area.matrix3D.TransformPoints(points); + rect.Location = points[0].PointF; + rect.Width = (float)Math.Abs(points[1].X - points[0].X); + rect.Height = (float)Math.Abs(points[1].Y - points[0].Y); + + // Draw open-close bar + if(rect.Height > 1) + { + graph.FillRectangleRel( + rect, + barColor, + point.BackHatchStyle, + point.BackImage, + point.BackImageWrapMode, + point.BackImageTransparentColor, + point.BackImageAlignment, + point.BackGradientStyle, + point.BackSecondaryColor, + barBorderColor, + point.BorderWidth, + point.BorderDashStyle, + ser.ShadowColor, + ser.ShadowOffset, + PenAlignment.Inset); + } + else + { + graph.DrawLineRel(barBorderColor, point.BorderWidth, point.BorderDashStyle, + new PointF(rect.X, rect.Y), + new PointF(rect.Right, rect.Y), + ser.ShadowColor, ser.ShadowOffset ); + } + } + + // Draw open-close marks as triangals + else if(style == StockOpenCloseMarkStyle.Triangle) + { + using (GraphicsPath path = new GraphicsPath()) + { + + // Translate coordinates + Point3D[] points = new Point3D[3]; + points[0] = new Point3D(xPosition, open, zPosition + depth / 2f); + points[1] = new Point3D(xPosition - width / 2f, open + height / 2f, zPosition + depth / 2f); + points[2] = new Point3D(xPosition - width / 2f, open - height / 2f, zPosition + depth / 2f); + area.matrix3D.TransformPoints(points); + points[0].PointF = graph.GetAbsolutePoint(points[0].PointF); + points[1].PointF = graph.GetAbsolutePoint(points[1].PointF); + points[2].PointF = graph.GetAbsolutePoint(points[2].PointF); + + using (Brush brush = new SolidBrush(point.Color)) + { + // Draw Open mark line + if (showOpen) + { + if (openY <= VAxis.ViewMaximum && openY >= VAxis.ViewMinimum) + { + path.AddLine(points[1].PointF, points[0].PointF); + path.AddLine(points[0].PointF, points[2].PointF); + path.AddLine(points[2].PointF, points[2].PointF); + graph.FillPath(brush, path); + } + } + + // Draw close mark line + if (showClose) + { + if (closeY <= VAxis.ViewMaximum && closeY >= VAxis.ViewMinimum) + { + points[0] = new Point3D(xPosition, close, zPosition + depth / 2f); + points[1] = new Point3D(xPosition + width / 2f, close + height / 2f, zPosition + depth / 2f); + points[2] = new Point3D(xPosition + width / 2f, close - height / 2f, zPosition + depth / 2f); + area.matrix3D.TransformPoints(points); + points[0].PointF = graph.GetAbsolutePoint(points[0].PointF); + points[1].PointF = graph.GetAbsolutePoint(points[1].PointF); + points[2].PointF = graph.GetAbsolutePoint(points[2].PointF); + + path.Reset(); + path.AddLine(points[1].PointF, points[0].PointF); + path.AddLine(points[0].PointF, points[2].PointF); + path.AddLine(points[2].PointF, points[2].PointF); + graph.FillPath(brush, path); + } + } + } + } + } + + // Draw ope-close marks as lines + else + { + // Draw Open mark line + if(showOpen) + { + if(openY <= VAxis.ViewMaximum && openY >= VAxis.ViewMinimum) + { + // Translate coordinates + Point3D[] points = new Point3D[2]; + points[0] = new Point3D(xPosition - width/2f, open, zPosition + depth/2f); + points[1] = new Point3D(xPosition, open, zPosition + depth/2f); + area.matrix3D.TransformPoints(points); + + graph.DrawLineRel(point.Color, point.BorderWidth, point.BorderDashStyle, + points[0].PointF, + points[1].PointF, + ser.ShadowColor, ser.ShadowOffset ); + } + } + + // Draw Close mark line + if(showClose) + { + if(closeY <= VAxis.ViewMaximum && closeY >= VAxis.ViewMinimum) + { + // Translate coordinates + Point3D[] points = new Point3D[2]; + points[0] = new Point3D(xPosition, close, zPosition + depth/2f); + points[1] = new Point3D(xPosition + width/2f, close, zPosition + depth/2f); + area.matrix3D.TransformPoints(points); + + graph.DrawLineRel(point.Color, point.BorderWidth, point.BorderDashStyle, + points[0].PointF, + points[1].PointF, + ser.ShadowColor, ser.ShadowOffset ); + } + } + } + + // Reset Clip Region + if(clipRegionSet) + { + graph.ResetClip(); + } + } + + #endregion + + #region Y values related methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + return point.YValues[yValueIndex]; + } + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + // Check if series is indexed + bool indexedSeries = ChartHelper.IndexedSeries(common, area.GetSeriesFromChartType(this.Name).ToArray() ); + + //************************************************************ + //** Set active horizontal/vertical axis + //************************************************************ + Axis hAxis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName); + Axis vAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName); + + //************************************************************ + //** Loop through all data points in the series + //************************************************************ + int markerIndex = 0; // Marker index + int index = 1; // Data points loop + foreach( DataPoint point in series.Points ) + { + //************************************************************ + //** Check if point values are in the chart area + //************************************************************ + + // Check for min/max Y values + double yValue = GetYValue(common, area, series, point, index - 1, 0); + + // Axis is Logarithmic + yValue = vAxis.GetLogValue( yValue ); + + if( yValue > vAxis.ViewMaximum || yValue < vAxis.ViewMinimum) + { + index++; + continue; + } + + // Check for min/max X values + double xValue = (indexedSeries) ? (double)index : point.XValue; + xValue = hAxis.GetLogValue(xValue); + if(xValue > hAxis.ViewMaximum || xValue < hAxis.ViewMinimum) + { + index++; + continue; + } + + //************************************************************ + //** Get marker position and size + //************************************************************ + + // Get marker position + PointF markerPosition = PointF.Empty; + markerPosition.Y = (float)vAxis.GetLinearPosition(yValue); + if( indexedSeries ) + { + // The formula for position is based on a distance + // from the grid line or nPoints position. + markerPosition.X = (float)hAxis.GetPosition( (double)index ); + } + else + { + markerPosition.X = (float)hAxis.GetPosition( point.XValue ); + } + + // Get point some point properties and save them in variables + string pointMarkerImage = point.MarkerImage; + MarkerStyle pointMarkerStyle = point.MarkerStyle; + + // Get marker size + SizeF markerSize = SizeF.Empty; + markerSize.Width = point.MarkerSize; + markerSize.Height = point.MarkerSize; + if (common != null && common.graph != null && common.graph.Graphics != null) + { + // Marker size is in pixels and we do the mapping for higher DPIs + markerSize.Width = point.MarkerSize * common.graph.Graphics.DpiX / 96; + markerSize.Height = point.MarkerSize * common.graph.Graphics.DpiY / 96; + } + + if (point.MarkerImage.Length > 0) + if(common.graph != null) + common.ImageLoader.GetAdjustedImageSize(point.MarkerImage, common.graph.Graphics, ref markerSize); + + // Transform marker position in 3D space + if(area.Area3DStyle.Enable3D) + { + // Get series depth and Z position + float seriesDepth, seriesZPosition; + area.GetSeriesZPositionAndDepth(series, out seriesDepth, out seriesZPosition); + + Point3D[] marker3DPosition = new Point3D[1]; + marker3DPosition[0] = new Point3D( + markerPosition.X, + markerPosition.Y, + (float)(seriesZPosition + seriesDepth/2f)); + + // Transform coordinates + area.matrix3D.TransformPoints(marker3DPosition); + markerPosition = marker3DPosition[0].PointF; + } + + // Check if marker visible + if(pointMarkerStyle != MarkerStyle.None || + pointMarkerImage.Length > 0) + { + // Check marker index + if(markerIndex == 0) + { + markerSize = common.graph.GetRelativeSize(markerSize); + + // Add marker position into the list + RectangleF markerRect = new RectangleF( + markerPosition.X - markerSize.Width / 2f, + markerPosition.Y - markerSize.Height, + markerSize.Width, + markerSize.Height); + list.Add(markerRect); + } + + // Increase the markers counter + ++markerIndex; + if(series.MarkerStep == markerIndex) + { + markerIndex = 0; + } + } + + ++index; + } + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/ChartTypes/ThreeLineBreakChart.cs b/System.Web.DataVisualization/Common/ChartTypes/ThreeLineBreakChart.cs new file mode 100644 index 000000000..5b0b74e09 --- /dev/null +++ b/System.Web.DataVisualization/Common/ChartTypes/ThreeLineBreakChart.cs @@ -0,0 +1,716 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ThreeLineBreakChart.cs +// +// Namespace: DataVisualization.Charting.ChartTypes +// +// Purpose: ThreeLineBreak chart type provides methods for +// calculations and depends on the Range Column chart +// type to do all the drawing. PrepareData method is +// used to create temporary RangeColumn series and fill +// it with data. Changes are then reversed in the +// UnPrepareData method. +// +// ThreeLineBreak Chart Overview: +// ------------------------------ +// +// The Three Line Break chart is popular in Japan for financial +// charting. These charts display a series of vertical boxes ("lines") +// that reflect changes in price values. Similar to Kagi, Renko, and +// Point & Figure charts, the Three Line Break chart ignores the +// passage of time. +// +// The Three Line Break charting method is so-named because of the +// number of lines typically used. Each line may indicate "Buy", +// "Sell", and "trend less" markets. An advantage of Three Line Break +// charts is that there is no arbitrary fixed reversal amount. It is +// the price action which gives the indication of a reversal. The +// disadvantage of Three Line Break charts is that the signals are +// generated after the new trend is well under way. However, many +// traders are willing to accept the late signals in exchange for +// calling major trends. +// +// The sensitivity of the reversal criteria can be set by changing +// the number of lines in the break. For example, short-term traders +// might use two-line breaks to get more reversals, while a +// longer-term investor might use four-line, or even 10-line breaks +// to reduce the number of reversals. This is done using the +// NumberOfLinesInBreak custom attribute. +// +// The following should be taken into account when working with +// Three Line Break charts: +// +// - The X values of data points are automatically indexed. +// +// - There is a formula applied to the original data before that data +// gets plotted. This formula changes the number of points in the data, +// and also changes the data points' X/Y values. +// +// - Due to data being recalculated, we do not recommend setting the +// minimum and/or maximum values for the X axis. This is because it +// cannot be determined how many data points will actually be plotted. +// However, if the axis' Maximum, or Minimum is set, then the Maximum, +// or Minimum properties should use data point index values. +// +// - Data point anchoring, used for annotations, is not supported in +// this type of chart. +// +// Reviewed: AG - Microsoft 7, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Resources; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel.Design; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else +using System.Web.UI.DataVisualization.Charting; + +using System.Web.UI.DataVisualization.Charting.ChartTypes; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes +#else +namespace System.Web.UI.DataVisualization.Charting.ChartTypes +#endif +{ + /// + /// ThreeLineBreakChart class provides methods to perform all nessesary + /// calculations to display ThreeLineBreak chart with the help of the + /// temporary RangeColumn series. This series is created in the + /// PrepareData method and then removed in the UnPrepareData method. + /// + internal class ThreeLineBreakChart : IChartType + { + #region Methods + + /// + /// Prepares ThreeLineBreak chart type for rendering. + /// + /// Series to be prepared. + internal static void PrepareData(Series series) + { + // Check series chart type + if(String.Compare(series.ChartTypeName, ChartTypeNames.ThreeLineBreak, StringComparison.OrdinalIgnoreCase ) != 0 || !series.IsVisible()) + { + return; + } + + // Get reference to the chart control + Chart chart = series.Chart; + if(chart == null) + { + throw (new InvalidOperationException(SR.ExceptionThreeLineBreakNullReference)); + } + + // ThreeLineBreak chart may not be combined with any other chart types + ChartArea area = chart.ChartAreas[series.ChartArea]; + foreach (Series currentSeries in chart.Series) + { + if (currentSeries.IsVisible() && currentSeries != series && area == chart.ChartAreas[currentSeries.ChartArea]) + { + throw (new InvalidOperationException(SR.ExceptionThreeLineBreakCanNotCobine)); + } + } + + // Create a temp series which will hold original series data points + Series seriesOriginalData = new Series("THREELINEBREAK_ORIGINAL_DATA_" + series.Name, series.YValuesPerPoint); + seriesOriginalData.Enabled = false; + seriesOriginalData.IsVisibleInLegend = false; + chart.Series.Add(seriesOriginalData); + foreach(DataPoint dp in series.Points) + { + seriesOriginalData.Points.Add(dp); + } + series.Points.Clear(); + if(series.IsCustomPropertySet("TempDesignData")) + { + seriesOriginalData["TempDesignData"] = "true"; + } + + + // Change ThreeLineBreak series type to range column + series["OldXValueIndexed"] = series.IsXValueIndexed.ToString(CultureInfo.InvariantCulture); + series["OldYValuesPerPoint"] = series.YValuesPerPoint.ToString(CultureInfo.InvariantCulture); + series.ChartType = SeriesChartType.RangeColumn; + series.IsXValueIndexed = true; + series.YValuesPerPoint = 2; + + // Calculate date-time interval for indexed series + if(series.ChartArea.Length > 0 && + series.IsXValueDateTime()) + { + // Get X axis connected to the series + Axis xAxis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName); + + // Change interval for auto-calculated interval only + if(xAxis.Interval == 0 && xAxis.IntervalType == DateTimeIntervalType.Auto) + { + // Check if original data has X values set to date-time values and + // calculate min/max X values. + bool nonZeroXValues = false; + double minX = double.MaxValue; + double maxX = double.MinValue; + foreach(DataPoint dp in seriesOriginalData.Points) + { + if(!dp.IsEmpty) + { + if(dp.XValue != 0.0) + { + nonZeroXValues = true; + } + if(dp.XValue > maxX) + { + maxX = dp.XValue; + } + if(dp.XValue < minX) + { + minX = dp.XValue; + } + } + } + + if(nonZeroXValues) + { + // Save flag that axis interval is automatic + series["OldAutomaticXAxisInterval"] = "true"; + + // Calculate and set axis date-time interval + DateTimeIntervalType intervalType = DateTimeIntervalType.Auto; + xAxis.interval = xAxis.CalcInterval(minX, maxX, true, out intervalType, series.XValueType); + xAxis.intervalType = intervalType; + } + } + } + + // Calculate ThreeLineBreak bricks data points values + FillThreeLineBreakData(series, seriesOriginalData); + } + + /// + /// Remove any changes done while preparing ThreeLineBreak chart type for rendering. + /// + /// Series to be un-prepared. + /// True if series was removed from collection. + internal static bool UnPrepareData(Series series) + { + if (series.Name.StartsWith("THREELINEBREAK_ORIGINAL_DATA_", StringComparison.Ordinal)) + { + // Get reference to the chart control + Chart chart = series.Chart; + if (chart == null) + { + throw (new InvalidOperationException(SR.ExceptionThreeLineBreakNullReference)); + } + + // Get original ThreeLineBreak series + Series threeLineBreakSeries = chart.Series[series.Name.Substring(29)]; + Series.MovePositionMarkers(threeLineBreakSeries, series); + // Copy data back to original ThreeLineBreak series + threeLineBreakSeries.Points.Clear(); + if (!series.IsCustomPropertySet("TempDesignData")) + { + foreach (DataPoint dp in series.Points) + { + threeLineBreakSeries.Points.Add(dp); + } + } + + // Restore ThreeLineBreak series properties + threeLineBreakSeries.ChartType = SeriesChartType.ThreeLineBreak; + + bool xValIndexed; + bool parseSucceed = bool.TryParse(threeLineBreakSeries["OldXValueIndexed"], out xValIndexed); + threeLineBreakSeries.IsXValueIndexed = parseSucceed && xValIndexed; + + int yValsPerPoint; + parseSucceed = int.TryParse(threeLineBreakSeries["OldYValuesPerPoint"], NumberStyles.Any, CultureInfo.InvariantCulture, out yValsPerPoint); + + if (parseSucceed) + { + threeLineBreakSeries.YValuesPerPoint = yValsPerPoint; + } + + + threeLineBreakSeries.DeleteCustomProperty("OldXValueIndexed"); + threeLineBreakSeries.DeleteCustomProperty("OldYValuesPerPoint"); + + series["OldAutomaticXAxisInterval"] = "true"; + if (threeLineBreakSeries.IsCustomPropertySet("OldAutomaticXAxisInterval")) + { + threeLineBreakSeries.DeleteCustomProperty("OldAutomaticXAxisInterval"); + + // Reset automatic interval for X axis + if (threeLineBreakSeries.ChartArea.Length > 0) + { + // Get X axis connected to the series + ChartArea area = chart.ChartAreas[threeLineBreakSeries.ChartArea]; + Axis xAxis = area.GetAxis(AxisName.X, threeLineBreakSeries.XAxisType, threeLineBreakSeries.XSubAxisName); + + xAxis.interval = 0.0; + xAxis.intervalType = DateTimeIntervalType.Auto; + } + } + + // Remove series from the collection + chart.Series.Remove(series); + return true; + } + + return false; + } + + /// + /// Fills range column series with data to draw the ThreeLineBreak chart. + /// + /// Range column chart series used to dispaly the ThreeLineBreak chart. + /// Series with original data. + private static void FillThreeLineBreakData(Series series, Series originalData) + { + // Get index of the Y values used + int yValueIndex = 0; + if(series.IsCustomPropertySet(CustomPropertyName.UsedYValue)) + { + try + { + yValueIndex = int.Parse(series[CustomPropertyName.UsedYValue], CultureInfo.InvariantCulture); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionThreeLineBreakUsedYValueInvalid)); + } + + if(yValueIndex >= series.YValuesPerPoint) + { + throw (new InvalidOperationException(SR.ExceptionThreeLineBreakUsedYValueOutOfRange)); + } + } + + // Get number of lines in the break + int linesInBreak = 3; + if(series.IsCustomPropertySet(CustomPropertyName.NumberOfLinesInBreak)) + { + try + { + linesInBreak = int.Parse(series[CustomPropertyName.NumberOfLinesInBreak], CultureInfo.InvariantCulture); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionThreeLineBreakNumberOfLinesInBreakFormatInvalid)); + } + + if(linesInBreak <= 0) + { + throw (new InvalidOperationException(SR.ExceptionThreeLineBreakNumberOfLinesInBreakValueInvalid)); + } + } + + // Create an array to store the history of high/low values of drawn lines + ArrayList highLowHistory = new ArrayList(); + + // Fill points + double prevLow = double.NaN; + double prevHigh = double.NaN; + int sameDirectionLines = 0; + int prevDirection = 0; + int pointIndex = 0; + foreach(DataPoint dataPoint in originalData.Points) + { + int direction = 0; // 1 up; -1 down + + // Skip empty points + if(dataPoint.IsEmpty) + { + ++pointIndex; + continue; + } + + // Check if previus values exists + if(double.IsNaN(prevLow) || double.IsNaN(prevHigh)) + { + prevHigh = dataPoint.YValues[yValueIndex]; + prevLow = dataPoint.YValues[yValueIndex]; + ++pointIndex; + continue; + } + + // Get up price color + Color priceUpColor = Color.Transparent; + string priceUpColorString = dataPoint[CustomPropertyName.PriceUpColor]; + if(priceUpColorString == null) + { + priceUpColorString = series[CustomPropertyName.PriceUpColor]; + } + if(priceUpColorString != null) + { + try + { + ColorConverter colorConverter = new ColorConverter(); + priceUpColor = (Color)colorConverter.ConvertFromString(null, CultureInfo.InvariantCulture, priceUpColorString); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionThreeLineBreakUpBrickColorInvalid)); + } + } + + // Check if close value exceeds last brick position by box size + if(dataPoint.YValues[yValueIndex] > prevHigh) + { + direction = 1; + } + else if(dataPoint.YValues[yValueIndex] < prevLow) + { + direction = -1; + } + else + { + direction = 0; + } + + // Process up/down direction + if(direction != 0) + { + // Check if direction is same as previous + if(prevDirection == direction) + { + ++sameDirectionLines; + } + else + { + // If number of lines darwn in same direction is more or equal + // to number of lines in the break, the price must extend the + // high or low price of the lines in the whole break. + if(sameDirectionLines >= linesInBreak) + { + if(direction == 1) + { + // Calculate high value for the last N lines + double lineBreakHigh = double.MinValue; + for(int index = 0; index < highLowHistory.Count; index += 2) + { + if(((double)highLowHistory[index]) > lineBreakHigh) + { + lineBreakHigh = ((double)highLowHistory[index]); + } + } + + // If point value is less - ignore it + if(dataPoint.YValues[yValueIndex] <= lineBreakHigh) + { + direction = 0; + } + } + else if(direction == -1) + { + // Calculate low value for the last N lines + double lineBreakLow = double.MaxValue; + for(int index = 1; index < highLowHistory.Count; index += 2) + { + if(((double)highLowHistory[index]) < lineBreakLow) + { + lineBreakLow = ((double)highLowHistory[index]); + } + } + + // If point value is more - ignore it + if(dataPoint.YValues[yValueIndex] >= lineBreakLow) + { + direction = 0; + } + } + } + + if(direction != 0) + { + sameDirectionLines = 1; + } + } + + if(direction != 0) + { + // Add point + DataPoint newDataPoint = (DataPoint)dataPoint.Clone(); + newDataPoint["OriginalPointIndex"] = pointIndex.ToString(CultureInfo.InvariantCulture); + newDataPoint.series = series; + newDataPoint.YValues = new double[2]; + newDataPoint.XValue = dataPoint.XValue; + newDataPoint.Tag = dataPoint; + if(direction == 1) + { + newDataPoint.YValues[1] = prevHigh; + newDataPoint.YValues[0] = dataPoint.YValues[yValueIndex]; + prevLow = prevHigh; + prevHigh = dataPoint.YValues[yValueIndex]; + + // Set ThreeLineBreak up brick appearance + newDataPoint.Color = priceUpColor; + if(newDataPoint.BorderWidth < 1) + { + newDataPoint.BorderWidth = 1; + } + if(newDataPoint.BorderDashStyle == ChartDashStyle.NotSet) + { + newDataPoint.BorderDashStyle = ChartDashStyle.Solid; + } + if( (newDataPoint.BorderColor == Color.Empty || newDataPoint.BorderColor == Color.Transparent) && + (newDataPoint.Color == Color.Empty || newDataPoint.Color == Color.Transparent) ) + { + newDataPoint.BorderColor = series.Color; + } + } + else + { + newDataPoint.YValues[1] = prevLow; + newDataPoint.YValues[0] = dataPoint.YValues[yValueIndex]; + prevHigh = prevLow; + prevLow = dataPoint.YValues[yValueIndex]; + } + + // Add ThreeLineBreak brick to the range column series + series.Points.Add(newDataPoint); + + // Remember high/low values of drawn line + highLowHistory.Add(prevHigh); + highLowHistory.Add(prevLow); + + // Do not store all values in array only number of break lines + if(highLowHistory.Count > linesInBreak * 2) + { + // Remove two items at a time (high & low) + highLowHistory.RemoveAt(0); + highLowHistory.RemoveAt(0); + } + } + } + + // Remember last direction + if(direction != 0) + { + prevDirection = direction; + } + + ++pointIndex; + } + } + + #endregion // Methods + + #region Painting and Selection methods + + /// + /// Paint chart. + /// + /// The Chart Graphics object. + /// The Common elements object. + /// Chart area for this chart. + /// Chart series to draw. + virtual public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw ) + { + // Three Line Break series is never drawn directly. It is replaced with the range column chart. + // See PrepareData method. + } + #endregion + + #region IChartType interface implementation + + /// + /// Chart type name + /// + virtual public string Name { get{ return ChartTypeNames.ThreeLineBreak;}} + + /// + /// True if chart type is stacked + /// + virtual public bool Stacked { get{ return false;}} + + + /// + /// True if stacked chart type supports groups + /// + virtual public bool SupportStackedGroups { get { return false; } } + + + /// + /// True if stacked chart type should draw separately positive and + /// negative data points ( Bar and column Stacked types ). + /// + public bool StackSign { get{ return false;}} + + /// + /// True if chart type supports axeses + /// + virtual public bool RequireAxes { get{ return true;} } + + /// + /// Chart type with two y values used for scale ( bubble chart type ) + /// + public bool SecondYScale{ get{ return false;} } + + /// + /// True if chart type requires circular chart area. + /// + public bool CircularChartArea { get{ return false;} } + + /// + /// True if chart type supports logarithmic axes + /// + virtual public bool SupportLogarithmicAxes { get{ return true;} } + + /// + /// True if chart type requires to switch the value (Y) axes position + /// + virtual public bool SwitchValueAxes { get{ return false;} } + + /// + /// True if chart series can be placed side-by-side. + /// + public bool SideBySideSeries { get{ return false;} } + + /// + /// True if each data point of a chart must be represented in the legend + /// + virtual public bool DataPointsInLegend { get{ return false;} } + + /// + /// If the crossing value is auto Crossing value should be + /// automatically set to zero for some chart + /// types (Bar, column, area etc.) + /// + virtual public bool ZeroCrossing { get{ return false;} } + + /// + /// True if palette colors should be applied for each data paoint. + /// Otherwise the color is applied to the series. + /// + virtual public bool ApplyPaletteColorsToPoints { get { return false; } } + + /// + /// Indicates that extra Y values are connected to the scale of the Y axis + /// + virtual public bool ExtraYValuesConnectedToYAxis{ get { return true; } } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercent{ get{return false;} } + + /// + /// Indicates that it's a hundredred percent chart. + /// Axis scale from 0 to 100 percent should be used. + /// + virtual public bool HundredPercentSupportNegative{ get{return false;} } + + /// + /// How to draw series/points in legend: + /// Filled rectangle, Line or Marker + /// + /// Legend item series. + /// Legend item style. + virtual public LegendImageStyle GetLegendImageStyle(Series series) + { + return LegendImageStyle.Rectangle; + } + + /// + /// Number of supported Y value(s) per point + /// + virtual public int YValuesPerPoint { get { return 1; } } + + /// + /// Gets chart type image. + /// + /// Chart types registry object. + /// Chart type image. + virtual public System.Drawing.Image GetImage(ChartTypeRegistry registry) + { + return (System.Drawing.Image)registry.ResourceManager.GetObject(this.Name + "ChartType"); + } + #endregion + + #region Y values related methods + + /// + /// Helper function, which returns the Y value of the point. + /// + /// Chart common elements. + /// Chart area the series belongs to. + /// Sereis of the point. + /// Point object. + /// Index of the point. + /// Index of the Y value to get. + /// Y value of the point. + virtual public double GetYValue( + CommonElements common, + ChartArea area, + Series series, + DataPoint point, + int pointIndex, + int yValueIndex) + { + return point.YValues[yValueIndex]; + } + + #endregion + + #region SmartLabelStyle methods + + /// + /// Adds markers position to the list. Used to check SmartLabelStyle overlapping. + /// + /// Common chart elements. + /// Chart area. + /// Series values to be used. + /// List to add to. + public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list) + { + } + + #endregion + + #region IDisposable interface implementation + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + //Nothing to dispose at the base class. + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} + diff --git a/System.Web.DataVisualization/Common/Converters/AnnotationConverters.cs b/System.Web.DataVisualization/Common/Converters/AnnotationConverters.cs new file mode 100644 index 000000000..8c7c21ef8 --- /dev/null +++ b/System.Web.DataVisualization/Common/Converters/AnnotationConverters.cs @@ -0,0 +1,136 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: AnnotationConverters.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: AnchorPointValueConverter, AnnotationAxisValueConverter +// +// Purpose: Annotation Converters. +// +// Reviewed: +// +//=================================================================== + + +#region Used namespace +using System; +using System.Globalization; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif +{ + /// + /// Converts anchor data point to string name. + /// + internal class AnchorPointValueConverter : TypeConverter + { + #region Converter methods + + /// + /// Converts anchor data point to string name. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + if (value == null) + { + return Constants.NotSetValue; + } + DataPoint dataPoint = value as DataPoint; + + if (dataPoint != null) + { + if (dataPoint.series != null) + { + int pointIndex = dataPoint.series.Points.IndexOf(dataPoint) + 1; + return dataPoint.series.Name + " - " + SR.DescriptionTypePoint + pointIndex.ToString(CultureInfo.InvariantCulture); + } + } + } + + // Call base class + return base.ConvertTo(context, culture, value, destinationType); + } + #endregion + } + + /// + /// Converts anchor data point to string name. + /// + internal class AnnotationAxisValueConverter : TypeConverter + { + #region Converter methods + + /// + /// Converts axis associated with anootation to string. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + if (value == null) + { + return Constants.NotSetValue; + } + + Axis axis = value as Axis; + if (axis != null) + { + if (axis.ChartArea != null) + { + return axis.ChartArea.Name + " - " + axis.Name; + } + } + } + + // Call base class + return base.ConvertTo(context, culture, value, destinationType); + } + #endregion + } +} + diff --git a/System.Web.DataVisualization/Common/Converters/AxesArrayConverter.cs b/System.Web.DataVisualization/Common/Converters/AxesArrayConverter.cs new file mode 100644 index 000000000..8eb22e152 --- /dev/null +++ b/System.Web.DataVisualization/Common/Converters/AxesArrayConverter.cs @@ -0,0 +1,94 @@ + +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: AxesArrayConverter.cs +// +// Namespace: DataVisualization.Charting.Design +// +// Classes: AxesArrayConverter +// +// Purpose: Converter for the Axes array. +// +// Reviewed: AG - August 7, 2002 +// +//=================================================================== + +#region Used Namespaces + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Design; +using System.IO; +using System.Globalization; +using System.Data; +using System.Reflection; +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + + +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.WebControls; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif +{ + /// + /// Converter object of axes array + /// + internal class AxesArrayConverter : TypeConverter + { + #region Converter methods + + /// + /// Subproperties NOT suported. + /// + /// Descriptor context. + /// Always false. + public override bool GetPropertiesSupported(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Overrides the ConvertTo method of TypeConverter. + /// + /// Descriptor context. + /// Culture information. + /// Value. + /// Destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + // Convert collection to string + if (destinationType == typeof(string)) + { + return (new CollectionConverter()).ConvertToString(new ArrayList()); + } + + return base.ConvertTo(context, culture, value, destinationType); + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Converters/AxisConverters.cs b/System.Web.DataVisualization/Common/Converters/AxisConverters.cs new file mode 100644 index 000000000..339a5ed02 --- /dev/null +++ b/System.Web.DataVisualization/Common/Converters/AxisConverters.cs @@ -0,0 +1,691 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: AxisConverter.cs +// +// Namespace: DataVisualization.Charting.Design +// +// Classes: AxisLabelDateValueConverter, AxisCrossingValueConverter +// AxisMinMaxValueConverter, AxisMinMaxAutoValueConverter, +// StripLineTitleAngleConverter +// +// Purpose: Converters for the Axis object properties. +// +// Reviewed: AG - August 7, 2002 +// +//=================================================================== + + +#region Used Namespaces + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Collections; +using System.Globalization; +using System.Reflection; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif +{ + /// + /// Converts labels, grid and ticks start position to support dates format + /// + internal class AxisLabelDateValueConverter : DoubleConverter + { + #region Converter methods + + /// + /// Convert Min and Max values to string if step type is set to one of the DateTime type + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (context != null && context.Instance != null) + { + // Convert to string + if (destinationType == typeof(string)) + { + DateTimeIntervalType intervalType = DateTimeIntervalType.Auto; + double interval = 0; + + // Get IntervalType property using reflection + PropertyInfo propertyInfo = context.Instance.GetType().GetProperty("IntervalType"); + if(propertyInfo != null) + { + intervalType = (DateTimeIntervalType)propertyInfo.GetValue(context.Instance, null); + } + + // Get Interval property using reflection + propertyInfo = context.Instance.GetType().GetProperty("Interval"); + if(propertyInfo != null) + { + interval = (double)propertyInfo.GetValue(context.Instance, null); + } + + // Try to get interval information from the axis + if(intervalType == DateTimeIntervalType.Auto) + { + // Get object's axis + Axis axis = null; + if(context.Instance is Axis) + { + axis = (Axis)context.Instance; + } + else + { + MethodInfo methodInfo = context.Instance.GetType().GetMethod("GetAxis"); + if(methodInfo != null) + { + // Get axis object + axis = (Axis)methodInfo.Invoke(context.Instance, null); + } + } + + // Get axis value type + if(axis != null) + { + intervalType = axis.GetAxisIntervalType(); + } + } + + // Convert value to date/time string + if(context.Instance.GetType() != typeof(StripLine) || interval == 0) + { + if(intervalType != DateTimeIntervalType.Number && intervalType != DateTimeIntervalType.Auto) + { + // Covert value to date/time + if(intervalType < DateTimeIntervalType.Hours) + { + return DateTime.FromOADate((double)value).ToShortDateString(); + } + return DateTime.FromOADate((double)value).ToString("g", System.Globalization.CultureInfo.CurrentCulture); + } + } + } + } + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Convert Min and Max values from string if step type is set to one of the DateTime type + /// + /// Descriptor context. + /// Culture information. + /// Value to convert from. + /// Converted object. + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + object result = null; + bool convertFromDate = false; + string stringValue = value as string; + + // If context interface provided check if we are dealing with DateTime values + if (context != null && context.Instance != null) + { + DateTimeIntervalType intervalType = DateTimeIntervalType.Auto; + + // Get intervalType property using reflection + PropertyInfo propertyInfo = context.Instance.GetType().GetProperty("intervalType"); + if(propertyInfo != null) + { + intervalType = (DateTimeIntervalType)propertyInfo.GetValue(context.Instance, null); + } + + // Try to get interval information from the axis + if(intervalType == DateTimeIntervalType.Auto) + { + // Get object's axis + Axis axis = null; + if(context.Instance is Axis) + { + axis = (Axis)context.Instance; + } + else + { + MethodInfo methodInfo = context.Instance.GetType().GetMethod("GetAxis"); + if(methodInfo != null) + { + // Get axis object + axis = (Axis)methodInfo.Invoke(context.Instance, null); + } + } + + // Get axis value type + if(axis != null) + { + intervalType = axis.GetAxisIntervalType(); + } + } + + if (stringValue != null && intervalType != DateTimeIntervalType.Number && intervalType != DateTimeIntervalType.Auto) + { + convertFromDate = true; + } + + } + + // Try to convert from double string + try + { + result = base.ConvertFrom(context, culture, value); + } + catch (ArgumentException) + { + result = null; + } + catch (NotSupportedException) + { + result = null; + } + + // Try to convert from date/time string + if (stringValue != null && (convertFromDate || result == null)) + { + DateTime valueAsDate; + bool parseSucceed = DateTime.TryParse(stringValue, CultureInfo.InvariantCulture, DateTimeStyles.None, out valueAsDate); + + if (parseSucceed) + { + // Succeded converting from date format + return valueAsDate.ToOADate(); + } + } + + // Call base converter + return base.ConvertFrom(context, culture, value); + } + + #endregion + } + + /// + /// Converts crossing property of the axis. + /// Possible values: double, date, "Auto", "Min", "Max" + /// + internal class AxisCrossingValueConverter : AxisMinMaxValueConverter + { + #region Converter methods + + /// + /// Standart values supported - return true. + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standart values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Fill in the list of standart values. + /// + /// Descriptor context. + /// Standart values collection. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + values.Add(Double.NaN); + values.Add(Double.MinValue); + values.Add(Double.MaxValue); + + return new StandardValuesCollection(values); + } + + /// + /// Convert crossing value to string. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + double doubleValue = (double)value; + if (destinationType == typeof(string)) + { + if(Double.IsNaN(doubleValue)) + { + return Constants.AutoValue; + } + else if(doubleValue == Double.MinValue) + { + return Constants.MinValue; + } + else if(doubleValue == Double.MaxValue) + { + return Constants.MaxValue; + } + } + + // Call base class + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Convert crossing values from string + /// + /// Descriptor context. + /// Culture information. + /// Value to convert from. + /// Converted object. + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + // If converting from string value + string crossingValue = value as string; + if (crossingValue != null) + { + if (String.Compare(crossingValue, Constants.AutoValue, StringComparison.OrdinalIgnoreCase) == 0) + { + return Double.NaN; + } + else if (String.Compare(crossingValue, Constants.MinValue, StringComparison.OrdinalIgnoreCase) == 0) + { + return Double.MinValue; + } + else if (String.Compare(crossingValue, Constants.MaxValue, StringComparison.OrdinalIgnoreCase) == 0) + { + return Double.MaxValue; + } + } + + // Call base converter + return base.ConvertFrom(context, culture, value); + } + + #endregion + } + + /// + /// Converts min and max properties of the axis depending on the values type + /// + internal class AxisMinMaxValueConverter : DoubleConverter + { + #region Converter methods + + /// + /// Convert Min and Max values to string if step type is set to one of the DateTime type + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (context != null && context.Instance != null && context.Instance is Axis) + { + Axis axis = (Axis)context.Instance; + if (destinationType == typeof(string)) + { + string strValue = DoubleDateNanValueConverter.ConvertDateTimeToString( + (double)value, + axis.GetAxisValuesType(), + axis.InternalIntervalType); + + if (strValue != null) + return strValue; + } + } + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Convert Min and Max values from string if step type is set to one of the DateTime type + /// + /// Descriptor context. + /// Culture information. + /// Value to convert from. + /// Converted object. + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + object result = null; + bool convertFromDate = false; + string stringValue = value as string; + + // If context interface provided check if we are dealing with DateTime values + if (context != null && context.Instance != null && context.Instance is Axis) + { + Axis axis = (Axis)context.Instance; + + if (stringValue != null) + { + if (axis.InternalIntervalType == DateTimeIntervalType.Auto) + { + if (axis.GetAxisValuesType() == ChartValueType.DateTime || + axis.GetAxisValuesType() == ChartValueType.Date || + axis.GetAxisValuesType() == ChartValueType.Time || + axis.GetAxisValuesType() == ChartValueType.DateTimeOffset) + { + convertFromDate = true; + } + } + else + { + if (axis.InternalIntervalType != DateTimeIntervalType.Number) + { + convertFromDate = true; + } + } + } + } + + // Try to convert from double string + try + { + result = base.ConvertFrom(context, culture, value); + } + catch (ArgumentException) + { + result = null; + } + catch (NotSupportedException) + { + result = null; + } + + // Try to convert from date/time string + if (stringValue != null && (convertFromDate || result == null)) + { + DateTime valueAsDate; + bool parseSucceed = DateTime.TryParse(stringValue, CultureInfo.CurrentCulture, DateTimeStyles.None, out valueAsDate); + + if (parseSucceed) + { + return valueAsDate.ToOADate(); + } + } + + // Call base converter + return base.ConvertFrom(context, culture, value); + } + + #endregion + } + + /// + /// Converts maximum and minimum property of the axis. + /// Possible values: double, date, "Auto", + /// + internal class AxisMinMaxAutoValueConverter : AxisMinMaxValueConverter + { + #region Converter methods + + /// + /// Standart values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standart values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Fill in the list of data series names. + /// + /// Descriptor context. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + values.Add(Double.NaN); + + return new StandardValuesCollection(values); + } + + /// + /// Convert minimum or maximum value to string + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + double doubleValue = (double)value; + if (destinationType == typeof(string)) + { + if(Double.IsNaN(doubleValue)) + { + return Constants.AutoValue; + } + } + + // Call base class + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Convert minimum or maximum values from string + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + // If converting from string value + string crossingValue = value as string; + if (crossingValue != null) + { + if (String.Compare(crossingValue, Constants.AutoValue, StringComparison.OrdinalIgnoreCase) == 0) + { + return Double.NaN; + } + } + + // Call base converter + return base.ConvertFrom(context, culture, value); + } + + #endregion + } + + /// + /// Converts title angle property of the strip line + /// Possible values: 0, 90, 180, 270 + /// + internal class StripLineTitleAngleConverter : Int32Converter + { + #region Converter methods + + /// + /// Standart values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standart values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Fill in the list of data series names. + /// + /// Descriptor context. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + values.Add(0); + values.Add(90); + values.Add(180); + values.Add(270); + + return new StandardValuesCollection(values); + } + + #endregion + } + + /// + /// Converts Interval and IntervalOffset properties of the axis + /// + internal class AxisIntervalValueConverter : DoubleConverter + { + #region Converter methods + + /// + /// Inicates that "NotSet" option is available + /// + internal bool hideNotSet = true; + + /// + /// Standart values supported - return true. + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standart values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Fill in the list of standart values. + /// + /// Descriptor context. + /// Standart values collection. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + if(!hideNotSet) + { + values.Add(Double.NaN); + } + values.Add(0.0); + + return new StandardValuesCollection(values); + } + + /// + /// Convert crossing value to string. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + double doubleValue = (double)value; + if (destinationType == typeof(string)) + { + if(Double.IsNaN(doubleValue)) + { + return Constants.NotSetValue; + } + else if(doubleValue == 0.0) + { + return Constants.AutoValue; + } + } + + // Call base class + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Convert crossing values from string + /// + /// Descriptor context. + /// Culture information. + /// Value to convert from. + /// Converted object. + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + // If converting from string value + string crossingValue = value as string; + if (crossingValue != null) + { + if (String.Compare(crossingValue, Constants.AutoValue, StringComparison.OrdinalIgnoreCase) == 0) + { + return 0.0; + } + else if (String.Compare(crossingValue, Constants.NotSetValue, StringComparison.OrdinalIgnoreCase) == 0) + { + return Double.NaN; + } + } + + // Call base converter + return base.ConvertFrom(context, culture, value); + } + + #endregion + } + + /// + /// Converts Interval and IntervalOffset properties of the label style, tick marks and grids + /// + internal class AxisElementIntervalValueConverter : AxisIntervalValueConverter + { + /// + /// Show the NotSet option for interval + /// + public AxisElementIntervalValueConverter() + { + base.hideNotSet = false; + } + } +} diff --git a/System.Web.DataVisualization/Common/Converters/CustomAttributesConverters.cs b/System.Web.DataVisualization/Common/Converters/CustomAttributesConverters.cs new file mode 100644 index 000000000..98783d596 --- /dev/null +++ b/System.Web.DataVisualization/Common/Converters/CustomAttributesConverters.cs @@ -0,0 +1,985 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: CustomattributesConverter.cs +// +// Namespace: DataVisualization.Charting.Design +// +// Interfaces: IDataPointCustomPropertiesProvider +// +// Classes: CustomPropertiesTypeConverter, DynamicPropertyDescriptor +// +// Purpose: AxisName converter of the design-time CustomProperties +// property object. +// +// Reviewed: +// +//=================================================================== + +#region Used Namespaces + +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + /// + /// Custom properties object type converter. + /// + internal class CustomPropertiesTypeConverter : TypeConverter + { + #region String to/from convertion methods + + /// + /// Overrides the CanConvertFrom method of TypeConverter. + /// + /// Descriptor context. + /// Convertion source type. + /// Indicates if convertion is possible. + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + if(sourceType == typeof(string)) + { + return true; + } + + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Overrides the CanConvertTo method of TypeConverter. + /// + /// Descriptor context. + /// Destination type. + /// Indicates if convertion is possible. + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + if(destinationType == typeof(CustomProperties)) + { + return true; + } + + return base.CanConvertTo(context, destinationType); + } + + /// + /// Overrides the ConvertTo method of TypeConverter. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + return ((CustomProperties)value).DataPointCustomProperties.CustomProperties; + } + + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Overrides the ConvertFrom method of TypeConverter. + /// Converts from string with comma separated values. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert from. + /// Indicates if convertion is possible. + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", + Justification = "Too large of a code change to justify making this change")] + public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) + { + string stringValue = value as string; + if(stringValue != null && context != null && context.Instance != null) + { + // Create new custom attribute class with a reference to the DataPointCustomProperties + if(context.Instance is DataPointCustomProperties) + { + ((DataPointCustomProperties)context.Instance).CustomProperties = stringValue; + CustomProperties newAttributes = new CustomProperties(((DataPointCustomProperties)context.Instance)); + return newAttributes; + } + + else if (context.Instance is CustomProperties) + { + CustomProperties newAttributes = new CustomProperties(((CustomProperties)context.Instance).DataPointCustomProperties); + return newAttributes; + } + else if (context.Instance is IDataPointCustomPropertiesProvider) + { + CustomProperties newAttributes = new CustomProperties(((IDataPointCustomPropertiesProvider)context.Instance).DataPointCustomProperties); + return newAttributes; + } + + else if (context.Instance is Array) + { + DataPointCustomProperties attributes = null; + foreach (object obj in ((Array)context.Instance)) + { + if (obj is DataPointCustomProperties) + { + attributes = (DataPointCustomProperties)obj; + attributes.CustomProperties = stringValue; + } + } + if (attributes != null) + { + CustomProperties newAttributes = new CustomProperties(attributes); + return newAttributes; + } + } + } + return base.ConvertFrom(context, culture, value); + } + + #endregion // String to/from convertion methods + + #region Property Descriptor Collection methods + + /// + /// Returns whether this object supports properties. + /// + /// An ITypeDescriptorContext that provides a format context. + /// true if GetProperties should be called to find the properties of this object; otherwise, false. + public override bool GetPropertiesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Returns a collection of properties for the type of array specified by the value parameter, + /// using the specified context and properties. + /// + /// An ITypeDescriptorContext that provides a format context. + /// An Object that specifies the type of array for which to get properties. + /// An array of type Attribute that is used as a filter. + /// A PropertyDescriptorCollection with the properties that are exposed for this data type, or a null reference (Nothing in Visual Basic) if there are no properties. + public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object obj, Attribute[] attributes) + { + PropertyDescriptorCollection propCollection = new PropertyDescriptorCollection(null); + CustomProperties attr = obj as CustomProperties; + if(attr != null && context != null) + { + // Get series associated with custom attribute + Series series = (attr.DataPointCustomProperties is Series) ? ( (Series) attr.DataPointCustomProperties) : attr.DataPointCustomProperties.series; + if(series != null && + series.Common != null) + { + // Loop through all registered custom properties + CustomPropertyRegistry registry = (CustomPropertyRegistry)series.Common.container.GetService(typeof(CustomPropertyRegistry)); + foreach(CustomPropertyInfo attrInfo in registry.registeredCustomProperties) + { + // Check if attribute description matches curent selection in property browser + if(IsApplicableCustomProperty(attrInfo, context.Instance)) + { + // Get array of property properties + Attribute[] propAttributes = GetPropertyAttributes(attrInfo); + + // Create property descriptor + CustomAttributesPropertyDescriptor propertyDescriptor = new CustomAttributesPropertyDescriptor( + typeof(CustomProperties), + attrInfo.Name, + attrInfo.ValueType, + propAttributes, + attrInfo); + + // Add descriptor into the collection + propCollection.Add(propertyDescriptor); + } + } + + // Always add "UserDefined" property for all user defined custom properties + Attribute[] propUserDefinedAttributes = new Attribute[] { + new NotifyParentPropertyAttribute(true), + new RefreshPropertiesAttribute(RefreshProperties.All), + new DescriptionAttribute(SR.DescriptionAttributeUserDefined) + }; + + // Create property descriptor + CustomAttributesPropertyDescriptor propertyUserDefinedDescriptor = new CustomAttributesPropertyDescriptor( + typeof(CustomProperties), + "UserDefined", + typeof(string), + propUserDefinedAttributes, + null); + + // Add descriptor into the collection + propCollection.Add(propertyUserDefinedDescriptor); + } + } + + return propCollection; + } + + /// + /// Checks if provided custom attribute appies to the selected points or series. + /// + /// Custom attribute information. + /// Selected series or points. + /// True if custom attribute applies. + private bool IsApplicableCustomProperty(CustomPropertyInfo attrInfo, object obj) + { + + CustomProperties customProperties = obj as CustomProperties; + if (customProperties != null) + { + obj = customProperties.DataPointCustomProperties; + } + + // Check if custom attribute applies to the series or points + if( (IsDataPoint(obj) && attrInfo.AppliesToDataPoint) || + (!IsDataPoint(obj) && attrInfo.AppliesToSeries) ) + { + // Check if attribute do not apply to 3D or 2D chart types + if( (Is3DChartType(obj) && attrInfo.AppliesTo3D) || + (!Is3DChartType(obj) && attrInfo.AppliesTo2D) ) + { + + // Check if custom attribute applies to the chart types selected + SeriesChartType[] chartTypes = GetSelectedChartTypes(obj); + foreach(SeriesChartType chartType in chartTypes) + { + foreach(SeriesChartType attrChartType in attrInfo.AppliesToChartType) + { + if(attrChartType == chartType) + { + return true; + } + } + } + + } + } + + return false; + } + + /// + /// Checks if specified object represent a single or array of data points. + /// + /// Object to test. + /// True if specified object contains one or more data points. + private bool IsDataPoint(object obj) + { + Series series = obj as Series; + if(series != null) + { + return false; + } + + Array array = obj as Array; + if(array != null && array.Length > 0) + { + if (array.GetValue(0) is Series) + { + return false; + } + } + return true; + } + + /// + /// Checks if specified object represent a single or array of data points. + /// + /// Object to test. + /// True if specified object contains one or more data points. + private bool Is3DChartType(object obj) + { + // Get array of series + Series[] seriesArray = GetSelectedSeries(obj); + + // Loop through all series and check if its plotted on 3D chart area + foreach(Series series in seriesArray) + { + ChartArea chartArea = series.Chart.ChartAreas[series.ChartArea]; + if(chartArea.Area3DStyle.Enable3D) + { + return true; + } + } + + return false; + } + + /// + /// Get array of selected series. + /// + /// Selected objects. + /// Selected series array. + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", + Justification = "Too large of a code change to justify making this change")] + private Series[] GetSelectedSeries(object obj) + { + // Get array of series + Series[] seriesArray = new Series[0]; + if(obj is Array && ((Array)obj).Length > 0) + { + if(((Array)obj).GetValue(0) is Series) + { + seriesArray = new Series[((Array)obj).Length]; + ((Array)obj).CopyTo(seriesArray, 0); + } + else if(((Array)obj).GetValue(0) is DataPointCustomProperties) + { + seriesArray = new Series[] { ((DataPointCustomProperties)((Array)obj).GetValue(0)).series }; + } + } + else if(obj is Series) + { + seriesArray = new Series[] { ((Series)obj) }; + } + else if(obj is DataPointCustomProperties) + { + seriesArray = new Series[] { ((DataPointCustomProperties)obj).series }; + } + + return seriesArray; + } + + /// + /// Get array of chart types from the selected series. + /// + /// Selected series or data points. + /// Array of selected chart types. + private SeriesChartType[] GetSelectedChartTypes(object obj) + { + // Get array of series + Series[] seriesArray = GetSelectedSeries(obj); + + // Create array of chart types + int index = 0; + SeriesChartType[] chartTypes = new SeriesChartType[seriesArray.Length]; + foreach(Series series in seriesArray) + { + chartTypes[index++] = series.ChartType; + } + + return chartTypes; + } + + /// + /// Gets array of properties for the dynamic property. + /// + /// Custom attribute information. + /// Array of properties. + private Attribute[] GetPropertyAttributes(CustomPropertyInfo attrInfo) + { + // Create default value attribute + DefaultValueAttribute defaultValueAttribute = null; + if (attrInfo.DefaultValue.GetType() == attrInfo.ValueType) + { + defaultValueAttribute = new DefaultValueAttribute(attrInfo.DefaultValue); + } + else if (attrInfo.DefaultValue is string) + { + defaultValueAttribute = new DefaultValueAttribute(attrInfo.ValueType, (string)attrInfo.DefaultValue); + } + else + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeDefaultValueTypeInvalid)); + } + // Add all properties into the list + ArrayList propList = new ArrayList(); + + propList.Add(new NotifyParentPropertyAttribute(true)); + propList.Add(new RefreshPropertiesAttribute(RefreshProperties.All)); + propList.Add(new DescriptionAttribute(attrInfo.Description)); + propList.Add(defaultValueAttribute); + + if (attrInfo.Name.Equals(CustomPropertyName.ErrorBarType, StringComparison.Ordinal)) + { + propList.Add(new TypeConverterAttribute(typeof(ErrorBarTypeConverter))); + } + + // Convert list to array + int index = 0; + Attribute[] propAttributes = new Attribute[propList.Count]; + foreach(Attribute attr in propList) + { + propAttributes[index++] = attr; + } + return propAttributes; + } + + /// + /// Special convertor for ErrorBarType custom attribute + /// + internal class ErrorBarTypeConverter : StringConverter + { + /// + /// Returns whether this object supports a standard set of values that can be picked from a list, using the specified context. + /// + /// An that provides a format context. + /// + /// true if should be called to find a common set of values the object supports; otherwise, false. + /// + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Returns whether the collection of standard values returned from is an exclusive list of possible values, using the specified context. + /// + /// An that provides a format context. + /// + /// true if the returned from is an exhaustive list of possible values; false if other values are possible. + /// + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Returns a collection of standard values for the data type this type converter is designed for when provided with a format context. + /// + /// An that provides a format context that can be used to extract additional information about the environment from which this converter is invoked. This parameter or properties of this parameter can be null. + /// + /// A that holds a standard set of valid values, or null if the data type does not support a standard set of values. + /// + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList result = new ArrayList(); + foreach (ChartTypes.ErrorBarType item in Enum.GetValues(typeof(ChartTypes.ErrorBarType))) + { + string itemStr = String.Format(CultureInfo.InvariantCulture, "{0}({1:N0})", item, ChartTypes.ErrorBarChart.DefaultErrorBarTypeValue(item)); + result.Add(itemStr); + } + return new StandardValuesCollection(result); + } + } + + #endregion // Property Descriptor Collection methods + + #region Custom Attributes Property Descriptor + + /// + /// Custom properties inner property descriptor class. + /// + protected class CustomAttributesPropertyDescriptor : TypeConverter.SimplePropertyDescriptor + { + #region Fields + + // Property name + private string _name = string.Empty; + + // Custom attribute information + private CustomPropertyInfo _customAttributeInfo = null; + + #endregion // Fields + + #region Constructor + + /// + /// Property descriptor constructor. + /// + /// Component type. + /// Property name. + /// Property type. + /// Property attributes. + /// Custom attribute information. + internal CustomAttributesPropertyDescriptor( + Type componentType, + string name, + Type propertyType, + Attribute[] attributes, + CustomPropertyInfo customAttributeInfo) + : base(componentType, name, propertyType, attributes) + { + this._name = name; + this._customAttributeInfo = customAttributeInfo; + } + + #endregion // Constructor + + #region Methods + + /// + /// Gets the current value of the property on a component. + /// + /// The component with the property for which to retrieve the value. + /// The value of a property for a given component. + public override object GetValue(object component) + { + // "UserDefined" property expose comma separated user defined properties + CustomProperties customAttr = component as CustomProperties; + if(this._name == "UserDefined") + { + return customAttr.GetUserDefinedCustomProperties(); + } + else + { + object val = null; + + // Check if custom attribute with this name is set + string stringValue = customAttr.DataPointCustomProperties[this._name]; + if(this._customAttributeInfo != null) + { + if(stringValue == null || stringValue.Length == 0) + { + val = GetValueFromString(this._customAttributeInfo.DefaultValue); + } + else + { + val = GetValueFromString(stringValue); + } + } + else + { + val = stringValue; + } + + return val; + } + } + + /// + /// Sets the value of the component to a different value. + /// + /// The component with the property value that is to be set. + /// The new value. + public override void SetValue(object component, object value) + { + // Validate new value + ValidateValue(this._name, value); + + // Get new value as string + string stringValue = GetStringFromValue(value); + + // "UserDefined" property expose comma separated user defined properties + CustomProperties customAttr = component as CustomProperties; + if( this._name == "UserDefined" ) + { + customAttr.SetUserDefinedAttributes(stringValue); + } + else + { + // Check if the new value is the same as DefaultValue + bool setAttributeValue = true; + if( IsDefaultValue(stringValue) ) + { + // Remove custom properties with default values from data point + // only when series do not have this attribute set. + if( !(customAttr.DataPointCustomProperties is DataPoint) || + !((DataPoint)customAttr.DataPointCustomProperties).series.IsCustomPropertySet(this._name) ) + { + // Delete attribute + if(customAttr.DataPointCustomProperties.IsCustomPropertySet(this._name)) + { + customAttr.DataPointCustomProperties.DeleteCustomProperty(this._name); + setAttributeValue = false; + } + } + } + + // Set custom attribute value + if( setAttributeValue ) + { + customAttr.DataPointCustomProperties[this._name] = stringValue; + } + } + customAttr.DataPointCustomProperties.CustomProperties = customAttr.DataPointCustomProperties.CustomProperties; + + IChangeTracking changeTracking = component as IChangeTracking; + if (changeTracking != null) + { + changeTracking.AcceptChanges(); + } + + } + + /// + /// Checks if specified value is the default value of the attribute. + /// + /// Value to check. + /// True if specified value is the default attribute value. + public bool IsDefaultValue(string val) + { + // Get default value string + string defaultValue = GetStringFromValue(this._customAttributeInfo.DefaultValue); + return (String.Compare(val, defaultValue, StringComparison.Ordinal) == 0); + } + + /// + /// Gets value from string a native type of attribute. + /// + /// Object to convert to string. + /// String representation of the specified object. + public virtual object GetValueFromString(object obj) + { + object result = null; + if(obj != null) + { + if(this._customAttributeInfo.ValueType == obj.GetType() ) + { + return obj; + } + + string stringValue = obj as string; + if (stringValue != null) + { + if(this._customAttributeInfo.ValueType == typeof(string) ) + { + result = stringValue; + } + else if(this._customAttributeInfo.ValueType == typeof(float) ) + { + result = float.Parse(stringValue, System.Globalization.CultureInfo.InvariantCulture); + } + else if(this._customAttributeInfo.ValueType == typeof(double) ) + { + result = double.Parse(stringValue, System.Globalization.CultureInfo.InvariantCulture); + } + else if(this._customAttributeInfo.ValueType == typeof(int) ) + { + result = int.Parse(stringValue, System.Globalization.CultureInfo.InvariantCulture); + } + else if(this._customAttributeInfo.ValueType == typeof(bool) ) + { + result = bool.Parse(stringValue); + } + else if(this._customAttributeInfo.ValueType == typeof(Color) ) + { + ColorConverter colorConverter = new ColorConverter(); + result = (Color)colorConverter.ConvertFromString(null, System.Globalization.CultureInfo.InvariantCulture, stringValue); + } + else if(this._customAttributeInfo.ValueType.IsEnum) + { + result = Enum.Parse(this._customAttributeInfo.ValueType, stringValue, true); + } + else + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeTypeUnsupported( this._customAttributeInfo.ValueType.ToString() ))); + } + + } + } + return result; + } + + + /// + /// Converts attribute value to string. + /// + /// Attribute value to convert. + /// Return attribute value converted to string. + public string GetStringFromValue(object value) + { + if(value is Color) + { + ColorConverter colorConverter = new ColorConverter(); + return colorConverter.ConvertToString(null, System.Globalization.CultureInfo.InvariantCulture, value); + } + else if(value is float) + { + return ((float)value).ToString(System.Globalization.CultureInfo.InvariantCulture); + } + else if(value is double) + { + return ((double)value).ToString(System.Globalization.CultureInfo.InvariantCulture); + } + else if(value is int) + { + return ((int)value).ToString(System.Globalization.CultureInfo.InvariantCulture); + } + else if(value is bool) + { + return ((bool)value).ToString(); + } + + return value.ToString(); + } + + /// + /// Validates attribute value. Method throws exception in case of any issues. + /// + /// Attribute name. + /// Attribute value to validate. + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", + Justification = "Too large of a code change to justify making this change")] + public virtual void ValidateValue(string attrName, object value) + { + // Check for validation rules + if(this._customAttributeInfo == null) + { + return; + } + + // Check if property Min/Max value is provided + bool outOfRange = false; + if(this._customAttributeInfo.MaxValue != null) + { + if(value.GetType() != this._customAttributeInfo.MaxValue.GetType()) + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeTypeOrMaximumPossibleValueInvalid( attrName ) ) ); + } + + if(value is float) + { + if((float)value > (float)this._customAttributeInfo.MaxValue) + { + outOfRange = true; + } + } + else if(value is double) + { + if((double)value > (double)this._customAttributeInfo.MaxValue) + { + outOfRange = true; + } + } + else if(value is int) + { + if((int)value > (int)this._customAttributeInfo.MaxValue) + { + outOfRange = true; + } + } + else + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeTypeOrMinimumPossibleValueUnsupported(attrName))); + } + + } + + // Check if property Min value is provided + if(this._customAttributeInfo.MinValue != null) + { + if(value.GetType() != this._customAttributeInfo.MinValue.GetType()) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeTypeOrMinimumPossibleValueInvalid( attrName ) ) ); + } + + if(value is float) + { + if((float)value < (float)this._customAttributeInfo.MinValue) + { + outOfRange = true; + } + } + else if(value is double) + { + if((double)value < (double)this._customAttributeInfo.MinValue) + { + outOfRange = true; + } + } + else if(value is int) + { + if((int)value < (int)this._customAttributeInfo.MinValue) + { + outOfRange = true; + } + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeTypeOrMinimumPossibleValueUnsupported(attrName))); + } + } + + // Value out of range exception + if(outOfRange) + { + if(this._customAttributeInfo.MaxValue != null && this._customAttributeInfo.MinValue != null) + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeMustBeInRange(attrName, this._customAttributeInfo.MinValue.ToString(),this._customAttributeInfo.MaxValue.ToString() ))); + } + else if(this._customAttributeInfo.MinValue != null) + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeMustBeBiggerThenValue(attrName, this._customAttributeInfo.MinValue.ToString()))); + } + else if(this._customAttributeInfo.MaxValue != null) + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeMustBeMoreThenValue(attrName, this._customAttributeInfo.MaxValue.ToString()))); + } + } + } + + #endregion // Methods + } + + #endregion // Custom Attributes Property Descriptor + } + + + /// + /// Property descriptor with ability to dynamically change properties + /// of the base property descriptor object. + /// + internal class DynamicPropertyDescriptor : PropertyDescriptor + { + #region Fields + + // Reference to the base property descriptor + private PropertyDescriptor _basePropertyDescriptor = null; + + // Dynamic display name of the property + private string _displayName = string.Empty; + + #endregion // Fields + + #region Constructor + + /// + /// Constructor of the dynamic property descriptor. + /// + /// Base property descriptor. + /// New display name of the property. + public DynamicPropertyDescriptor( + PropertyDescriptor basePropertyDescriptor, + string displayName) + : base(basePropertyDescriptor) + { + this._displayName = displayName; + this._basePropertyDescriptor = basePropertyDescriptor; + } + + #endregion // Constructor + + #region Properties + + /// + /// Gets the type of the component this property is bound to. + /// + public override Type ComponentType + { + get + { + return _basePropertyDescriptor.ComponentType; + } + } + + /// + /// Gets the name that can be displayed in a window, such as a Properties window. + /// + public override string DisplayName + { + get + { + if(this._displayName.Length > 0) + { + return this._displayName; + } + return this._basePropertyDescriptor.DisplayName; + } + } + + /// + /// Gets a value indicating whether this property is browsable. + /// + public override bool IsBrowsable + { + get + { + return this._basePropertyDescriptor.IsBrowsable; + } + } + + /// + /// Gets a value indicating whether this property is read-only. + /// + public override bool IsReadOnly + { + get + { + return this._basePropertyDescriptor.IsReadOnly; + } + } + + /// + /// Gets the type of the property. + /// + public override Type PropertyType + { + get + { + return this._basePropertyDescriptor.PropertyType; + } + } + + #endregion // Properties + + #region Methods + + /// + /// Returns whether resetting an object changes its value. + /// + /// The component to test for reset capability. + /// true if resetting the component changes its value; otherwise, false. + public override bool CanResetValue(object component) + { + return _basePropertyDescriptor.CanResetValue(component); + } + + /// + /// Gets the current value of the property on a component. + /// + /// The component with the property for which to retrieve the value. + /// The value of a property for a given component. + public override object GetValue(object component) + { + return this._basePropertyDescriptor.GetValue(component); + } + + /// + /// Resets the value for this property of the component to the default value. + /// + /// The component with the property value that is to be reset to the default value. + public override void ResetValue(object component) + { + this._basePropertyDescriptor.ResetValue(component); + } + + /// + /// Determines a value indicating whether the value of this property needs to be persisted. + /// + /// The component with the property to be examined for persistence. + /// True if the property should be persisted; otherwise, false. + public override bool ShouldSerializeValue(object component) + { + return this._basePropertyDescriptor.ShouldSerializeValue(component); + } + + /// + /// Sets the value of the component to a different value. + /// + /// The component with the property value that is to be set. + /// The new value. + public override void SetValue(object component, object value) + { + this._basePropertyDescriptor.SetValue(component, value); + } + + #endregion // Methods + } + + internal interface IDataPointCustomPropertiesProvider + { + DataPointCustomProperties DataPointCustomProperties { get; } + } +} diff --git a/System.Web.DataVisualization/Common/Converters/DataManagerConverters.cs b/System.Web.DataVisualization/Common/Converters/DataManagerConverters.cs new file mode 100644 index 000000000..c72c7a762 --- /dev/null +++ b/System.Web.DataVisualization/Common/Converters/DataManagerConverters.cs @@ -0,0 +1,899 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: DataManagerConverters.cs +// +// Namespace: DataVisualization.Charting.Design +// +// Classes: SeriesAreaNameConverter, +// ChartTypeConverter, SeriesNameConverter, +// NoNameExpandableObjectConverter, DoubleArrayConverter, +// DataPointValueConverter, SeriesYValueTypeConverter +// +// Purpose: Converter classes for the Series and DataPoint properties. +// +// Reviewed: AG - August 7, 2002 +// +//=================================================================== + + + +using System.ComponentModel.Design.Serialization; +#region Used Namespaces + +using System; +using System.Resources; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Design; +using System.Drawing.Text; +using System.IO; +using System.Globalization; +using System.Data; +using System.Reflection; +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Collections.Generic; + +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.WebControls; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif +{ + /// + /// Chart area name converter. Displays list of available areas names + /// + internal class SeriesAreaNameConverter : StringConverter + { + #region Converter methods + + /// + /// Standart values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standart values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Fill in the list of the chart areas for the series. + /// + /// Descriptor context. + /// Standart values collection. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + + Chart chart = ConverterHelper.GetChartFromContext(context); + + if (chart != null) + { + foreach (ChartArea area in chart.ChartAreas) + { + values.Add(area.Name); + } + } + return new StandardValuesCollection(values); + } + + #endregion + } + + /// + /// Chart data source design-time converter. Displays list of available data sources. + /// + internal class ChartDataSourceConverter : StringConverter + { + #region Converter methods + + /// + /// Standart values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standart values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Fill in the list of chart type names. + /// + /// Descriptor context. + /// Standard values collection. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + + if (context != null && context.Container != null) + { + // Loop through all components in the container + foreach(IComponent comonent in context.Container.Components) + { + // Check if component can be a data source + if(ChartImage.IsValidDataSource(comonent)) + { + // Add component name + values.Add(comonent.Site.Name); + } + } + } + + // Add "None" data source + values.Add("(none)"); + + return new StandardValuesCollection(values); + } + + #endregion + } + + /// + /// Series data source members converter. + /// + internal class SeriesDataSourceMemberConverter : StringConverter + { + #region Converter methods + + /// + /// Standart values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standart values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Fill in the list of the data source members. + /// + /// Descriptor context. + /// Standart values collection. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + + Chart chart = ConverterHelper.GetChartFromContext(context); + object dataSource = null; + + if(chart != null) + { + if (chart != null && ChartImage.IsValidDataSource(chart.DataSource)) + { + dataSource = chart.DataSource; + } + + // Check if it's Y values member + bool usedForYValues = false; + if (context.PropertyDescriptor != null && context.PropertyDescriptor.Name == "YValueMembers") + { + usedForYValues = true; + } + + // Populate list with all members names + ArrayList memberNames = ChartImage.GetDataSourceMemberNames(dataSource, usedForYValues); + foreach(string name in memberNames) + { + values.Add(name); + } + + values.Add("(none)"); + } + + return new StandardValuesCollection(values); + } + + #endregion + } + + /// + /// Chart legend name converter. Displays list of available legend names + /// + internal class SeriesLegendNameConverter : StringConverter + { + #region Converter methods + + /// + /// Standart values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standart values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Fill in the list of the chart legend for the series. + /// + /// Descriptor context. + /// Standart values collection. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + + Chart chart = ConverterHelper.GetChartFromContext(context); + + if (chart != null) + { + foreach (Legend legend in chart.Legends) + { + values.Add(legend.Name); + } + } + + return new StandardValuesCollection(values); + } + + #endregion + } + + /// + /// Chart type converter. Displays list of available chart type names + /// + internal class ChartTypeConverter : StringConverter + { + #region Converter methods + + /// + /// Standart values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standart values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Fill in the list of chart type names. + /// + /// Descriptor context. + /// Standard values collection. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ChartTypeRegistry registry = null; + ArrayList values = new ArrayList(); + + Chart chart = ConverterHelper.GetChartFromContext(context); + if (chart!=null) + { + // Get chart type registry service + registry = (ChartTypeRegistry)chart.GetService(typeof(ChartTypeRegistry)); + if(registry != null) + { + // Enumerate all chart types names + foreach(Object obj in registry.registeredChartTypes.Keys) + { + if(obj is string) + { + values.Add(obj); + } + } + } + else + { + throw (new InvalidOperationException(SR.ExceptionEditorChartTypeRegistryServiceInaccessible)); + } + } + + // Sort all values + values.Sort(); + + return new StandardValuesCollection(values); + } + + #endregion + } + + + /// + /// Data series name converter. Displays list of available series names + /// + internal class SeriesNameConverter : StringConverter + { + #region Converter methods + + /// + /// Standart values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standart values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Fill in the list of data series names. + /// + /// Descriptor context. + /// Standard values collection. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + DataManager dataManager = null; + ArrayList values = new ArrayList(); + + if (context != null && context.Instance != null) + { + // Call GetService method using reflection + MethodInfo methodInfo = context.Instance.GetType().GetMethod("GetService"); + if(methodInfo != null) + { + object[] parameters = new object[1]; + parameters[0] = typeof(DataManager); + dataManager = (DataManager)methodInfo.Invoke(context.Instance, parameters); + } + + // If data manager service was seccesfully retrived + if(dataManager != null) + { + foreach(Series series in dataManager.Series) + { + values.Add(series.Name); + } + } + else + { + throw (new InvalidOperationException(SR.ExceptionEditorChartTypeRegistryServiceInObjectInaccessible(context.Instance.GetType().ToString()))); + } + } + + return new StandardValuesCollection(values); + } + + #endregion + } + + /// + /// Data point properties converter + /// + internal class NoNameExpandableObjectConverter : ExpandableObjectConverter + { + #region Converter methods + + /// + /// Overrides the ConvertTo method of TypeConverter. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (context != null && context.Instance != null) + { + if (destinationType == typeof(string)) + { + return ""; + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + + #endregion + } + + /// + /// Converter for the array of doubles + /// + internal class DoubleArrayConverter : ArrayConverter + { + #region Converter methods + + /// + /// Overrides the CanConvertFrom method of TypeConverter. + /// The ITypeDescriptorContext interface provides the context for the + /// conversion. Typically this interface is used at design time to + /// provide information about the design-time container. + /// + /// Descriptor context. + /// Convertion source type. + /// Indicates if convertion is possible. + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Overrides the ConvertFrom method of TypeConverter. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert from. + /// Converted object. + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + object result = null; + bool convertFromDate = false; + + // Try to check if value type is date + if (context != null && context.Instance != null) + { + DataPoint dataPoint = (DataPoint)context.Instance; + if(dataPoint.series != null && dataPoint.series.IsYValueDateTime()) + { + convertFromDate = true; + } + } + + // Can convert from string where each array element is separated by comma + string stringValue = value as string; + if (stringValue != null) + { + string[] values = stringValue.Split(new char[] {','}); + double[] array = new double[values.Length]; + for(int index = 0; index < values.Length; index ++) + { + // Try to convert from date-time string format + if (convertFromDate) + { + DateTime valueAsDate; + if (DateTime.TryParse(values[index], CultureInfo.InvariantCulture, DateTimeStyles.None, out valueAsDate)) + { + result = valueAsDate; + } + else if (DateTime.TryParse(values[index], CultureInfo.CurrentCulture, DateTimeStyles.None, out valueAsDate)) + { + result = valueAsDate; + } + else + { + result = null; + } + } + + // Save converted value in the array + if(result != null) + { + array[index] = (double)result; + } + else + { + array[index] = CommonElements.ParseDouble(values[index]); + } + } + + return array; + } + + // Call base class + return base.ConvertFrom(context, culture, value); + } + + /// + /// Overrides the ConvertTo method of TypeConverter. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + bool convertToDate = false; + + // Check if we should convert to date string format + if (context != null && context.Instance != null) + { + DataPoint dataPoint = (DataPoint)context.Instance; + if(dataPoint.series != null && dataPoint.series.IsYValueDateTime()) + { + convertToDate = true; + } + } + + + if (destinationType == typeof(string)) + { + double[] array = (double[]) value; + string result = ""; + + foreach(double d in array) + { + if(convertToDate) + { + result += DateTime.FromOADate(d).ToString("g", System.Globalization.CultureInfo.InvariantCulture) + ","; + } + else + { + result += d.ToString(System.Globalization.CultureInfo.InvariantCulture) + ","; + } + } + + return result.TrimEnd(','); + } + + + return base.ConvertTo(context, culture, value, destinationType); + } + + #endregion + } + + /// + /// Converts data point values to and from date string format + /// + internal class DataPointValueConverter : DoubleConverter + { + #region Converter methods + + /// + /// Convert values to date string + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (context != null && context.Instance != null) + { + DataPoint dataPoint = (DataPoint)context.Instance; + + if (destinationType == typeof(string) && dataPoint.series.IsXValueDateTime()) + { + DateTime valueAsSate = DateTime.FromOADate((double)value); + return valueAsSate.ToString("g", System.Globalization.CultureInfo.CurrentCulture); + } + } + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Convert values from date string. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert from. + /// Converted object. + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (context != null && context.Instance != null) + { + string stringValue = value as string; + + if (stringValue != null) + { + DataPoint dataPoint = (DataPoint)context.Instance; + + if (dataPoint.series.IsXValueDateTime()) + { + DateTime valueAsSate = DateTime.Parse(stringValue, System.Globalization.CultureInfo.CurrentCulture); + return valueAsSate.ToOADate(); + } + } + } + + return base.ConvertFrom(context, culture, value); + } + + #endregion + } + + /// + /// Removes the String type for Y axes + /// + internal class SeriesYValueTypeConverter : EnumConverter + { + #region Converter methods + + /// + /// Public constructor + /// + /// Enumeration type. + public SeriesYValueTypeConverter(Type type) : base(type) + { + } + + /// + /// Fill in the list of data series names. + /// + /// Descriptor context. + /// Standard values collection. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + + // Call base class + StandardValuesCollection val = base.GetStandardValues(context); + + // Remove string type + foreach(object o in val) + { + if(o.ToString() != "String") + { + + values.Add(o); + } + } + + return new StandardValuesCollection(values); + } + + #endregion + } + + /// + /// Data point properties converter + /// + internal class ColorArrayConverter : TypeConverter + { + #region Converter methods + + /// + /// This method overrides CanConvertTo from TypeConverter. This is called when someone + /// wants to convert an instance of object to another type. Here, + /// only conversion to an InstanceDescriptor is supported. + /// + /// Descriptor context. + /// Destination type. + /// True if object can be converted. + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + { + return true; + } + + // Always call the base to see if it can perform the conversion. + return base.CanConvertTo(context, destinationType); + } + + /// + /// Overrides the CanConvertFrom method of TypeConverter. + /// The ITypeDescriptorContext interface provides the context for the + /// conversion. Typically this interface is used at design time to + /// provide information about the design-time container. + /// + /// Descriptor context. + /// Convertion source type. + /// Indicates if convertion is possible. + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Overrides the ConvertTo method of TypeConverter. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + return ColorArrayToString(value as Color[]); + } + + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Overrides the ConvertFrom method of TypeConverter. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert from. + /// Converted object. + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + // Can convert from string where each array element is separated by comma + string stringValue = value as string; + if (stringValue != null) + { + return StringToColorArray(stringValue); + } + + // Call base class + return base.ConvertFrom(context, culture, value); + } + + /// + /// Converts array of colors into string. + /// + /// Colors array. + /// Result string. + public static string ColorArrayToString(Color[] colors) + { + if(colors != null && colors.GetLength(0) > 0) + { + ColorConverter colorConverter = new ColorConverter(); + string result = string.Empty; + foreach(Color color in colors) + { + if(result.Length > 0) + { + result += "; "; + } + result += colorConverter.ConvertToInvariantString(color); + } + return result; + } + return string.Empty; + } + + /// + /// Converts string into array of colors. + /// + /// String data. + /// Array of colors. + public static Color[] StringToColorArray(String colorNames) + { + ColorConverter colorConverter = new ColorConverter(); + Color[] array = new Color[0]; + if(colorNames.Length > 0) + { + string[] colorValues = colorNames.Split(';'); + array = new Color[colorValues.Length]; + int index = 0; + foreach(string str in colorValues) + { + array[index++] = (Color)colorConverter.ConvertFromInvariantString(str); + } + } + return array; + } + + #endregion + } + + /// + /// Provides a set of helper methods used by converters + /// + internal static class ConverterHelper + { + + #region Static + /// + /// Gets the chart from context. + /// + /// The context. + public static Chart GetChartFromContext(ITypeDescriptorContext context) + { + if (context == null || context.Instance == null) + { + return null; + } + + IChartElement element = context.Instance as IChartElement; + if (element != null && element.Common != null) + { + return element.Common.Chart; + } + + IList list = context.Instance as IList; + if (list != null && list.Count > 0) + { + element = list[0] as IChartElement; + if (element.Common != null) + { + return element.Common.Chart; + } + + } + + Chart chart = context.Instance as Chart; + if (chart != null) + { + return chart; + } + + IServiceProvider provider = context.Instance as IServiceProvider; + if (provider != null) + { + chart = provider.GetService(typeof(Chart)) as Chart; + if (chart != null) + { + return chart; + } + } + + return null; + } + #endregion + } +} + + diff --git a/System.Web.DataVisualization/Common/Converters/ElementPositionConverter.cs b/System.Web.DataVisualization/Common/Converters/ElementPositionConverter.cs new file mode 100644 index 000000000..63b3b85e1 --- /dev/null +++ b/System.Web.DataVisualization/Common/Converters/ElementPositionConverter.cs @@ -0,0 +1,140 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ElementPositionConverter.cs +// +// Namespace: DataVisualization.Charting.Design +// +// Classes: ElementPositionConverter +// +// Purpose: Converter of the element position. +// +// Reviewed: AG - August 7, 2002 +// +//=================================================================== + + +#region Used Namespaces + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web.UI.DataVisualization.Charting; +#endif + +#endregion + +#if Microsoft_CONTROL + + namespace System.Windows.Forms.DataVisualization.Charting + +#else + namespace System.Web.UI.DataVisualization.Charting +#endif +{ + /// + /// Element position converter. + /// + internal class ElementPositionConverter : ExpandableObjectConverter + { + #region Converter methods + + /// + /// Overrides the CanConvertFrom method of TypeConverter. + /// + /// Descriptor context. + /// Convertion source type. + /// Indicates if convertion is possible. + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + if(sourceType == typeof(string)) + { + return true; + } + + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Overrides the CanConvertTo method of TypeConverter. + /// + /// Descriptor context. + /// Destination type. + /// Indicates if convertion is possible. + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + { + return true; + } + + return base.CanConvertTo(context, destinationType); + } + + /// + /// Overrides the ConvertTo method of TypeConverter. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + return ((ElementPosition)value).ToString(); + } + + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Overrides the ConvertFrom method of TypeConverter. + /// Converts from string with comma separated values. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert from. + /// Indicates if convertion is possible. + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + string posValue = value as string; + if(posValue != null) + { + if (String.Compare(posValue, Constants.AutoValue, StringComparison.OrdinalIgnoreCase) == 0) + { + return new ElementPosition(); + } + else + { + string[] array = posValue.Split(','); + if(array.Length == 4) + { + return new ElementPosition( + float.Parse(array[0], System.Globalization.CultureInfo.CurrentCulture), + float.Parse(array[1], System.Globalization.CultureInfo.CurrentCulture), + float.Parse(array[2], System.Globalization.CultureInfo.CurrentCulture), + float.Parse(array[3], System.Globalization.CultureInfo.CurrentCulture)); + } + else + { + throw(new ArgumentException( SR.ExceptionElementPositionConverter )); + } + } + } + return base.ConvertFrom(context, culture, value); + } + + #endregion + } + +} diff --git a/System.Web.DataVisualization/Common/Converters/LegendConverters.cs b/System.Web.DataVisualization/Common/Converters/LegendConverters.cs new file mode 100644 index 000000000..b036d17e7 --- /dev/null +++ b/System.Web.DataVisualization/Common/Converters/LegendConverters.cs @@ -0,0 +1,502 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: LegendConverters.cs +// +// Namespace: DataVisualization.Charting.Design +// +// Classes: LegendAreaNameConverter, LegendConverter, +// SizeEmptyValueConverter, MarginExpandableObjectConverter, +// IntNanValueConverter +// +// Purpose: Converter classes for Legend. +// +// Reviewed: AG - August 7, 2002 +// +//=================================================================== + +#region Used Namespaces + +using System; +using System.Collections; +using System.ComponentModel; +using System.Reflection; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web.UI.WebControls; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif + +{ + /// + /// Chart area name converter. Displays list of available areas names + /// + internal class LegendAreaNameConverter : StringConverter + { + #region Converter methods + + /// + /// Standart values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standart values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Fill in the list of data series names. + /// + /// Descriptor context. + /// Standart values collection. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + values.Add(Constants.NotSetValue); + + ChartAreaCollection areaCollection = null; + string areaName = ""; + if (context != null && context.Instance != null) + { + if (context.Instance is Legend) + { + Legend legend = (Legend)context.Instance; + if(legend.Common != null && legend.Common.ChartPicture != null) + { + areaCollection = legend.Common.ChartPicture.ChartAreas; + } + } + else if (context.Instance is ChartArea) + { + ChartArea area = (ChartArea)context.Instance; + if(area.Common != null && area.Common.ChartPicture != null) + { + areaCollection = area.Common.ChartPicture.ChartAreas; + areaName = area.Name; + } + } + else if (context.Instance is Title) + { + Title title = (Title)context.Instance; + if(title.Chart != null && title.Chart.chartPicture != null) + { + areaCollection = title.Chart.chartPicture.ChartAreas; + } + } + + else if (context.Instance is Annotation) + { + Annotation annotation = (Annotation)context.Instance; + if(annotation.Chart != null && annotation.Chart.chartPicture != null) + { + areaCollection = annotation.Chart.chartPicture.ChartAreas; + } + } + else if (context.Instance is IServiceProvider) + { + IServiceProvider provider = context.Instance as IServiceProvider; + + Chart chart = provider.GetService(typeof(Chart)) as Chart; + + if (chart != null) + { + areaCollection = chart.ChartAreas; + } + } + else if (context.Instance is Array) + { + if (((Array)context.Instance).Length > 0 && ((Array)context.Instance).GetValue(0) is Legend) + { + Legend legend = (Legend)((Array)context.Instance).GetValue(0); + if (legend.Common != null && legend.Common.ChartPicture != null) + { + areaCollection = legend.Common.ChartPicture.ChartAreas; + } + } + else if (((Array)context.Instance).Length > 0 && ((Array)context.Instance).GetValue(0) is ChartArea) + { + ChartArea area = (ChartArea)((Array)context.Instance).GetValue(0); + if (area.Common != null && area.Common.ChartPicture != null) + { + areaCollection = area.Common.ChartPicture.ChartAreas; + } + } + else if (((Array)context.Instance).Length > 0 && ((Array)context.Instance).GetValue(0) is Title) + { + Title title = (Title)((Array)context.Instance).GetValue(0); + if (title.Chart != null && title.Chart.chartPicture != null) + { + areaCollection = title.Chart.chartPicture.ChartAreas; + } + } + + else if (((Array)context.Instance).Length > 0 && ((Array)context.Instance).GetValue(0) is Annotation) + { + Annotation annotation = (Annotation)((Array)context.Instance).GetValue(0); + if (annotation.Chart != null && annotation.Chart.chartPicture != null) + { + areaCollection = annotation.Chart.chartPicture.ChartAreas; + } + } + + + } + } + + if (areaCollection != null) + { + foreach(ChartArea area in areaCollection) + { + if(area.Name != areaName) + { + values.Add(area.Name); + } + } + } + + return new StandardValuesCollection(values); + } + + #endregion + } + + /// + /// Legend converter + /// + internal class LegendConverter : NoNameExpandableObjectConverter + { + #region Converter methods + +#if !Microsoft_CONTROL + /// + /// Overrides the GetPropertiesSupported method of TypeConverter. + /// Save reference to the descriptor context. + /// + /// Descriptor context. + /// Indicates if properties are supported. + public override bool GetPropertiesSupported(ITypeDescriptorContext context) + { + if (context != null && context.Instance != null) + { + // Save current control type descriptor context + if(context.Instance is Chart) + { + Chart.controlCurrentContext = context; + } + } + return base.GetPropertiesSupported(context); + } +#endif // !Microsoft_CONTROL + + #endregion + } + + /// + /// Designer converter class + /// Converts Size.Emty tofrom "Auto". + /// + internal class SizeEmptyValueConverter : System.Drawing.SizeConverter + { + #region Converter methods + + /// + /// Standard values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standard values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Fill in the list of predefined values. + /// + /// Descriptor context. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + values.Add(System.Drawing.Size.Empty); + + return new StandardValuesCollection(values); + } + + /// + /// Convert Size.IsEmpty value to string "Auto" + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + if(((System.Drawing.Size)value).IsEmpty) + { + return Constants.AutoValue; + } + } + + // Call base class + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Convert minimum or maximum values from string + /// + public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) + { + // If converting from string value + string stringValue = value as string; + if (stringValue != null) + { + if (String.Compare(stringValue, Constants.AutoValue, StringComparison.OrdinalIgnoreCase) == 0) + { + return System.Drawing.Size.Empty; + } + } + + // Call base converter + return base.ConvertFrom(context, culture, value); + } + + #endregion + } + + /// + /// Data point properties converter + /// + internal class MarginExpandableObjectConverter : ExpandableObjectConverter + { + #region Converter methods + + /// + /// This method overrides CanConvertTo from TypeConverter. This is called when someone + /// wants to convert an instance of object to another type. Here, + /// only conversion to an InstanceDescriptor is supported. + /// + /// Descriptor context. + /// Destination type. + /// True if object can be converted. + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(string)) + { + return true; + } + + + // Always call the base to see if it can perform the conversion. + return base.CanConvertTo(context, destinationType); + } + + /// + /// Returns whether this converter can convert an object of the given type + /// to the type of this converter, using the specified context. + /// + /// Descriptor context. + /// Source type. + /// True if object can be converted. + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + { + return true; + } + + // Always call the base to see if it can perform the conversion. + return base.CanConvertFrom(context, sourceType); + } + + /// + /// This code performs the actual conversion from an object to a string. + /// + /// Descriptor context. + /// Culture information. + /// Object value. + /// Destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + Margins margins = value as Margins; + if (destinationType == typeof(string) && margins != null) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0:D}, {1:D}, {2:D}, {3:D}", + margins.Top, + margins.Bottom, + margins.Left, + margins.Right); + } + + // Always call base, even if you can't convert. + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Overrides the ConvertFrom method of TypeConverter. + /// + /// Descriptor context. + /// Culture information. + /// Value to convert from. + /// Converted object. + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + // Can convert from string where each array element is separated by comma + string stringValue = value as string; + if (stringValue != null) + { + Margins margins = new Margins(); + string[] values = stringValue.Split(','); + if(values.Length == 4) + { + try + { + margins.Top = int.Parse(values[0].Trim(), CultureInfo.InvariantCulture); + margins.Bottom = int.Parse(values[1].Trim(), CultureInfo.InvariantCulture); + margins.Left = int.Parse(values[2].Trim(), CultureInfo.InvariantCulture); + margins.Right = int.Parse(values[3].Trim(), CultureInfo.InvariantCulture); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionLegendDesignerMarginObjectInvalid(stringValue))); + } + } + else + { + throw (new InvalidOperationException(SR.ExceptionLegendDesignerMarginObjectInvalid(stringValue))); + } + + return margins; + } + + // Call base class + return base.ConvertFrom(context, culture, value); + } + + #endregion + } + + /// + /// Designer converter class + /// Converts Integer value -1 to/from "Auto". + /// + internal class IntNanValueConverter : Int32Converter + { + #region Converter methods + + /// + /// Standard values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standard values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Fill in the list of predefined values. + /// + /// Descriptor context. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + values.Add(-1); + + return new StandardValuesCollection(values); + } + + /// + /// Convert integer value -1 to string "Auto" + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Convertion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) + { + int intValue = (int)value; + if (destinationType == typeof(string)) + { + if(intValue == -1) + { + return Constants.AutoValue; + } + } + + // Call base class + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Convert minimum or maximum values from string + /// + public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) + { + // If converting from string value + string stringValue = value as string; + if (stringValue != null) + { + if (String.Compare(stringValue, Constants.AutoValue, StringComparison.OrdinalIgnoreCase) == 0) + { + return -1; + } + } + + // Call base converter + return base.ConvertFrom(context, culture, value); + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/DataManager/DataManager.cs b/System.Web.DataVisualization/Common/DataManager/DataManager.cs new file mode 100644 index 000000000..51b9afd49 --- /dev/null +++ b/System.Web.DataVisualization/Common/DataManager/DataManager.cs @@ -0,0 +1,1183 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: DataManager.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Data +// +// Classes: DataManager +// +// Purpose: Series storage and manipulation class. +// +// Reviewed: AG - Aug 1, 2002; GS - Aug 7, 2002 +// +//=================================================================== + + +#region Used namespaces + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; + +#if Microsoft_CONTROL + + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + + +#else + using System.Web.UI; + using System.Web.UI.WebControls; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Data +#else + namespace System.Web.UI.DataVisualization.Charting.Data +#endif +{ + /// + /// Data Manager. + /// + internal class DataManager : ChartElement, IServiceProvider + { + #region Fields + // Series collection + private SeriesCollection _series = null; + + // Servise container reference + internal IServiceContainer serviceContainer = null; + + // Chart color palette + private ChartColorPalette _colorPalette = ChartColorPalette.BrightPastel; + + #endregion + + #region Constructors and initialization + + /// + /// Data manager public constructor + /// + /// Service container object. + public DataManager(IServiceContainer container) + { + if(container == null) + { + throw(new ArgumentNullException(SR.ExceptionInvalidServiceContainer)); + } + serviceContainer = container; + Common = new CommonElements(container); + _series = new SeriesCollection(this); + } + + /// + /// Returns Data Manager service object. + /// + /// Service type requested. + /// Data Manager service object. + [EditorBrowsableAttribute(EditorBrowsableState.Never)] + object IServiceProvider.GetService(Type serviceType) + { + if(serviceType == typeof(DataManager)) + { + return this; + } + throw (new ArgumentException( SR.ExceptionDataManagerUnsupportedType(serviceType.ToString()))); + } + + /// + /// Initialize data manger object + /// + internal void Initialize() + { + // Attach to the Chart Picture painting events + ChartImage chartPicture = (ChartImage)serviceContainer.GetService(typeof(ChartImage)); + chartPicture.BeforePaint += new EventHandler(this.ChartPicture_BeforePaint); + chartPicture.AfterPaint += new EventHandler(this.ChartPicture_AfterPaint); + } + + #endregion + + #region Chart picture painting events hanlers + + internal override void Invalidate() + { + base.Invalidate(); + +#if Microsoft_CONTROL + if (Chart!=null) + Chart.Invalidate(); +#endif + } + + + /// + /// Event fired when chart picture is going to be painted. + /// + /// Sender object. + /// Event arguments. + private void ChartPicture_BeforePaint(object sender, ChartPaintEventArgs e) + { + // Prepare series for drawing + int markerIndex = 1; + for(int index = 0; index < this.Series.Count; index++) + { + Series series = this.Series[index]; + + // Reset series "X values are zeros" flag + series.xValuesZerosChecked = false; + series.xValuesZeros = false; + + // Set series colors from palette + IChartType chartType = e.CommonElements.ChartTypeRegistry.GetChartType(series.ChartTypeName); + bool paletteColorsInPoints = chartType.ApplyPaletteColorsToPoints; + // if the series palette is set the we can color all data points, even on column chart. + if (series.Palette != ChartColorPalette.None) + { + paletteColorsInPoints = true; + } + + this.PrepareData( + paletteColorsInPoints, + series.Name); + + // Clear temp. marker style + if(series.tempMarkerStyleIsSet) + { + series.MarkerStyle = MarkerStyle.None; + series.tempMarkerStyleIsSet = false; + } + + // Set marker style for chart types based on markes + if(chartType.GetLegendImageStyle(series) == LegendImageStyle.Marker && series.MarkerStyle == MarkerStyle.None) + { + series.MarkerStyle = (MarkerStyle)markerIndex++; + series.tempMarkerStyleIsSet = true; + + if(markerIndex > 9) + { + markerIndex = 1; + } + } + } + } + + /// + /// Event fired after chart picture was painted. + /// + /// Sender object. + /// Event arguments. + private void ChartPicture_AfterPaint(object sender, ChartPaintEventArgs e) + { + Chart control = (Chart)serviceContainer.GetService(typeof(Chart)); + if(control != null) + { + // Clean up series after drawing + for(int index = 0; index < this.Series.Count; index++) + { + Series series = this.Series[index]; + if(series.UnPrepareData(control.Site)) + { + --index; + } + } + } + } + + #endregion + + #region Series data preparation methods + + /// + /// Apply palette colors to the data series if UsePaletteColors property is set. + /// + internal void ApplyPaletteColors() + { + ChartColorPalette palette = this.Palette; + // switch to default pallette if is none and custom collors array is empty. + if (palette == ChartColorPalette.None && this.PaletteCustomColors.Length == 0) + { + palette = ChartColorPalette.BrightPastel; + } + + // Get palette colors + int colorIndex = 0; + Color[] paletteColors = (palette == ChartColorPalette.None) ? + this.PaletteCustomColors : ChartPaletteColors.GetPaletteColors(palette); + + foreach (Series dataSeries in _series) + { + // Check if chart area name is valid + bool validAreaName = false; + if (Chart!=null) + { + validAreaName = Chart.ChartAreas.IsNameReferenceValid(dataSeries.ChartArea); + } + + // Change color of the series only if valid chart area name is specified + if(validAreaName) + { + // Change color of the series only if default color is set + if(dataSeries.Color == Color.Empty || dataSeries.tempColorIsSet) + { + dataSeries.color = paletteColors[colorIndex++]; + dataSeries.tempColorIsSet = true; + if(colorIndex >= paletteColors.Length) + { + colorIndex = 0; + } + } + } + } + } + + /// + /// Called just before the data from the series to be used to perform these operations: + /// - apply palette colors to the data series + /// - prepare data in series + /// + /// If true each data point will be assigned a color from the palette (if it's set) + /// List of series indexes, which requires data preparation + internal void PrepareData(bool pointsApplyPaletteColors, params string[] series) + { + this.ApplyPaletteColors(); + + // Prepare data in series + Chart control = (Chart)serviceContainer.GetService(typeof(Chart)); + if(control != null) + { + foreach(string seriesName in series) + { + this.Series[seriesName].PrepareData(pointsApplyPaletteColors); + } + } + } + + #endregion + + #region Series Min/Max values methods + + /// + /// This method checks if data point should be skipped. This + /// method will return true if data point is empty. + /// + /// Data point + /// This method returns true if data point is empty. + private bool IsPointSkipped( DataPoint point ) + { + if( point.IsEmpty ) + { + return true; + } + + return false; + } + + /// + /// Gets max number of data points in specified series. + /// + /// Series IDs + /// Maximum number of data points + internal int GetNumberOfPoints(params string[] series) + { + int numberOfPoints = 0; + foreach(string seriesName in series) + { + numberOfPoints = Math.Max(numberOfPoints, this._series[seriesName].Points.Count); + } + return numberOfPoints; + } + + /// + /// Gets maximum Y value from many series + /// + /// Index of Y value to use + /// Series IDs + /// Maximum Y value + internal double GetMaxYValue(int valueIndex, params string[] series) + { + double returnValue = Double.MinValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + // The empty point + if( IsPointSkipped( seriesPoint ) ) + { + continue; + } + + if(!double.IsNaN(seriesPoint.YValues[valueIndex])) + { + returnValue = Math.Max(returnValue, seriesPoint.YValues[valueIndex]); + } + } + } + return returnValue; + } + + /// + /// Get Maximum value for Y and and Radius (Y2) ( used for bubble chart ) + /// + /// Chart Area + /// Series IDs + /// Maximum Y value + internal double GetMaxYWithRadiusValue( ChartArea area, params string[] series ) + { + double returnValue = Double.MinValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + // The empty point + if( IsPointSkipped( seriesPoint ) ) + { + continue; + } + + if(!double.IsNaN(seriesPoint.YValues[0])) + { + if (seriesPoint.YValues.Length > 1) + { + returnValue = Math.Max(returnValue, seriesPoint.YValues[0] + BubbleChart.AxisScaleBubbleSize(area.Common, area, seriesPoint.YValues[1], true)); + } + else + { + returnValue = Math.Max(returnValue, seriesPoint.YValues[0]); + } + } + } + } + return returnValue; + } + + /// + /// Get Maximum value for X and Radius (Y2) ( used for bubble chart ) + /// + /// Chart Area + /// Series IDs + /// Maximum X value + internal double GetMaxXWithRadiusValue( ChartArea area, params string[] series ) + { + double returnValue = Double.MinValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + // The empty point + if( IsPointSkipped( seriesPoint ) ) + { + continue; + } + + if(!double.IsNaN(seriesPoint.XValue)) + { + if (seriesPoint.YValues.Length > 1) + { + returnValue = Math.Max(returnValue, seriesPoint.XValue + BubbleChart.AxisScaleBubbleSize(area.Common, area, seriesPoint.XValue, false)); + } + else + { + returnValue = Math.Max(returnValue, seriesPoint.XValue); + } + } + } + } + return returnValue; + } + + /// + /// Get Minimum value for X and Radius Y2 ( used for bubble chart ) + /// + /// Chart Area + /// Series IDs + /// Minimum X value + internal double GetMinXWithRadiusValue( ChartArea area, params string[] series ) + { + double returnValue = Double.MaxValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + // The empty point + if( IsPointSkipped( seriesPoint ) ) + { + continue; + } + + if(!double.IsNaN(seriesPoint.XValue)) + { + if (seriesPoint.YValues.Length > 1) + { + returnValue = Math.Min(returnValue, seriesPoint.XValue - BubbleChart.AxisScaleBubbleSize(area.Common, area, seriesPoint.YValues[1], false)); + } + else + { + returnValue = Math.Min(returnValue, seriesPoint.XValue); + } + } + } + } + return returnValue; + } + + /// + /// Gets maximum Y value from many series + /// + /// Series IDs + /// Maximum Y value + internal double GetMaxYValue(params string[] series) + { + double returnValue = Double.MinValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + // The empty point + if( IsPointSkipped( seriesPoint ) ) + { + continue; + } + + foreach( double y in seriesPoint.YValues ) + { + if(!double.IsNaN(y)) + { + returnValue = Math.Max(returnValue, y); + } + } + } + } + return returnValue; + } + + /// + /// Gets maximum X value from many series + /// + /// Series IDs + /// Maximum X value + internal double GetMaxXValue(params string[] series) + { + double returnValue = Double.MinValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + returnValue = Math.Max(returnValue, seriesPoint.XValue); + } + } + return returnValue; + } + + /// + /// Gets minimum and maximum X value from many series. + /// + /// Returns maximum X value. + /// Returns minimum X value. + /// Series IDs + internal void GetMinMaxXValue(out double min, out double max, params string[] series) + { + max = Double.MinValue; + min = Double.MaxValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + max = Math.Max(max, seriesPoint.XValue); + min = Math.Min(min, seriesPoint.XValue); + } + } + } + + /// + /// Gets minimum and maximum Y value from many series. + /// + /// Index of Y value to use. + /// Returns maximum Y value. + /// Returns minimum Y value. + /// Series IDs + internal void GetMinMaxYValue(int valueIndex, out double min, out double max, params string[] series) + { + max = Double.MinValue; + min = Double.MaxValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + // Skip empty point + if( IsPointSkipped( seriesPoint ) ) + { + continue; + } + + double yValue = seriesPoint.YValues[valueIndex]; + if(!double.IsNaN(yValue)) + { + max = Math.Max(max, yValue); + min = Math.Min(min, yValue); + } + } + } + } + + /// + /// Gets minimum and maximum Y value from many series. + /// + /// Returns maximum Y value. + /// Returns minimum Y value. + /// Series IDs + internal void GetMinMaxYValue(out double min, out double max, params string[] series) + { + max = Double.MinValue; + min = Double.MaxValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + // Skip empty point + if( IsPointSkipped( seriesPoint ) ) + { + continue; + } + + // Iterate through all Y values + foreach( double y in seriesPoint.YValues ) + { + if(!double.IsNaN(y)) + { + max = Math.Max(max, y); + min = Math.Min(min, y); + } + } + } + } + } + + /// + /// Gets minimum and maximum Y value from many series. + /// + /// Series objects list. + /// Returns maximum Y value. + /// Returns minimum Y value. + internal void GetMinMaxYValue(System.Collections.ArrayList seriesList, out double min, out double max) + { + max = Double.MinValue; + min = Double.MaxValue; + foreach(Series series in seriesList) + { + foreach(DataPoint seriesPoint in series.Points) + { + // Skip empty point + if( IsPointSkipped( seriesPoint ) ) + { + continue; + } + + // Iterate through all Y values + foreach( double y in seriesPoint.YValues ) + { + if(!double.IsNaN(y)) + { + max = Math.Max(max, y); + min = Math.Min(min, y); + } + } + } + } + } + + /// + /// Gets maximum stacked Y value from many series + /// + /// Index of Y value to use + /// Series IDs + /// Maximum stacked Y value + internal double GetMaxStackedYValue(int valueIndex, params string[] series) + { + double returnValue = 0; + double numberOfPoints = GetNumberOfPoints(series); + for(int pointIndex = 0; pointIndex < numberOfPoints; pointIndex++) + { + double stackedMax = 0; + double noStackedMax = 0; + foreach(string seriesName in series) + { + if(this._series[seriesName].Points.Count > pointIndex) + { + // Take chart type from the series + ChartTypeRegistry chartTypeRegistry = (ChartTypeRegistry)serviceContainer.GetService(typeof(ChartTypeRegistry)); + IChartType chartType = chartTypeRegistry.GetChartType(this._series[seriesName].ChartTypeName); + + // If stacked area + if( !chartType.StackSign ) + continue; + + if( chartType.Stacked ) + { + if(this._series[seriesName].Points[pointIndex].YValues[valueIndex] > 0) + { + stackedMax += this._series[seriesName].Points[pointIndex].YValues[valueIndex]; + } + } + else + { + noStackedMax = Math.Max(noStackedMax,this._series[seriesName].Points[pointIndex].YValues[valueIndex]); + } + } + } + stackedMax = Math.Max(stackedMax, noStackedMax); + returnValue = Math.Max(returnValue, stackedMax); + } + return returnValue; + } + + /// + /// Gets maximum Unsigned stacked Y value from many series ( Stacked Area chart ) + /// + /// Index of Y value to use + /// Series IDs + /// Maximum stacked Y value + internal double GetMaxUnsignedStackedYValue(int valueIndex, params string[] series) + { + double returnValue = 0; + double maxValue = Double.MinValue; + double numberOfPoints = GetNumberOfPoints(series); + for(int pointIndex = 0; pointIndex < numberOfPoints; pointIndex++) + { + double stackedMax = 0; + double noStackedMax = 0; + foreach(string seriesName in series) + { + if (this._series[seriesName].Points.Count > pointIndex) + { + // Take chart type from the series + ChartTypeRegistry chartTypeRegistry = (ChartTypeRegistry)serviceContainer.GetService(typeof(ChartTypeRegistry)); + IChartType chartType = chartTypeRegistry.GetChartType(this._series[seriesName].ChartTypeName); + + // If stacked column and bar + if (chartType.StackSign || double.IsNaN(this._series[seriesName].Points[pointIndex].YValues[valueIndex])) + { + continue; + } + + if (chartType.Stacked) + { + maxValue = Double.MinValue; + stackedMax += this._series[seriesName].Points[pointIndex].YValues[valueIndex]; + if (stackedMax > maxValue) + maxValue = stackedMax; + } + else + { + noStackedMax = Math.Max(noStackedMax, this._series[seriesName].Points[pointIndex].YValues[valueIndex]); + } + } + } + maxValue = Math.Max(maxValue, noStackedMax); + returnValue = Math.Max(returnValue, maxValue); + } + return returnValue; + } + + /// + /// Gets maximum stacked X value from many series + /// + /// Series IDs + /// Maximum stacked X value + internal double GetMaxStackedXValue(params string[] series) + { + double returnValue = 0; + double numberOfPoints = GetNumberOfPoints(series); + for(int pointIndex = 0; pointIndex < numberOfPoints; pointIndex++) + { + double doubleIndexValue = 0; + foreach(string seriesName in series) + { + if (this._series[seriesName].Points.Count > pointIndex) + { + if (this._series[seriesName].Points[pointIndex].XValue > 0) + { + doubleIndexValue += this._series[seriesName].Points[pointIndex].XValue; + } + } + } + returnValue = Math.Max(returnValue, doubleIndexValue); + } + return returnValue; + } + + /// + /// Gets minimum Y value from many series + /// + /// Index of Y value to use + /// Series IDs + /// Minimum Y value + internal double GetMinYValue(int valueIndex, params string[] series) + { + double returnValue = Double.MaxValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + // The empty point + if( IsPointSkipped( seriesPoint ) ) + { + continue; + } + + if(!double.IsNaN(seriesPoint.YValues[valueIndex])) + { + returnValue = Math.Min(returnValue, seriesPoint.YValues[valueIndex]); + } + } + } + return returnValue; + } + + /// + /// Get Minimum value for Y and and Radius (Y2) ( used for bubble chart ) + /// + /// Chart Area + /// Series IDs + /// Minimum Y value + internal double GetMinYWithRadiusValue( ChartArea area, params string[] series ) + { + double returnValue = Double.MaxValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + // The empty point + if( IsPointSkipped( seriesPoint ) ) + { + continue; + } + + if(!double.IsNaN(seriesPoint.YValues[0])) + { + if (seriesPoint.YValues.Length > 1) + { + returnValue = Math.Min(returnValue, seriesPoint.YValues[0] - BubbleChart.AxisScaleBubbleSize(area.Common, area, seriesPoint.YValues[1], true)); + } + else + { + returnValue = Math.Min(returnValue, seriesPoint.YValues[0]); + } + } + } + } + return returnValue; + } + + /// + /// Gets minimum Y value from many series + /// + /// Series IDs + /// Minimum Y value + internal double GetMinYValue(params string[] series) + { + double returnValue = Double.MaxValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + // The empty point + if( IsPointSkipped( seriesPoint ) ) + { + continue; + } + + foreach(double y in seriesPoint.YValues) + { + if(!double.IsNaN(y)) + { + returnValue = Math.Min(returnValue, y); + } + } + } + } + return returnValue; + } + + /// + /// Gets minimum X value from many series + /// + /// Series IDs + /// Minimum X value + internal double GetMinXValue(params string[] series) + { + double returnValue = Double.MaxValue; + foreach(string seriesName in series) + { + foreach(DataPoint seriesPoint in this._series[seriesName].Points) + { + returnValue = Math.Min(returnValue, seriesPoint.XValue); + } + } + return returnValue; + } + + /// + /// Gets minimum stacked Y value from many series + /// + /// Index of Y value to use + /// Series IDs + /// Minimum stacked Y value + internal double GetMinStackedYValue(int valueIndex, params string[] series) + { + double returnValue = Double.MaxValue; + double numberOfPoints = GetNumberOfPoints(series); + for(int pointIndex = 0; pointIndex < numberOfPoints; pointIndex++) + { + double stackedMin = 0; + double noStackedMin = 0; + foreach(string seriesName in series) + { + if(this._series[seriesName].Points.Count > pointIndex) + { + // Take chart type from the series + ChartTypeRegistry chartTypeRegistry = (ChartTypeRegistry)serviceContainer.GetService(typeof(ChartTypeRegistry)); + IChartType chartType = chartTypeRegistry.GetChartType(this._series[seriesName].ChartTypeName); + + // If stacked area + if( !chartType.StackSign || double.IsNaN(this._series[seriesName].Points[pointIndex].YValues[valueIndex])) + continue; + + if( chartType.Stacked ) + { + if(this._series[seriesName].Points[pointIndex].YValues[valueIndex] < 0) + { + stackedMin += this._series[seriesName].Points[pointIndex].YValues[valueIndex]; + } + } + else + { + noStackedMin = Math.Min(noStackedMin,this._series[seriesName].Points[pointIndex].YValues[valueIndex]); + } + } + } + stackedMin = Math.Min(stackedMin, noStackedMin); + if( stackedMin == 0 ) + { + stackedMin = this._series[series[0]].Points[this._series[series[0]].Points.Count - 1].YValues[valueIndex]; + } + returnValue = Math.Min(returnValue, stackedMin); + } + return returnValue; + } + + /// + /// Gets minimum Unsigned stacked Y value from many series + /// + /// Index of Y value to use + /// Series IDs + /// Minimum stacked Y value + internal double GetMinUnsignedStackedYValue(int valueIndex, params string[] series) + { + double returnValue = Double.MaxValue; + double minValue = Double.MaxValue; + double numberOfPoints = GetNumberOfPoints(series); + for(int pointIndex = 0; pointIndex < numberOfPoints; pointIndex++) + { + double stackedMin = 0; + double noStackedMin = 0; + minValue = Double.MaxValue; + foreach(string seriesName in series) + { + if (this._series[seriesName].Points.Count > pointIndex) + { + // Take chart type from the series + ChartTypeRegistry chartTypeRegistry = (ChartTypeRegistry)serviceContainer.GetService(typeof(ChartTypeRegistry)); + IChartType chartType = chartTypeRegistry.GetChartType(this._series[seriesName].ChartTypeName); + + // If stacked column and bar + if (chartType.StackSign || double.IsNaN(this._series[seriesName].Points[pointIndex].YValues[valueIndex])) + { + continue; + } + + if (chartType.Stacked) + { + if (this._series[seriesName].Points[pointIndex].YValues[valueIndex] < 0) + { + stackedMin += this._series[seriesName].Points[pointIndex].YValues[valueIndex]; + if (stackedMin < minValue) + minValue = stackedMin; + } + } + else + { + noStackedMin = Math.Min(noStackedMin, this._series[seriesName].Points[pointIndex].YValues[valueIndex]); + } + } + } + minValue = Math.Min(noStackedMin, minValue); + returnValue = Math.Min(returnValue, minValue); + } + return returnValue; + } + + /// + /// Gets minimum stacked X value from many series + /// + /// Series IDs + /// Minimum stacked X value + internal double GetMinStackedXValue(params string[] series) + { + double returnValue = 0; + double numberOfPoints = GetNumberOfPoints(series); + for(int pointIndex = 0; pointIndex < numberOfPoints; pointIndex++) + { + double doubleIndexValue = 0; + foreach(string seriesName in series) + { + if(this._series[seriesName].Points[pointIndex].XValue < 0) + { + doubleIndexValue += this._series[seriesName].Points[pointIndex].XValue; + } + } + returnValue = Math.Min(returnValue, doubleIndexValue); + } + return returnValue; + } + + + /// + /// Gets maximum hundred percent stacked Y value + /// + /// Indicates that negative values are shown on the other side of the axis. + /// Series names + /// Maximum 100% stacked Y value + internal double GetMaxHundredPercentStackedYValue(bool supportNegative, params string[] series) + { + double returnValue = 0; + + // Convert array of series names into array of series + Series[] seriesArray = new Series[series.Length]; + int seriesIndex = 0; + foreach(string seriesName in series) + { + seriesArray[seriesIndex++] = this._series[seriesName]; + } + + // Loop through all dat points + try + { + for(int pointIndex = 0; pointIndex < this._series[series[0]].Points.Count; pointIndex++) + { + // Calculate the total for all series + double totalPerPoint = 0; + double positiveTotalPerPoint = 0; + foreach(Series ser in seriesArray) + { + if(supportNegative) + { + totalPerPoint += Math.Abs(ser.Points[pointIndex].YValues[0]); + } + else + { + totalPerPoint += ser.Points[pointIndex].YValues[0]; + } + + if(ser.Points[pointIndex].YValues[0] > 0 || supportNegative == false) + { + positiveTotalPerPoint += ser.Points[pointIndex].YValues[0]; + } + } + totalPerPoint = Math.Abs(totalPerPoint); + + // Calculate percentage of total + if(totalPerPoint != 0) + { + returnValue = Math.Max(returnValue, + (positiveTotalPerPoint / totalPerPoint) * 100.0); + } + } + } + catch(System.Exception) + { + throw (new InvalidOperationException(SR.ExceptionDataManager100StackedSeriesPointsNumeberMismatch)); + } + + return returnValue; + } + + /// + /// Gets minimum hundred percent stacked Y value + /// + /// Indicates that negative values are shown on the other side of the axis. + /// Series names + /// Minimum 100% stacked Y value + internal double GetMinHundredPercentStackedYValue(bool supportNegative, params string[] series) + { + double returnValue = 0.0; + + // Convert array of series names into array of series + Series[] seriesArray = new Series[series.Length]; + int seriesIndex = 0; + foreach(string seriesName in series) + { + seriesArray[seriesIndex++] = this._series[seriesName]; + } + + // Loop through all dat points + try + { + for(int pointIndex = 0; pointIndex < this._series[series[0]].Points.Count; pointIndex++) + { + // Calculate the total for all series + double totalPerPoint = 0; + double negativeTotalPerPoint = 0; + foreach(Series ser in seriesArray) + { + if(supportNegative) + { + totalPerPoint += Math.Abs(ser.Points[pointIndex].YValues[0]); + } + else + { + totalPerPoint += ser.Points[pointIndex].YValues[0]; + } + + if(ser.Points[pointIndex].YValues[0] < 0 || supportNegative == false) + { + negativeTotalPerPoint += ser.Points[pointIndex].YValues[0]; + } + } + + totalPerPoint = Math.Abs(totalPerPoint); + + // Calculate percentage of total + if(totalPerPoint != 0) + { + returnValue = Math.Min(returnValue, + (negativeTotalPerPoint / totalPerPoint) * 100.0); + } + } + } + catch(System.Exception) + { + throw (new InvalidOperationException(SR.ExceptionDataManager100StackedSeriesPointsNumeberMismatch)); + } + + return returnValue; + } + + #endregion + + #region DataManager Properties + + /// + /// Chart series collection. + /// + [ + SRCategory("CategoryAttributeData"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif + Editor(Editors.SeriesCollectionEditor.Editor, Editors.SeriesCollectionEditor.Base), + Bindable(true) + ] + public SeriesCollection Series + { + get + { + return _series; + } + } + + /// + /// Color palette to use + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributePalette"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif + DefaultValue(ChartColorPalette.BrightPastel), + Editor(Editors.ColorPaletteEditor.Editor, Editors.ColorPaletteEditor.Base) + ] + public ChartColorPalette Palette + { + get + { + return _colorPalette; + } + set + { + _colorPalette = value; + } + } + + // Array of custom palette colors. + private Color[] _paletteCustomColors = new Color[0]; + + /// + /// Array of custom palette colors. + /// + /// + /// When this custom colors array is non-empty the Palette property is ignored. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), + SerializationVisibilityAttribute(SerializationVisibility.Attribute), + SRDescription("DescriptionAttributeDataManager_PaletteCustomColors"), + TypeConverter(typeof(ColorArrayConverter)) + ] + public Color[] PaletteCustomColors + { + set + { + this._paletteCustomColors = value; + } + get + { + return this._paletteCustomColors; + } + } + + + + + #endregion + + #region IDisposable Members + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_series != null) + { + _series.Dispose(); + _series = null; + } + } + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/DataManager/DataPoint.cs b/System.Web.DataVisualization/Common/DataManager/DataPoint.cs new file mode 100644 index 000000000..de9402c6c --- /dev/null +++ b/System.Web.DataVisualization/Common/DataManager/DataPoint.cs @@ -0,0 +1,7044 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: DataPoint.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Data +// +// Classes: DataPoint, DataPointCustomProperties, DataPointCollection, +// DataPointComparer, DataPoint3D, CustomProperties +// +// Purpose: Classes related to the Data Points: +// DataPointCollection - data points collection class +// DataPoint - data point properties and methods +// DataPointCustomProperties - data point & series properties +// DataPointComparer - used for sorting data points in series +// +// Reviewed: AG - Aug 1, 2002, GS - Aug 7, 2002 +// +//=================================================================== + + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Data.Common; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + + + using System.ComponentModel.Design.Serialization; + using System.Reflection; + using System.CodeDom; + using System.Windows.Forms.Design; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.IO; + +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif + { + #region CustomProperties enumeration + + /// + /// Enumeration of common properties names. + /// + internal enum CommonCustomProperties + { + PointName, + Label, + AxisLabel, + LabelFormat, + IsValueShownAsLabel, + Color, + BorderColor, + BorderDashStyle, + BorderWidth, + BackImage, + BackImageWrapMode, + BackImageAlignment, + BackImageTransparentColor, + BackGradientStyle, + BackSecondaryColor, + BackHatchStyle, + Font, + LabelForeColor, + LabelAngle, + MarkerStyle, + MarkerSize, + MarkerImage, + MarkerImageTransparentColor, + MarkerColor, + MarkerBorderColor, + MarkerBorderWidth, + MapAreaAttributes, + PostBackValue, + MapAreaType, + LegendMapAreaType, + LabelMapAreaType, + Url, + ToolTip, + Tag, + LegendUrl, + LegendToolTip, + LegendText, + LegendMapAreaAttributes, + LegendPostBackValue, + IsVisibleInLegend, + LabelUrl, + LabelToolTip, + LabelMapAreaAttributes, + LabelPostBackValue, + LabelBorderColor, + LabelBorderDashStyle, + LabelBorderWidth, + LabelBackColor, + }; + + #endregion + + /// + /// Data points comparer class + /// + [ + SRDescription("DescriptionAttributeDataPointComparer_DataPointComparer") + ] + public class DataPointComparer : IComparer + { + #region Fields + + // Sorting order + private PointSortOrder _sortingOrder = PointSortOrder.Ascending; + + // Sorting value index + private int _sortingValueIndex = 1; + + #endregion + + #region Constructors + + /// + /// Private default constructor. + /// + private DataPointComparer() + { + } + + /// + /// Data points comparer class constructor. + /// + /// Data series. + /// Sorting order. + /// Value used for sorting ("X", "Y or Y1", "Y2", ...). +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public DataPointComparer(Series series, PointSortOrder sortOrder, string sortBy) + { + // Check if sorting value is valid + sortBy = sortBy.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + if(String.Compare(sortBy, "X", StringComparison.Ordinal) == 0) + { + _sortingValueIndex = -1; + } + else if (String.Compare(sortBy, "Y", StringComparison.Ordinal) == 0) + { + _sortingValueIndex = 0; + } + else if (String.Compare(sortBy, "AXISLABEL", StringComparison.Ordinal) == 0) + { + _sortingValueIndex = -2; + } + else if(sortBy.Length == 2 && + sortBy.StartsWith("Y", StringComparison.Ordinal) && + Char.IsDigit(sortBy[1])) + { + _sortingValueIndex = Int32.Parse(sortBy.Substring(1), System.Globalization.CultureInfo.InvariantCulture) - 1; + } + else + { + throw(new ArgumentException( SR.ExceptionDataPointConverterInvalidSorting, "sortBy")); + } + + // Check if data series support as many Y values as required + if(_sortingValueIndex > 0 && _sortingValueIndex >= series.YValuesPerPoint) + { + throw(new ArgumentException( SR.ExceptionDataPointConverterUnavailableSorting(sortBy, series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture) ), "sortBy")); + } + + this._sortingOrder = sortOrder; + } + + #endregion + + #region Comparing method + + /// + /// Compares two data points. + /// + /// First data point. + /// Second data point. + /// If the two values are equal, it returns zero. If point 1 is greater than point 2, + /// it returns a positive integer; otherwise, it returns a negative integer. + /// + public int Compare(DataPoint x, DataPoint y) + { + int result = -1; + + // Compare X value + if(_sortingValueIndex == -1) + { + result = x.XValue.CompareTo(y.XValue); + } + // Compare Axis Label value + else if(_sortingValueIndex == -2) + { + result = string.Compare(x.AxisLabel, y.AxisLabel, StringComparison.CurrentCulture); + } + // Compare one of the Y value(s) + else + { + result = x.YValues[_sortingValueIndex].CompareTo(y.YValues[_sortingValueIndex]); + } + + // Invert result depending on the sorting order + if(this._sortingOrder == PointSortOrder.Descending) + { + result = -result; + } + + return result; + } + + #endregion + } + + /// + /// A collection of data points. + /// + [ + SRDescription("DescriptionAttributeDataPointCollection_DataPointCollection"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif +#if !Microsoft_CONTROL + [Themeable(false)] +#endif + public class DataPointCollection : ChartElementCollection + { + #region Fields + + // Reference to the sereies of data points + internal Series series = null; + + #endregion + + #region Constructors and Initialization + + /// + /// Data Point Collection object constructor. + /// + /// Series object, which the Data Point Collection belongs to. + internal DataPointCollection(Series series) : base(series) + { + this.series = series; + } + + /// + /// Initialize data point series and name. + /// + /// Reference to the data point object to initialize. + internal void DataPointInit(ref DataPoint dataPoint) + { + DataPointInit(this.series, ref dataPoint); + } + + /// + /// Initialize data point series and name. + /// + /// Series the data point belongs to. + /// Reference to the data point object to initialize. + internal static void DataPointInit(Series series, ref DataPoint dataPoint) + { + dataPoint.series = series; + + if(dataPoint.AxisLabel.Length > 0 && series != null) + { + series.noLabelsInPoints = false; + } + +#if Microsoft_CONTROL + // Set flag that tooltips flags should be recalculated + if(dataPoint.ToolTip.Length > 0 && + dataPoint.LegendToolTip.Length > 0 && + dataPoint.LabelToolTip.Length > 0 && + series != null && series.Chart != null && series.Chart.selection != null) + { + series.Chart.selection.enabledChecked = false; + } +#endif + } + + #endregion + + #region Data point binding, adding and inserting methods + + /// + /// Adds the new DataPoint to a collection and sets its Y values. + /// + /// The y. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public DataPoint Add(params double[] y) + { + DataPoint point = new DataPoint(0, y); + this.Add(point); + return point; + } + + /// + /// Parse the input parameter with other point attribute binding rule + /// in format: PointProperty=Field[{Format}] [,PointProperty=Field[{Format}]]. + /// For example: "Tooltip=Price{C1},Url=WebSiteName". + /// + /// Other fields parameter. + /// Returns array of attribute names. + /// Returns array of field names. + /// Returns array of format strings. + internal static void ParsePointFieldsParameter( + string otherFields, + ref string[] otherAttributeNames, + ref string[] otherFieldNames, + ref string[] otherValueFormat) + { + if(otherFields != null && otherFields.Length > 0) + { + // Split string by comma + otherAttributeNames = otherFields.Replace(",,", "\n").Split(','); + otherFieldNames = new string[otherAttributeNames.Length]; + otherValueFormat = new string[otherAttributeNames.Length]; + + // Loop through all strings + for(int index = 0; index < otherAttributeNames.Length; index++) + { + // Split string by equal sign + int equalSignIndex = otherAttributeNames[index].IndexOf('='); + if(equalSignIndex > 0) + { + otherFieldNames[index] = otherAttributeNames[index].Substring(equalSignIndex + 1); + otherAttributeNames[index] = otherAttributeNames[index].Substring(0, equalSignIndex); + } + else + { + throw (new ArgumentException(SR.ExceptionParameterFormatInvalid, "otherFields")); + } + + // Check if format string was specified + int bracketIndex = otherFieldNames[index].IndexOf('{'); + if(bracketIndex > 0 && otherFieldNames[index][otherFieldNames[index].Length - 1] == '}') + { + otherValueFormat[index] = otherFieldNames[index].Substring(bracketIndex + 1); + otherValueFormat[index] = otherValueFormat[index].Trim('{', '}'); + otherFieldNames[index] = otherFieldNames[index].Substring(0, bracketIndex); + } + + // Trim and replace new line character + otherAttributeNames[index] = otherAttributeNames[index].Trim().Replace("\n", ","); + otherFieldNames[index] = otherFieldNames[index].Trim().Replace("\n", ","); + if ( otherValueFormat[index] != null ) + otherValueFormat[index] = otherValueFormat[index].Trim().Replace("\n", ","); + } + } + } + + /// + /// Data bind X, Y and other values (like Tooltip, LabelStyle,...) of the data points to the data source. + /// Data source can be the Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow. + /// + /// Data source. + /// Name of the field for X values. + /// Comma separated names of the fields for Y values. + /// Other point properties binding rule in format: PointProperty=Field[{Format}] [,PointProperty=Field[{Format}]]. For example: "Tooltip=Price{C1},Url=WebSiteName". + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public void DataBind(IEnumerable dataSource, string xField, string yFields, string otherFields) + { + // Check arguments + if (dataSource == null) + throw new ArgumentNullException("dataSource", SR.ExceptionDataPointInsertionNoDataSource); + if (dataSource is string) + throw (new ArgumentException(SR.ExceptionDataBindSeriesToString, "dataSource")); + if (yFields == null) + throw new ArgumentNullException("yFields"); + + // Convert comma separated Y values field names string to array of names + string[] yFieldNames = yFields.Replace(",,", "\n").Split(','); + for(int index = 0; index < yFieldNames.Length; index++) + { + yFieldNames[index] = yFieldNames[index].Replace("\n", ","); + } + + if (yFieldNames.GetLength(0) > series.YValuesPerPoint) + throw (new ArgumentOutOfRangeException("yFields", SR.ExceptionDataPointYValuesCountMismatch(series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture)))); + + // Convert other fields/properties names to two arrays of names + string[] otherAttributeNames = null; + string[] otherFieldNames = null; + string[] otherValueFormat = null; + ParsePointFieldsParameter( + otherFields, + ref otherAttributeNames, + ref otherFieldNames, + ref otherValueFormat); + + // Remove all existing data points + this.Clear(); + + // Get and reset enumerator + IEnumerator enumerator = GetDataSourceEnumerator(dataSource); + if (enumerator.GetType() != typeof(System.Data.Common.DbEnumerator)) + { + try + { + enumerator.Reset(); + } + // Some enumerators may not support Resetting + catch (InvalidOperationException) + { + } + catch (NotImplementedException) + { + } + catch (NotSupportedException) + { + } + } + + // Add data points + bool valueExsist = true; + object[] yValuesObj = new object[yFieldNames.Length]; + object xValueObj = null; + bool autoDetectType = true; + + this.SuspendUpdates(); + try + { + do + { + // Move to the next objects in the enumerations + if (valueExsist) + { + valueExsist = enumerator.MoveNext(); + } + + // Auto detect valu(s) type + if (autoDetectType) + { + autoDetectType = false; + AutoDetectValuesType(this.series, enumerator, xField, enumerator, yFieldNames[0]); + } + + // Create and initialize data point + if (valueExsist) + { + DataPoint newDataPoint = new DataPoint(series); + bool emptyValues = false; + + // Set X to the value provided + if (xField.Length > 0) + { + xValueObj = ConvertEnumerationItem(enumerator.Current, xField); + if (IsEmptyValue(xValueObj)) + { + emptyValues = true; + xValueObj = 0.0; + } + } + + // Set Y values + if (yFieldNames.Length == 0) + { + yValuesObj[0] = ConvertEnumerationItem(enumerator.Current, null); + if (IsEmptyValue(yValuesObj[0])) + { + emptyValues = true; + yValuesObj[0] = 0.0; + } + } + else + { + for (int i = 0; i < yFieldNames.Length; i++) + { + yValuesObj[i] = ConvertEnumerationItem(enumerator.Current, yFieldNames[i]); + if (IsEmptyValue(yValuesObj[i])) + { + emptyValues = true; + yValuesObj[i] = 0.0; + } + } + } + + // Set other values + if (otherAttributeNames != null && + otherAttributeNames.Length > 0) + { + for (int i = 0; i < otherFieldNames.Length; i++) + { + // Get object by field name + object obj = ConvertEnumerationItem(enumerator.Current, otherFieldNames[i]); + if (!IsEmptyValue(obj)) + { + newDataPoint.SetPointCustomProperty( + obj, + otherAttributeNames[i], + otherValueFormat[i]); + } + } + } + + // IsEmpty value was detected + if (emptyValues) + { + if (xValueObj != null) + { + newDataPoint.SetValueXY(xValueObj, yValuesObj); + } + else + { + newDataPoint.SetValueXY(0, yValuesObj); + } + DataPointInit(ref newDataPoint); + newDataPoint.IsEmpty = true; + this.Add(newDataPoint); + } + else + { + if (xValueObj != null) + { + newDataPoint.SetValueXY(xValueObj, yValuesObj); + } + else + { + newDataPoint.SetValueXY(0, yValuesObj); + } + DataPointInit(ref newDataPoint); + this.Add(newDataPoint); + } + } + + } while (valueExsist); + + } + finally + { + this.ResumeUpdates(); + } + } + + /// + /// Data bind Y values of the data points to the data source. + /// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow. + /// + /// One or more enumerable objects with Y values. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "Y is a cartesian coordinate and well understood")] + public void DataBindY(params IEnumerable[] yValue) + { + DataBindXY(null, yValue); + } + + /// + /// Data bind X and Y values of the data points to the data source. + /// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow. + /// + /// Enumerable objects with X values. + /// One or more enumerable objects with Y values. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public void DataBindXY(IEnumerable xValue, params IEnumerable[] yValues) + { + // Y value must be provided + if (yValues == null || + yValues.Length==1 && yValues[0]==null) + throw new ArgumentNullException("yValues"); + if (yValues.GetLength(0) == 0) + throw new ArgumentException(SR.ExceptionDataPointBindingYValueNotSpecified, "yValues"); + + // Double check that a string object is not provided for data binding + for(int i = 0; i < yValues.Length; i++) + { + if(yValues[i] is string) + { + throw (new ArgumentException(SR.ExceptionDataBindYValuesToString, "yValues")); + } + } + + // Check if number of Y values do not out of range + if(yValues.GetLength(0) > series.YValuesPerPoint) + { + throw(new ArgumentOutOfRangeException("yValues", SR.ExceptionDataPointYValuesBindingCountMismatch( series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture) ) ) ); + } + + // Remove all existing data points + this.Clear(); + + // Reset X, Y enumerators + IEnumerator xEnumerator = null; + IEnumerator[] yEnumerator = new IEnumerator[yValues.GetLength(0)]; + if(xValue != null) + { + // Double check that a string object is not provided for data binding + if(xValue is string) + { + throw (new ArgumentException(SR.ExceptionDataBindXValuesToString, "xValue")); + } + + // Get and reset Y values enumerators + xEnumerator = GetDataSourceEnumerator(xValue); + if(xEnumerator.GetType() != typeof(System.Data.Common.DbEnumerator)) + { + xEnumerator.Reset(); + } + } + for(int i = 0; i < yValues.Length; i++) + { + // Get and reset Y values enumerators + yEnumerator[i] = GetDataSourceEnumerator(yValues[i]); + if(yEnumerator[i].GetType() != typeof(System.Data.Common.DbEnumerator)) + { + yEnumerator[i].Reset(); + } + } + + // Add data points + bool xValueExsist = false; + bool yValueExsist = true; + object[] yValuesObj = new object[series.YValuesPerPoint]; + object xValueObj = null; + bool autoDetectType = true; + + SuspendUpdates(); + try + { + do + { + // Move to the next objects in the enumerations + yValueExsist = true; + for (int i = 0; i < yValues.Length; i++) + { + if (yValueExsist) + { + yValueExsist = yEnumerator[i].MoveNext(); + } + } + if (xValue != null) + { + xValueExsist = xEnumerator.MoveNext(); + if (yValueExsist && !xValueExsist) + { + throw (new ArgumentOutOfRangeException("xValue", SR.ExceptionDataPointInsertionXValuesQtyIsLessYValues)); + } + } + + // Auto detect value(s) type + if (autoDetectType) + { + autoDetectType = false; + AutoDetectValuesType(this.series, xEnumerator, null, yEnumerator[0], null); + } + + // Create and initialize data point + if (xValueExsist || yValueExsist) + { + DataPoint newDataPoint = new DataPoint(series); + bool emptyValues = false; + + // Set X to the value provided + if (xValueExsist) + { + xValueObj = ConvertEnumerationItem(xEnumerator.Current, null); + if (xValueObj is System.DBNull || xValueObj == null) + { + emptyValues = true; + xValueObj = 0.0; + } + } + + // Set Y values + for (int i = 0; i < yValues.Length; i++) + { + yValuesObj[i] = ConvertEnumerationItem(yEnumerator[i].Current, null); + if (yValuesObj[i] is System.DBNull || yValuesObj[i] == null) + { + emptyValues = true; + yValuesObj[i] = 0.0; + } + } + + // IsEmpty value was detected + if (emptyValues) + { + if (xValueObj != null) + { + newDataPoint.SetValueXY(xValueObj, yValuesObj); + } + else + { + newDataPoint.SetValueXY(0, yValuesObj); + } + DataPointInit(ref newDataPoint); + newDataPoint.IsEmpty = true; + this.Add(newDataPoint); + } + else + { + if (xValueObj != null) + { + newDataPoint.SetValueXY(xValueObj, yValuesObj); + } + else + { + newDataPoint.SetValueXY(0, yValuesObj); + } + DataPointInit(ref newDataPoint); + this.Add(newDataPoint); + } + + } + + } while (xValueExsist || yValueExsist); + + } + finally + { + this.ResumeUpdates(); + } + } + + /// + /// Data bind Y values of the data points to the data source. + /// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow. + /// + /// Enumerable objects with Y values. + /// Name of the fields for Y values. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public void DataBindY(IEnumerable yValue, string yFields) + { + DataBindXY(null, null, yValue, yFields); + } + + /// + /// Data bind X and Y values of the data points to the data source. + /// Data source can be the Array, Collection, Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow. + /// + /// Enumerable object with X values. + /// Name of the field for X values. + /// Enumerable objects with Y values. + /// Comma separated names of the fields for Y values. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public void DataBindXY(IEnumerable xValue, string xField, IEnumerable yValue, string yFields) + { + // Check arguments + if (xValue is string) + throw new ArgumentException(SR.ExceptionDataBindXValuesToString, "xValue"); + if (yValue == null) + throw new ArgumentNullException("yValue", SR.ExceptionDataPointInsertionYValueNotSpecified); + if (yValue is string) + throw new ArgumentException(SR.ExceptionDataBindYValuesToString, "yValue"); + if (yFields == null) + throw new ArgumentOutOfRangeException("yFields", SR.ExceptionDataPointYValuesCountMismatch(series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture))); + + // Convert comma separated field names string to array of names + string[] yFieldNames = yFields.Replace(",,", "\n").Split(',');; + for(int index = 0; index < yFieldNames.Length; index++) + { + yFieldNames[index] = yFieldNames[index].Replace("\n", ","); + } + if (yFieldNames.GetLength(0) > series.YValuesPerPoint) + throw new ArgumentOutOfRangeException("yFields", SR.ExceptionDataPointYValuesCountMismatch(series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture))); + + // Remove all existing data points + this.Clear(); + + // Reset X, Y enumerators + IEnumerator xEnumerator = null; + IEnumerator yEnumerator = GetDataSourceEnumerator(yValue); + + if(yEnumerator.GetType() != typeof(System.Data.Common.DbEnumerator)) + { + yEnumerator.Reset(); + } + + if(xValue != null) + { + if(xValue != yValue) + { + xEnumerator = GetDataSourceEnumerator(xValue); + if(xEnumerator.GetType() != typeof(System.Data.Common.DbEnumerator)) + { + xEnumerator.Reset(); + } + } + else + { + xEnumerator = yEnumerator; + } + } + + // Add data points + bool xValueExsist = false; + bool yValueExsist = true; + object[] yValuesObj = new object[yFieldNames.Length]; + object xValueObj = null; + bool autoDetectType = true; + + this.SuspendUpdates(); + try + { + do + { + // Move to the next objects in the enumerations + if (yValueExsist) + { + yValueExsist = yEnumerator.MoveNext(); + } + if (xValue != null) + { + if (xValue != yValue) + { + xValueExsist = xEnumerator.MoveNext(); + if (yValueExsist && !xValueExsist) + { + throw (new ArgumentOutOfRangeException("xValue", SR.ExceptionDataPointInsertionXValuesQtyIsLessYValues)); + } + } + else + { + xValueExsist = yValueExsist; + } + } + + // Auto detect valu(s) type + if (autoDetectType) + { + autoDetectType = false; + AutoDetectValuesType(this.series, xEnumerator, xField, yEnumerator, yFieldNames[0]); + } + + // Create and initialize data point + if (xValueExsist || yValueExsist) + { + DataPoint newDataPoint = new DataPoint(series); + bool emptyValues = false; + + // Set X to the value provided or use sequence numbers starting with 1 + if (xValueExsist) + { + xValueObj = ConvertEnumerationItem(xEnumerator.Current, xField); + if (IsEmptyValue(xValueObj)) + { + emptyValues = true; + xValueObj = 0.0; + } + + } + + if (yFieldNames.Length == 0) + { + yValuesObj[0] = ConvertEnumerationItem(yEnumerator.Current, null); + if (IsEmptyValue(yValuesObj[0])) + { + emptyValues = true; + yValuesObj[0] = 0.0; + } + } + else + { + for (int i = 0; i < yFieldNames.Length; i++) + { + yValuesObj[i] = ConvertEnumerationItem(yEnumerator.Current, yFieldNames[i]); + if (IsEmptyValue(yValuesObj[i])) + { + emptyValues = true; + yValuesObj[i] = 0.0; + } + } + } + + // IsEmpty value was detected + if (emptyValues) + { + if (xValueObj != null) + { + newDataPoint.SetValueXY(xValueObj, yValuesObj); + } + else + { + newDataPoint.SetValueXY(0, yValuesObj); + } + DataPointInit(ref newDataPoint); + newDataPoint.IsEmpty = true; + this.Add(newDataPoint); + } + else + { + if (xValueObj != null) + { + newDataPoint.SetValueXY(xValueObj, yValuesObj); + } + else + { + newDataPoint.SetValueXY(0, yValuesObj); + } + DataPointInit(ref newDataPoint); + this.Add(newDataPoint); + } + } + + } while (xValueExsist || yValueExsist); + + } + finally + { + this.ResumeUpdates(); + } + } + + /// + /// Returns true if objet represents an empty value. + /// + /// Value to test. + /// True if empty. + internal static bool IsEmptyValue(object val) + { + if(val is System.DBNull || val == null) + { + return true; + } + if(val is double && double.IsNaN((double)val)) + { + return true; + } + if(val is Single && Single.IsNaN((Single)val)) + { + return true; + } + + return false; + } + + /// + /// Adds one data point with one Y value. + /// + /// Y value of the data point. + /// Index of newly added data point. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "Y is a cartesian coordinate and well understood")] + public int AddY(double yValue) + { + // Create new point object + DataPoint newDataPoint = new DataPoint(series); + newDataPoint.SetValueY(yValue); + DataPointInit(ref newDataPoint); + Add(newDataPoint); + return Count - 1; + } + + /// + /// Adds one data point with one or more Y values. + /// + /// List of Y values of the data point. + /// Index of newly added data point. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "Y is a cartesian coordinate and well understood")] + public int AddY(params object[] yValue) + { + //Check arguments + if (yValue == null || + yValue.Length==1 && yValue[0]==null) + throw new ArgumentNullException("yValue"); + + // Auto detect DateTime values type + if(this.series.YValueType == ChartValueType.Auto && + yValue.Length > 0 && + yValue[0] != null) + { + if (yValue[0] is DateTime) + { + this.series.YValueType = ChartValueType.DateTime; + this.series.autoYValueType = true; + } + else if (yValue[0] is DateTimeOffset) + { + this.series.YValueType = ChartValueType.DateTimeOffset; + this.series.autoYValueType = true; + } + } + + // Create new point object + DataPoint newDataPoint = new DataPoint(series); + newDataPoint.SetValueY(yValue); + DataPointInit(ref newDataPoint); + Add(newDataPoint); + return Count - 1; + } + + /// + /// Adds one data point with X value and one Y value. + /// + /// Y value of the data point. + /// X value of the data point. + /// Index of newly added data poit. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public int AddXY(double xValue, double yValue) + { + // Create new point object + DataPoint newDataPoint = new DataPoint(series); + newDataPoint.SetValueXY(xValue, yValue); + DataPointInit(ref newDataPoint); + Add(newDataPoint); + return Count - 1; + } + + /// + /// Adds one data point with X value and one or more Y values. + /// + /// List of Y values of the data point. + /// X value of the data point. + /// Index of newly added data poit. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public int AddXY(object xValue, params object[] yValue) + { + + // Auto detect DateTime and String values type + if(this.series.XValueType == ChartValueType.Auto) + { + if(xValue is DateTime) + { + this.series.XValueType = ChartValueType.DateTime; + } + if(xValue is DateTimeOffset) + { + this.series.XValueType = ChartValueType.DateTimeOffset; + } + if(xValue is string) + { + this.series.XValueType = ChartValueType.String; + } + + this.series.autoXValueType = true; + } + + if(this.series.YValueType == ChartValueType.Auto && + yValue.Length > 0 && + yValue[0] != null) + { + if (yValue[0] is DateTime) + { + this.series.YValueType = ChartValueType.DateTime; + this.series.autoYValueType = true; + } + else if (yValue[0] is DateTimeOffset) + { + this.series.YValueType = ChartValueType.DateTimeOffset; + this.series.autoYValueType = true; + } + } + + // Create new point object + DataPoint newDataPoint = new DataPoint(series); + newDataPoint.SetValueXY(xValue, yValue); + DataPointInit(ref newDataPoint); + Add(newDataPoint); + return Count - 1; + } + + /// + /// Insert one data point with X value and one or more Y values. + /// + /// Index after which to insert the data point. + /// X value of the data point. + /// List of Y values of the data point. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public void InsertXY(int index, object xValue, params object[] yValue) + { + DataPoint newDataPoint = new DataPoint(series); + newDataPoint.SetValueXY(xValue, yValue); + DataPointInit(ref newDataPoint); + this.Insert(index, newDataPoint); + } + + /// + /// Insert one data point with one or more Y values. + /// + /// Index after which to insert the data point. + /// List of Y values of the data point. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "Y is a cartesian coordinate and well understood")] + public void InsertY(int index, params object[] yValue) + { + DataPoint newDataPoint = new DataPoint(series); + newDataPoint.SetValueY(yValue); + DataPointInit(ref newDataPoint); + this.Insert(index, newDataPoint); + } + + /// + /// Get data source enumerator object helper function. + /// + /// Data source. + /// Returns data source enumerator. + internal static IEnumerator GetDataSourceEnumerator(IEnumerable dataSource) + { + DataView dataView = dataSource as DataView; + if(dataView != null) + { + return dataView.GetEnumerator(); + } + DataSet dataSet = dataSource as DataSet; + if(dataSet != null) + { + if(dataSet.Tables.Count > 0) + { + return dataSet.Tables[0].Rows.GetEnumerator(); + } + } + + return dataSource.GetEnumerator(); + } + + /// + /// Convert enumeration item object from DataRow and DataRowView + /// to the actual value of specified column in row + /// + /// Enumeration item. + /// Converted item. + /// + internal static object ConvertEnumerationItem(object item, string fieldName) + { + object result = item; + + // If original object is DataRow + DataRow dataRow = item as DataRow; + if(dataRow != null) + { + if(fieldName != null && fieldName.Length > 0) + { + // Check if specified column exist + bool failed = true; + if (dataRow.Table.Columns.Contains(fieldName)) + { + result = dataRow[fieldName]; + failed = false; + } + else + { + // Try to treat field name as column index number + int columnIndex; + failed = !int.TryParse(fieldName, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex); + + if (!failed && columnIndex < dataRow.Table.Columns.Count && columnIndex >= 0) + { + result = dataRow[columnIndex]; + } + } + + if(failed) + { + throw(new ArgumentException( SR.ExceptionColumnNameNotFound( fieldName) ) ); + } + } + else + { + // Get first column value if name not specified + result = dataRow[0]; + } + } + + // If original object is DataRowView + + DataRowView dataRowView = item as DataRowView; + if(dataRowView != null) + { + if(fieldName != null && fieldName.Length > 0) + { + // Check if specified column exist + bool failed = true; + if (dataRowView.DataView.Table.Columns.Contains(fieldName)) + { + result = dataRowView[fieldName]; + failed = false; + } + else + { + // Try to treat field name as column index number + int columnIndex; + failed = !int.TryParse(fieldName, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex); + if (!failed && columnIndex < dataRowView.DataView.Table.Columns.Count && columnIndex >= 0) + { + result = dataRowView[columnIndex]; + } + } + + if(failed) + { + throw(new ArgumentException( SR.ExceptionColumnNameNotFound(fieldName))); + } + } + else + { + // Get first column value if name not specified + result = dataRowView[0]; + } + } + + // If original object is DbDataRecord + DbDataRecord dbDataRecord = item as DbDataRecord; + if(dbDataRecord != null) + { + if(fieldName != null && fieldName.Length > 0) + { + // Check if specified column exist + bool failed = true; + if(!Char.IsNumber(fieldName, 0)) + { + try + { + result = dbDataRecord[fieldName]; + failed = false; + } + catch (IndexOutOfRangeException) + { + failed = true; + } + } + + if(failed) + { + // Try to treat field name as column index number + try + { + int columnIndex; + bool parseSucceed = int.TryParse(fieldName, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex); + + if (parseSucceed) + { + result = dbDataRecord[columnIndex]; + failed = false; + } + else + { + failed = true; + } + } + catch (IndexOutOfRangeException) + { + failed = true; + } + } + + if(failed) + { + throw(new ArgumentException( SR.ExceptionColumnNameNotFound(fieldName))); + } + + } + else + { + // Get first column value if name not specified + result = dbDataRecord[0]; + } + } + else + { + if (fieldName != null && fieldName.Length > 0) + { + PropertyDescriptor descriptor = TypeDescriptor.GetProperties(item).Find(fieldName, true); + if (descriptor != null) + { + result = descriptor.GetValue(item); + return result ?? null; + + } + } + } + + return result; + } + /// + /// Auto detects the X and Y(s) values type + /// + /// Series the values type is detected for. + /// X values enumerator. + /// X value field. + /// Y values enumerator. + /// Y value field. + internal static void AutoDetectValuesType( + Series series, + IEnumerator xEnumerator, + string xField, + IEnumerator yEnumerator, + string yField) + { + if(series.XValueType == ChartValueType.Auto) + { + series.XValueType = GetValueType(xEnumerator, xField); + if(series.XValueType != ChartValueType.Auto) + { + series.autoXValueType = true; + } + } + if(series.YValueType == ChartValueType.Auto) + { + series.YValueType = GetValueType(yEnumerator, yField); + if(series.YValueType != ChartValueType.Auto) + { + series.autoYValueType = true; + } + } + } + + /// + /// Return value type. + /// + /// Values enumerator. + /// Value field. + private static ChartValueType GetValueType(IEnumerator enumerator, string field) + { + ChartValueType type = ChartValueType.Auto; + Type columnDataType = null; + + // Check parameters + if(enumerator == null) + { + return type; + } + + // Check if current enumeration element is available + try + { + if(enumerator.Current == null) + { + return type; + } + } + catch(InvalidOperationException) + { + return type; + } + + + // If original object is DataRow + if(enumerator.Current is DataRow) + { + if(field != null && field.Length > 0) + { + // Check if specified column exist + bool failed = true; + if(((DataRow)enumerator.Current).Table.Columns.Contains(field)) + { + columnDataType = ((DataRow)enumerator.Current).Table.Columns[field].DataType; + failed = false; + } + + // Try to treat field as column number + if (failed) + { + int columnIndex; + bool parseSucceed = int.TryParse(field, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex); + + if (parseSucceed) + { + columnDataType = ((DataRow)enumerator.Current).Table.Columns[columnIndex].DataType; + failed = false; + } + else + { + failed = true; + } + } + + if(failed) + { + throw(new ArgumentException( SR.ExceptionColumnNameNotFound(field))); + } + + } + else if(((DataRow)enumerator.Current).Table.Columns.Count > 0) + { + columnDataType = ((DataRow)enumerator.Current).Table.Columns[0].DataType; + } + } + + // If original object is DataRowView + else if(enumerator.Current is DataRowView) + { + if(field != null && field.Length > 0) + { + // Check if specified column exist + bool failed = true; + if(((DataRowView)enumerator.Current).DataView.Table.Columns.Contains(field)) + { + columnDataType = ((DataRowView)enumerator.Current).DataView.Table.Columns[field].DataType; + failed = false; + } + + // Try to treat field as column number + if (failed) + { + int columnIndex; + bool parseSucceed = int.TryParse(field, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex); + if (parseSucceed) + { + columnDataType = ((DataRowView)enumerator.Current).DataView.Table.Columns[columnIndex].DataType; + failed = false; + } + else + { + failed = true; + } + } + + if(failed) + { + throw(new ArgumentException(SR.ExceptionColumnNameNotFound(field))); + } + + } + else if(((DataRowView)enumerator.Current).DataView.Table.Columns.Count > 0) + { + columnDataType = ((DataRowView)enumerator.Current).DataView.Table.Columns[0].DataType; + } + } + + // If original object is DbDataRecord + else if(enumerator.Current is DbDataRecord) + { + if(field != null && field.Length > 0) + { + bool failed = true; + int columnIndex = 0; + if(!Char.IsNumber(field, 0)) + { + columnIndex = ((DbDataRecord)enumerator.Current).GetOrdinal(field); + columnDataType = ((DbDataRecord)enumerator.Current).GetFieldType(columnIndex); + failed = false; + } + + // Try to treat field as column number + if (failed) + { + failed = !int.TryParse(field, NumberStyles.Any, CultureInfo.InvariantCulture, out columnIndex); + + if (!failed) + { + columnDataType = ((DbDataRecord)enumerator.Current).GetFieldType(columnIndex); + } + } + + if(failed) + { + throw(new ArgumentException(SR.ExceptionColumnNameNotFound(field))); + } + + } + else if(((DbDataRecord)enumerator.Current).FieldCount > 0) + { + columnDataType = ((DbDataRecord)enumerator.Current).GetFieldType(0); + } + } + // Try detecting simple data types + else + { + if (field != null && field.Length > 0) + { + PropertyDescriptor descriptor = TypeDescriptor.GetProperties(enumerator.Current).Find(field, true); + if (descriptor != null) + { + columnDataType = descriptor.PropertyType; + } + } + if ( columnDataType == null ) + { + columnDataType = enumerator.Current.GetType(); + } + } + + // Use data type + if(columnDataType != null) + { + if(columnDataType == typeof(DateTime)) + type = ChartValueType.DateTime; + else if (columnDataType == typeof(DateTimeOffset)) + type = ChartValueType.DateTimeOffset; + else if (columnDataType == typeof(TimeSpan)) + type = ChartValueType.Time; + else if (columnDataType == typeof(Double)) + type = ChartValueType.Double; + else if (columnDataType == typeof(Int32)) + type = ChartValueType.Int32; + else if(columnDataType == typeof(Int64)) + type = ChartValueType.Int64; + else if(columnDataType == typeof(Single)) + type = ChartValueType.Single; + else if(columnDataType == typeof(String)) + type = ChartValueType.String; + else if(columnDataType == typeof(UInt32)) + type = ChartValueType.UInt32; + else if(columnDataType == typeof(UInt64)) + type = ChartValueType.UInt64; + } + + return type; + } + + #endregion + + #region DataPoint finding functions + + /// + /// Find all the points that equal to the specified value starting from the specified index. + /// + /// Point value to find. + /// Which point value to use (X, Y1, Y2,...). + /// Index of the point to start looking from. + /// Enumerator of datapoints. + public IEnumerable FindAllByValue(double valueToFind, string useValue, int startIndex) + { + // Loop through all points from specified index + for (int i = startIndex; i < this.Count; i++) + { + DataPoint point = this[i]; + if (point.GetValueByName(useValue) == valueToFind) + { + yield return point; + } + } + } + + /// + /// Find all the points that equal to the specified value. + /// + /// Point value to find. + /// Which point value to use (X, Y1, Y2,...). + /// Enumerator of datapoints. + public IEnumerable FindAllByValue(double valueToFind, string useValue) + { + // Loop through all points from specified index + for (int i = 0; i < this.Count; i++) + { + DataPoint point = this[i]; + if (point.GetValueByName(useValue) == valueToFind) + { + yield return point; + } + } + } + + /// + /// Find all the points that equal to the specified value. + /// + /// Point value to find. + /// Enumerator of datapoints. + public IEnumerable FindAllByValue(double valueToFind) + { + return FindAllByValue(valueToFind, "Y"); + } + + /// + /// Find the first point that equals to the specified value starting from the specified index. + /// + /// Point value to find. + /// Which point value to use (X, Y1, Y2,...). + /// Index of the point to start looking from. + /// Datapoint which matches the value. Null if there is no match. + public DataPoint FindByValue(double valueToFind, string useValue, int startIndex) + { + //Check arguments + if (useValue == null) + throw new ArgumentNullException("useValue"); + if (startIndex < 0 || startIndex >= this.Count) + throw new ArgumentOutOfRangeException("startIndex"); + + // Loop through all points from specified index + for (int i = startIndex; i < this.Count; i++) + { + DataPoint point = this[i]; + if (point.GetValueByName(useValue) == valueToFind) + { + return point; + } + } + + // Nothing was found + return null; + } + + /// + /// Find the first point that equals to the specified value. + /// + /// Point value to find. + /// Which point value to use (X, Y1, Y2,...). + /// Datapoint which matches the value. Null if there is no match. + public DataPoint FindByValue(double valueToFind, string useValue) + { + return FindByValue(valueToFind, useValue, 0); + } + + /// + /// Find the first point that equals to the specified value. + /// + /// Point value to find. + /// Datapoint which matches the value. Null if there is no match. + public DataPoint FindByValue(double valueToFind) + { + return FindByValue(valueToFind, "Y"); + } + + /// + /// Find point with the maximum value starting from specified index. + /// + /// Which point value to use (X, Y1, Y2,...). + /// Index of the point to start looking from. + /// Datapoint with the maximum value. + public DataPoint FindMaxByValue(string useValue, int startIndex) + { + //Check arguments + if (useValue == null) + throw new ArgumentNullException("useValue"); + if (startIndex < 0 || startIndex >= this.Count) + throw new ArgumentOutOfRangeException("startIndex"); + + bool isYValue = useValue.StartsWith("Y", StringComparison.OrdinalIgnoreCase); + double maxValue = double.MinValue; + DataPoint maxPoint = null; + + for (int i = startIndex; i < this.Count; i++) + { + DataPoint point = this[i]; + + // Skip empty points when searching for the Y values + if (point.IsEmpty && isYValue) + continue; + + double pointValue = point.GetValueByName(useValue); + + if (maxValue < pointValue) + { + maxValue = pointValue; + maxPoint = point; + } + } + + return maxPoint; + } + + /// + /// Find point with the maximum value. + /// + /// Which point value to use (X, Y1, Y2,...). + /// Datapoint with the maximum value. + public DataPoint FindMaxByValue(string useValue) + { + return FindMaxByValue(useValue, 0); + } + + /// + /// Find data point with the maximum value. + /// + /// Datapoint with the maximum value. + public DataPoint FindMaxByValue() + { + return FindMaxByValue("Y"); + } + + /// + /// Find point with the Min value starting from specified index. + /// + /// Which point value to use (X, Y1, Y2,...). + /// Index of the point to start looking from. + /// Datapoint with the Min value. + public DataPoint FindMinByValue(string useValue, int startIndex) + { + if (useValue == null) + throw new ArgumentNullException("useValue"); + if (startIndex < 0 || startIndex >= this.Count) + throw new ArgumentOutOfRangeException("startIndex"); + + bool isYValue = useValue.StartsWith("Y", StringComparison.OrdinalIgnoreCase); + double minValue = double.MaxValue; + DataPoint minPoint = null; + + for (int i = startIndex; i < this.Count; i++) + { + DataPoint point = this[i]; + + // Skip empty points when searching for the Y values + if (point.IsEmpty && isYValue) + continue; + + double pointValue = point.GetValueByName(useValue); + + if (minValue > pointValue) + { + minValue = pointValue; + minPoint = point; + } + } + + return minPoint; + } + + /// + /// Find point with the Min value. + /// + /// Which point value to use (X, Y1, Y2,...). + /// Datapoint with the Min value. + public DataPoint FindMinByValue(string useValue) + { + return FindMinByValue(useValue, 0); + } + + /// + /// Find point with the Min value + /// + /// Datapoint with the Min value. + public DataPoint FindMinByValue() + { + return FindMinByValue("Y"); + } + + #endregion + + #region Collection overrides + + /// + /// Initializes the specified item. + /// + /// The item. + internal override void Initialize(DataPoint item) + { + DataPointInit(ref item); + base.Initialize(item); + } + +#if Microsoft_CONTROL + /// + /// Removes all elements from the . + /// + protected override void ClearItems() + { + + // Refresh Minimum and Maximum from data + // after recalc and set data + if (Common != null && Common.ChartPicture != null) + { + Common.ChartPicture.ResetMinMaxFromData(); + } + + base.ClearItems(); + } +#endif + + #endregion + } + + /// + /// Stores values and properties of a DataPoint of a Series. + /// + [ + SRDescription("DescriptionAttributeDataPoint_DataPoint"), + DefaultProperty("YValues"), + TypeConverter(Editors.DataPointConverter.Convertor) + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif +#if !Microsoft_CONTROL + [Themeable(false)] +#endif + public class DataPoint : DataPointCustomProperties + { + #region Fields + + // Point X value + private double _xValue; + + // Point Y values + private double[] _yValue = new double[1]; + + // Pre calculated (during painting) relative position of data point + internal PointF positionRel = PointF.Empty; + + // VSTS:199794 - Accessibility needs the last rendered label content to be exposed. + // The current label content evaluation is scattered over different chart types and cannot be isolated without risk of regression. + // This variable will cache the label content taken just before drawing. + internal string _lastLabelText = String.Empty; + + #endregion + + #region Constructors + + /// + /// DataPoint object constructor. + /// + public DataPoint() : base(null, true) + { + _yValue = new double[1]; + } + + /// + /// DataPoint object constructor. + /// + /// series object, which the DataPoint belongs to. + public DataPoint(Series series) : base(series, true) + { + // Create Y value(s) array + _yValue = new double[series.YValuesPerPoint]; + _xValue = 0; + } + + /// + /// DataPoint object constructor. + /// + /// X value. + /// Y value. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public DataPoint(double xValue, double yValue) + : base(null, true) + { + // Set Y value + this._yValue = new double[1]; + this._yValue[0] = yValue; + + // Set X value + this._xValue = xValue; + } + + /// + /// DataPoint object constructor. + /// + /// X value. + /// Array of Y values. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public DataPoint(double xValue, double[] yValues) + : base(null, true) + { + // Set Y value + this._yValue = yValues; + + // Set X value + this._xValue = xValue; + } + + /// + /// DataPoint object constructor. + /// + /// + /// This method is only used during the Windows Forms serialization of the chart. + /// + /// X value. + /// String of comma separated Y values. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + [EditorBrowsable(EditorBrowsableState.Never)] + public DataPoint(double xValue, string yValues) + : base(null, true) + { + string[] values = yValues.Split(','); + + // Create Y value(s) array + _yValue = new double[values.Length]; + + for (int index = 0; index < values.Length; index++) + { + _yValue[index] = CommonElements.ParseDouble(values[index], true); + } + + // Set X value + this._xValue = xValue; + } + + #endregion + + #region Data point methods + + /// + /// Sets the specified data point attribute to the specified value. + /// + /// Attribute value. + /// Attribute name. + /// Value format. + internal void SetPointCustomProperty( + object obj, + string propertyName, + string format) + { + // Convert value to string + string stringValue = obj as string; + if(stringValue == null) + { + double doubleObj = double.NaN; + ChartValueType valueType = ChartValueType.Auto; + if(obj is DateTime) + { + doubleObj = ((DateTime)obj).ToOADate(); + valueType = ChartValueType.Date; + } + else + { + doubleObj = this.ConvertValue(obj); + } + + // Try converting to string + if( !double.IsNaN(doubleObj) ) + { + try + { + stringValue = ValueConverter.FormatValue( + this.Chart, + this, + this.Tag, + doubleObj, + format, + valueType, + ChartElementType.DataPoint); + } + catch(FormatException) + { + // Use basic string converter + stringValue = obj.ToString(); + } + } + else + { + // Use basic string converter + stringValue = obj.ToString(); + } + } + + // Assign data point attribute by name + if(stringValue.Length > 0) + { + if(String.Compare(propertyName, "AxisLabel", StringComparison.OrdinalIgnoreCase) == 0) + { + this.AxisLabel = stringValue; + } + else if (String.Compare(propertyName, "Tooltip", StringComparison.OrdinalIgnoreCase) == 0) + { + this.ToolTip = stringValue; + } +#if !Microsoft_CONTROL + else if(String.Compare(propertyName, "Url", StringComparison.OrdinalIgnoreCase) == 0) + { + this.Url = stringValue; + } + else if (String.Compare(propertyName, "PostBackValue", StringComparison.OrdinalIgnoreCase) == 0) + { + this.PostBackValue = stringValue; + } + else if (String.Compare(propertyName, "LabelUrl", StringComparison.OrdinalIgnoreCase) == 0) + { + this.LabelUrl = stringValue; + } + else if (String.Compare(propertyName, "LabelPostBackValue", StringComparison.OrdinalIgnoreCase) == 0) + { + this.LabelPostBackValue = stringValue; + } + else if (String.Compare(propertyName, "LegendUrl", StringComparison.OrdinalIgnoreCase) == 0) + { + this.LegendUrl = stringValue; + } + else if (String.Compare(propertyName, "LegendPostBackValue", StringComparison.OrdinalIgnoreCase) == 0) + { + this.LegendPostBackValue = stringValue; + } +#endif // !Microsoft_CONTROL + else if (String.Compare(propertyName, "Label", StringComparison.OrdinalIgnoreCase) == 0) + { + this.Label = stringValue; + } + else if (String.Compare(propertyName, "LegendTooltip", StringComparison.OrdinalIgnoreCase) == 0) + { + this.LegendToolTip = stringValue; + } + else if (String.Compare(propertyName, "LegendText", StringComparison.OrdinalIgnoreCase) == 0) + { + this.LegendText = stringValue; + } + else if (String.Compare(propertyName, "LabelToolTip", StringComparison.OrdinalIgnoreCase) == 0) + { + this.LabelToolTip = stringValue; + } + else + { + this[propertyName] = stringValue; + } + } + } + + + /// + /// Converts object to double. + /// + /// Object to convert. + /// Double value. + private double ConvertValue(object value) + { + if(value == null) + { + return 0; + } + + if(value is Double) + { + return (double)value; + } + else if(value is Single) + { + return (double)((float)value); + } + else if(value is Decimal) + { + return (double)((Decimal)value); + } + else if(value is Int32) + { + return (double)((Int32)value); + } + else if(value is UInt32) + { + return (double)((UInt32)value); + } + else if(value is Int64) + { + return (double)((Int64)value); + } + else if(value is UInt64) + { + return (double)((UInt64)value); + } + else if(value is Byte) + { + return (double)((Byte)value); + } + else if(value is SByte) + { + return (double)((SByte)value); + } + else if(value is Boolean) + { + return ((Boolean)value) ? 1.0 : 0.0; + } + else + { + string stringValue = ""; + stringValue = value.ToString(); + return CommonElements.ParseDouble(stringValue); + } + } + + /// + /// Set X value and one or more Y values of the data point. + /// + /// X value of the data point. + /// List of Y values of the data point. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public void SetValueXY(object xValue, params object[] yValue) + { + // Check arguments + if (xValue == null) + throw new ArgumentNullException("xValue"); + + // Set Y value first + SetValueY(yValue); + + // Check if parameters type matches with series type + Type paramType = xValue.GetType(); + if(base.series != null) + { + base.series.CheckSupportedTypes(paramType); + } + + // Save value in the array + if(paramType == typeof(String)) + { + AxisLabel = (string)xValue; + } + else if(paramType == typeof(DateTime)) + { + this._xValue = ((DateTime)xValue).ToOADate(); + } + else + { + this._xValue = ConvertValue(xValue); + } + + // Get Date or Time if required + if(base.series != null && xValue is DateTime) + { + if(base.series.XValueType == ChartValueType.Date) + { + DateTime time = new DateTime( + ((DateTime)xValue).Year, + ((DateTime)xValue).Month, + ((DateTime)xValue).Day, + 0, + 0, + 0, + 0); + this._xValue = time.ToOADate(); + } + else if(base.series.XValueType == ChartValueType.Time) + { + DateTime time = new DateTime( + 1899, + 12, + 30, + ((DateTime)xValue).Hour, + ((DateTime)xValue).Minute, + ((DateTime)xValue).Second, + ((DateTime)xValue).Millisecond); + this._xValue = time.ToOADate(); + } + } + + // Check if one of Y values are not avilable + bool empty = false; + foreach(double d in this._yValue) + { + if(double.IsNaN(d)) + { + empty = true; + break; + } + } + + // Set point empty flag and values to zero + if(empty) + { + this.IsEmpty = true; + for(int valueIndex = 0; valueIndex < this._yValue.Length; valueIndex++) + { + this._yValue[valueIndex] = 0.0; + } + } + } + + /// + /// Set one or more Y values of the data point. + /// + /// List of Y values of the data point. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "Y is a cartesian coordinate and well understood")] + public void SetValueY(params object[] yValue) + { + // Check arguments + if (yValue == null) + throw new ArgumentNullException("yValue"); + + // Check number of parameters. Should be more than 0 and + if(yValue.Length == 0 || (base.series != null && yValue.Length > base.series.YValuesPerPoint)) + throw(new ArgumentOutOfRangeException("yValue", SR.ExceptionDataPointYValuesSettingCountMismatch(base.series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture)))); + + // Check if there is a Null Y value + for( int i = 0 ; i < yValue.Length ; i++ ) + { + if(yValue[i] == null || yValue[i] is System.DBNull) + { + yValue[i] = 0.0; + if(i == 0) + { + this.IsEmpty = true; + } + } + } + + // Check if parameters type matches with series type + Type paramType = yValue[0].GetType(); + if(base.series != null) + { + base.series.CheckSupportedTypes(paramType); + } + + // Make sure the Y values array is big enough + if (this._yValue.Length < yValue.Length) + { + this._yValue = new double[yValue.Length]; + } + + // Save value in the array + if(paramType == typeof(String)) + { + try + { + for (int i = 0; i < yValue.Length; i++) + { + this._yValue[i] = CommonElements.ParseDouble((string)yValue[i]); + } + } + catch + { + // Get reference to the chart object + if (Common!=null && Common.ChartPicture!=null && Common.ChartPicture.SuppressExceptions) + { + this.IsEmpty = true; + for (int i = 0; i < yValue.Length; i++) + { + yValue[i] = 0.0; + } + } + else + { + throw (new ArgumentException( SR.ExceptionDataPointYValueStringFormat)); + } + } + + } + else if(paramType == typeof(DateTime)) + { + for( int i = 0 ; i < yValue.Length ; i++ ) + { + if(yValue[i] == null || + (yValue[i] is double && ((double)yValue[i]) == 0.0) ) + { + this._yValue[i] = DateTime.Now.ToOADate(); + } + else + { + this._yValue[i] = ((DateTime)yValue[i]).ToOADate(); + } + } + } + else + { + for( int i = 0 ; i < yValue.Length ; i++ ) + { + this._yValue[i] = ConvertValue(yValue[i]); + } + } + + // Get Date or Time if required + if(base.series != null) + { + for( int i = 0 ; i < yValue.Length ; i++ ) + { + if(yValue[i] == null || + (yValue[i] is double && ((double)yValue[i]) == 0.0) ) + { + if(base.series.YValueType == ChartValueType.Date) + { + this._yValue[i] = Math.Floor(this._yValue[i]); + } + else if(base.series.YValueType == ChartValueType.Time) + { + this._yValue[i] = this._xValue - Math.Floor(this._yValue[i]); + } + } + else + { + if(base.series.YValueType == ChartValueType.Date) + { + DateTime yDate; + if (yValue[i] is DateTime) + yDate = (DateTime)yValue[i]; + else if (yValue[i] is Double) + yDate = DateTime.FromOADate((Double)yValue[i]); + else + yDate = Convert.ToDateTime(yValue[i], CultureInfo.InvariantCulture); //This will throw an exception in case when the yValue type is not compatible with the DateTime + + DateTime date = new DateTime( + yDate.Year, + yDate.Month, + yDate.Day, + 0, + 0, + 0, + 0); + + this._yValue[i] = date.ToOADate(); + } + else if (base.series.YValueType == ChartValueType.Time) + { + DateTime yTime; + if (yValue[i] is DateTime) + yTime = (DateTime)yValue[i]; + if (yValue[i] is Double) + yTime = DateTime.FromOADate((Double)yValue[i]); + else + yTime = Convert.ToDateTime(yValue[i], CultureInfo.InvariantCulture); //This will throw an exception in case when the yValue type is not compatible with the DateTime + + DateTime time = new DateTime( + 1899, + 12, + 30, + yTime.Hour, + yTime.Minute, + yTime.Second, + yTime.Millisecond); + + this._yValue[i] = time.ToOADate(); + } + } + } + } + + } + + /// + /// Creates an exact copy of this DataPoint object. + /// + /// An exact copy of this DataPoint object. + public DataPoint Clone() + { + // Create new data point + DataPoint clonePoint = new DataPoint(); + + // Reset series pointer + clonePoint.series = null; + clonePoint.pointCustomProperties = this.pointCustomProperties; + + // Copy values + clonePoint._xValue = this.XValue; + clonePoint._yValue = new double[this._yValue.Length]; + this._yValue.CopyTo(clonePoint._yValue, 0); + clonePoint.tempColorIsSet = this.tempColorIsSet; + clonePoint.isEmptyPoint = this.isEmptyPoint; + + // Copy properties + foreach(object key in this.properties.Keys) + { + clonePoint.properties.Add(key, this.properties[key]); + } + + return clonePoint; + } + + /// + /// Resize Y values array. + /// + /// New number of Y values in array. + internal void ResizeYValueArray(int newSize) + { + // Create new array + double[] newArray = new Double[newSize]; + + // Copy elements + if(_yValue != null) + { + for(int i = 0; i < ((_yValue.Length < newSize) ? _yValue.Length : newSize); i++) + { + newArray[i] = _yValue[i]; + } + } + + _yValue = newArray; + } + + /// + /// Helper function, which returns point value by it's name. + /// + /// Point value names. X, Y, Y2,... + /// Point value. + public double GetValueByName(string valueName) + { + // Check arguments + if (valueName == null) + throw new ArgumentNullException("valueName"); + + valueName = valueName.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + if(String.Compare(valueName, "X", StringComparison.Ordinal) == 0) + { + return this.XValue; + } + else if (valueName.StartsWith("Y", StringComparison.Ordinal)) + + { + if(valueName.Length == 1) + { + return this.YValues[0]; + } + else + { + int yIndex = 0; + try + { + yIndex = Int32.Parse(valueName.Substring(1), System.Globalization.CultureInfo.InvariantCulture) - 1; + } + catch(System.Exception) + { + throw(new ArgumentException( SR.ExceptionDataPointValueNameInvalid, "valueName")); + } + + if(yIndex < 0) + { + throw(new ArgumentException( SR.ExceptionDataPointValueNameYIndexIsNotPositive, "valueName")); + } + + if(yIndex >= this.YValues.Length) + { + throw(new ArgumentException( SR.ExceptionDataPointValueNameYIndexOutOfRange, "valueName")); + } + + return this.YValues[yIndex]; + } + } + else + { + throw(new ArgumentException( SR.ExceptionDataPointValueNameInvalid, "valueName")); + } + } + + /// + /// Replaces predefined keyword inside the string with their values. + /// + /// Original string with keywords. + /// Modified string. + internal override string ReplaceKeywords(string strOriginal) + { + // Nothing to process + if(strOriginal == null || strOriginal.Length == 0) + return strOriginal; + + // Replace all "\n" strings with '\n' character + string result = strOriginal; + result = result.Replace("\\n", "\n"); + + // #LABEL - point label + result = result.Replace(KeywordName.Label, this.Label); + + // #LEGENDTEXT - series name + result = result.Replace(KeywordName.LegendText, this.LegendText); + + // #AXISLABEL - series name + result = result.Replace(KeywordName.AxisLabel, this.AxisLabel); + + // #CUSTOMPROPERTY - one of the custom properties by name + result = DataPoint.ReplaceCustomPropertyKeyword(result, this); + + if(this.series != null) + { + // #INDEX - point index + result = result.Replace(KeywordName.Index, this.series.Points.IndexOf(this).ToString(System.Globalization.CultureInfo.InvariantCulture)); + + // Replace series keywords + result = this.series.ReplaceKeywords(result); + + // #PERCENT - percentage of Y value from total + result = this.series.ReplaceOneKeyword( + this.Chart, + this, + this.Tag, + ChartElementType.DataPoint, + result, + KeywordName.Percent, + (this.YValues[0]/(this.series.GetTotalYValue())), + ChartValueType.Double, + "P"); + + // #VAL[X] - point value X, Y, Y2, ... + if(this.series.XValueType == ChartValueType.String) + { + result = result.Replace(KeywordName.ValX, this.AxisLabel); + } + else + { + result = this.series.ReplaceOneKeyword( + this.Chart, + this, + this.Tag, + ChartElementType.DataPoint, + result, + KeywordName.ValX, + this.XValue, + this.series.XValueType, + ""); + } + + // remove keywords #VAL? for unexisted Y value indices + for (int index = this.YValues.Length; index <= 7; index++) + { + result = this.RemoveOneKeyword(result, KeywordName.ValY + index + 1, SR.FormatErrorString); + } + + for(int index = 1; index <= this.YValues.Length; index++) + { + result = this.series.ReplaceOneKeyword( + this.Chart, + this, + this.Tag, + ChartElementType.DataPoint, + result, + KeywordName.ValY + index, + this.YValues[index - 1], + this.series.YValueType, + ""); + } + + result = this.series.ReplaceOneKeyword( + Chart, + this, + this.Tag, + ChartElementType.DataPoint, + result, + KeywordName.ValY, + this.YValues[0], + this.series.YValueType, + ""); + + result = this.series.ReplaceOneKeyword( + Chart, + this, + this.Tag, + ChartElementType.DataPoint, + result, + KeywordName.Val, + this.YValues[0], + this.series.YValueType, + ""); + } + + return result; + } + + /// + /// Removes one keyword from format string. + /// + /// Original format string + /// The keyword + /// String to replace the keyword. + /// Modified format string + private string RemoveOneKeyword(string strOriginal, string keyword, string strToReplace) + { + string result = strOriginal; + int keyIndex = -1; + while ((keyIndex = result.IndexOf(keyword, StringComparison.Ordinal)) != -1) + { + // Get optional format + int keyEndIndex = keyIndex + keyword.Length; + if (result.Length > keyEndIndex && result[keyEndIndex] == '{') + { + int formatEnd = result.IndexOf('}', keyEndIndex); + if (formatEnd == -1) + { + throw (new InvalidOperationException(SR.ExceptionDataSeriesKeywordFormatInvalid(result))); + } + + keyEndIndex = formatEnd + 1; + } + // Remove keyword string (with optional format) + result = result.Remove(keyIndex, keyEndIndex - keyIndex); + if (!String.IsNullOrEmpty(strToReplace)) + { + result = result.Insert(keyIndex, strToReplace); + } + } + return result; + } + + + /// + /// Replaces all "#CUSTOMPROPERTY(XXX)" (where XXX is the custom attribute name) + /// keywords in the string provided. + /// + /// String where the keyword need to be replaced. + /// DataPoint or Series properties class. + /// Converted string. + internal static string ReplaceCustomPropertyKeyword(string originalString, DataPointCustomProperties properties) + { + string result = originalString; + int keyStartIndex = -1; + while ((keyStartIndex = result.IndexOf(KeywordName.CustomProperty, StringComparison.Ordinal)) >= 0) + { + string attributeValue = string.Empty; + string attributeName = string.Empty; + + // Forward to the end of the keyword + int keyEndIndex = keyStartIndex + KeywordName.CustomProperty.Length; + + // An opening bracket '(' must follow + if (result.Length > keyEndIndex && result[keyEndIndex] == '(') + { + ++keyEndIndex; + int attributeNameStartIndex = keyEndIndex; + + // Search for the closing bracket + int closingBracketIndex = result.IndexOf(')', keyEndIndex); + if (closingBracketIndex >= keyEndIndex) + { + keyEndIndex = closingBracketIndex + 1; + attributeName = result.Substring(attributeNameStartIndex, keyEndIndex - attributeNameStartIndex - 1); + + // Get attribute value + if (properties.IsCustomPropertySet(attributeName)) + { + attributeValue = properties.GetCustomProperty(attributeName); + } + else + { + // In case of the DataPoint check if the attribute is set in the parent series + DataPoint dataPoint = properties as DataPoint; + if (dataPoint != null && dataPoint.series != null) + { + if (dataPoint.series.IsCustomPropertySet(attributeName)) + { + attributeValue = dataPoint.series.GetCustomProperty(attributeName); + } + } + } + } + } + + // Remove keyword string with attribute name + result = result.Remove(keyStartIndex, keyEndIndex - keyStartIndex); + + // Insert value of the custom attribute + result = result.Insert(keyStartIndex, attributeValue); + } + + return result; + } + + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + internal override string ToStringInternal() + { + StringBuilder sb = new StringBuilder(); + sb.AppendFormat(CultureInfo.CurrentCulture, "{{X={0}, ", XValue); + if (YValues.Length == 1) + { + sb.AppendFormat(CultureInfo.CurrentCulture, "Y={0}", YValues[0]); + } + else + { + sb.Append("Y={"); + for (int i = 0; i < YValues.Length; i++) + if (i == 0) + sb.AppendFormat(CultureInfo.CurrentCulture, "{0}", YValues[i]); + else + sb.AppendFormat(CultureInfo.CurrentCulture, ", {0}", YValues[i]); + sb.Append("}"); + } + sb.Append("}"); + return sb.ToString(); + } + #endregion + + #region DataPoint Properties + + + /// + /// X value of the data point. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeDataPoint_XValue"), + TypeConverter(typeof(DataPointValueConverter)), + DefaultValue(typeof(double), "0.0"), + + +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), +#else + PersistenceMode(PersistenceMode.Attribute) +#endif + ] + public double XValue + { + get + { + return _xValue; + } + set + { + _xValue = value; + this.Invalidate(false); + } + } + + /// + /// List of Y values of the data point. + /// + [ + SRCategory("CategoryAttributeData"), + SRDescription("DescriptionAttributeDataPoint_YValues"), + Bindable(true), + +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), +#else + PersistenceMode(PersistenceMode.Attribute), +#endif + TypeConverter(typeof(DoubleArrayConverter)), + Editor(typeof(UITypeEditor), typeof(UITypeEditor)), + RefreshProperties(RefreshProperties.All), + SerializationVisibilityAttribute(SerializationVisibility.Attribute) + ] + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public double[] YValues + { + get + { + return _yValue; + } + set + { + if(value == null) + { + // Clear array data + for(int i=0; i < _yValue.Length; i++) + { + _yValue[i] = 0; + } + } + else + { + _yValue = value; + } + this.Invalidate(false); + } + } + + /// + /// A flag which indicates whether the data point is empty. + /// + [ + SRCategory("CategoryAttributeData"), + + Bindable(true), + SRDescription("DescriptionAttributeDataPoint_Empty"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + DefaultValue(false) + ] + public bool IsEmpty + { + get + { + return base.isEmptyPoint; + } + set + { + base.isEmptyPoint = value; + this.Invalidate(true); + } + } + + /// + /// Name of the data point. This field is reserved for internal use only. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + Browsable(false), + SRDescription("DescriptionAttributeDataPoint_Name"), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public override string Name + { + get + { + return "DataPoint"; + } + set + { + //Dont call the base method - the names don't need to be unique + } + } + + #endregion + + } + + /// + /// Stores properties of one Data Point and Data series. + /// + [ + SRDescription("DescriptionAttributeDataPointCustomProperties_DataPointCustomProperties"), + DefaultProperty("LabelStyle"), + TypeConverter(Editors.DataPointCustomPropertiesConverter.Convertor) + ] +#if Microsoft_CONTROL + public class DataPointCustomProperties : ChartNamedElement +#else +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class DataPointCustomProperties : ChartNamedElement, IChartMapArea +#endif + { + #region Fields and enumerations + + // True indicates data point properties. Otherwise - series. + internal bool pointCustomProperties = true; + + // Reference to the data point series + internal Series series = null; + + // Storage for the custom properties names/values + internal Hashtable properties = new Hashtable(); + + // Flag indicating that temp. color was set + internal bool tempColorIsSet = false; + + // Design time custom properties data + internal CustomProperties customProperties = null; + + // IsEmpty point indicator + internal bool isEmptyPoint = false; + + #endregion + + #region Constructors + + /// + /// DataPointCustomProperties constructor. + /// + public DataPointCustomProperties() + { + // Initialize the data series + this.series = null; + this.customProperties = new CustomProperties(this); + } + + /// + /// DataPointCustomProperties constructor. + /// + /// The series which the data point belongs to. + /// Indicates whether this is a data point custom properties. + public DataPointCustomProperties(Series series, bool pointProperties): base( series, String.Empty) + { + // Initialize the data series + this.series = series; + this.pointCustomProperties = pointProperties; + this.customProperties = new CustomProperties(this); + } + + #endregion + + #region Custom Properties methods + + /// + /// Checks if custom property with specified name was set. + /// + /// Name of the custom property to check. + /// True if custom property was set. + virtual public bool IsCustomPropertySet(string name) + { + return properties.ContainsKey(name); + } + + /// + /// Checks if the custom property with specified name was set. + /// + /// The CommonCustomProperties object to check for. + /// True if attribute was set. + internal bool IsCustomPropertySet(CommonCustomProperties property) + { + return properties.ContainsKey((int)property); + } + + /// + /// Delete the data point custom property with the specified name. + /// + /// Name of the property to delete. + virtual public void DeleteCustomProperty(string name) + { + if(name == null) + { + throw (new ArgumentNullException(SR.ExceptionAttributeNameIsEmpty)); + } + + // Check if trying to delete the common attribute + string[] AttributesNames = CommonCustomProperties.GetNames(typeof(CommonCustomProperties)); + foreach(string commonName in AttributesNames) + { + if(name == commonName) + { + DeleteCustomProperty((CommonCustomProperties)Enum.Parse(typeof(CommonCustomProperties), commonName)); + } + } + + // Remove attribute + properties.Remove(name); + } + + /// + /// Delete Data Point attribute with specified name. + /// + /// ID of the attribute to delete. + internal void DeleteCustomProperty(CommonCustomProperties property) + { + // Check if trying to delete the common attribute from the series + if(!this.pointCustomProperties) + { + throw(new ArgumentException( SR.ExceptionAttributeUnableToDelete)); + } + + // Remove attribute + properties.Remove((int)property); + } + + /// + /// Gets the data point custom property with the specified name. + /// + /// Name of the property to get. + /// Returns the data point custom property with the specified name. If the requested one is not set, + /// the default custom property of the data series will be returned. + virtual public string GetCustomProperty(string name) + { + if(!IsCustomPropertySet(name) && this.pointCustomProperties) + { + // Check if we are in serialization mode + bool serializing = false; + + if(Chart != null && Chart.serializing) + { + serializing = true; + } + + if(!serializing) + { + + if(this.isEmptyPoint) + { + // Return empty point properties from series + return (string)series.EmptyPointStyle.properties[name]; + } + + // Return properties from series + return (string)series.properties[name]; + } + else + { + // Return default properties + return (string)Series.defaultCustomProperties[name]; + } + } + + return (string)properties[name]; + } + + + /// + /// Checks if data is currently serialized. + /// + /// True if serialized. + internal bool IsSerializing() + { + // Check if series object is provided + if(series == null) + { + return true; + } + + // Check if we are in serialization mode + if(Chart != null) + { + return Chart.serializing; + } + else + { + return false; + } + } + + /// + /// Returns an attribute object of the Data Point. If required attribute is not set + /// in the Data Point the default attribute of the Data series is returned. + /// + /// Attribute name ID. + /// Attribute value. + internal object GetAttributeObject(CommonCustomProperties attrib) + { + // Get series properties + if(!this.pointCustomProperties || series == null) + { + return properties[(int)attrib]; + } + + // Get data point properties + if(properties.Count == 0 || !IsCustomPropertySet(attrib)) + { + // Check if we are in serialization mode + bool serializing = false; + if(Chart != null) + { + serializing = Chart.serializing; + } + + if(!serializing) + { + if(this.isEmptyPoint) + { + // Return empty point properties from series + return series.EmptyPointStyle.properties[(int)attrib]; + } + + // Return properties from series + return series.properties[(int)attrib]; + } + else + { + // Return default properties + return Series.defaultCustomProperties.properties[(int)attrib]; + } + } + return properties[(int)attrib]; + } + + /// + /// Sets a custom property of the data point. + /// + /// Property name. + /// Property value. + virtual public void SetCustomProperty(string name, string propertyValue) + { + properties[name] = propertyValue; + } + + /// + /// Sets an attribute of the Data Point as an object. + /// + /// Attribute name ID. + /// Attribute new value. + internal void SetAttributeObject(CommonCustomProperties attrib, object attributeValue) + { + properties[(int)attrib] = attributeValue; + } + + /// + /// Set the default properties of the data point. + /// Indicates that previous properties must be cleared. + /// + virtual public void SetDefault(bool clearAll) + { + // If setting defaults for the data series - clear all properties and initialize common one + if(!this.pointCustomProperties) + { + if(clearAll) + { + properties.Clear(); + } + + // !!! IMPORTANT !!! + // After changing the default value of the common attribute you must also + // change the DefaultAttribute of the property representing this attribute. + if(!IsCustomPropertySet(CommonCustomProperties.ToolTip)) + SetAttributeObject(CommonCustomProperties.ToolTip, ""); + if(!IsCustomPropertySet(CommonCustomProperties.LegendToolTip)) + SetAttributeObject(CommonCustomProperties.LegendToolTip, ""); + if(!IsCustomPropertySet(CommonCustomProperties.Color)) + SetAttributeObject(CommonCustomProperties.Color, Color.Empty); + if(!IsCustomPropertySet(CommonCustomProperties.IsValueShownAsLabel)) + SetAttributeObject(CommonCustomProperties.IsValueShownAsLabel, false); + if(!IsCustomPropertySet(CommonCustomProperties.MarkerStyle)) + SetAttributeObject(CommonCustomProperties.MarkerStyle, MarkerStyle.None); + if(!IsCustomPropertySet(CommonCustomProperties.MarkerSize)) + SetAttributeObject(CommonCustomProperties.MarkerSize, 5); + if(!IsCustomPropertySet(CommonCustomProperties.MarkerImage)) + SetAttributeObject(CommonCustomProperties.MarkerImage, ""); + if(!IsCustomPropertySet(CommonCustomProperties.Label)) + SetAttributeObject(CommonCustomProperties.Label, ""); + if(!IsCustomPropertySet(CommonCustomProperties.BorderWidth)) + SetAttributeObject(CommonCustomProperties.BorderWidth, 1); + if(!IsCustomPropertySet(CommonCustomProperties.BorderDashStyle)) + SetAttributeObject(CommonCustomProperties.BorderDashStyle, ChartDashStyle.Solid); + + + if(!IsCustomPropertySet(CommonCustomProperties.AxisLabel)) + SetAttributeObject(CommonCustomProperties.AxisLabel, ""); + if(!IsCustomPropertySet(CommonCustomProperties.LabelFormat)) + SetAttributeObject(CommonCustomProperties.LabelFormat, ""); + if(!IsCustomPropertySet(CommonCustomProperties.BorderColor)) + SetAttributeObject(CommonCustomProperties.BorderColor, Color.Empty); + if(!IsCustomPropertySet(CommonCustomProperties.BackImage)) + SetAttributeObject(CommonCustomProperties.BackImage, ""); + if(!IsCustomPropertySet(CommonCustomProperties.BackImageWrapMode)) + SetAttributeObject(CommonCustomProperties.BackImageWrapMode, ChartImageWrapMode.Tile); + if(!IsCustomPropertySet(CommonCustomProperties.BackImageAlignment)) + SetAttributeObject(CommonCustomProperties.BackImageAlignment, ChartImageAlignmentStyle.TopLeft); + if(!IsCustomPropertySet(CommonCustomProperties.BackImageTransparentColor)) + SetAttributeObject(CommonCustomProperties.BackImageTransparentColor, Color.Empty); + if(!IsCustomPropertySet(CommonCustomProperties.BackGradientStyle)) + SetAttributeObject(CommonCustomProperties.BackGradientStyle, GradientStyle.None); + if(!IsCustomPropertySet(CommonCustomProperties.BackSecondaryColor)) + SetAttributeObject(CommonCustomProperties.BackSecondaryColor, Color.Empty); + if(!IsCustomPropertySet(CommonCustomProperties.BackHatchStyle)) + SetAttributeObject(CommonCustomProperties.BackHatchStyle, ChartHatchStyle.None); + if(!IsCustomPropertySet(CommonCustomProperties.Font)) + SetAttributeObject(CommonCustomProperties.Font, null); + if(!IsCustomPropertySet(CommonCustomProperties.MarkerImageTransparentColor)) + SetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor, Color.Empty); + if(!IsCustomPropertySet(CommonCustomProperties.MarkerColor)) + SetAttributeObject(CommonCustomProperties.MarkerColor, Color.Empty); + if(!IsCustomPropertySet(CommonCustomProperties.MarkerBorderColor)) + SetAttributeObject(CommonCustomProperties.MarkerBorderColor, Color.Empty); + if(!IsCustomPropertySet(CommonCustomProperties.MarkerBorderWidth)) + SetAttributeObject(CommonCustomProperties.MarkerBorderWidth, 1); + if(!IsCustomPropertySet(CommonCustomProperties.MapAreaAttributes)) + SetAttributeObject(CommonCustomProperties.MapAreaAttributes, ""); + if (!IsCustomPropertySet(CommonCustomProperties.PostBackValue)) + SetAttributeObject(CommonCustomProperties.PostBackValue, ""); + + if (!IsCustomPropertySet(CommonCustomProperties.LabelForeColor)) + SetAttributeObject(CommonCustomProperties.LabelForeColor, Color.Black); + if (!IsCustomPropertySet(CommonCustomProperties.LabelAngle)) + SetAttributeObject(CommonCustomProperties.LabelAngle, 0); + if (!IsCustomPropertySet(CommonCustomProperties.LabelToolTip)) + SetAttributeObject(CommonCustomProperties.LabelToolTip, ""); + if(!IsCustomPropertySet(CommonCustomProperties.LabelUrl)) + SetAttributeObject(CommonCustomProperties.LabelUrl, ""); + if (!IsCustomPropertySet(CommonCustomProperties.LabelPostBackValue)) + SetAttributeObject(CommonCustomProperties.LabelPostBackValue, ""); + if (!IsCustomPropertySet(CommonCustomProperties.LabelMapAreaAttributes)) + SetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes, ""); + if(!IsCustomPropertySet(CommonCustomProperties.LabelBackColor)) + SetAttributeObject(CommonCustomProperties.LabelBackColor, Color.Empty); + if(!IsCustomPropertySet(CommonCustomProperties.LabelBorderWidth)) + SetAttributeObject(CommonCustomProperties.LabelBorderWidth, 1); + if(!IsCustomPropertySet(CommonCustomProperties.LabelBorderDashStyle)) + SetAttributeObject(CommonCustomProperties.LabelBorderDashStyle, ChartDashStyle.Solid); + if(!IsCustomPropertySet(CommonCustomProperties.LabelBorderColor)) + SetAttributeObject(CommonCustomProperties.LabelBorderColor, Color.Empty); + + if(!IsCustomPropertySet(CommonCustomProperties.Url)) + SetAttributeObject(CommonCustomProperties.Url, ""); + if(!IsCustomPropertySet(CommonCustomProperties.LegendUrl)) + SetAttributeObject(CommonCustomProperties.LegendUrl, ""); + if (!IsCustomPropertySet(CommonCustomProperties.LegendPostBackValue)) + SetAttributeObject(CommonCustomProperties.LegendPostBackValue, ""); + if (!IsCustomPropertySet(CommonCustomProperties.LegendText)) + SetAttributeObject(CommonCustomProperties.LegendText, ""); + if(!IsCustomPropertySet(CommonCustomProperties.LegendMapAreaAttributes)) + SetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes, ""); + if(!IsCustomPropertySet(CommonCustomProperties.IsVisibleInLegend)) + SetAttributeObject(CommonCustomProperties.IsVisibleInLegend, true); + } + + // If setting defaults for the data point - clear all properties + else + { + properties.Clear(); + } + } + + #endregion + + #region DataPointCustomProperties Properties + + /// + /// Indexer of the custom properties. Returns the DataPointCustomProperties object by index. + /// + /// Index of the custom property. + public string this[int index] + { + get + { + int currentIndex = 0; + foreach(object key in properties.Keys) + { + if(currentIndex == index) + { + string keyStr = key as string; + if (keyStr != null) + { + return keyStr; + } + else if (key is int) + { + return Enum.GetName(typeof(CommonCustomProperties), key); + } + return key.ToString(); + } + ++currentIndex; + } + // we can't throw IndexOutOfRangeException here, it is reserved + // by the CLR. + throw (new InvalidOperationException()); + } + } + + /// + /// Indexer of the custom properties. Returns the DataPointCustomProperties object by name. + /// + /// Name of the custom property. + public string this[string name] + { + get + { + // If attribute is not set in data point - try getting it from the series + if(!IsCustomPropertySet(name) && this.pointCustomProperties) + { + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.properties[name]; + } + + return (string)series.properties[name]; + } + return (string)properties[name]; + } + set + { + properties[name] = value; + this.Invalidate(true); + } + } + + /// + /// The text of the data point label. + /// + [ + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + SRCategory("CategoryAttributeLabel"), + Bindable(true), + SRDescription("DescriptionAttributeLabel"), + ] + virtual public string Label + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Label)) + { + return (string)GetAttributeObject(CommonCustomProperties.Label); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.Label); + } + + return series.label; + } + } + else + { + return series.label; + } + } + set + { + // Replace NULL with empty string + if(value == null) + { + value = string.Empty; + } + + if (this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.Label, value); + else + series.label = value; + + this.Invalidate(true); + } + } + + /// + /// The text of X axis label for the data point. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + SRDescription("DescriptionAttributeAxisLabel"), + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + virtual public string AxisLabel + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.AxisLabel)) + { + return (string)GetAttributeObject(CommonCustomProperties.AxisLabel); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.AxisLabel); + } + + return series.axisLabel; + + } + } + else + { + return series.axisLabel; + } + } + set + { + // Replace NULL with empty string + if(value == null) + { + value = string.Empty; + } + + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.AxisLabel, value); + else + series.axisLabel = value; + + // Set flag that there are non-empy axis labels in series or points + if(value.Length > 0 && series != null) + { + series.noLabelsInPoints = false; + } + + this.Invalidate(false); + } + } + + /// + /// Format string of the data point label. + /// + [ + + SRCategory("CategoryAttributeLabel"), + Bindable(true), + SRDescription("DescriptionAttributeLabelFormat"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public string LabelFormat + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelFormat)) + { + return (string)GetAttributeObject(CommonCustomProperties.LabelFormat); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelFormat); + } + + return series.labelFormat; + } + } + else + { + return series.labelFormat; + } + } + set + { + // Replace NULL with empty string + if(value == null) + { + value = string.Empty; + } + + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LabelFormat, value); + else + series.labelFormat = value; + this.Invalidate(false); + } + } + + /// + /// A flag which indicates whether to show the data point's value on the label. + /// + [ + + SRCategory("CategoryAttributeLabel"), + Bindable(true), + SRDescription("DescriptionAttributeShowLabelAsValue"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsValueShownAsLabel + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.IsValueShownAsLabel)) + { + return (bool)GetAttributeObject(CommonCustomProperties.IsValueShownAsLabel); + } + else + { + if(IsSerializing()) + { + return false; + } + if(this.isEmptyPoint) + { + return (bool)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.IsValueShownAsLabel); + } + + return series.showLabelAsValue; + + } + } + else + { + return series.showLabelAsValue; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.IsValueShownAsLabel, value); + else + series.showLabelAsValue = value; + this.Invalidate(false); + } + } + + /// + /// Color of the data point. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeColor4"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color Color + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Color)) + { + return (Color)GetAttributeObject(CommonCustomProperties.Color); + } + else + { + if(IsSerializing()) + { + return Color.Empty; + } + if(this.isEmptyPoint) + { + return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.Color); + } + + return series.color; + } + } + else + { + return series.color; + } + } + set + { + // Remove the temp color flag + this.tempColorIsSet = false; + + if(value == Color.Empty && this.pointCustomProperties) + { + DeleteCustomProperty(CommonCustomProperties.Color); + } + else + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.Color, value); + else + series.color = value; + this.Invalidate(true); + } + } + } + + /// + /// Border color of the data point. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeBorderColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BorderColor + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BorderColor)) + { + return (Color)GetAttributeObject(CommonCustomProperties.BorderColor); + } + else + { + if(IsSerializing()) + { + return Color.Empty; + } + if(this.isEmptyPoint) + { + return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BorderColor); + } + + return series.borderColor; + } + } + else + { + return series.borderColor; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.BorderColor, value); + else + series.borderColor = value; + this.Invalidate(true); + } + } + + /// + /// Border style of the data point. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeBorderDashStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartDashStyle BorderDashStyle + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BorderDashStyle)) + { + return (ChartDashStyle)GetAttributeObject(CommonCustomProperties.BorderDashStyle); + } + else + { + if(IsSerializing()) + { + return ChartDashStyle.Solid; + } + if(this.isEmptyPoint) + { + return (ChartDashStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BorderDashStyle); + } + + return series.borderDashStyle; + + } + } + else + { + return series.borderDashStyle; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.BorderDashStyle, value); + else + series.borderDashStyle = value; + this.Invalidate(true); + } + } + + /// + /// Border width of the data point. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeBorderWidth"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int BorderWidth + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BorderWidth)) + { + return (int)GetAttributeObject(CommonCustomProperties.BorderWidth); + } + else + { + if(IsSerializing()) + { + return 1; + } + if(this.isEmptyPoint) + { + return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BorderWidth); + } + + return series.borderWidth; + + } + } + else + { + return series.borderWidth; + } + } + set + { + if(value < 0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionBorderWidthIsNotPositive)); + } + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.BorderWidth, value); + else + series.borderWidth = value; + this.Invalidate(true); + } + } + + /// + /// Background image of the data point. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeBackImage"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public string BackImage + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImage)) + { + return (string)GetAttributeObject(CommonCustomProperties.BackImage); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImage); + } + + return series.backImage; + + } + } + else + { + return series.backImage; + } + } + set + { + // Replace NULL with empty string + if(value == null) + { + value = string.Empty; + } + + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.BackImage, value); + else + series.backImage = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the drawing mode of the background image. + /// + /// + /// A value that defines the drawing mode of the image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeImageWrapMode"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageWrapMode BackImageWrapMode + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImageWrapMode)) + { + return (ChartImageWrapMode)GetAttributeObject(CommonCustomProperties.BackImageWrapMode); + } + else + { + if(IsSerializing()) + { + return ChartImageWrapMode.Tile; + } + if(this.isEmptyPoint) + { + return (ChartImageWrapMode)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImageWrapMode); + } + + return series.backImageWrapMode; + + } + } + else + { + return series.backImageWrapMode; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.BackImageWrapMode, value); + else + series.backImageWrapMode = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets a color which will be replaced with a transparent color while drawing the background image. + /// + /// + /// A value which will be replaced with a transparent color while drawing the image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackImageTransparentColor + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImageTransparentColor)) + { + return (Color)GetAttributeObject(CommonCustomProperties.BackImageTransparentColor); + } + else + { + if(IsSerializing()) + { + return Color.Empty; + } + if(this.isEmptyPoint) + { + return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImageTransparentColor); + } + + return series.backImageTransparentColor; + + } + } + else + { + return series.backImageTransparentColor; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.BackImageTransparentColor, value); + else + series.backImageTransparentColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the alignment of the background image which is used by ClampUnscale drawing mode. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackImageAlign"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageAlignmentStyle BackImageAlignment + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackImageAlignment)) + { + return (ChartImageAlignmentStyle)GetAttributeObject(CommonCustomProperties.BackImageAlignment); + } + else + { + if(IsSerializing()) + { + return ChartImageAlignmentStyle.TopLeft; + } + if(this.isEmptyPoint) + { + return (ChartImageAlignmentStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackImageAlignment); + } + + return series.backImageAlignment; + + } + } + else + { + return series.backImageAlignment; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.BackImageAlignment, value); + else + series.backImageAlignment = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the background gradient style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeBackGradientStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + public GradientStyle BackGradientStyle + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackGradientStyle)) + { + return (GradientStyle)GetAttributeObject(CommonCustomProperties.BackGradientStyle); + } + else + { + if(IsSerializing()) + { + return GradientStyle.None; + } + if(this.isEmptyPoint) + { + return (GradientStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackGradientStyle); + } + + return series.backGradientStyle; + + } + } + else + { + return series.backGradientStyle; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.BackGradientStyle, value); + else + series.backGradientStyle = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the secondary background color. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackSecondaryColor + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackSecondaryColor)) + { + return (Color)GetAttributeObject(CommonCustomProperties.BackSecondaryColor); + } + else + { + if(IsSerializing()) + { + return Color.Empty; + } + if(this.isEmptyPoint) + { + return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackSecondaryColor); + } + + return series.backSecondaryColor; + + } + } + else + { + return series.backSecondaryColor; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.BackSecondaryColor, value); + else + series.backSecondaryColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the background hatch style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeBackHatchStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + public ChartHatchStyle BackHatchStyle + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.BackHatchStyle)) + { + return (ChartHatchStyle)GetAttributeObject(CommonCustomProperties.BackHatchStyle); + } + else + { + if(IsSerializing()) + { + return ChartHatchStyle.None; + } + if(this.isEmptyPoint) + { + return (ChartHatchStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.BackHatchStyle); + } + + return series.backHatchStyle; + + } + } + else + { + return series.backHatchStyle; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.BackHatchStyle, value); + else + series.backHatchStyle = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the font of the data point. + /// + [ + SRCategory("CategoryAttributeLabelAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeFont"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Font Font + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Font)) + { + Font font = GetAttributeObject(CommonCustomProperties.Font) as Font; + if (font != null) + return font; + } + + if(IsSerializing()) + { + return series.FontCache.DefaultFont; + } + + if(this.isEmptyPoint) + { + return series.EmptyPointStyle.Font; + } + + return series.font; + } + else + { + return series.font; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.Font, value); + else + series.font = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the label color. + /// + [ + SRCategory("CategoryAttributeLabelAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeFontColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color LabelForeColor + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelForeColor)) + { + Color color = (Color)GetAttributeObject(CommonCustomProperties.LabelForeColor); + return color; + } + else + { + if(IsSerializing()) + { + return Color.Black; + } + if(this.isEmptyPoint) + { + return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelForeColor); + } + + return series.fontColor; + + } + } + else + { + return series.fontColor; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LabelForeColor, value); + else + series.fontColor = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the angle of the label. + /// + [ + SRCategory("CategoryAttributeLabelAppearance"), + Bindable(true), + SRDescription(SR.Keys.DescriptionAttributeLabel_FontAngle), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public int LabelAngle + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelAngle)) + { + return (int)GetAttributeObject(CommonCustomProperties.LabelAngle); + } + else + { + if(IsSerializing()) + { + return 0; + } + if(this.isEmptyPoint) + { + return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelAngle); + } + + return series.fontAngle; + + } + } + else + { + return series.fontAngle; + } + } + set + { + if(value < -90 || value > 90) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAngleRangeInvalid)); + } + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LabelAngle, value); + else + series.fontAngle = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the marker style. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + SRDescription("DescriptionAttributeMarkerStyle4"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.MarkerStyleEditor.Editor, Editors.MarkerStyleEditor.Base), + RefreshProperties(RefreshProperties.All) + ] + public MarkerStyle MarkerStyle + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerStyle)) + { + return (MarkerStyle)GetAttributeObject(CommonCustomProperties.MarkerStyle); + } + else + { + if(IsSerializing()) + { + return MarkerStyle.None; + } + if(this.isEmptyPoint) + { + return (MarkerStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerStyle); + } + + return series.markerStyle; + + } + } + else + { + return series.markerStyle; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.MarkerStyle, value); + else + series.markerStyle = value; + + Series thisSeries = this as Series; + if(thisSeries != null) + { + thisSeries.tempMarkerStyleIsSet = false; + } + this.Invalidate(true); + } + } + + /// + /// Gets or sets the size of the marker. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + SRDescription("DescriptionAttributeMarkerSize"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshProperties(RefreshProperties.All) + ] + public int MarkerSize + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerSize)) + { + return (int)GetAttributeObject(CommonCustomProperties.MarkerSize); + } + else + { + if(IsSerializing()) + { + return 5; + } + if(this.isEmptyPoint) + { + return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerSize); + } + + return series.markerSize; + + } + } + else + { + return series.markerSize; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.MarkerSize, value); + else + series.markerSize = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the marker image. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + SRDescription("DescriptionAttributeMarkerImage"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshProperties(RefreshProperties.All) + ] + public string MarkerImage + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerImage)) + { + return (string)GetAttributeObject(CommonCustomProperties.MarkerImage); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerImage); + } + + return series.markerImage; + + } + } + else + { + return series.markerImage; + } + } + set + { + // Replace NULL with empty string + if(value == null) + { + value = string.Empty; + } + + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.MarkerImage, value); + else + series.markerImage = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the color which will be replaced with a transparent color while drawing the marker image. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshProperties(RefreshProperties.All) + ] + public Color MarkerImageTransparentColor + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerImageTransparentColor)) + { + return (Color)GetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor); + } + else + { + if(IsSerializing()) + { + return Color.Empty; + } + if(this.isEmptyPoint) + { + return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor); + } + + return series.markerImageTransparentColor; + + } + } + else + { + return series.markerImageTransparentColor; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.MarkerImageTransparentColor, value); + else + series.markerImageTransparentColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the marker color. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + SRDescription("DescriptionAttributeMarkerColor3"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshProperties(RefreshProperties.All) + ] + public Color MarkerColor + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerColor)) + { + return (Color)GetAttributeObject(CommonCustomProperties.MarkerColor); + } + else + { + if(IsSerializing()) + { + return Color.Empty; + } + if(this.isEmptyPoint) + { + return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerColor); + } + + return series.markerColor; + + } + } + else + { + return series.markerColor; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.MarkerColor, value); + else + series.markerColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the border color of the marker. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + SRDescription("DescriptionAttributeMarkerBorderColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshProperties(RefreshProperties.All) + ] + public Color MarkerBorderColor + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerBorderColor)) + { + return (Color)GetAttributeObject(CommonCustomProperties.MarkerBorderColor); + } + else + { + if(IsSerializing()) + { + return Color.Empty; + } + if(this.isEmptyPoint) + { + return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerBorderColor); + } + + return series.markerBorderColor; + + } + } + else + { + return series.markerBorderColor; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.MarkerBorderColor, value); + else + series.markerBorderColor = value; + this.Invalidate(true); + } + } + + + + /// + /// Gets or sets the border width of the marker. + /// + [ + + SRCategory("CategoryAttributeMarker"), + Bindable(true), + SRDescription("DescriptionAttributeMarkerBorderWidth"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int MarkerBorderWidth + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MarkerBorderWidth)) + { + return (int)GetAttributeObject(CommonCustomProperties.MarkerBorderWidth); + } + else + { + if(IsSerializing()) + { + return 1; + } + if(this.isEmptyPoint) + { + return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MarkerBorderWidth); + } + + return series.markerBorderWidth; + + } + } + else + { + return series.markerBorderWidth; + } + } + set + { + if(value < 0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionBorderWidthIsNotPositive)); + } + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.MarkerBorderWidth, value); + else + series.markerBorderWidth = value; + this.Invalidate(true); + } + } + + + + /// + /// Gets or sets the extended custom properties of the data point. + /// Extended custom properties can be specified in the following format: + /// AttrName1=Value1, AttrName2=Value2, ... + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(false), + SRDescription("DescriptionAttributeCustomAttributesExtended"), + DefaultValue(null), + RefreshProperties(RefreshProperties.All), + NotifyParentPropertyAttribute(true), + DesignOnlyAttribute(true), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DisplayName("CustomProperties") + ] + public CustomProperties CustomPropertiesExtended + { + set + { + customProperties = value; + } + get + { + return customProperties; + } + } + + /// + /// Gets or sets the custom properties of the data point. + /// Custom properties can be specified in the following format: + /// AttrName1=Value1, AttrName2=Value2, ... + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + Browsable(false), + SRDescription("DescriptionAttributeCustomAttributesExtended"), + DefaultValue(""), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public string CustomProperties + { + get + { + // Save all custom properties in a string + string result = ""; + string[] attributesNames = CommonCustomProperties.GetNames(typeof(CommonCustomProperties)); + for(int i = properties.Count - 1; i >= 0; i--) + { + if(this[i] != null) + { + string attributeName = this[i]; + + // Check if attribute is custom + bool customAttribute = true; + foreach(string name in attributesNames) + { + if(String.Compare(attributeName, name, StringComparison.OrdinalIgnoreCase) == 0) + { + customAttribute = false; + break; + } + } + + // Add custom attribute to the string + if(customAttribute && properties[attributeName] != null) + { + if(result.Length > 0) + { + result += ", "; + } + string attributeValue = properties[attributeName].ToString().Replace(",", "\\,"); + attributeValue = attributeValue.Replace("=", "\\="); + + result += attributeName + "=" + attributeValue; + } + } + } + + return result; + } + set + { + // Replace NULL with empty string + if(value == null) + { + value = string.Empty; + } + + // Copy all common properties to the new collection + Hashtable newAttributes = new Hashtable(); + Array enumValues = Enum.GetValues(typeof(CommonCustomProperties)); + foreach(object val in enumValues) + { + if(IsCustomPropertySet((CommonCustomProperties)val)) + { + newAttributes[(int)val] = properties[(int)val]; + } + } + + if(value.Length > 0) + { + // Replace commas in value string + value = value.Replace("\\,", "\\x45"); + value = value.Replace("\\=", "\\x46"); + + // Add new custom properties + string[] nameValueStrings = value.Split(','); + foreach(string nameValue in nameValueStrings) + { + string[] values = nameValue.Split('='); + + // Check format + if(values.Length != 2) + { + throw(new FormatException( SR.ExceptionAttributeInvalidFormat)); + } + + // Check for empty name or value + values[0] = values[0].Trim(); + values[1] = values[1].Trim(); + if(values[0].Length == 0) + { + throw(new FormatException( SR.ExceptionAttributeInvalidFormat)); + } + + // Check if value already defined + foreach(object existingAttributeName in newAttributes.Keys) + { + string existingAttributeNameStr = existingAttributeName as string; + if (existingAttributeNameStr != null) + { + if (String.Compare(existingAttributeNameStr, values[0], StringComparison.OrdinalIgnoreCase) == 0) + { + throw(new FormatException( SR.ExceptionAttributeNameIsNotUnique(values[0] ) ) ); + } + } + } + + string newValue = values[1].Replace("\\x45", ","); + newAttributes[values[0]] = newValue.Replace("\\x46", "="); + + } + } + properties = newAttributes; + this.Invalidate(true); + } + } + + #endregion + + #region IMapAreaAttributesutes Properties implementation + + /// + /// Tooltip. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeToolTip"), + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base), +#if !Microsoft_CONTROL + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute) +#endif + ] + public string ToolTip + { + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.ToolTip, value); + else + series.toolTip = value; + +#if Microsoft_CONTROL + if(Chart != null && Chart.selection != null) + { + Chart.selection.enabledChecked = false; + } +#endif + } + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.ToolTip)) + { + return (String)GetAttributeObject(CommonCustomProperties.ToolTip); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.ToolTip); + } + + return series.toolTip; + + } + } + else + { + return series.toolTip; + } + } + } + +#if !Microsoft_CONTROL + + /// + /// URL target of the area. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeUrl"), + DefaultValue(""), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base) +#endif + ] + public string Url + { + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.Url, value); + else + series.url = value; + } + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.Url)) + { + return (String)GetAttributeObject(CommonCustomProperties.Url); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.Url); + } + + return series.url; + + } + } + else + { + return series.url; + } + } + } + + /// + /// Other attributes of the area. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeMapAreaAttributes"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base) + ] + public string MapAreaAttributes + { + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.MapAreaAttributes, value); + else + series.mapAreaAttributes = value; + } + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.MapAreaAttributes)) + { + return (String)GetAttributeObject(CommonCustomProperties.MapAreaAttributes); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.MapAreaAttributes); + } + + return series.mapAreaAttributes; + } + } + else + { + return series.mapAreaAttributes; + } + } + } + + /// + /// Gets or sets the postback value which can be processed on click event. + /// + /// The value which is passed to click event as argument. + [DefaultValue("")] + [SRCategory(SR.Keys.CategoryAttributeMapArea)] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + [Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)] + public string PostBackValue + { + get + { + if (this.pointCustomProperties) + { + if (properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.PostBackValue)) + { + return (String)GetAttributeObject(CommonCustomProperties.PostBackValue); + } + else + { + if (IsSerializing()) + { + return ""; + } + if (this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.PostBackValue); + } + + return series.postbackValue; + } + } + else + { + return series.postbackValue; + } + } + set + { + if (this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.PostBackValue, value); + else + series.postbackValue = value; + } + } + + + + +#endif + /// + /// Replaces predefined keyword inside the string with their values. + /// + /// Original string with keywords. + /// Modified string. + internal virtual string ReplaceKeywords(string strOriginal) + { + return strOriginal; + } + + #endregion + + #region Legend properties + + /// + /// Indicates whether the item is shown in the legend. + /// + [ + SRCategory("CategoryAttributeLegend"), + + Bindable(true), + SRDescription("DescriptionAttributeShowInLegend"), + #if !Microsoft_CONTROL + DefaultValue(true), + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsVisibleInLegend + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.IsVisibleInLegend)) + { + return (bool)GetAttributeObject(CommonCustomProperties.IsVisibleInLegend); + } + else + { + if(IsSerializing()) + { + return true; + } + if(this.isEmptyPoint) + { + return (bool)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.IsVisibleInLegend); + } + + return series.showInLegend; + } + } + else + { + return series.showInLegend; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.IsVisibleInLegend, value); + else + series.showInLegend = value; + this.Invalidate(true); + } + } + + /// + /// Text of the item in the legend + /// + [ + SRCategory("CategoryAttributeLegend"), + Bindable(true), + SRDescription("DescriptionAttributeLegendText"), + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base), + #if !Microsoft_CONTROL + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public string LegendText + { + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LegendText, value); + else + series.legendText = value; + this.Invalidate(true); + } + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendText)) + { + return (String)GetAttributeObject(CommonCustomProperties.LegendText); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendText); + } + + return series.legendText; + } + } + else + { + return series.legendText; + } + } + } + + /// + /// Tooltip of the item in the legend + /// + [ + SRCategory("CategoryAttributeLegend"), + Bindable(true), + SRDescription("DescriptionAttributeLegendToolTip"), + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base), + #if !Microsoft_CONTROL + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public string LegendToolTip + { + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LegendToolTip, value); + else + series.legendToolTip = value; + +#if Microsoft_CONTROL + if(Chart != null && Chart.selection != null) + { + Chart.selection.enabledChecked = false; + } +#endif + } + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendToolTip)) + { + return (String)GetAttributeObject(CommonCustomProperties.LegendToolTip); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendToolTip); + } + + return series.legendToolTip; + + } + } + else + { + return series.legendToolTip; + } + } + } + + + + /// + /// Background color of the data point label. + /// + [ + SRCategory("CategoryAttributeLabelAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeLabelBackColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + DefaultValue(typeof(Color), ""), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color LabelBackColor + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBackColor)) + { + return (Color)GetAttributeObject(CommonCustomProperties.LabelBackColor); + } + else + { + if(IsSerializing()) + { + return Color.Empty; + } + if(this.isEmptyPoint) + { + return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBackColor); + } + + return series.labelBackColor; + } + } + else + { + return series.labelBackColor; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LabelBackColor, value); + else + series.labelBackColor = value; + this.Invalidate(true); + } + } + + /// + /// Border color of the data point label. + /// + [ + SRCategory("CategoryAttributeLabelAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeBorderColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + DefaultValue(typeof(Color), ""), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color LabelBorderColor + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBorderColor)) + { + return (Color)GetAttributeObject(CommonCustomProperties.LabelBorderColor); + } + else + { + if(IsSerializing()) + { + return Color.Empty; + } + if(this.isEmptyPoint) + { + return (Color)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBorderColor); + } + + return series.labelBorderColor; + } + } + else + { + return series.labelBorderColor; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LabelBorderColor, value); + else + series.labelBorderColor = value; + this.Invalidate(true); + } + } + + /// + /// Border style of the label. + /// + [ + SRCategory("CategoryAttributeLabelAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeLabelBorderDashStyle"), + #if !Microsoft_CONTROL + DefaultValue(ChartDashStyle.Solid), + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartDashStyle LabelBorderDashStyle + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBorderDashStyle)) + { + return (ChartDashStyle)GetAttributeObject(CommonCustomProperties.LabelBorderDashStyle); + } + else + { + if(IsSerializing()) + { + return ChartDashStyle.Solid; + } + if(this.isEmptyPoint) + { + return (ChartDashStyle)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBorderDashStyle); + } + + return series.labelBorderDashStyle; + + } + } + else + { + return series.labelBorderDashStyle; + } + } + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LabelBorderDashStyle, value); + else + series.labelBorderDashStyle = value; + this.Invalidate(true); + } + } + + /// + /// Border width of the label. + /// + [ + SRCategory("CategoryAttributeLabelAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeBorderWidth"), + #if !Microsoft_CONTROL + DefaultValue(1), + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int LabelBorderWidth + { + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelBorderWidth)) + { + return (int)GetAttributeObject(CommonCustomProperties.LabelBorderWidth); + } + else + { + if(IsSerializing()) + { + return 1; + } + if(this.isEmptyPoint) + { + return (int)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelBorderWidth); + } + + return series.labelBorderWidth; + + } + } + else + { + return series.labelBorderWidth; + } + } + set + { + if(value < 0) + { + throw(new ArgumentOutOfRangeException("value", SR.ExceptionLabelBorderIsNotPositive)); + } + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LabelBorderWidth, value); + else + series.labelBorderWidth = value; + this.Invalidate(true); + } + } + + /// + /// Tooltip of the data point label. + /// + [ + SRCategory("CategoryAttributeLabel"), + Bindable(true), + SRDescription("DescriptionAttributeLabelToolTip"), + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base), + #if !Microsoft_CONTROL + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public string LabelToolTip + { + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LabelToolTip, value); + else + series.labelToolTip = value; + +#if Microsoft_CONTROL + if(Chart != null && Chart.selection != null) + { + Chart.selection.enabledChecked = false; + } +#endif + } + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelToolTip)) + { + return (String)GetAttributeObject(CommonCustomProperties.LabelToolTip); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelToolTip); + } + + return series.labelToolTip; + + } + } + else + { + return series.labelToolTip; + } + } + } + + +#if !Microsoft_CONTROL + + /// + /// URL target of the item in the legend. + /// + [ + SRCategory("CategoryAttributeLegend"), + Bindable(true), + SRDescription("DescriptionAttributeLegendUrl"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base), + SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings") + ] + public string LegendUrl + { + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LegendUrl, value); + else + series.legendUrl = value; + } + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendUrl)) + { + return (String)GetAttributeObject(CommonCustomProperties.LegendUrl); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendUrl); + } + + return series.legendUrl; + } + } + else + { + return series.legendUrl; + } + } + } + +#endif + +#if !Microsoft_CONTROL + + /// + /// Other attributes of the legend map area. + /// + [ + SRCategory("CategoryAttributeLegend"), + Bindable(true), + SRDescription("DescriptionAttributeMapAreaAttributes"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base) + ] + public string LegendMapAreaAttributes + { + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes, value); + else + series.legendMapAreaAttributes = value; + } + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendMapAreaAttributes)) + { + return (String)GetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendMapAreaAttributes); + } + + return series.legendMapAreaAttributes; + + } + } + else + { + return series.legendMapAreaAttributes; + } + } + } + + /// + /// Gets or sets the postback value which can be processed on click event. + /// + /// The value which is passed to click event as argument. + [DefaultValue("")] + [SRCategory("CategoryAttributeLegend")] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + [Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)] + public string LegendPostBackValue + { + get + { + if (this.pointCustomProperties) + { + if (properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LegendPostBackValue)) + { + return (String)GetAttributeObject(CommonCustomProperties.LegendPostBackValue); + } + else + { + if (IsSerializing()) + { + return ""; + } + if (this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LegendPostBackValue); + } + + return series.legendPostbackValue; + } + } + else + { + return series.legendPostbackValue; + } + } + set + { + if (this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LegendPostBackValue, value); + else + series.legendPostbackValue = value; + } + } + +#endif // !Microsoft_CONTROL + + + +#if !Microsoft_CONTROL + + /// + /// URL target of the data point label. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeUrl"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base), + SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings") + ] + public string LabelUrl + { + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LabelUrl, value); + else + series.labelUrl = value; + } + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelUrl)) + { + return (String)GetAttributeObject(CommonCustomProperties.LabelUrl); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelUrl); + } + + return series.labelUrl; + } + } + else + { + return series.labelUrl; + } + } + } + +#endif //if !Microsoft_CONTROL + +#if !Microsoft_CONTROL + + /// + /// Other attributes of the data point label. + /// + [ + SRCategory("CategoryAttributeLabel"), + Bindable(true), + SRDescription("DescriptionAttributeMapAreaAttributes"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute) + ] + public string LabelMapAreaAttributes + { + set + { + if(this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes, value); + else + series.labelMapAreaAttributes = value; + } + get + { + if(this.pointCustomProperties) + { + if(properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelMapAreaAttributes)) + { + return (String)GetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes); + } + else + { + if(IsSerializing()) + { + return ""; + } + if(this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelMapAreaAttributes); + } + + return series.labelMapAreaAttributes; + + } + } + else + { + return series.labelMapAreaAttributes; + } + } + } + + /// + /// Gets or sets the postback value which can be processed on click event. + /// + /// The value which is passed to click event as argument. + [DefaultValue("")] + [SRCategory("CategoryAttributeLabel")] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + [Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base)] + public string LabelPostBackValue + { + get + { + if (this.pointCustomProperties) + { + if (properties.Count != 0 && IsCustomPropertySet(CommonCustomProperties.LabelPostBackValue)) + { + return (String)GetAttributeObject(CommonCustomProperties.LabelPostBackValue); + } + else + { + if (IsSerializing()) + { + return ""; + } + if (this.isEmptyPoint) + { + return (string)series.EmptyPointStyle.GetAttributeObject(CommonCustomProperties.LabelPostBackValue); + } + + return series.labelPostbackValue; + } + } + else + { + return series.labelPostbackValue; + } + } + set + { + if (this.pointCustomProperties) + SetAttributeObject(CommonCustomProperties.LabelPostBackValue, value); + else + series.labelPostbackValue = value; + } + } + + +#endif // !Microsoft_CONTROL + + + + #endregion + + #region Serialization control + + + + private bool CheckIfSerializationRequired(CommonCustomProperties attribute) + { + if(this is DataPoint) + { + return IsCustomPropertySet(attribute); + } + else + { + object attr1 = this.GetAttributeObject(attribute); + object attr2 = Series.defaultCustomProperties.GetAttributeObject(attribute); + if(attr1 == null || attr2 == null) + { + return false; + } + return ! attr1.Equals(attr2); + } + } + + private void ResetProperty(CommonCustomProperties attribute) + { + if(this is DataPoint) + { + DeleteCustomProperty(attribute); + } + else + { + this.SetAttributeObject(attribute, Series.defaultCustomProperties.GetAttributeObject(attribute)); + } + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLabel() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.Label); + else + return !String.IsNullOrEmpty(series.label); + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeAxisLabel() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.AxisLabel); + else + return !String.IsNullOrEmpty(series.axisLabel); + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLabelFormat() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LabelFormat); + else + return !String.IsNullOrEmpty(series.labelFormat); + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeIsValueShownAsLabel() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.IsValueShownAsLabel); + else + return series.showLabelAsValue != false; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeColor() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.Color); + else + return series.color != Color.Empty; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeBorderColor() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.BorderColor); + else + return series.borderColor != Color.Empty; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeBorderDashStyle() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.BorderDashStyle); + else + return series.borderDashStyle != ChartDashStyle.Solid; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeBorderWidth() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.BorderWidth); + else + return series.borderWidth != 1; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeMarkerBorderWidth() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.MarkerBorderWidth); + else + return series.markerBorderWidth != 1; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeBackImage() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.BackImage); + else + return !String.IsNullOrEmpty(series.backImage); + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeBackImageWrapMode() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.BackImageWrapMode); + else + return series.backImageWrapMode != ChartImageWrapMode.Tile; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeBackImageTransparentColor() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.BackImageTransparentColor); + else + return series.backImageTransparentColor != Color.Empty; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeBackImageAlignment() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.BackImageAlignment); + else + return series.backImageAlignment != ChartImageAlignmentStyle.TopLeft; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeBackGradientStyle() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.BackGradientStyle); + else + return series.backGradientStyle != GradientStyle.None; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeBackSecondaryColor() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.BackSecondaryColor); + else + return series.backSecondaryColor != Color.Empty; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeBackHatchStyle() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.BackHatchStyle); + else + return series.backHatchStyle != ChartHatchStyle.None; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeFont() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.Font); + else + { + return series.font != series.FontCache.DefaultFont; + } + } + + /// + /// Returns true if property should be serialized. + /// + internal bool ShouldSerializeLabelForeColor() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LabelForeColor); + else + return series.fontColor != Color.Black; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLabelAngle() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LabelAngle); + else + return series.fontAngle != 0f; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeMarkerStyle() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.MarkerStyle); + else + return series.markerStyle != MarkerStyle.None; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeMarkerSize() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.MarkerSize); + else + return series.markerSize != 5; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeMarkerImage() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.MarkerImage); + else + return !String.IsNullOrEmpty(series.markerImage); + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeMarkerImageTransparentColor() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.MarkerImageTransparentColor); + else + return series.markerImageTransparentColor != Color.Empty; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeMarkerColor() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.MarkerColor); + else + return series.markerColor != Color.Empty; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeMarkerBorderColor() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.MarkerBorderColor); + else + return series.markerBorderColor != Color.Empty; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeToolTip() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.ToolTip); + else + return !String.IsNullOrEmpty(series.toolTip); + } + +#if !Microsoft_CONTROL + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeUrl() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.Url); + else + return !String.IsNullOrEmpty(series.url); + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeMapAreaAttributes() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.MapAreaAttributes); + else + return !String.IsNullOrEmpty(series.mapAreaAttributes); + } + + /// + /// Returns true if property should be serialized. + /// + internal bool ShouldSerializePostBackValue() + { + if (this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.PostBackValue); + else + return !String.IsNullOrEmpty(series.postbackValue); + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLegendUrl() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LegendUrl); + else + return !String.IsNullOrEmpty(series.legendUrl); + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLegendMapAreaAttributes() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LegendMapAreaAttributes); + else + return !String.IsNullOrEmpty(series.legendMapAreaAttributes); + } + + + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLabelUrl() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LabelUrl); + else + return !String.IsNullOrEmpty(series.labelUrl); + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLabelMapAreaAttributes() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LabelMapAreaAttributes); + else + return !String.IsNullOrEmpty(series.labelMapAreaAttributes); + } + + + +#endif // !Microsoft_CONTROL + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeIsVisibleInLegend() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.IsVisibleInLegend); + else + return series.showInLegend != true; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLegendText() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LegendText); + else + return !String.IsNullOrEmpty(series.legendText); + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLegendToolTip() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LegendToolTip); + else + return !String.IsNullOrEmpty(series.legendToolTip); + } + + + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLabelToolTip() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LabelToolTip); + else + return !String.IsNullOrEmpty(series.labelToolTip); + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLabelBackColor() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LabelBackColor); + else + return series.labelBackColor != Color.Empty; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLabelBorderColor() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LabelBorderColor); + else + return series.labelBorderColor != Color.Empty; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLabelBorderDashStyle() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LabelBorderDashStyle); + else + return series.labelBorderDashStyle != ChartDashStyle.Solid; + } + + /// + /// Returns true if property should be serialized. + /// + + internal bool ShouldSerializeLabelBorderWidth() + { + if(this.pointCustomProperties) + return CheckIfSerializationRequired(CommonCustomProperties.LabelBorderWidth); + else + return series.labelBorderWidth != 1; + } + + + /// + /// Resets property to its default value. + /// + + internal void ResetLabel() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.Label); + else + series.label = ""; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetAxisLabel() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.AxisLabel); + else + series.axisLabel = ""; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetLabelFormat() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LabelFormat); + else + series.labelFormat = ""; + } + + /// + /// Resets property to its default value. + /// + + public void ResetIsValueShownAsLabel() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.IsValueShownAsLabel); + else + series.IsValueShownAsLabel = false; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetColor() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.Color); + else + series.color = Color.Empty; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetBorderColor() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.BorderColor); + else + series.borderColor = Color.Empty; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetBorderDashStyle() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.BorderDashStyle); + else + series.borderDashStyle = ChartDashStyle.Solid; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetBorderWidth() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.BorderWidth); + else + series.borderWidth = 1; + } + + + + /// + /// Resets property to its default value. + /// + + internal void ResetMarkerBorderWidth() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.MarkerBorderWidth); + else + series.markerBorderWidth = 1; + } + + + + /// + /// Resets property to its default value. + /// + + internal void ResetBackImage() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.BackImage); + else + series.backImage = ""; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetBackImageWrapMode() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.BackImageWrapMode); + else + series.backImageWrapMode = ChartImageWrapMode.Tile; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetBackImageTransparentColor() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.BackImageTransparentColor); + else + series.backImageTransparentColor = Color.Empty; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetBackSecondaryColor() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.BackSecondaryColor); + else + series.backSecondaryColor = Color.Empty; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetBackHatchStyle() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.BackHatchStyle); + else + series.backHatchStyle = ChartHatchStyle.None; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetFont() + { + if (this.pointCustomProperties) + ResetProperty(CommonCustomProperties.Font); + else + { + series.font = series.FontCache.DefaultFont; + } + } + + + /// + /// Resets property to its default value. + /// + + internal void ResetLabelAngle() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LabelAngle); + else + series.fontAngle = 0; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetMarkerStyle() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.MarkerStyle); + else + series.markerStyle = MarkerStyle.None; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetMarkerSize() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.MarkerSize); + else + series.markerSize = 5; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetMarkerImage() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.MarkerImage); + else + series.markerImage = ""; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetMarkerImageTransparentColor() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.MarkerImageTransparentColor); + else + series.markerImageTransparentColor = Color.Empty; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetMarkerColor() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.MarkerColor); + else + series.markerColor = Color.Empty; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetMarkerBorderColor() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.MarkerBorderColor); + else + series.markerBorderColor = Color.Empty; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetToolTip() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.ToolTip); + else + series.toolTip = ""; + +#if Microsoft_CONTROL + if(Chart != null && Chart.selection != null) + { + Chart.selection.enabledChecked = false; + } +#endif + } + +#if !Microsoft_CONTROL + + /// + /// Resets property to its default value. + /// + + internal void ResetUrl() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.Url); + else + series.url = ""; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetMapAreaAttributes() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.MapAreaAttributes); + else + series.mapAreaAttributes = ""; + } + + /// + /// Resets property to its default value. + /// + internal void ResetPostBackValue() + { + if (this.pointCustomProperties) + ResetProperty(CommonCustomProperties.PostBackValue); + else + series.postbackValue = ""; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetLegendUrl() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LegendUrl); + else + series.legendUrl = ""; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetLegendMapAreaAttributes() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LegendMapAreaAttributes); + else + series.legendMapAreaAttributes = ""; + } + + + + /// + /// Resets property to its default value. + /// + + internal void ResetLabelUrl() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LabelUrl); + else + series.labelUrl = ""; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetLabelMapAreaAttributes() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LabelMapAreaAttributes); + else + series.labelMapAreaAttributes = ""; + } + + +#endif // !Microsoft_CONTROL + + /// + /// Resets property to its default value. + /// + + public void ResetIsVisibleInLegend() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.IsVisibleInLegend); + else + series.showInLegend = true; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetLegendText() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LegendText); + else + series.legendText = ""; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetLegendToolTip() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LegendToolTip); + else + series.legendToolTip = ""; + +#if Microsoft_CONTROL + if(Chart != null && Chart.selection != null) + { + Chart.selection.enabledChecked = false; + } +#endif + } + + + + /// + /// Resets property to its default value. + /// + + internal void ResetLabelBackColor() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LabelBackColor); + else + series.labelBackColor = Color.Empty; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetLabelBorderColor() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LabelBorderColor); + else + series.labelBorderColor = Color.Empty; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetLabelBorderDashStyle() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LabelBorderDashStyle); + else + series.labelBorderDashStyle = ChartDashStyle.Solid; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetLabelBorderWidth() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LabelBorderWidth); + else + series.labelBorderWidth = 1; + } + + /// + /// Resets property to its default value. + /// + + internal void ResetLabelToolTip() + { + if(this.pointCustomProperties) + ResetProperty(CommonCustomProperties.LabelToolTip); + else + series.labelToolTip = ""; + +#if Microsoft_CONTROL + if(Chart != null && Chart.selection != null) + { + Chart.selection.enabledChecked = false; + } +#endif + } + + + + #endregion + + #region Invalidating method + + /// + /// Invalidate chart area. + /// + /// Invalidate legend area only. + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This parameter is used when compiling for the Microsoft version of Chart")] + internal void Invalidate(bool invalidateLegend) + { +#if Microsoft_CONTROL + if(this.series != null) + { + series.Invalidate(true, invalidateLegend); + } + else + { + Series thisSeries = this as Series; + if (thisSeries != null) + { + thisSeries.Invalidate(true, invalidateLegend); + } + } +#endif + } + + #endregion + } + + /// + /// Class stores additional information about the data point in 3D space. + /// + internal class DataPoint3D + { + #region Fields + + /// + /// Reference to the 2D data point object + /// + internal DataPoint dataPoint = null; + + /// + /// Data point index. + /// + internal int index = 0; + + /// + /// Point X position in relative coordinates. + /// + internal double xPosition = 0.0; + + /// + /// Point Y position in relative coordinates. + /// + internal double yPosition = 0.0; + + /// + /// Point X center position in relative coordinates. Used for side-by-side charts. + /// + internal double xCenterVal = 0.0; + + /// + /// Point Z position in relative coordinates. + /// + internal float zPosition = 0f; + + /// + /// Point width. + /// + internal double width = 0.0; + + /// + /// Point height. + /// + internal double height = 0.0; + + /// + /// Point depth. + /// + internal float depth = 0f; + + /// + /// Indicates that point belongs to indexed series. + /// + internal bool indexedSeries = false; + + #endregion + } + + /// + /// Design-time representation of the CustomProperties. + /// This class is used instead of the string "CustomProperties" + /// property at design time and supports expandable list + /// of custom properties. + /// + [ TypeConverter(typeof(CustomPropertiesTypeConverter)) ] + [EditorBrowsable(EditorBrowsableState.Never)] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class CustomProperties + { + #region Fields + + // Reference to the properties class + internal DataPointCustomProperties m_DataPointCustomProperties = null; + + #endregion // Fields + + #region Constructor + + /// + /// Constructor + /// + /// Attributes object. + internal CustomProperties(DataPointCustomProperties properties) + { + this.m_DataPointCustomProperties = properties; + } + + #endregion // Constructor + + #region Properties + + internal virtual DataPointCustomProperties DataPointCustomProperties + { + get + { + return this.m_DataPointCustomProperties; + } + set + { + this.m_DataPointCustomProperties = value; + } + + } + + #endregion //Properties + + #region Methods + + /// + /// Gets a comma separated string of user defined custom properties. + /// + /// Comma separated string of user defined custom properties. + internal virtual string GetUserDefinedCustomProperties() + { + return GetUserDefinedCustomProperties(true); + } + + /// + /// Gets a comma separated string of user defined or non-user defined custom properties. + /// + /// True if user defined properties must be returned. + /// Comma separated string of user defined custom properties. + internal virtual string GetUserDefinedCustomProperties(bool userDefined) + { + // Get comma separated string of custom properties + string customAttribute = this.DataPointCustomProperties.CustomProperties; + string userDefinedCustomAttribute = string.Empty; + + // Get custom attribute registry + CustomPropertyRegistry registry = (CustomPropertyRegistry)this.DataPointCustomProperties.Common.container.GetService(typeof(CustomPropertyRegistry)); + + // Replace commas in value string + customAttribute = customAttribute.Replace("\\,", "\\x45"); + customAttribute = customAttribute.Replace("\\=", "\\x46"); + + // Split custom properties by commas into individual properties + if(customAttribute.Length > 0) + { + string[] nameValueStrings = customAttribute.Split(','); + foreach(string nameValue in nameValueStrings) + { + string[] values = nameValue.Split('='); + + // Check format + if(values.Length != 2) + { + throw(new FormatException(SR.ExceptionAttributeInvalidFormat)); + } + + // Check for empty name or value + values[0] = values[0].Trim(); + values[1] = values[1].Trim(); + if(values[0].Length == 0) + { + throw(new FormatException(SR.ExceptionAttributeInvalidFormat)); + } + + // Check if attribute is registered or user defined + bool userDefinedAttribute = true; + foreach(CustomPropertyInfo info in registry.registeredCustomProperties) + { + if(string.Compare(info.Name, values[0], StringComparison.OrdinalIgnoreCase) == 0) + { + userDefinedAttribute = false; + } + } + + // Copy attribute into the output string + if(userDefinedAttribute == userDefined) + { + if(userDefinedCustomAttribute.Length > 0) + { + userDefinedCustomAttribute += ", "; + } + + string val = values[1].Replace("\\x45", ","); + val = val.Replace("\\x46", "="); + userDefinedCustomAttribute += values[0] + "=" + val; + } + } + } + + return userDefinedCustomAttribute; + } + + /// + /// Sets user defined custom properties without cleaning registered properties. + /// + /// New user defined properties. + internal virtual void SetUserDefinedAttributes(string val) + { + // Get non-user defined custom properties + string properties = GetUserDefinedCustomProperties(false); + + // Check if new string is empty + if(val.Length > 0) + { + // Add comma at the end + if(properties.Length > 0) + { + properties += ", "; + } + + // Add new user defined properties + properties += val; + } + + // Set new custom attribute string + this.DataPointCustomProperties.CustomProperties = properties; + } + + + #endregion // Methods + } +} + + diff --git a/System.Web.DataVisualization/Common/DataManager/DataSeries.cs b/System.Web.DataVisualization/Common/DataManager/DataSeries.cs new file mode 100644 index 000000000..9f16542df --- /dev/null +++ b/System.Web.DataVisualization/Common/DataManager/DataSeries.cs @@ -0,0 +1,2694 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: DataSries.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Data +// +// Classes: SeriesCollection, Series +// +// Purpose: Chart series collection class and series properties class. +// +// Reviewed: AG - Aug 1, 2002; +// GS - Aug 7, 2002 +// +//=================================================================== + + +#region Used namespaces + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Collections.Generic; +using System.Collections; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; + using System.ComponentModel.Design.Serialization; + using System.Reflection; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.Data; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif +{ + #region Series enumerations + + /// + /// Chart axis type (Primary or Secondary). + /// + public enum AxisType + { + /// + /// Primary axis. For X axis - bottom, for Y axis - left. + /// + Primary, + + /// + /// Secondary axis. For X axis - top, for Y axis - right. + /// + Secondary + }; + + /// + /// Sorting order (Ascending or Descending). + /// + public enum PointSortOrder + { + /// + /// Ascending sorting order + /// + Ascending, + + /// + /// Descending sorting order + /// + Descending + } + + #endregion + + /// + /// Data series collection + /// + [ + SRDescription("DescriptionAttributeSeriesCollection_SeriesCollection"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class SeriesCollection : ChartNamedElementCollection + { + + #region Constructors + + /// + /// Data series collection object constructor. + /// + internal SeriesCollection(DataManager dataManager) + : base(dataManager) + { + } + + #endregion + + #region Methods + + /// + /// Creates a new Series with the specified name and adds it to the collection. + /// + /// The new chart area name. + /// New series + public Series Add(string name) + { + Series series = new Series(name); + this.Add(series); + return series; + } + + /// + /// Fixes the name references of the item. + /// + /// Item to verify and fix. + internal override void FixNameReferences(Series item) + { + if (item != null && Chart != null) + { + if (String.IsNullOrEmpty(item.ChartArea) && Chart.ChartAreas != null) + { + item.ChartArea = Chart.ChartAreas.DefaultNameReference; + } + if (String.IsNullOrEmpty(item.Legend) && Chart.Legends != null) + { + item.Legend = Chart.Legends.DefaultNameReference; + } + } + } + #endregion + + #region Event handlers + /// + /// Updates the Series' references to ChartAreas. + /// + /// The sender. + /// The instance containing the event data. + internal void ChartAreaNameReferenceChanged(object sender, NameReferenceChangedEventArgs e) + { + foreach (Series series in this) + if (series.ChartArea == e.OldName) + series.ChartArea = e.NewName; + } + + /// + /// Updates the Series' references to Legends. + /// + /// The sender. + /// The instance containing the event data. + internal void LegendNameReferenceChanged(object sender, NameReferenceChangedEventArgs e) + { + foreach (Series series in this) + if (series.Legend == e.OldName) + series.Legend = e.NewName; + } + #endregion + + } + + /// + /// The class stores the data points and the default series properties. + /// + [ + SRDescription("DescriptionAttributeSeries_Series"), + DefaultProperty("Points"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class Series : DataPointCustomProperties + { + #region Fields + + // Private data members, which store properties values + private ChartValueType _xValueType = ChartValueType.Auto; + private ChartValueType _yValueType = ChartValueType.Auto; + private bool _isXValueIndexed = false; + private int _yValuesPerPoint = 1; + private int _markersStep = 1; + private ChartColorPalette _colorPalette = ChartColorPalette.None; + private AxisType _xAxisType = AxisType.Primary; + private AxisType _yAxisType = AxisType.Primary; +#if SUBAXES + private string _ySubAxisName = string.Empty; + private string _xSubAxisName = string.Empty; +#endif // SUBAXES + private DataPointCustomProperties _emptyPointCustomProperties = null; + private DataPointCollection _points; + private int _shadowOffset = 0; + private Color _shadowColor = Color.FromArgb(128, 0, 0, 0); + private string _chartType = ChartTypeNames.Column; + private string _chartArea = String.Empty; + + // Series enabled flag + private bool _enabled = true; + + // Legend name used by this series + private string _legend = String.Empty; + + // Member of the chart data source used to data bind to the X value of the series. + private string _dataSourceXMember = String.Empty; + + // Members of the chart data source used to data bind to the Y values of the series. + private string _dataSourceYMembers = String.Empty; + + // Automatic values type flags + internal bool autoXValueType = false; + internal bool autoYValueType = false; + + // Total Y value of all data points + private double _totalYvalue = double.NaN; + + // Array of dummy data used at design time + private double[] _dummyDoubleValues = null; + + // X value type if X value is indexed + internal ChartValueType indexedXValueType = ChartValueType.Auto; + + // Default properties + static internal DataPointCustomProperties defaultCustomProperties = InitializeDefaultCustomProperties(); + + // Indicates that a temp. marker style was set for drawing + internal bool tempMarkerStyleIsSet = false; + + // Indicates that number of Y values should be checked + private bool _checkPointsNumber = true; + + // SmartLabelStyle style + private SmartLabelStyle _smartLabelStyle = null; + + // Indicates that there is no custom axis labels in data points or series + internal bool noLabelsInPoints = true; + + // Indicates if series has all X values set to 0 + internal bool xValuesZeros = false; + + // Indicates if check for series X zero values was done + internal bool xValuesZerosChecked = false; + + + // fake data points for selector service in design time. + // note: in design time fake points are generated + // with short life time - during painting. + // this collection keep a copy of design time datapoints. + internal DataPointCollection fakeDataPoints; + + + #endregion + + #region Series properties fields + + /// + /// Data point label text. + /// + internal string label = ""; + + /// + /// Data point X axis label text. + /// + internal string axisLabel = ""; + + /// + /// Data point label format string + /// + internal string labelFormat = ""; + + /// + /// If true shows point's value as a label. + /// + internal bool showLabelAsValue = false; + + /// + /// Data point color + /// + internal Color color = Color.Empty; + + /// + /// Data point border color + /// + internal Color borderColor = Color.Empty; + + /// + /// Data point border style + /// + internal ChartDashStyle borderDashStyle = ChartDashStyle.Solid; + + /// + /// Data point border width + /// + internal int borderWidth = 1; + + /// + /// Data point marker border width + /// + internal int markerBorderWidth = 1; + + /// + /// Data point background image + /// + internal string backImage = ""; + + /// + /// Data point background image drawing mode. + /// + internal ChartImageWrapMode backImageWrapMode = ChartImageWrapMode.Tile; + + /// + /// Background image transparent color. + /// + internal Color backImageTransparentColor = Color.Empty; + + /// + /// Background image alignment used by ClampUnscale drawing mode. + /// + internal ChartImageAlignmentStyle backImageAlignment = ChartImageAlignmentStyle.TopLeft; + + /// + /// Data point background gradient type. + /// + internal GradientStyle backGradientStyle = GradientStyle.None; + + /// + /// Data point background gradient end color + /// + internal Color backSecondaryColor = Color.Empty; + + /// + /// Data point hatch style + /// + internal ChartHatchStyle backHatchStyle = ChartHatchStyle.None; + + /// + /// Font cache for the fonts used in the Series and DataPoint + /// + private FontCache _fontCache = new FontCache(); + + /// + /// Data point font + /// + internal Font font = null; + + /// + /// Data point line color + /// + internal Color fontColor = Color.Black; + + /// + /// Data point font angle + /// + internal int fontAngle = 0; + + /// + /// Data point marker style + /// + internal MarkerStyle markerStyle = MarkerStyle.None; + + /// + /// Data point marker size + /// + internal int markerSize = 5; + + /// + /// Data point marker image + /// + internal string markerImage = ""; + + /// + /// Data point marker image transparent color. + /// + internal Color markerImageTransparentColor = Color.Empty; + + /// + /// Data point marker color + /// + internal Color markerColor = Color.Empty; + + /// + /// Data point marker border color + /// + internal Color markerBorderColor = Color.Empty; + + /// + /// The tooltip. + /// + internal string toolTip = ""; + +#if !Microsoft_CONTROL + + /// + /// URL target of the area. + /// + internal string url = ""; + /// + /// Other attributes of the area. + /// + internal string mapAreaAttributes = ""; + + /// + /// Other attributes of the area. + /// + internal string postbackValue = ""; + +#endif + + /// + /// Indicates that item is shown in the legend. + /// + internal bool showInLegend = true; + + /// + /// Text of the item in the legend + /// + internal string legendText = ""; + + /// + /// Tooltip of the item in the legend + /// + internal string legendToolTip = ""; + + /// + /// Data point label back color + /// + internal Color labelBackColor = Color.Empty; + + /// + /// Data point label border color + /// + internal Color labelBorderColor = Color.Empty; + + /// + /// Data point label border style + /// + internal ChartDashStyle labelBorderDashStyle = ChartDashStyle.Solid; + + /// + /// Data point label border width + /// + internal int labelBorderWidth = 1; + + /// + /// Tooltip of the data point label + /// + internal string labelToolTip = ""; + +#if !Microsoft_CONTROL + + /// + /// URL target of the data point label. + /// + internal string labelUrl = ""; + + /// + /// Other attributes of the data point label. + /// + internal string labelMapAreaAttributes = ""; + + /// + /// Other attributes of the area. + /// + internal string labelPostbackValue = ""; + + /// + /// URL target of the item in the legend. + /// + internal string legendUrl = ""; + + /// + /// Other attributes of the legend map area. + /// + internal string legendMapAreaAttributes = ""; + + /// + /// Other attributes of the area. + /// + internal string legendPostbackValue = ""; + + +#endif + + #endregion + + #region Constructors and initialization + + /// + /// Initializes the default custom properties field. + /// + /// A DataPointCustomProperties initialized to defaults + private static DataPointCustomProperties InitializeDefaultCustomProperties() + { + DataPointCustomProperties customProperties = new DataPointCustomProperties(null, false); + customProperties.SetDefault(true); + customProperties.pointCustomProperties = true; + + return customProperties; + } + + /// + /// Series object constructor. + /// + public Series() : base(null, false) + { + InitProperties(null, 0); + } + + /// + /// Series object constructor. + /// + /// Name of the data series + public Series(string name) : base(null, false) + { + if(name == null) + { + throw (new ArgumentNullException(SR.ExceptionDataSeriesNameIsEmpty)); + } + + InitProperties(name, 0); + } + + /// + /// Series object constructor. + /// + /// Name of the data series. + /// Number of y values per data point. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "Y is a cartesian coordinate and well understood")] + public Series(string name, int yValues) + : base(null, false) + { + if(name == null) + { + throw (new ArgumentNullException("name", SR.ExceptionDataSeriesNameIsEmpty)); + } + if(YValuesPerPoint < 1) + { + throw (new ArgumentOutOfRangeException("yValues", SR.ExceptionDataSeriesYValuesPerPointIsZero)); + } + + InitProperties(name, yValues); + } + + /// + /// Initialize series properties + /// + private void InitProperties(string name, int YValuesPerPoint) + { + this.font = _fontCache.DefaultFont; + this.series = this; + this._emptyPointCustomProperties = new DataPointCustomProperties(this, false); + this._emptyPointCustomProperties.series = this; + + // Initialize properties + _points = new DataPointCollection(this); + + fakeDataPoints = new DataPointCollection(this); + + if(name != null) + { + base.Name = name; + } + if(YValuesPerPoint != 0) + { + _yValuesPerPoint = YValuesPerPoint; + } + base.SetDefault(true); + _emptyPointCustomProperties.SetDefault(true); + _emptyPointCustomProperties.pointCustomProperties = true; +// +#if !SQLRS_CONTROL + // Use transparent colors for empty points + emptyPointAttributes.Color = Color.Transparent; + emptyPointAttributes.BorderColor = Color.Transparent; + emptyPointAttributes.FontColor = Color.Transparent; + emptyPointAttributes.MarkerColor = Color.Transparent; + emptyPointAttributes.MarkerBorderColor = Color.Transparent; +#endif //!SQLRS_CONTROL + + // Create SmartLabelStyle style object + _smartLabelStyle = new SmartLabelStyle(this); + + } + + + #endregion + + #region Helper methods + + /// + /// Gets series caption that may not be the same as series name. + /// + /// Series caption string. + internal string GetCaption() + { + if (this.IsCustomPropertySet("SeriesCaption")) + { + return this["SeriesCaption"]; + } + return this.Name; + } + + /// + /// Gets custom points depth and gap depth from series properties. + /// + /// Chart graphics. + /// Cate----cal axis. + /// Returns point depth. + /// Return point gap depth. + internal void GetPointDepthAndGap( + ChartGraphics graph, + Axis axis, + ref double pointDepth, + ref double pointGapDepth) + { + + + // Check if series provide custom value for point depth in pixels + string attribValue = this[CustomPropertyName.PixelPointDepth]; + if(attribValue != null) + { + try + { + pointDepth = CommonElements.ParseDouble(attribValue); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid2("PixelPointDepth"))); + } + + if (pointDepth <= 0) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeIsNotLargerThenZiro("PixelPointDepth"))); + } + if (pointDepth > CustomPropertyRegistry.MaxValueOfPixelAttribute) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeMustBeInRange("PixelPointDepth", (0).ToString(CultureInfo.CurrentCulture), CustomPropertyRegistry.MaxValueOfPixelAttribute.ToString(CultureInfo.CurrentCulture)))); + } + + SizeF relativeSize = graph.GetRelativeSize(new SizeF((float)pointDepth, (float)pointDepth)); + pointDepth = relativeSize.Width; + if(axis.AxisPosition == AxisPosition.Left || axis.AxisPosition == AxisPosition.Right) + { + pointDepth = relativeSize.Height; + } + } + + // Check if series provide custom value for point gap depth in pixels + attribValue = this[CustomPropertyName.PixelPointGapDepth]; + if(attribValue != null) + { + try + { + pointGapDepth = CommonElements.ParseDouble(attribValue); + } + catch + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid2("PixelPointGapDepth"))); + } + + if (pointGapDepth <= 0) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeIsNotLargerThenZiro("PixelPointGapDepth"))); + } + if (pointGapDepth > CustomPropertyRegistry.MaxValueOfPixelAttribute) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeMustBeInRange("PixelPointGapDepth", (0).ToString(CultureInfo.CurrentCulture), CustomPropertyRegistry.MaxValueOfPixelAttribute.ToString(CultureInfo.CurrentCulture)))); + } + + SizeF relativeSize = graph.GetRelativeSize(new SizeF((float)pointGapDepth, (float)pointGapDepth)); + pointGapDepth = relativeSize.Width; + if(axis.AxisPosition == AxisPosition.Left || axis.AxisPosition == AxisPosition.Right) + { + pointGapDepth = relativeSize.Height; + } + } + + + } + + + /// + /// Gets data point width in relative coordinates. + /// + /// Chart graphics. + /// Axis object. + /// Current minimum axis interval. + /// Default width in percentage of interval. + /// Point width. + internal double GetPointWidth( + ChartGraphics graph, + Axis axis, + double interval, + double defaultWidth) + { + double pointPercentageWidth = defaultWidth; + double pointWidth = 0.0; + + // Check if series provide custom value for point width in percentage of interval + string strWidth = this[CustomPropertyName.PointWidth]; + if(strWidth != null) + { + pointPercentageWidth = CommonElements.ParseDouble(strWidth); + } + + // Get column width in relative and pixel coordinates + pointWidth = axis.GetPixelInterval( interval * pointPercentageWidth ); + SizeF pointSize = graph.GetAbsoluteSize(new SizeF((float)pointWidth, (float)pointWidth)); + double pixelPointWidth = pointSize.Width; + if(axis.AxisPosition == AxisPosition.Left || axis.AxisPosition == AxisPosition.Right) + { + pixelPointWidth = pointSize.Height; + } + + + // Check if series provide custom value for Min point width in pixels + bool usePixelWidth = false; + string attribValue = this[CustomPropertyName.MinPixelPointWidth]; + if(attribValue != null) + { + double minPixelPointWidth = 0.0; + try + { + minPixelPointWidth = CommonElements.ParseDouble(attribValue); + } + catch + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid2("MinPixelPointWidth"))); + } + if(minPixelPointWidth <= 0.0) + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeIsNotLargerThenZiro("MinPixelPointWidth"))); + } + if (minPixelPointWidth > CustomPropertyRegistry.MaxValueOfPixelAttribute) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeMustBeInRange("MinPixelPointWidth", (0).ToString(CultureInfo.CurrentCulture), CustomPropertyRegistry.MaxValueOfPixelAttribute.ToString(CultureInfo.CurrentCulture)))); + } + + if(pixelPointWidth < minPixelPointWidth) + { + usePixelWidth = true; + pixelPointWidth = minPixelPointWidth; + } + } + + // Check if series provide custom value for Max point width in pixels + attribValue = this[CustomPropertyName.MaxPixelPointWidth]; + if(attribValue != null) + { + double maxPixelPointWidth = 0.0; + try + { + maxPixelPointWidth = CommonElements.ParseDouble(attribValue); + } + catch + { + throw(new InvalidOperationException( SR.ExceptionCustomAttributeValueInvalid2("MaxPixelPointWidth"))); + } + if(maxPixelPointWidth <= 0) + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeIsNotLargerThenZiro("MaxPixelPointWidth"))); + } + + if(pixelPointWidth > maxPixelPointWidth) + { + usePixelWidth = true; + pixelPointWidth = maxPixelPointWidth; + } + } + + // Check if series provide custom value for point width in pixels + attribValue = this[CustomPropertyName.PixelPointWidth]; + if(attribValue != null) + { + usePixelWidth = true; + pixelPointWidth = 0.0; + try + { + pixelPointWidth = CommonElements.ParseDouble(attribValue); + } + catch + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid2("PixelPointWidth"))); + } + if(pixelPointWidth <= 0) + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeIsNotLargerThenZiro("PixelPointWidth"))); + } + if (pixelPointWidth > CustomPropertyRegistry.MaxValueOfPixelAttribute) + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeMustBeInRange("PixelPointWidth", (0).ToString(CultureInfo.CurrentCulture), CustomPropertyRegistry.MaxValueOfPixelAttribute.ToString(CultureInfo.CurrentCulture)))); + } + } + + // Translate pixel width to relative coordinates + if(usePixelWidth) + { + SizeF pointRelativeSize = graph.GetRelativeSize(new SizeF((float)pixelPointWidth, (float)pixelPointWidth)); + pointWidth = pointRelativeSize.Width; + if(axis.AxisPosition == AxisPosition.Left || axis.AxisPosition == AxisPosition.Right) + { + pointWidth = pointRelativeSize.Height; + } + } + + + + return pointWidth; + } + + /// + /// Get chart type name by it's type + /// + /// Chart type. + /// Chart type name. + static internal string GetChartTypeName(SeriesChartType type) + { + if(type == SeriesChartType.StackedArea100) + return ChartTypeNames.OneHundredPercentStackedArea; + if(type == SeriesChartType.StackedBar100) + return ChartTypeNames.OneHundredPercentStackedBar; + if(type == SeriesChartType.StackedColumn100) + return ChartTypeNames.OneHundredPercentStackedColumn; + return Enum.GetName(typeof(SeriesChartType), type); + } + + /// + /// Checks if Y values of the series represent date-time. + /// + /// True if date-time. + internal bool IsYValueDateTime() + { + if(this.YValueType == ChartValueType.Date || + this.YValueType == ChartValueType.DateTime || + this.YValueType == ChartValueType.Time || + this.YValueType == ChartValueType.DateTimeOffset) + { + return true; + } + return false; + } + + /// + /// Checks if X values of the series represent date-time. + /// + /// True if date-time. + internal bool IsXValueDateTime() + { + if(this.XValueType == ChartValueType.Date || + this.XValueType == ChartValueType.DateTime || + this.XValueType == ChartValueType.Time || + this.XValueType == ChartValueType.DateTimeOffset) + { + return true; + } + return false; + } + + /// + /// Checks if series is visible. + /// + /// True if series is visible. + internal bool IsVisible() + { + // Check if enabled flag is set and the ChartArea is defined + if(this.Enabled && !String.IsNullOrEmpty(this.ChartArea)) + { + return true; + } + return false; + } + + /// + /// Checks if series chart type uses a "Fast" mode chart type. + /// + /// True if series uses "Fast" mode chart type. + internal bool IsFastChartType() + { + + // Check if fast mode chart type is used in the series + if(this.ChartType == SeriesChartType.FastLine) + { + return true; + } + + // Check if fast mode chart type is used in the series + if(this.ChartType == SeriesChartType.FastPoint) + { + return true; + } + + return false; + } + + /// + /// Throws exception if specified value type is not supported. + /// + /// Value type to check. + internal void CheckSupportedTypes(Type type) + { + // Check parameters type + if(type == typeof(Double) || + type == typeof(DateTime) || + type == typeof(String) || + type == typeof(Int32) || + type == typeof(UInt32) || + type == typeof(Decimal) || + type == typeof(Single) || + type == typeof(Int16) || + type == typeof(UInt16) || + type == typeof(Int64) || + type == typeof(UInt64) || + type == typeof(Byte) || + type == typeof(SByte) || + type == typeof(System.DBNull) || + type == typeof(Boolean) ) + { + return; + } + + // Unsupported parameter type + throw(new ArgumentException(SR.ExceptionDataSeriesPointTypeUnsupported( type.ToString() ) )); + + } + + /// + /// Apply palette colors to the data series points if UsePaletteColors property is set. + /// + internal void ApplyPaletteColors() + { + // Use Series or Data Manager palette + DataManager dataManager = this.Common.DataManager; + + ChartColorPalette currentPalette = (this.Palette == ChartColorPalette.None) ? + dataManager.Palette : this.Palette; + + // if it is still none - check if custom colors pallete is empty. + if ( + currentPalette == ChartColorPalette.None && + dataManager.PaletteCustomColors.Length == 0 + ) + { + currentPalette = ChartColorPalette.BrightPastel; + } + + // Get palette colors + int colorIndex = 0; + Color[] paletteColors = (currentPalette == ChartColorPalette.None) ? + dataManager.PaletteCustomColors : ChartPaletteColors.GetPaletteColors(currentPalette); + foreach(DataPoint dataPoint in _points) + { + // Change color of the series data points only if no color is set + if((!dataPoint.IsCustomPropertySet(CommonCustomProperties.Color) || dataPoint.tempColorIsSet ) && !dataPoint.IsEmpty) + { + dataPoint.SetAttributeObject(CommonCustomProperties.Color, paletteColors[colorIndex]); + dataPoint.tempColorIsSet = true; + ++colorIndex; + if(colorIndex >= paletteColors.Length) + { + colorIndex = 0; + } + } + } + } + + /// + /// Gets design time dummy data. + /// + /// AxisName of the data to get. + /// Dummy data for chart in design-time. + internal IEnumerable GetDummyData(ChartValueType type) + { + string[] stringValues = { "abc1", "abc2", "abc3", "abc4", "abc5", "abc6" }; + DateTime[] dateValues = { DateTime.Now.Date, DateTime.Now.Date.AddDays(1), DateTime.Now.Date.AddDays(2), DateTime.Now.Date.AddDays(3), DateTime.Now.Date.AddDays(4), DateTime.Now.Date.AddDays(4) }; + + // Fill array of random data + if(_dummyDoubleValues == null) + { +#if !SQLRS_CONTROL + Random random2 = new Random(unchecked((int)DateTime.Now.Ticks + + this.Color.B + this.Color.G + this.Color.R)); +#else + int seed = 0; + for (int index = 0; index < this.Name.Length; index++) + seed += (int)this.Name[index]; + + Random random2 = new Random(seed); + +#endif + _dummyDoubleValues = new double[6]; + for(int valueIndex = 0; valueIndex < 6; valueIndex++) + { + _dummyDoubleValues[valueIndex] = random2.Next(10, 100); + } + } + + // Return dummy data + if(type == ChartValueType.DateTime || type == ChartValueType.Date || type == ChartValueType.DateTimeOffset) + { + return dateValues; + } + else if(type == ChartValueType.Time) + { + dateValues = new DateTime[] { DateTime.Now, DateTime.Now.AddMinutes(1), DateTime.Now.AddMinutes(2), DateTime.Now.AddMinutes(3), DateTime.Now.AddMinutes(4), DateTime.Now.AddMinutes(4) }; + return dateValues; + } + else if(type == ChartValueType.String) + { + return stringValues; + } + return _dummyDoubleValues; + } + + /// + /// Returns total of the Y values. + /// + /// Y values total. + internal double GetTotalYValue() + { + return this.GetTotalYValue(0); + } + + /// + /// Returns total of the Y values. + /// + /// Index of the Y value to use + /// Y values total. + internal double GetTotalYValue(int yValueIndex) + { + if(yValueIndex == 0) + { + // Total was already calculated + if(!double.IsNaN(_totalYvalue)) + { + return _totalYvalue; + } + + // Calculate total + _totalYvalue = 0; + foreach(DataPoint point in this.Points) + { + _totalYvalue += point.YValues[yValueIndex]; + } + + return _totalYvalue; + } + + // Check if series has enough Y values + if(yValueIndex >= this.YValuesPerPoint) + { + throw(new InvalidOperationException( SR.ExceptionDataSeriesYValueIndexNotExists(yValueIndex.ToString(CultureInfo.InvariantCulture), this.Name ) ) ); + } + + // Calculate total + double yValue = 0; + foreach(DataPoint point in this.Points) + { + yValue += point.YValues[yValueIndex]; + } + + return yValue; + } + + /// + /// Replaces predefined keyword inside the string with their values. + /// + /// Original string with keywords. + /// Modified string. + internal override string ReplaceKeywords(string strOriginal) + { + // Nothing to process + if(strOriginal == null || strOriginal.Length == 0) + return strOriginal; + + // Replace all "\n" strings with '\n' character + string result = strOriginal.Replace("\\n", "\n"); + + // #SERIESNAME - series name + result = result.Replace(KeywordName.SeriesName, this.Name); + result = result.Replace(KeywordName.Ser, this.Name); // #SER Depricated Keyword + + // #CUSTOMPROPERTY - one of the custom attributes by name + result = DataPoint.ReplaceCustomPropertyKeyword(result, this); + + // #TOTAL - total of Y values + result = ReplaceOneKeyword( + this.Chart, + this, + this.Tag, + ChartElementType.Nothing, + result, + KeywordName.Total, + SeriesValuesFormulaType.Total, + this.YValueType, + ""); + + // #AVG - total of Y values + result = ReplaceOneKeyword( + this.Chart, + this, + this.Tag, + ChartElementType.Nothing, + result, + KeywordName.Avg, + SeriesValuesFormulaType.Average, + this.YValueType, + ""); + + // #MAX - total of Y values + result = ReplaceOneKeyword( + this.Chart, + this, + this.Tag, + ChartElementType.Nothing, + result, + KeywordName.Max, + SeriesValuesFormulaType.Maximum, + this.YValueType, + ""); + + // #MIN - total of Y values + result = ReplaceOneKeyword( + this.Chart, + this, + this.Tag, + ChartElementType.Nothing, + result, + KeywordName.Min, + SeriesValuesFormulaType.Minimum, + this.YValueType, + ""); + + // #FIRST - total of Y values + result = ReplaceOneKeyword( + this.Chart, + this, + this.Tag, + ChartElementType.Nothing, + result, + KeywordName.First, + SeriesValuesFormulaType.First, + this.YValueType, + ""); + + // #LAST - total of Y values + result = ReplaceOneKeyword( + this.Chart, + this, + this.Tag, + ChartElementType.Nothing, + result, + KeywordName.Last, + SeriesValuesFormulaType.Last, + this.YValueType, + ""); + + + // #LEGENDTEXT - series name + result = result.Replace(KeywordName.LegendText, this.LegendText); + + return result; + } + + + /// + /// Helper function which replaces one keyword. + /// + /// Chart object reference. + /// Chart element type. + /// Object being formatted. + /// Additional object tag. + /// Original string. + /// Keyword to replace. + /// Formula used to calculate the value. + /// AxisName of value. + /// Default format string. + /// Result string. + internal string ReplaceOneKeyword( + Chart chart, + object obj, + object objTag, + ChartElementType elementType, + string strOriginal, + string keyword, + SeriesValuesFormulaType formulaType, + ChartValueType valueType, + string defaultFormat) + { + string result = strOriginal; + int keyIndex = -1; + while((keyIndex = result.IndexOf(keyword, StringComparison.Ordinal)) != -1) + { + int keyEndIndex = keyIndex + keyword.Length; + + // Get optional Y value index + int yValueIndex = 0; + if(result.Length > keyEndIndex + 1 && + result[keyEndIndex] == 'Y' && + char.IsDigit(result[keyEndIndex + 1])) + { + yValueIndex = int.Parse(result.Substring(keyEndIndex + 1, 1), CultureInfo.InvariantCulture); + keyEndIndex += 2; + } + + // Get optional format + string format = defaultFormat; + if(result.Length > keyEndIndex && result[keyEndIndex] == '{') + { + int formatEnd = result.IndexOf('}', keyEndIndex); + if(formatEnd == -1) + { + throw(new InvalidOperationException( SR.ExceptionDataSeriesKeywordFormatInvalid( result ))); + } + + format = result.Substring(keyEndIndex, formatEnd - keyEndIndex).Trim('{', '}'); + keyEndIndex = formatEnd + 1; + } + + // Remove keyword string (with optional format) + result = result.Remove(keyIndex, keyEndIndex - keyIndex); + + // Calculate value + double totalValue = this.GetTotalYValue(yValueIndex); + double keywordValue = 0.0; + switch(formulaType) + { + case(SeriesValuesFormulaType.Average): + { + if(this.Points.Count > 0) + { + keywordValue = totalValue / this.Points.Count; + } + break; + } + case(SeriesValuesFormulaType.First): + { + if(this.Points.Count > 0) + { + keywordValue = this.Points[0].YValues[yValueIndex]; + } + break; + } + case(SeriesValuesFormulaType.Last): + { + if(this.Points.Count > 0) + { + keywordValue = this.Points[this.Points.Count - 1].YValues[yValueIndex]; + } + break; + } + case(SeriesValuesFormulaType.Maximum): + { + if (this.Points.Count > 0) + { + keywordValue = double.MinValue; + foreach (DataPoint point in this.Points) + { + keywordValue = Math.Max(keywordValue, point.YValues[yValueIndex]); + } + } + break; + } + case(SeriesValuesFormulaType.Minimum): + { + if (this.Points.Count > 0) + { + keywordValue = double.MaxValue; + foreach (DataPoint point in this.Points) + { + keywordValue = Math.Min(keywordValue, point.YValues[yValueIndex]); + } + } + break; + } + case(SeriesValuesFormulaType.Total): + { + keywordValue = totalValue; + break; + } + } + + // Insert value + result = result.Insert(keyIndex, + ValueConverter.FormatValue(chart, obj, objTag, keywordValue, format, valueType, elementType)); + } + + return result; + } + + + /// + /// Helper function which replaces one keyword. + /// + /// Chart object reference. + /// Chart element type. + /// Object being formatted. + /// Additional object tag. + /// Original string. + /// Keyword to replace. + /// Value to replace with. + /// AxisName of value. + /// Default format string. + /// Result string. + internal string ReplaceOneKeyword(Chart chart, object obj, object objTag, ChartElementType elementType, string strOriginal, string keyword, double value, ChartValueType valueType, string defaultFormat) + + { + string result = strOriginal; + int keyIndex = -1; + while((keyIndex = result.IndexOf(keyword, StringComparison.Ordinal)) != -1) + { + // Get optional format + int keyEndIndex = keyIndex + keyword.Length; + string format = defaultFormat; + if(result.Length > keyEndIndex && result[keyEndIndex] == '{') + { + int formatEnd = result.IndexOf('}', keyEndIndex); + if(formatEnd == -1) + { + throw(new InvalidOperationException( SR.ExceptionDataSeriesKeywordFormatInvalid(result))); + } + + format = result.Substring(keyEndIndex, formatEnd - keyEndIndex).Trim('{', '}'); + keyEndIndex = formatEnd + 1; + } + + // Remove keyword string (with optional format) + result = result.Remove(keyIndex, keyEndIndex - keyIndex); + + // Insert value + result = result.Insert(keyIndex, + ValueConverter.FormatValue(chart, obj, objTag, value, format, valueType, elementType)); + } + + return result; + } + + + #endregion + + #region Points sorting methods + + /// + /// Sorts the points in the series. + /// + /// Sorting order. + /// Value used for sorting (X, Y, Y2, ...). + public void Sort(PointSortOrder pointSortOrder, string sortBy) + { + // Check arguments + if (sortBy==null) + throw new ArgumentNullException("sortBy"); + + // Sort items using data points comparer class + DataPointComparer comparer = new DataPointComparer(this, pointSortOrder, sortBy); + this.Points.ItemList.Sort(comparer); + + // Invalidate chart area only + this.Invalidate(true, false); + } + + /// + /// Sorts the points in the series. + /// + /// Sorting order. + public void Sort(PointSortOrder pointSortOrder) + { + Sort(pointSortOrder, "Y"); + } + + /// + /// Sorts the points in the series using IComparer interface. + /// + /// IComparer interface. + public void Sort(IComparer comparer) + { + // Check arguments + if (comparer == null) + throw new ArgumentNullException("comparer"); + + // Sort points + this.Points.ItemList.Sort(comparer); + + // Invalidate chart area only + this.Invalidate(true, false); + + } + + #endregion + + #region Series preparation/cleanup for drawing + + /// + /// Moves the position markers. + /// + /// From series. + /// To series. + internal static void MovePositionMarkers(Series fromSeries, Series toSeries) + { + foreach (DataPoint dp in fromSeries.Points) + { + if (dp.IsCustomPropertySet("OriginalPointIndex")) + { + int index = -1; + if (Int32.TryParse(dp["OriginalPointIndex"], NumberStyles.Integer, CultureInfo.InvariantCulture, out index)) + { + if (index > -1 && index < toSeries.Points.Count) + { + toSeries.Points[index].positionRel = dp.positionRel; + } + } + } + } + } + + /// + /// Called after the series was drawn. + /// + /// Site interface of the control. + /// True if series was removed from collection. + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This parameter is used when compiling for the Microsoft version of Chart")] + internal bool UnPrepareData(ISite controlSite) + { + bool result = false; + + + + + // Process Renko chart type data calculations + if(RenkoChart.UnPrepareData(this)) + { + result = true; + } + + // Process ThreeLineBreak chart type data calculations + if(ThreeLineBreakChart.UnPrepareData(this)) + { + result = true; + } + + // Process Kagi chart type data calculations + if(KagiChart.UnPrepareData(this)) + { + result = true; + } + + // Process PointAndFigure chart type data calculations + if(PointAndFigureChart.UnPrepareData(this)) + { + result = true; + } + + // Undo all changes done for the collected slice support + if(PieChart.UnPrepareData(this)) + { + result = true; + } + + + // Reset original value type which was temp. set to String + if(_isXValueIndexed) + { + _xValueType = indexedXValueType; + } + + // Reset auro values only at design time + bool reset = false; + if(controlSite != null && controlSite.DesignMode) + { + reset = true; + } + + ResetAutoValues(reset); + + return result; + } + + /// + /// Reset auto calculated series values. + /// + internal void ResetAutoValues() + { + ResetAutoValues(true); + } + + /// + /// Reset auto calculated series values. + /// + /// Indicates that value types should be reset. + internal void ResetAutoValues(bool reset) + { + // If temporary data attribute is set - remove all data points + if(this.IsCustomPropertySet("TempDesignData")) + { + this.DeleteCustomProperty("TempDesignData"); + + // save the fake DataPoints for selector service + bool savePoints = true; + if (this.Chart != null && !this.Chart.IsDesignMode()) + { + savePoints = false; + } + if ( savePoints ) + { + fakeDataPoints.Clear(); + foreach (DataPoint p in this.Points) + { + fakeDataPoints.Add(p); + } + } + + this.Points.Clear(); + } + + // Reset series color + if(this.tempColorIsSet) + { + this.tempColorIsSet = false; + this.Color = Color.Empty; + } + + // Reset series marker + if(this.tempMarkerStyleIsSet) + { + this.tempMarkerStyleIsSet = false; + this.MarkerStyle = MarkerStyle.None; + } + + // Reset points color + foreach(DataPoint dataPoint in _points) + { + if(dataPoint.tempColorIsSet) + { + dataPoint.Color = Color.Empty; + } + } + + // Reset value type to Auto (if not Serializing data) + if(reset) + { + if(this.Chart == null || this.Chart.serializing == false) + { + if(autoXValueType) + { + _xValueType = ChartValueType.Auto; + autoXValueType = false; + } + if(autoYValueType) + { + _yValueType = ChartValueType.Auto; + autoYValueType = false; + } + } + } + } + + /// + /// Called just before the data from the series to be used to perform these operations: + /// - apply palette colors to the data points + /// - fill empty data points + /// - provide fake data in design mode + /// - retrieving data from the DataSource + /// + /// If true each data point will be assigned a color from the palette (if it's set) + internal void PrepareData(bool applyPaletteColors) + { + if(!this.IsVisible()) + { + return; + } + + // Series chart area name can be empty or a valid area name + Chart.ChartAreas.VerifyNameReference(this.ChartArea); + + // Check if sereis data points have required number of Y values + if(this.Points.Count > 0 && this.Points[0].YValues.Length < this.YValuesPerPoint) + { + // Resize data points Y value(s) arrays + foreach(DataPoint dp in this.Points) + { + dp.ResizeYValueArray(this.YValuesPerPoint); + } + } + + // Get series data source + bool fillTempData = false; + if(this.Points.Count == 0) + { + // If there is no points defined in design-time + if(Chart.IsDesignMode()) + { + fillTempData = true; + } + else if(this.IsCustomPropertySet("UseDummyData")) + { + if(String.Compare(this["UseDummyData"], "True", StringComparison.OrdinalIgnoreCase) == 0) + { + fillTempData = true; + } + } + } + + // Create dummy data only if there was no points + if(fillTempData) + { + if(this.IsXValueDateTime() || _xValueType == ChartValueType.String) + { + this.Points.DataBindXY(GetDummyData(_xValueType), GetDummyData(_yValueType)); + } + else + { + double[] xValues = new double[] { 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 }; + if(this.ChartType == SeriesChartType.Polar) + { + xValues = new double[] { 0.0, 45.0, 115.0, 145.0, 180.0, 220.0 }; + } + this.Points.DataBindXY(xValues, GetDummyData(_yValueType)); + } + + // If point has more than one Y value - copy the data from first value + if(this.YValuesPerPoint > 1) + { + foreach(DataPoint point in this.Points) + { + for(int valueIndex = 1; valueIndex < this.YValuesPerPoint; valueIndex++) + { + point.YValues[valueIndex] = point.YValues[0]; + } + + if(this.YValuesPerPoint >= 2) + { + point.YValues[1] = point.YValues[0] / 2 - 1; + } + + if(this.YValuesPerPoint >= 4) + { + point.YValues[2] = point.YValues[1] + (point.YValues[0] - point.YValues[1]) / 3; + point.YValues[3] = point.YValues[2] + (point.YValues[0] - point.YValues[1]) / 3; + } + + if(this.YValuesPerPoint >= 6) + { + point.YValues[4] = point.YValues[2] + (point.YValues[3] - point.YValues[2]) / 2; + point.YValues[5] = point.YValues[2] + (point.YValues[3] - point.YValues[2]) / 3; + } + + } + } + + // Set data series attribute that data is temporary + this["TempDesignData"] = "true"; + } + + // If value type was not Auto detected - set it to double + if(_xValueType == ChartValueType.Auto) + { + _xValueType = ChartValueType.Double; + autoXValueType = true; + } + if(_yValueType == ChartValueType.Auto) + { + _yValueType = ChartValueType.Double; + autoYValueType = true; + } + + // Use data point index as X value + indexedXValueType = _xValueType; + + // Reset total Y value + _totalYvalue = double.NaN; + + // Supress zero and negative values with logarithmic axis exceptions + if(this.Chart != null && this.Chart.chartPicture.SuppressExceptions) + { + // Get series axis + Axis axisY = this.Chart.ChartAreas[this.ChartArea].GetAxis(AxisName.Y, this.YAxisType, this.YSubAxisName); + + foreach(DataPoint point in this.Points) + { + for(int yValueIndex = 0; yValueIndex < point.YValues.Length; yValueIndex++) + { + if(axisY.IsLogarithmic) + { + // Look for Y values less or equal to Zero + if(point.YValues[yValueIndex] <= 0.0) + { + point.YValues[yValueIndex] = 1.0; + point.IsEmpty = true; + } + } + + // Check All Y values for NaN + if(double.IsNaN(point.YValues[yValueIndex])) + { + point.YValues[yValueIndex] = 0.0; + point.IsEmpty = true; + } + } + } + } + + + + // Process Error Bar chart type data linking and calculations + ErrorBarChart.GetDataFromLinkedSeries(this); + ErrorBarChart.CalculateErrorAmount(this); + + // Process Box chart type data calculations + BoxPlotChart.CalculateBoxPlotFromLinkedSeries(this); + + // Process Renko chart type data calculations + RenkoChart.PrepareData(this); + + // Process ThreeLineBreak chart type data calculations + ThreeLineBreakChart.PrepareData(this); + + // Process Kagi chart type data calculations + KagiChart.PrepareData(this); + + // Process PointAndFigure chart type data calculations + PointAndFigureChart.PrepareData(this); + + // Check if Collected slice should be displayed in Pie/Doughnut charts + PieChart.PrepareData(this); + + + // Apply palette colors to the data points + if (applyPaletteColors) + { + this.ApplyPaletteColors(); + } + } + + #endregion + + #region Series Properties + + /// + /// Data series name. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_Name"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public override string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + + /// + /// Member of the chart data source used to data bind to the X value of the series. + /// + [ + + SRCategory("CategoryAttributeDataSource"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_ValueMemberX"), + DefaultValue(""), + #if !Microsoft_CONTROL + TypeConverter(Editors.SeriesDataFieldXConvertor.Convertor) + #else + TypeConverter(typeof(SeriesDataSourceMemberConverter)) + #endif + ] + public string XValueMember + { + get + { + return _dataSourceXMember; + } + set + { + if(value == "(none)") + { + _dataSourceXMember = String.Empty; + } + else + { + _dataSourceXMember = value; + } + + // Reset data bound flag + if(this.Common!=null && this.Common.ChartPicture!=null) + { + this.Common.ChartPicture.boundToDataSource = false; + } + + } + } + + /// + /// Members of the chart data source used to data bind to the Y values of the series. + /// + [ + + SRCategory("CategoryAttributeDataSource"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_ValueMembersY"), + DefaultValue(""), + #if !Microsoft_CONTROL + TypeConverter(Editors.SeriesDataFieldYConvertor.Convertor), + Editor(Editors.SeriesDataFieldValueAxisUITypeEditor.Editor, Editors.SeriesDataFieldValueAxisUITypeEditor.Base) + #else + TypeConverter(typeof(SeriesDataSourceMemberConverter)), + Editor(Editors.SeriesDataSourceMemberValueAxisUITypeEditor.Editor, Editors.SeriesDataSourceMemberValueAxisUITypeEditor.Base) + #endif + ] + public string YValueMembers + { + get + { + return _dataSourceYMembers; + } + set + { + if(value == "(none)") + { + _dataSourceYMembers = String.Empty; + } + else + { + _dataSourceYMembers = value; + } + + // Reset data bound flag + if(this.Common != null && this.Common.ChartPicture!=null) + { + this.Common.ChartPicture.boundToDataSource = false; + } + + } + } + + + /// + /// Name of the Chart legend used by the series. + /// + [ + SRCategory("CategoryAttributeLegend"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_Legend"), + DefaultValue(""), + TypeConverter(typeof(SeriesLegendNameConverter)) + ] + public string Legend + { + get + { + return _legend; + } + set + { + if (value != _legend) + { + if (Chart != null && Chart.Legends != null) + { + Chart.Legends.VerifyNameReference(value); + } + _legend = value; + this.Invalidate(false, true); + } + } + } + + /// + /// The value type of the X axis. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_XValueType"), + DefaultValue(ChartValueType.Auto), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartValueType XValueType + { + get + { + return _xValueType; + } + set + { + _xValueType = value; + this.autoXValueType = false; + this.Invalidate(true, false); + } + } + + /// + /// Indicates whether a data point index (1,2,...) will be used for the X value. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_XValueIndexed"), + DefaultValue(false), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsXValueIndexed + { + get + { + return _isXValueIndexed; + } + set + { + _isXValueIndexed = value; + this.Invalidate(true, false); + } + } + + /// + /// The value type of the Y axis. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_YValueType"), + DefaultValue(ChartValueType.Auto), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + TypeConverter(typeof(SeriesYValueTypeConverter)), + ] + public ChartValueType YValueType + { + get + { + return _yValueType; + } + set + { + _yValueType = value; + this.autoYValueType = false; + this.Invalidate(true, false); + } + } + + /// + /// Number of Y values stored for each Data Point. + /// + [ + + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_YValuesPerPoint"), + DefaultValue(1), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int YValuesPerPoint + { + get + { + // If number of Y value(s) is not set - get one from the chart type + if(this._checkPointsNumber && this.ChartTypeName.Length > 0 && this.Common != null) + { + _checkPointsNumber = false; + ChartTypeRegistry chartTypeRegistry = this.Common.ChartTypeRegistry; + IChartType chartType = chartTypeRegistry.GetChartType(this.ChartTypeName); + if(chartType.YValuesPerPoint > _yValuesPerPoint) + { + _yValuesPerPoint = chartType.YValuesPerPoint; + + // Resize Y value(s) array of data points + if(_points.Count > 0) + { + // Resize data points Y value(s) arrays + foreach(DataPoint dp in _points) + { + dp.ResizeYValueArray(_yValuesPerPoint); + } + } + } + } + + return _yValuesPerPoint; + } + set + { + // Check if argument is in range + if(value < 1 || value > 32) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionDataSeriesYValueNumberInvalid)); + } + + _checkPointsNumber = true; + + // Resize Y value(s) array of data points + if(_points.Count > 0) + { + // Resize data points Y value(s) arrays + foreach(DataPoint dp in _points) + { + dp.ResizeYValueArray(value); + } + } + + _yValuesPerPoint = value; + this.Invalidate(true, false); + } + } + + /// + /// Collection of data points in the series. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_Points"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + Themeable(false), + PersistenceMode(PersistenceMode.InnerProperty), +#endif + Editor(Editors.DataPointCollectionEditor.Editor, Editors.DataPointCollectionEditor.Base) + ] + public DataPointCollection Points + { + get + { + return _points; + } + } + + /// + /// Default properties of an empty data point. + /// + [ + SRCategory("CategoryAttributeEmptyPoints"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_EmptyPointStyle"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + + ] + public DataPointCustomProperties EmptyPointStyle + { + get + { + return _emptyPointCustomProperties; + } + set + { + if (value.series == null && _emptyPointCustomProperties.series != null) + { + value.series = _emptyPointCustomProperties.series; + } + _emptyPointCustomProperties = value; + _emptyPointCustomProperties.pointCustomProperties = false; + _emptyPointCustomProperties.SetDefault(false); + _emptyPointCustomProperties.pointCustomProperties = true; + _emptyPointCustomProperties.Parent = this; + this.Invalidate(true, false); + } + } + + /// + /// Color palette to use. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributePalette"), + DefaultValue(ChartColorPalette.None), + Editor(Editors.ColorPaletteEditor.Editor, Editors.ColorPaletteEditor.Base) + ] + public ChartColorPalette Palette + { + get + { + return _colorPalette; + } + set + { + _colorPalette = value; + this.Invalidate(true, true); + } + } + + /// + /// Specify how often to display data point markers. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_MarkerStep"), + DefaultValue(1) + ] + public int MarkerStep + { + get + { + return _markersStep; + } + set + { + if(value <= 0) + { + throw(new ArgumentException( SR.ExceptionMarkerStepNegativeValue, "value")); + } + _markersStep = value; + this.Invalidate(true, false); + } + } + + /// + /// Shadow offset of series. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + + SRDescription("DescriptionAttributeShadowOffset"), + DefaultValue(0) + ] + public int ShadowOffset + { + get + { + return _shadowOffset; + } + set + { + _shadowOffset = value; + this.Invalidate(true, true); + } + } + + /// + /// Shadow color of series. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "128,0,0,0"), + SRDescription("DescriptionAttributeShadowColor"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color ShadowColor + { + get + { + return _shadowColor; + } + set + { + _shadowColor = value; + this.Invalidate(true, true); + } + } + + +#if SUBAXES + + /// + /// Name of the Y sub-axis this series is attached to. + /// + [ + SRCategory("CategoryAttributeAxes"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_YSubAxisName"), + DefaultValue("") + ] + public string YSubAxisName + { + get + { + return this._ySubAxisName; + } + set + { + this._ySubAxisName = value; + this.Invalidate(true, false); + } + } + + /// + /// Name of the X sub-axis this series is attached to. + /// + [ + + SRCategory("CategoryAttributeAxes"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_XSubAxisName"), + DefaultValue("") + ] + public string XSubAxisName + { + get + { + return this._xSubAxisName; + } + set + { + this._xSubAxisName = value; + this.Invalidate(true, false); + } + } + +#else // SUBAXES + /// + /// Name of the Y sub-axis this series is attached to. + /// + [ + SRCategory("CategoryAttributeAxes"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_YSubAxisName"), + DefaultValue(""), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value") + ] + internal string YSubAxisName + { + get + { + return string.Empty; + } + set + { + } + } + + /// + /// Name of the X sub-axis this series is attached to. + /// + [ + SRCategory("CategoryAttributeAxes"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_XSubAxisName"), + DefaultValue(""), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value") + ] + internal string XSubAxisName + { + get + { + return string.Empty; + } + set + { + } + } +#endif // SUBAXES + + /// + /// Axis type of horizontal axes. + /// + [ + SRCategory("CategoryAttributeAxes"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_XAxisType"), + DefaultValue(AxisType.Primary) + ] + public AxisType XAxisType + { + get + { + return _xAxisType; + } + set + { + _xAxisType = value; + this.Invalidate(true, false); + } + } + + /// + /// Axis type of vertical axes. + /// + [ + SRCategory("CategoryAttributeAxes"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_YAxisType"), + DefaultValue(AxisType.Primary) + ] + public AxisType YAxisType + { + get + { + return _yAxisType; + } + set + { + _yAxisType = value; + this.Invalidate(true, false); + } + } + + /// + /// Gets or sets a flag which indicates whether the series is enabled. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeSeries_Enabled"), + NotifyParentPropertyAttribute(true), + ParenthesizePropertyNameAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool Enabled + { + get + { + return _enabled; + } + set + { + _enabled = value; + this.Invalidate(true, true); + } + } + + /// + /// Chart type used to draw the series. + /// + [ + SRCategory("CategoryAttributeChart"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_Type"), + DefaultValue(SeriesChartType.Column), + RefreshProperties(RefreshProperties.All), + Editor(Editors.ChartTypeEditor.Editor, Editors.ChartTypeEditor.Base) + ] + public SeriesChartType ChartType + { + get + { + SeriesChartType type = SeriesChartType.Column; + if(String.Compare(this.ChartTypeName, ChartTypeNames.OneHundredPercentStackedArea, StringComparison.OrdinalIgnoreCase) == 0) + { + type = SeriesChartType.StackedArea100; + } + else if (String.Compare(this.ChartTypeName, ChartTypeNames.OneHundredPercentStackedBar, StringComparison.OrdinalIgnoreCase) == 0) + { + type = SeriesChartType.StackedBar100; + } + else if (String.Compare(this.ChartTypeName, ChartTypeNames.OneHundredPercentStackedColumn, StringComparison.OrdinalIgnoreCase) == 0) + { + type = SeriesChartType.StackedColumn100; + } + else + { + try + { + type = (SeriesChartType)Enum.Parse(typeof(SeriesChartType), this.ChartTypeName, true); + } + catch (ArgumentException) + { + } + } + + return type; + } + set + { + this.ChartTypeName = Series.GetChartTypeName(value); + } + } + + /// + /// Chart type used to draw the series. + /// + [ + Browsable(false), + EditorBrowsableAttribute(EditorBrowsableState.Never), + SRCategory("CategoryAttributeChart"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_Type"), + DefaultValue(ChartTypeNames.Column), + TypeConverter(typeof(ChartTypeConverter)), + Editor(Editors.ChartTypeEditor.Editor, Editors.ChartTypeEditor.Base), + RefreshProperties(RefreshProperties.All), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) + ] + public string ChartTypeName + { + get + { + return _chartType; + } + set + { + if(_chartType != value && value.Length > 0) + { + if(Common != null) + { + ChartTypeRegistry chartTypeRegistry = Common.ChartTypeRegistry; + if(chartTypeRegistry != null) + { + IChartType type = chartTypeRegistry.GetChartType(value); + if(_yValuesPerPoint < type.YValuesPerPoint) + { + // Set minimum Y values number for the chart type + _yValuesPerPoint = type.YValuesPerPoint; + + // Resize Y value(s) array of data points + if(_points.Count > 0) + { + // Resize data points Y value(s) arrays + foreach(DataPoint dp in _points) + { + dp.ResizeYValueArray(_yValuesPerPoint); + } + } + } +#if Microsoft_CONTROL + // Refresh Minimum and Maximum from data + // after recalc and set data + if(Chart != null && Chart.chartPicture != null) + { + Chart.chartPicture.ResetMinMaxFromData(); + } +#endif + } + } + } + + _chartType = value; + + this.Invalidate(false, true); + } + } + + + /// + /// Chart area in which this series is drawn. + /// + [ + SRCategory("CategoryAttributeChart"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_ChartArea"), + DefaultValue(""), + TypeConverter(typeof(SeriesAreaNameConverter)) + ] + public string ChartArea + { + get + { + return _chartArea; + } + set + { + if (value != _chartArea) + { + if (Chart != null && Chart.ChartAreas != null) + { + Chart.ChartAreas.VerifyNameReference(value); + } + _chartArea = value; + this.Invalidate(false, true); + } + } + } +/* + /// + /// If set to true, each data point of the series will use a random color from the palette. + /// + [ + SRCategory("CategoryAttributeChart"), + Bindable(true), + SRDescription("DescriptionAttributeDataSeriesGroupID"), + PersistenceModeAttribute(PersistenceMode.Attribute), + DefaultValue("") + ] + public string GroupID + { + get + { + return groupID; + } + set + { + groupID = value; + } + } +*/ + /// + /// Text of X axis label. + /// + [ + Browsable(false), + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeAxisLabel"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + override public string AxisLabel + { + get + { + return base.AxisLabel; + } + set + { + base.AxisLabel = value; + this.Invalidate(true, false); + } + } + + + + /// + /// Style of the SmartLabel. + /// + [ + Browsable(true), + SRCategory("CategoryAttributeLabel"), + Bindable(true), + SRDescription("DescriptionAttributeSeries_SmartLabels"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + ] + public SmartLabelStyle SmartLabelStyle + { + get + { + return _smartLabelStyle; + } + set + { + value.chartElement = this; + _smartLabelStyle = value; + this.Invalidate(false, false); + } + } + + + /// + /// Series font cache is reused by points. + /// + /// The font cache. + internal FontCache FontCache + { + get { return _fontCache; } + } + + + #endregion + + #region Invalidating method + + /// + /// Invalidate chart or just a chart area and/or legend when collection is changed + /// + /// Invalidate chart area only. + /// Invalidate legend area only. + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This parameter is used when compiling for the Microsoft version of Chart")] + internal void Invalidate(bool invalidateAreaOnly, bool invalidateLegend) + { +#if Microsoft_CONTROL + + + if(Chart != null) + { + if(!invalidateAreaOnly) + { + this.Invalidate(); + } + else + { + // Invalidate one chart area (area with this name may not exist) + try + { + Chart.ChartAreas[this.ChartArea].Invalidate(); + } + catch(ArgumentException) + { + // occurs if the chart area is not found in the collection + } + + // Invalidate legend + if(invalidateLegend && Chart.Legends.IndexOf(this.Legend) >= 0) + { + Chart.Legends[this.Legend].Invalidate(true); + } + } + } +#endif + } + + #endregion + + #region Series Enumeration + + + + /// + /// Series values formula type used in the keywords + /// + internal enum SeriesValuesFormulaType + { + Total, + Average, + Maximum, + Minimum, + First, + Last + } + + + + #endregion // Series Enumeration + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_fontCache != null) + { + _fontCache.Dispose(); + _fontCache = null; + } + if (this._emptyPointCustomProperties != null) + { + this._emptyPointCustomProperties.Dispose(); + this._emptyPointCustomProperties = null; + } + if (this._points != null) + { + this._points.Dispose(); + this._points = null; + } + if (this.fakeDataPoints != null) + { + this.fakeDataPoints.Dispose(); + this.fakeDataPoints = null; + } + } + base.Dispose(disposing); + } + + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/EditorNames.cs b/System.Web.DataVisualization/Common/EditorNames.cs new file mode 100644 index 000000000..e6c16bca3 --- /dev/null +++ b/System.Web.DataVisualization/Common/EditorNames.cs @@ -0,0 +1,263 @@ +using System; +using System.Collections.Generic; +using System.Text; + +#if WINFORMS_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + internal static class Editors + { + #region Assembly configuration strings + +#if WINFORMS_CONTROL + private const string AssemblyName = "System.Windows.Forms.DataVisualization.Design"; + internal const string Version = ThisAssembly.Version; + private const string Culture = "neutral"; + private const string PublicKeyToken = AssemblyRef.SharedLibPublicKeyToken; + private const string Namespace = "System.Windows.Forms.Design.DataVisualization.Charting"; +#else + private const string AssemblyName = "System.Web.DataVisualization.Design"; + internal const string Version = ThisAssembly.Version; + private const string Culture = "neutral"; + private const string PublicKeyToken = AssemblyRef.SharedLibPublicKeyToken; + private const string Namespace = "System.Web.UI.Design.DataVisualization.Charting"; +#endif + #endregion Assembly configuration strings + + public const string UITypeEditorBase = "System.Drawing.Design.UITypeEditor, System.Drawing, Version=" + Version + ", Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken; + + internal static class ChartColorEditor + { + private const string ClassName = "ChartColorEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class FlagsEnumUITypeEditor + { + private const string ClassName = "FlagsEnumUITypeEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class SeriesDataSourceMemberValueAxisUITypeEditor + { + private const string ClassName = "SeriesDataSourceMemberValueAxisUITypeEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class SeriesDataFieldValueAxisUITypeEditor + { + private const string ClassName = "SeriesDataFieldValueAxisUITypeEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class ChartTypeEditor + { + private const string ClassName = "ChartTypeEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class ChartCollectionEditor + { + private const string ClassName = "ChartCollectionEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class DataPointCollectionEditor + { + private const string ClassName = "DataPointCollectionEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class SeriesCollectionEditor + { + private const string ClassName = "SeriesCollectionEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class AreaCollectionEditor + { + private const string ClassName = "AreaCollectionEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class AnnotationCollectionEditor + { + private const string ClassName = "AnnotationCollectionEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class AnchorPointUITypeEditor + { + private const string ClassName = "AnchorPointUITypeEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class AnnotationAxisUITypeEditor + { + private const string ClassName = "AnnotationAxisUITypeEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class ImageValueEditor + { + private const string ClassName = "ImageValueEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class HatchStyleEditor + { + private const string ClassName = "HatchStyleEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class UITypeEditorProxy + { + private const string ClassName = "UITypeEditorProxy"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class UITypeEditorProxyEx + { + private const string ClassName = "UITypeEditorProxyEx"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class ColorPaletteEditor + { + private const string ClassName = "ColorPaletteEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class UIPropertyEditor + { + private const string ClassName = "UIPropertyEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class MarkerStyleEditor + { + private const string ClassName = "MarkerStyleEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class GradientEditor + { + private const string ClassName = "GradientEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class AxesArrayEditor + { + private const string ClassName = "AxesArrayEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class LegendItemCollectionEditor + { + private const string ClassName = "LegendItemCollectionEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class LegendCollectionEditor + { + private const string ClassName = "LegendCollectionEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class LegendCellColumnCollectionEditor + { + private const string ClassName = "LegendCellColumnCollectionEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class LegendCellCollectionEditor + { + private const string ClassName = "LegendCellCollectionEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class KeywordsStringEditor + { + private const string ClassName = "KeywordsStringEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class UrlValueEditor + { + private const string ClassName = "UrlValueEditor"; + public const string Editor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = UITypeEditorBase; + } + + internal static class SeriesDataFieldXConvertor + { + private const string ClassName = "SeriesDataFieldXConvertor"; + public const string Convertor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + } + + internal static class SeriesDataFieldYConvertor + { + private const string ClassName = "SeriesDataFieldYConvertor"; + public const string Convertor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + } + + + internal static class DataPointCustomPropertiesConverter + { + private const string ClassName = "DataPointCustomPropertiesConverter"; + public const string Convertor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + } + + internal static class DataPointConverter + { + private const string ClassName = "DataPointConverter"; + public const string Convertor = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + } + + + #region Designers + + public const string ChartWinDesigner = Namespace + ".ChartWinDesigner, " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + + internal static class ChartWinDesignerSerializer + { + private const string ClassName = "ChartWinDesignerSerializer"; + public const string Designer = Namespace + "." + ClassName + ", " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + public const string Base = "System.ComponentModel.Design.Serialization.CodeDomSerializer, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; + } + + public const string ChartWebDesigner = Namespace + ".ChartWebDesigner, " + AssemblyName + ", Version=" + Version + ", Culture=" + Culture + ", PublicKeyToken=" + PublicKeyToken; + + + #endregion Designers + } +} diff --git a/System.Web.DataVisualization/Common/Formulas/FormulaHelpers.cs b/System.Web.DataVisualization/Common/Formulas/FormulaHelpers.cs new file mode 100644 index 000000000..bcc888202 --- /dev/null +++ b/System.Web.DataVisualization/Common/Formulas/FormulaHelpers.cs @@ -0,0 +1,1636 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=victark, alexgor, deliant +using System; +using System.Collections.Generic; +using System.Text; +using System.Globalization; +using System.Diagnostics; + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting.Formulas +#else +namespace System.Web.UI.DataVisualization.Charting.Formulas +#endif +{ + + #region class FormulaHelper + /// + /// Formula helper is a static utility class implementing common formula related routines. + /// + internal static class FormulaHelper + { + #region Static + /// + /// Gets the formula info instance. + /// + /// The formula. + /// FomulaInfo instance + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")] + internal static FormulaInfo GetFormulaInfo(FinancialFormula formula) + { + switch (formula) + { + //Price indicators + case FinancialFormula.MovingAverage: + return new MovingAverageFormulaInfo(); + case FinancialFormula.ExponentialMovingAverage: + return new ExponentialMovingAverageFormulaInfo(); + case FinancialFormula.WeightedMovingAverage: + return new WeightedMovingAverageFormulaInfo(); + case FinancialFormula.TriangularMovingAverage: + return new TriangularMovingAverageFormulaInfo(); + case FinancialFormula.TripleExponentialMovingAverage: + return new TripleExponentialMovingAverageFormulaInfo(); + case FinancialFormula.BollingerBands: + return new BollingerBandsFormulaInfo(); + case FinancialFormula.TypicalPrice: + return new TypicalPriceFormulaInfo(); + case FinancialFormula.WeightedClose: + return new WeightedCloseFormulaInfo(); + case FinancialFormula.MedianPrice: + return new MedianPriceFormulaInfo(); + case FinancialFormula.Envelopes: + return new EnvelopesFormulaInfo(); + case FinancialFormula.StandardDeviation: + return new StandardDeviationFormulaInfo(); + + // Oscilators + case FinancialFormula.ChaikinOscillator: + return new ChaikinOscillatorFormulaInfo(); + case FinancialFormula.DetrendedPriceOscillator: + return new DetrendedPriceOscillatorFormulaInfo(); + case FinancialFormula.VolatilityChaikins: + return new VolatilityChaikinsFormulaInfo(); + case FinancialFormula.VolumeOscillator: + return new VolumeOscillatorFormulaInfo(); + case FinancialFormula.StochasticIndicator: + return new StochasticIndicatorFormulaInfo(); + case FinancialFormula.WilliamsR: + return new WilliamsRFormulaInfo(); + + // General technical indicators + case FinancialFormula.AverageTrueRange: + return new AverageTrueRangeFormulaInfo(); + case FinancialFormula.EaseOfMovement: + return new EaseOfMovementFormulaInfo(); + case FinancialFormula.MassIndex: + return new MassIndexFormulaInfo(); + case FinancialFormula.Performance: + return new PerformanceFormulaInfo(); + case FinancialFormula.RateOfChange: + return new RateOfChangeFormulaInfo(); + case FinancialFormula.RelativeStrengthIndex: + return new RelativeStrengthIndexFormulaInfo(); + case FinancialFormula.MovingAverageConvergenceDivergence: + return new MovingAverageConvergenceDivergenceFormulaInfo(); + case FinancialFormula.CommodityChannelIndex: + return new CommodityChannelIndexFormulaInfo(); + + // Forecasting + case FinancialFormula.Forecasting: + return new ForecastingFormulaInfo(); + + // Volume Indicators + case FinancialFormula.MoneyFlow: + return new MoneyFlowFormulaInfo(); + case FinancialFormula.PriceVolumeTrend: + return new PriceVolumeTrendFormulaInfo(); + case FinancialFormula.OnBalanceVolume: + return new OnBalanceVolumeFormulaInfo(); + case FinancialFormula.NegativeVolumeIndex: + return new NegativeVolumeIndexFormulaInfo(); + case FinancialFormula.PositiveVolumeIndex: + return new PositiveVolumeIndexFormulaInfo(); + case FinancialFormula.AccumulationDistribution: + return new AccumulationDistributionFormulaInfo(); + + default: + Debug.Fail(String.Format(CultureInfo.InvariantCulture, "{0} case is not defined", formula)); + return null; + } + } + + /// + /// Gets the data fields of the specified chart type. + /// + /// Type of the chart. + /// Data fields + internal static IList GetDataFields(SeriesChartType chartType) + { + switch (chartType) + { + case SeriesChartType.BoxPlot: + return new DataField[] { + DataField.LowerWisker, DataField.UpperWisker, + DataField.LowerBox, DataField.UpperBox, + DataField.Average, DataField.Median }; + case SeriesChartType.Bubble: + return new DataField[] { + DataField.Bubble, DataField.BubbleSize }; + case SeriesChartType.Candlestick: + case SeriesChartType.Stock: + return new DataField[] { + DataField.High, DataField.Low, + DataField.Open, DataField.Close }; + case SeriesChartType.ErrorBar: + return new DataField[] { + DataField.Center, + DataField.LowerError, DataField.UpperError}; + case SeriesChartType.RangeBar: + case SeriesChartType.Range: + case SeriesChartType.RangeColumn: + case SeriesChartType.SplineRange: + return new DataField[] { + DataField.Top, DataField.Bottom }; + default: + return new DataField[] { DataField.Y }; + } + } + + /// + /// Gets the default type of the chart associated with this field name. + /// + /// The field. + /// + internal static SeriesChartType GetDefaultChartType(DataField field) + { + switch (field) + { + default: + case DataField.Y: + return SeriesChartType.Line; + case DataField.LowerWisker: + case DataField.UpperWisker: + case DataField.LowerBox: + case DataField.UpperBox: + case DataField.Average: + case DataField.Median: + return SeriesChartType.BoxPlot; + case DataField.Bubble: + case DataField.BubbleSize: + return SeriesChartType.Bubble; + case DataField.High: + case DataField.Low: + case DataField.Open: + case DataField.Close: + return SeriesChartType.Stock; + case DataField.Center: + case DataField.LowerError: + case DataField.UpperError: + return SeriesChartType.ErrorBar; + case DataField.Top: + case DataField.Bottom: + return SeriesChartType.Range; + } + } + + /// + /// Maps formula data field to a chart type specific data field. + /// + /// Type of the chart. + /// The formula field to be mapped. + /// The series field + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + internal static DataField? MapFormulaDataField(SeriesChartType chartType, DataField formulaField) + { + switch (formulaField) + { + case DataField.Top: + case DataField.High: + switch (chartType) + { + default: return null; + case SeriesChartType.BoxPlot: return DataField.UpperBox; + case SeriesChartType.Candlestick: + case SeriesChartType.Stock: return DataField.High; + case SeriesChartType.ErrorBar: return DataField.UpperError; + case SeriesChartType.RangeBar: + case SeriesChartType.Range: + case SeriesChartType.RangeColumn: + case SeriesChartType.SplineRange: return DataField.Top; + } + + case DataField.Bottom: + case DataField.Low: + switch (chartType) + { + default: return null; + case SeriesChartType.BoxPlot: return DataField.LowerBox; + case SeriesChartType.Candlestick: + case SeriesChartType.Stock: return DataField.Low; + case SeriesChartType.ErrorBar: return DataField.LowerError; + case SeriesChartType.RangeBar: + case SeriesChartType.Range: + case SeriesChartType.RangeColumn: + case SeriesChartType.SplineRange: return DataField.Bottom; + } + + case DataField.Open: + switch (chartType) + { + default: return null; + case SeriesChartType.BoxPlot: return DataField.Average; + case SeriesChartType.Candlestick: + case SeriesChartType.Stock: return DataField.Open; + case SeriesChartType.ErrorBar: return DataField.Center; + case SeriesChartType.RangeBar: + case SeriesChartType.Range: + case SeriesChartType.RangeColumn: + case SeriesChartType.SplineRange: return DataField.Bottom; + } + + case DataField.Close: + case DataField.Y: + switch (chartType) + { + default: return DataField.Y; + case SeriesChartType.BoxPlot: return DataField.Average; + case SeriesChartType.Bubble: return DataField.Bubble; + case SeriesChartType.Candlestick: + case SeriesChartType.Stock: return DataField.Close; + case SeriesChartType.ErrorBar: return DataField.Center; + case SeriesChartType.RangeBar: + case SeriesChartType.Range: + case SeriesChartType.RangeColumn: + case SeriesChartType.SplineRange: return DataField.Top; + } + default: + return null; + } + } + + #endregion + } + #endregion + + #region class FormulaInfo and inherited FormulaSpecific classes + + /// + /// This a base class of the formula metainfo classes. + /// + internal abstract class FormulaInfo + { + #region Fields + DataField[] _inputFields; + DataField[] _outputFields; + object[] _parameters; + #endregion + + #region Properties + /// + /// Gets the input data fields of the formula. + /// + /// The input fields. + public DataField[] InputFields + { + get { return _inputFields; } + } + + /// + /// Gets the output data fields of the formula. + /// + /// The output fields. + public DataField[] OutputFields + { + get { return _outputFields; } + } + + /// + /// Gets the parameters of the formula. + /// + /// The parameters. + public object[] Parameters + { + get { return _parameters; } + } + #endregion + + #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// The input data fields. + /// The output data fields. + /// The default formula params. + public FormulaInfo(DataField[] inputFields, DataField[] outputFields, params object[] defaultParams) + { + _inputFields = inputFields; + _outputFields = outputFields; + _parameters = defaultParams; + } + #endregion + + #region Methods + /// + /// Saves the formula parameters to a string. + /// + /// Csv string with parameters + internal virtual string SaveParametersToString() + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < _parameters.Length; i++) + { + if (i > 0) sb.Append(','); + sb.AppendFormat(CultureInfo.InvariantCulture, "{0}", _parameters[i]); + } + return sb.ToString(); + } + + /// + /// Loads the formula parameters from string. + /// + /// Csv string with parameters. + internal virtual void LoadParametersFromString(string parameters) + { + if (String.IsNullOrEmpty(parameters)) + return; + + string[] paramStringList = parameters.Split(','); + int paramStringIndex = 0; + for (int i = 0; i < _parameters.Length && paramStringIndex < paramStringList.Length; i++) + { + string newParamValue = paramStringList[paramStringIndex++]; + if (!String.IsNullOrEmpty(newParamValue)) + { + _parameters[i] = ParseParameter(i, newParamValue); + } + } + } + + /// + /// Parses the formula parameter. + /// + /// The param index. + /// The parameter value string. + /// Parameter value. + internal virtual object ParseParameter(int index, string newParamValue) + { + object param = _parameters[index]; + if (param is int) + { + return Convert.ToInt32(newParamValue, CultureInfo.InvariantCulture); + } + else if (param is bool) + { + return Convert.ToBoolean(newParamValue, CultureInfo.InvariantCulture); + } + else if (param is double) + { + return Convert.ToDouble(newParamValue, CultureInfo.InvariantCulture); + } + return null; + } + + /// + /// Checks the formula parameter string. + /// + /// The parameters. + internal virtual void CheckParameterString(string parameters) + { + if (String.IsNullOrEmpty(parameters)) + return; + + string[] paramStringList = parameters.Split(','); + int paramStringIndex = 0; + for (int i = 0; i < _parameters.Length && paramStringIndex < paramStringList.Length; i++) + { + string newParamValue = paramStringList[paramStringIndex++]; + if (!String.IsNullOrEmpty(newParamValue)) + { + try + { + ParseParameter(i, newParamValue); + } + catch (FormatException) + { + throw new ArgumentException(SR.ExceptionFormulaDataFormatInvalid(parameters)); + } + } + } + } + #endregion + } + + /// + /// MovingAverage FormulaInfo + /// + internal class MovingAverageFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public MovingAverageFormulaInfo() + : this(2, false) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + /// if set to true [start from first]. + public MovingAverageFormulaInfo(int period, bool startFromFirst) + : base( + new DataField[] { DataField.Y }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period, startFromFirst) + { + } + } + + /// + /// ExponentialMoving AverageFormulaInfo + /// + internal class ExponentialMovingAverageFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public ExponentialMovingAverageFormulaInfo() + : this(2, false) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + /// if set to true [start from first]. + public ExponentialMovingAverageFormulaInfo(int period, bool startFromFirst) + : base( + new DataField[] { DataField.Y }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period, startFromFirst) + { + } + } + + /// + /// WeightedMovingAverageFormulaInfo + /// + internal class WeightedMovingAverageFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public WeightedMovingAverageFormulaInfo() + : this(2, false) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + /// if set to true [start from first]. + public WeightedMovingAverageFormulaInfo(int period, bool startFromFirst) + : base( + new DataField[] { DataField.Y }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period, startFromFirst) + { + } + } + + /// + /// TriangularMovingAverage FormulaInfo + /// + internal class TriangularMovingAverageFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public TriangularMovingAverageFormulaInfo() + : this(2, false) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + /// if set to true [start from first]. + public TriangularMovingAverageFormulaInfo(int period, bool startFromFirst) + : base( + new DataField[] { DataField.Y }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period, startFromFirst) + { + } + } + + /// + /// TripleExponentialMovingAverage FormulaInfo + /// + internal class TripleExponentialMovingAverageFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public TripleExponentialMovingAverageFormulaInfo() + : this(12) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + public TripleExponentialMovingAverageFormulaInfo(int period) + : base( + new DataField[] { DataField.Y }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period) + { + } + } + + /// + /// BollingerBands FormulaInfo + /// + internal class BollingerBandsFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public BollingerBandsFormulaInfo() + : this(3, 2, true) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + /// The deviation. + /// if set to true [start from first]. + public BollingerBandsFormulaInfo(int period, double deviation, bool startFromFirst) + : base( + new DataField[] { DataField.Y }, //Input fields + new DataField[] { DataField.Top, DataField.Bottom }, //Output fields + period, deviation, startFromFirst) + { + } + } + + /// + /// TypicalPrice FormulaInfo + /// + internal class TypicalPriceFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public TypicalPriceFormulaInfo() + : base( + new DataField[] { DataField.Close, DataField.High, DataField.Low }, //Input fields + new DataField[] { DataField.Y }) //Output fields + { + } + } + + /// + /// WeightedClose FormulaInfo + /// + internal class WeightedCloseFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public WeightedCloseFormulaInfo() + : base( + new DataField[] { DataField.Close, DataField.High, DataField.Low }, //Input fields + new DataField[] { DataField.Y }) //Output fields + { + } + } + + /// + /// MedianPrice FormulaInfo + /// + internal class MedianPriceFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public MedianPriceFormulaInfo() + : base( + new DataField[] { DataField.High, DataField.Low }, //Input fields + new DataField[] { DataField.Y }) //Output fields + { + } + } + + + /// + /// Envelopes FormulaInfo + /// + internal class EnvelopesFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public EnvelopesFormulaInfo() + : this(2, 10, true) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + /// The shift percentage. + /// if set to true [start from first]. + public EnvelopesFormulaInfo(int period, double shiftPercentage, bool startFromFirst) + : base( + new DataField[] { DataField.Y }, //Input fields + new DataField[] { DataField.Top, DataField.Bottom }, //Output fields + period, shiftPercentage, startFromFirst) + { + } + } + + + /// + /// StandardDeviation FormulaInfo + /// + internal class StandardDeviationFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public StandardDeviationFormulaInfo() + : this(2, false) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + /// if set to true [start from first]. + public StandardDeviationFormulaInfo(int period, bool startFromFirst) + : base( + new DataField[] { DataField.Y }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period, startFromFirst) + { + } + } + + /// + /// ChaikinOscillatorFormulaInfo + /// + internal class ChaikinOscillatorFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public ChaikinOscillatorFormulaInfo() + : this(3, 10, false) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The short period. + /// The long period. + /// if set to true [start from first]. + public ChaikinOscillatorFormulaInfo(int shortPeriod, int longPeriod, bool startFromFirst) + : base( + new DataField[] { DataField.High, DataField.Low, DataField.Close, DataField.Y }, //Input fields + new DataField[] { DataField.Y }, //Output fields + shortPeriod, longPeriod, startFromFirst) + { + } + } + + /// + /// DetrendedPriceOscillator FormulaInfo + /// + internal class DetrendedPriceOscillatorFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public DetrendedPriceOscillatorFormulaInfo() + : this(2, false) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + /// if set to true [start from first]. + public DetrendedPriceOscillatorFormulaInfo(int period, bool startFromFirst) + : base( + new DataField[] { DataField.Y }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period, startFromFirst) + { + } + } + + + /// + /// VolatilityChaikins FormulaInfo + /// + internal class VolatilityChaikinsFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public VolatilityChaikinsFormulaInfo() + : this(10, 10) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + /// The signal period. + public VolatilityChaikinsFormulaInfo(int period, int signalPeriod) + : base( + new DataField[] { DataField.High, DataField.Low }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period, signalPeriod) + { + } + } + + /// + /// VolumeOscillator FormulaInfo + /// + internal class VolumeOscillatorFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public VolumeOscillatorFormulaInfo() + : this(5, 10, true) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The short period. + /// The long period. + /// if set to true [percentage]. + public VolumeOscillatorFormulaInfo(int shortPeriod, int longPeriod, bool percentage) + : base( + new DataField[] { DataField.Y }, //Input fields + new DataField[] { DataField.Y }, //Output fields + shortPeriod, longPeriod, percentage) + { + } + } + + /// + /// StochasticIndicatorFormulaInfo + /// + internal class StochasticIndicatorFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public StochasticIndicatorFormulaInfo() + : this(10, 10) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period D. + /// The period K. + public StochasticIndicatorFormulaInfo(int periodD, int periodK) + : base( + new DataField[] { DataField.High, DataField.Low, DataField.Close }, //Input fields + new DataField[] { DataField.Y, DataField.Y }, //Output fields + periodD, periodK) + { + } + } + + /// + /// WilliamsRFormulaInfo + /// + internal class WilliamsRFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public WilliamsRFormulaInfo() + : this(14) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + public WilliamsRFormulaInfo(int period) + : base( + new DataField[] { DataField.High, DataField.Low, DataField.Close }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period) + { + } + } + + /// + /// AverageTrueRange FormulaInfo + /// + internal class AverageTrueRangeFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public AverageTrueRangeFormulaInfo() + : this(14) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + public AverageTrueRangeFormulaInfo(int period) + : base( + new DataField[] { DataField.High, DataField.Low, DataField.Close }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period) + { + } + } + + /// + /// EaseOfMovement FormulaInfo + /// + internal class EaseOfMovementFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public EaseOfMovementFormulaInfo() + : base( + new DataField[] { DataField.High, DataField.Low, DataField.Close }, //Input fields + new DataField[] { DataField.Y }) //Output fields + { + } + } + + /// + /// MassIndex FormulaInfo + /// + internal class MassIndexFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public MassIndexFormulaInfo() + : this(25, 9) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + /// The average period. + public MassIndexFormulaInfo(int period, int averagePeriod) + : base( + new DataField[] { DataField.High, DataField.Low }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period, averagePeriod) + { + } + } + + /// + /// Performance FormulaInfo + /// + internal class PerformanceFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public PerformanceFormulaInfo() + : base( + new DataField[] { DataField.Close }, //Input fields + new DataField[] { DataField.Y }) //Output fields + { + } + } + + /// + /// RateOfChange FormulaInfo + /// + internal class RateOfChangeFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public RateOfChangeFormulaInfo() + : this(10) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + public RateOfChangeFormulaInfo(int period) + : base( + new DataField[] { DataField.Close }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period) + { + } + } + + /// + /// RelativeStrengthIndex FormulaInfo + /// + internal class RelativeStrengthIndexFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public RelativeStrengthIndexFormulaInfo() + : this(10) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + public RelativeStrengthIndexFormulaInfo(int period) + : base( + new DataField[] { DataField.Close }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period) + { + } + } + + /// + /// MovingAverageConvergenceDivergence FormulaInfo + /// + internal class MovingAverageConvergenceDivergenceFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public MovingAverageConvergenceDivergenceFormulaInfo() + : this(12, 26) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The short period. + /// The long period. + public MovingAverageConvergenceDivergenceFormulaInfo(int shortPeriod, int longPeriod) + : base( + new DataField[] { DataField.Close }, //Input fields + new DataField[] { DataField.Y }, //Output fields + shortPeriod, longPeriod) + { + } + } + + /// + /// CommodityChannelIndex FormulaInfo + /// + internal class CommodityChannelIndexFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public CommodityChannelIndexFormulaInfo() + : this(10) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + public CommodityChannelIndexFormulaInfo(int period) + : base( + new DataField[] { DataField.High, DataField.Low, DataField.Close }, //Input fields + new DataField[] { DataField.Y }, //Output fields + period) + { + } + } + + /// + /// Forecasting FormulaInfo + /// + internal class ForecastingFormulaInfo : FormulaInfo + { + //Fields + string _parameters; + + //Constructor + /// + /// Initializes a new instance of the class. + /// + public ForecastingFormulaInfo() + : this(TimeSeriesAndForecasting.RegressionType.Polynomial, 2, 0, true, true) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// Type of the regression. + /// The polynomial degree. + /// The forecasting period. + /// if set to true [return approximation error]. + /// if set to true [return forecasting error]. + public ForecastingFormulaInfo(TimeSeriesAndForecasting.RegressionType regressionType, int polynomialDegree, int forecastingPeriod, bool returnApproximationError, bool returnForecastingError) + : base( + new DataField[] { DataField.Close }, //Input fields + new DataField[] { DataField.Close, DataField.High, DataField.Low }, //Output fields + regressionType, polynomialDegree, forecastingPeriod, returnApproximationError, returnForecastingError) + { + } + + //Methods + /// + /// Loads the formula parameters from string. + /// + /// Csv string with parameters. + internal override void LoadParametersFromString(string parameters) + { + _parameters = parameters; + } + + /// + /// Checks the formula parameter string. + /// + /// The parameters. + internal override void CheckParameterString(string parameters) + { + if (String.IsNullOrEmpty(parameters)) + return; + + string[] paramStringList = parameters.Split(','); + int paramStringIndex = 1; + //Don't check the first param + for (int i = 2; i < Parameters.Length && paramStringIndex < paramStringList.Length; i++) + { + string newParamValue = paramStringList[paramStringIndex++]; + if (!String.IsNullOrEmpty(newParamValue)) + { + try + { + ParseParameter(i, newParamValue); + } + catch (FormatException) + { + throw new ArgumentException(SR.ExceptionFormulaDataFormatInvalid(parameters)); + } + } + } + } + + /// + /// Saves the formula parameters to a string. + /// + /// Csv string with parameters + internal override string SaveParametersToString() + { + if (String.IsNullOrEmpty(_parameters)) + return _parameters; + else + return "2,0,true,true"; + } + } + + /// + /// MoneyFlow FormulaInfo + /// + internal class MoneyFlowFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public MoneyFlowFormulaInfo() + : this(2) //Defaults + { + } + /// + /// Initializes a new instance of the class. + /// + /// The period. + public MoneyFlowFormulaInfo(int period) + : base( + new DataField[] { DataField.High, DataField.Low, DataField.Close, DataField.Y }, //Input fields: High,Low,Close,Volume + new DataField[] { DataField.Y }, //Output fields + period) + { + } + } + + /// + /// PriceVolumeTrend FormulaInfo + /// + internal class PriceVolumeTrendFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public PriceVolumeTrendFormulaInfo() + : base( + new DataField[] { DataField.Close, DataField.Y }, //Input=Close,Volume + new DataField[] { DataField.Y }) //Output fields + { + } + } + + /// + /// OnBalanceVolume FormulaInfo + /// + internal class OnBalanceVolumeFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public OnBalanceVolumeFormulaInfo() + : base( + new DataField[] { DataField.Close, DataField.Y }, //Input=Close,Volume + new DataField[] { DataField.Y }) //Output fields + { + } + } + + /// + /// NegativeVolumeIndex FormulaInfo + /// + internal class NegativeVolumeIndexFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public NegativeVolumeIndexFormulaInfo() //Note about parameters: Start value is mandatory so we don't provide the default + : this(double.NaN) + { + } + /// + /// Initializes a new instance of the class. + /// + /// The start value. + public NegativeVolumeIndexFormulaInfo(double startValue) + : base( + new DataField[] { DataField.Close, DataField.Y }, //Input=Close,Volume + new DataField[] { DataField.Y }, + startValue) //Output fields + { + } + } + + /// + /// PositiveVolumeIndex FormulaInfo + /// + internal class PositiveVolumeIndexFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public PositiveVolumeIndexFormulaInfo() //Note about parameters: Start value is mandatory so we don't provide the default + : this(double.NaN) + { + } + /// + /// Initializes a new instance of the class. + /// + /// The start value. + public PositiveVolumeIndexFormulaInfo(double startValue) + : base( + new DataField[] { DataField.Close, DataField.Y }, //Input=Close,Volume + new DataField[] { DataField.Y }, + startValue) //Output fields + { + } + } + + /// + /// AccumulationDistribution FormulaInfo + /// + internal class AccumulationDistributionFormulaInfo : FormulaInfo + { + //Constructor + /// + /// Initializes a new instance of the class. + /// + public AccumulationDistributionFormulaInfo() //Note about parameters: Start value is mandatory so we don't provide the default + : base( + new DataField[] { DataField.High, DataField.Low, DataField.Close, DataField.Y }, //Input=High, Low, Close, Volume + new DataField[] { DataField.Y }) //Output fields + { + } + } + + #endregion + + #region enum DataField + /// + /// Chart data fields + /// + internal enum DataField + { + X, + Y, + LowerWisker, + UpperWisker, + LowerBox, + UpperBox, + Average, + Median, + Bubble, + BubbleSize, + High, + Low, + Open, + Close, + Center, + LowerError, + UpperError, + Top, + Bottom + } + #endregion + + #region class SeriesFieldInfo + /// + /// SeriesFieldInfo class is a OO representation formula input/output data params ("Series1:Y2") + /// + internal class SeriesFieldInfo + { + #region Fields + private Series _series; + private string _seriesName; + private DataField _dataField; + #endregion + + #region Properties + /// + /// Gets the series. + /// + /// The series. + public Series Series + { + get { return _series; } + } + /// + /// Gets the name of the series. + /// + /// The name of the series. + public string SeriesName + { + get { return _series != null ? _series.Name : _seriesName; } + } + /// + /// Gets the data field. + /// + /// The data field. + public DataField DataField + { + get { return _dataField; } + } + #endregion + + #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// The series. + /// The data field. + public SeriesFieldInfo(Series series, DataField dataField) + { + _series = series; + _dataField = dataField; + } + /// + /// Initializes a new instance of the class. + /// + /// Name of the series. + /// The data field. + public SeriesFieldInfo(string seriesName, DataField dataField) + { + _seriesName = seriesName; + _dataField = dataField; + } + #endregion + } + #endregion + + #region class SeriesFieldList + /// + /// SeriesFieldInfo class is a OO representation formula input/output data params ("Series1:Y2,Series2.Y4") + /// + internal class SeriesFieldList : List + { + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < this.Count; i++) + { + SeriesFieldInfo info = this[i]; + + if (i > 0) + sb.Append(','); + + SeriesChartType seriesChartType = info.Series != null ? + info.Series.ChartType : + FormulaHelper.GetDefaultChartType(info.DataField); + + IList dataFields = FormulaHelper.GetDataFields(seriesChartType); + + int dataFieldIndex = dataFields.IndexOf(info.DataField); + if (dataFieldIndex == 0) + sb.AppendFormat(CultureInfo.InvariantCulture, "{0}:Y", info.SeriesName); //The string field descriptor is 1 based ;-( + else + sb.AppendFormat(CultureInfo.InvariantCulture, "{0}:Y{1}", info.SeriesName, dataFieldIndex + 1); //The string field descriptor is 1 based ;-( + } + return sb.ToString(); + } + + //Static + /// + /// Parse the string defining the formula's input/output series and fields. + /// + /// The chart. + /// The series fields list. The series name can be followed by the field names. For example: "Series1:Y,Series1:Y3,Series2:Close" + /// The formula fields list. + /// + public static SeriesFieldList FromString(Chart chart, string seriesFields, IList formulaFields) + { + SeriesFieldList result = new SeriesFieldList(); + if (String.IsNullOrEmpty(seriesFields)) + { + return result; + } + + List unmappedFormulaFields = new List(formulaFields); + + //Loop through the series/field pairs + foreach (string seriesField in seriesFields.Split(',')) + { + //Stop processing if all the formula fields are mapped + if (unmappedFormulaFields.Count == 0) + break; + + //Split a pair into a series + field + string[] seriesFieldParts = seriesField.Split(':'); + if (seriesFieldParts.Length > 2) + { + throw new ArgumentException(SR.ExceptionFormulaDataFormatInvalid(seriesField)); + } + + //Get the series and series fields + string seriesName = seriesFieldParts[0].Trim(); + Series series = chart.Series.FindByName(seriesName); + if (series != null) + { + switch (seriesFieldParts.Length) + { + case 1: //Only series name is specified: "Series1" + AddSeriesFieldInfo(result, series, unmappedFormulaFields); + break; + case 2: //Series and field names are provided: "Series1:Y3" + AddSeriesFieldInfo(result, series, unmappedFormulaFields, seriesFieldParts[1]); + break; + } + } + else + { + switch (seriesFieldParts.Length) + { + case 1: //Only series name is specified: "Series1" + AddSeriesFieldInfo(result, seriesName, unmappedFormulaFields); + break; + case 2: //Series and field names are provided: "Series1:Y3" + AddSeriesFieldInfo(result, seriesName, unmappedFormulaFields, seriesFieldParts[1]); + break; + } + } + } + return result; + } + + /// + /// Adds the series field info. + /// + /// The result. + /// The series. + /// The unmapped formula fields. + private static void AddSeriesFieldInfo(SeriesFieldList result, Series series, IList unmappedFormulaFields) + { + List seriesFields = new List(FormulaHelper.GetDataFields(series.ChartType)); + + for (int i = 0; i < unmappedFormulaFields.Count && seriesFields.Count > 0; ) + { + DataField formulaField = unmappedFormulaFields[i]; + DataField? seriesField = null; + + // Case 1. Check if the formulaField is valid for this chart type + if (seriesFields.Contains(formulaField)) + { + seriesField = formulaField; + } + // Case 2. Try to map the formula field to the series field + if (seriesField == null) + { + seriesField = FormulaHelper.MapFormulaDataField(series.ChartType, formulaField); + } + + // If the seriesField is found - add it to the results + if (seriesField != null) + { + result.Add(new SeriesFieldInfo(series, (DataField)seriesField)); + seriesFields.Remove((DataField)formulaField); + unmappedFormulaFields.Remove(formulaField); + } + else + { + i++; + } + } + } + /// + /// Adds the series field info. + /// + /// The result. + /// The series. + /// The unmapped formula fields. + /// The series field id. + private static void AddSeriesFieldInfo(SeriesFieldList result, Series series, IList unmappedFormulaFields, string seriesFieldId) + { + IList seriesFields = FormulaHelper.GetDataFields(series.ChartType); + + DataField? seriesField = null; + + seriesFieldId = seriesFieldId.ToUpperInvariant().Trim(); + if (seriesFieldId == "Y") + { + seriesField = seriesFields[0]; + } + else if (seriesFieldId.StartsWith("Y", StringComparison.Ordinal)) + { + int id = 0; + if (int.TryParse(seriesFieldId.Substring(1), out id)) + if (id - 1 < seriesFields.Count) + { + seriesField = seriesFields[id - 1]; + } + else + { + throw (new ArgumentException(SR.ExceptionFormulaYIndexInvalid, seriesFieldId)); + } + } + else + { + seriesField = (DataField)Enum.Parse(typeof(DataField), seriesFieldId, true); + } + + // Add the seriesField to the results + if (seriesField != null) + { + result.Add(new SeriesFieldInfo(series, (DataField)seriesField)); + if (unmappedFormulaFields.Contains((DataField)seriesField)) + unmappedFormulaFields.Remove((DataField)seriesField); + else + unmappedFormulaFields.RemoveAt(0); + } + else + { + throw new ArgumentException(SR.ExceptionDataPointValueNameInvalid, seriesFieldId); + } + + } + + /// + /// Adds the series field info. + /// + /// The result. + /// Name of the series. + /// The unmapped formula fields. + private static void AddSeriesFieldInfo(SeriesFieldList result, string seriesName, IList unmappedFormulaFields) + { + SeriesChartType chartType = FormulaHelper.GetDefaultChartType(unmappedFormulaFields[0]); + List seriesFields = new List(FormulaHelper.GetDataFields(chartType)); + + for (int i = 0; i < unmappedFormulaFields.Count && seriesFields.Count > 0; ) + { + DataField formulaField = unmappedFormulaFields[i]; + DataField? seriesField = null; + + // Check if the formulaField is valid for this chart type + if (seriesFields.Contains(formulaField)) + { + seriesField = formulaField; + } + + // If the seriesField is found - add it to the results + if (seriesField != null) + { + result.Add(new SeriesFieldInfo(seriesName, (DataField)seriesField)); + seriesFields.Remove((DataField)formulaField); + unmappedFormulaFields.Remove(formulaField); + } + else + { + i++; + } + } + } + /// + /// Adds the series field info. + /// + /// The result. + /// Name of the series. + /// The unmapped formula fields. + /// The series field id. + private static void AddSeriesFieldInfo(SeriesFieldList result, string seriesName, IList unmappedFormulaFields, string seriesFieldId) + { + SeriesChartType chartType = FormulaHelper.GetDefaultChartType(unmappedFormulaFields[0]); + IList seriesFields = FormulaHelper.GetDataFields(chartType); + + //Find the field + DataField? seriesField = null; + + seriesFieldId = seriesFieldId.ToUpperInvariant().Trim(); + + if (seriesFieldId == "Y") + { + seriesField = seriesFields[0]; + } + else if (seriesFieldId.StartsWith("Y", StringComparison.Ordinal)) + { + int seriesFieldIndex = 0; + if (int.TryParse(seriesFieldId.Substring(1), out seriesFieldIndex)) + if (seriesFieldIndex < seriesFields.Count) + { + seriesField = seriesFields[seriesFieldIndex - 1]; + } + else + { + throw (new ArgumentException(SR.ExceptionFormulaYIndexInvalid, seriesFieldId)); + } + } + else + { + //Try parse the field name + try + { + seriesField = (DataField)Enum.Parse(typeof(DataField), seriesFieldId, true); + } + catch (ArgumentException) + { } + } + + if (seriesField != null) + { + result.Add(new SeriesFieldInfo(seriesName, (DataField)seriesField)); + unmappedFormulaFields.Remove((DataField)seriesField); + } + else + { + throw new ArgumentException(SR.ExceptionDataPointValueNameInvalid, seriesFieldId); + } + } + } + #endregion + +} + diff --git a/System.Web.DataVisualization/Common/Formulas/FormulaRegistry.cs b/System.Web.DataVisualization/Common/Formulas/FormulaRegistry.cs new file mode 100644 index 000000000..c220c3795 --- /dev/null +++ b/System.Web.DataVisualization/Common/Formulas/FormulaRegistry.cs @@ -0,0 +1,201 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: FormulaRegistry.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Formulas +// +// Classes: FormulaRegistry +// +// Purpose: Keep track of all registered formula module types. +// +// Reviewed: GS - August 6, 2002 +// AG - August 7, 2002 +// +//=================================================================== + + +#region Used namespace + +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; + +#endregion + + + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Formulas +#else + namespace System.Web.UI.DataVisualization.Charting.Formulas +#endif +{ + /// + /// Keep track of all registered formula modules types. + /// + internal class FormulaRegistry : IServiceProvider + { + #region Fields + + // Storage for all registered formula modules + internal Hashtable registeredModules = new Hashtable(StringComparer.OrdinalIgnoreCase); + private Hashtable _createdModules = new Hashtable(StringComparer.OrdinalIgnoreCase); + private ArrayList _modulesNames = new ArrayList(); + + #endregion + + #region Methods + + /// + /// Formula Registry public constructor + /// + public FormulaRegistry() + { + } + + /// + /// Adds modules into the registry. + /// + /// Module name. + /// Module class type. + public void Register(string name, Type moduleType) + { + // First check if module with specified name already registered + if(registeredModules.Contains(name)) + { + // If same type provided - ignore + if(registeredModules[name].GetType() == moduleType) + { + return; + } + + // Error - throw exception + throw( new ArgumentException( SR.ExceptionFormulaModuleNameIsNotUnique( name ) ) ); + } + + // Add Module Name + _modulesNames.Add(name); + + // Make sure that specified class support IFormula interface + bool found = false; + Type[] interfaces = moduleType.GetInterfaces(); + foreach(Type type in interfaces) + { + if(type == typeof(IFormula)) + { + found = true; + break; + } + } + if(!found) + { + throw( new ArgumentException( SR.ExceptionFormulaModuleHasNoInterface)); + } + + // Add formula module to the hash table + registeredModules[name] = moduleType; + } + + /// + /// Returns formula module registry service object. + /// + /// Service AxisName. + /// Service object. + [EditorBrowsableAttribute(EditorBrowsableState.Never)] + object IServiceProvider.GetService(Type serviceType) + { + if(serviceType == typeof(FormulaRegistry)) + { + return this; + } + throw (new ArgumentException( SR.ExceptionFormulaModuleRegistryUnsupportedType( serviceType.ToString()))); + } + + /// + /// Returns formula module object by name. + /// + /// Formula Module name. + /// Formula module object derived from IFormula. + public IFormula GetFormulaModule(string name) + { + // First check if formula module with specified name registered + if(!registeredModules.Contains(name)) + { + throw( new ArgumentException( SR.ExceptionFormulaModuleNameUnknown( name ) ) ); + } + + // Check if the formula module object is already created + if(!_createdModules.Contains(name)) + { + // Create formula module object + _createdModules[name] = + ((Type)registeredModules[name]).Assembly. + CreateInstance(((Type)registeredModules[name]).ToString()); + } + + return (IFormula)_createdModules[name]; + } + + /// + /// Returns the name of the module. + /// + /// Module index. + /// Module Name. + public string GetModuleName( int index ) + { + return (string)_modulesNames[index]; + } + + #endregion + + #region Properties + + /// + /// Return the number of registered modules. + /// + public int Count + { + get + { + return _modulesNames.Count; + } + } + + #endregion + } + + /// + /// Interface which defines the set of standard methods and + /// properties for each formula module + /// + internal interface IFormula + { + #region IFormula Properties and Methods + + /// + /// Formula Module name + /// + string Name { get; } + + /// + /// The first method in the module, which converts a formula + /// name to the corresponding private method. + /// + /// String which represent a formula name + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Formula parameters + /// Array of strings - Extra Formula parameters from DataManipulator object + /// Array of strings - Used for Labels. Description for output results. + void Formula(string formulaName, double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList, out string [][] outLabels ); + + #endregion + } +} + diff --git a/System.Web.DataVisualization/Common/Formulas/GeneralFormulas.cs b/System.Web.DataVisualization/Common/Formulas/GeneralFormulas.cs new file mode 100644 index 000000000..ac8cf448b --- /dev/null +++ b/System.Web.DataVisualization/Common/Formulas/GeneralFormulas.cs @@ -0,0 +1,193 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: GeneralFormulas.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Formulas +// +// Classes: GeneralFormulas +// +// Purpose: This class calculates Running total and average. +// Could be used for Pareto chart. +// +// Reviewed: GS - August 6, 2002 +// AG - August 7, 2002 +// +//=================================================================== + + +using System; + + + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Formulas +#else + namespace System.Web.UI.DataVisualization.Charting.Formulas +#endif +{ + /// + /// This class calculates Running total and average. + /// Could be used for Pareto chart + /// + internal class GeneralFormulas : PriceIndicators + { + #region Properties + + /// + /// Formula Module name + /// + override public string Name { get { return SR.FormulaNameGeneralFormulas; } } + + #endregion + + #region Formulas + + /// + /// Formula which calculates cumulative total. + /// --------------------------------------------------------- + /// Input: + /// - Y values. + /// Output: + /// - Running Total. + /// + /// Arrays of doubles: 1. row - X values, 2. row - Y values + /// Arrays of doubles: 1. row - X values, 2. row - Moving average + private void RuningTotal(double [][] inputValues, out double [][] outputValues) + { + // There is not enough series + if( inputValues.Length != 2 ) + { + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + } + + // Different number of x and y values + CheckNumOfValues( inputValues, 1 ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length]; + outputValues[1] = new double [inputValues[1].Length]; + + // Cumulative total + for( int index = 0; index < inputValues[0].Length; index++ ) + { + outputValues[0][index] = inputValues[0][index]; + + if( index > 0 ) + { + outputValues[1][index] = inputValues[1][index] + outputValues[1][index-1]; + } + else + { + outputValues[1][index] = inputValues[1][index]; + } + } + } + + /// + /// Running Average Formula + /// --------------------------------------------------------- + /// Input: + /// - Y values. + /// Output: + /// - Running Average. + /// + /// Arrays of doubles: 1. row - X values, 2. row - Y values + /// Arrays of doubles: 1. row - X values, 2. row - Moving average + private void RunningAverage(double [][] inputValues, out double [][] outputValues) + { + // There is no enough series + if( inputValues.Length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + CheckNumOfValues( inputValues, 1 ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length]; + outputValues[1] = new double [inputValues[1].Length]; + + // Total + double total = 0; + for( int index = 0; index < inputValues[0].Length; index++ ) + { + total += inputValues[1][index]; + } + + // Runing Average + for( int index = 0; index < inputValues[0].Length; index++ ) + { + outputValues[0][index] = inputValues[0][index]; + + if( index > 0 ) + outputValues[1][index] = inputValues[1][index] / total * 100 + outputValues[1][index-1]; + else + outputValues[1][index] = inputValues[1][index] / total * 100; + } + } + + #endregion + + #region Methods + + /// + /// Default constructor. + /// + public GeneralFormulas() + { + } + + /// + /// The first method in the module, which converts a formula + /// name to the corresponding private method. + /// + /// String which represent a formula name. + /// Arrays of doubles - Input values. + /// Arrays of doubles - Output values. + /// Array of strings - Formula parameters. + /// Array of strings - Extra Formula parameters from DataManipulator object. + /// Array of strings - Used for Labels. Description for output results. + override public void Formula( string formulaName, double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList, out string [][] outLabels ) + { + string name; + outputValues = null; + + // Not used for these formulas. + outLabels = null; + + name = formulaName.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + try + { + switch( name ) + { + case "RUNINGTOTAL": + RuningTotal( inputValues, out outputValues ); + break; + case "RUNINGAVERAGE": + RunningAverage( inputValues, out outputValues ); + break; + default: + outputValues = null; + break; + } + } + catch( IndexOutOfRangeException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaInvalidPeriod(name) ); + } + catch( OverflowException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaNotEnoughDataPoints(name) ); + } + } + #endregion + + } +} diff --git a/System.Web.DataVisualization/Common/Formulas/Oscillator.cs b/System.Web.DataVisualization/Common/Formulas/Oscillator.cs new file mode 100644 index 000000000..8f90849d5 --- /dev/null +++ b/System.Web.DataVisualization/Common/Formulas/Oscillator.cs @@ -0,0 +1,686 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: Oscillator.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Formulas +// +// Classes: Oscillators +// +// Purpose: This class is used to calculate oscillator +// indicators used in Technical Analyses. +// +// Reviewed: GS - August 7, 2002 +// AG - August 7, 2002 +// +//=================================================================== + + +using System; +using System.Globalization; + + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Formulas +#else + namespace System.Web.UI.DataVisualization.Charting.Formulas +#endif +{ + /// + /// This class is used to calculate oscillator + /// indicators used in Technical Analyses. + /// + internal class Oscillators : PriceIndicators + { + #region Properties + + /// + /// Formula Module name + /// + override public string Name { get{ return "Oscillators";}} + + #endregion + + #region Formulas + + /// + /// The Chaikin Oscillator is created by subtracting a 10 period + /// exponential moving average of the Accumulation/Distribution + /// line from a 3 period moving average of the + /// Accumulation/Distribution Line. + /// --------------------------------------------------------- + /// Input: + /// - 4 Y values ( Hi, Low, Close, Volume ). + /// Output: + /// - 1 Y value Chaikin Oscillator + /// Parameters: + /// - Short Period for Exponential Moving average (default=3) + /// - Int64 Period for Exponential Moving average (default=10) + /// Extra Parameters: + /// - Start from First + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Extra parameters + private void ChaikinOscillator(double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList) + { + // There is no enough input series + if( inputValues.Length != 5 ) + { + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresFourArrays); + } + + // Different number of x and y values + CheckNumOfValues( inputValues, 4 ); + + // Short Period for Exp moving average + int shortPeriod; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out shortPeriod)) + { + shortPeriod = 3; + } + + // Int64 Period for Exp moving average + int longPeriod; + if (parameterList.Length < 2 || + !int.TryParse(parameterList[1], NumberStyles.Any, CultureInfo.InvariantCulture, out longPeriod)) + { + longPeriod = 10; + } + + if( shortPeriod > longPeriod || longPeriod <= 0 || shortPeriod <= 0 ) + { + throw new ArgumentException(SR.ExceptionOscillatorObjectInvalidPeriod); + } + + // Starting average from the first data point or after period. + bool startFromFirst = bool.Parse( extraParameterList[0] ); + + VolumeIndicators volume = new VolumeIndicators(); + + double [][] outputDistribution = new double [2][]; + + // Accumulation Distribution + volume.AccumulationDistribution( inputValues, out outputDistribution ); + + double [] ExpAvgDistribution; + + // Exponential Moving average of Accumulation Distribution + ExponentialMovingAverage(outputDistribution[1],out ExpAvgDistribution,longPeriod,startFromFirst); + + double [] ExpAvg; + + // Exponential Moving average of close + ExponentialMovingAverage(outputDistribution[1],out ExpAvg,shortPeriod,startFromFirst); + + outputValues = new double [2][]; + + int period = Math.Min(ExpAvg.Length,ExpAvgDistribution.Length); + + outputValues[0] = new double [period]; + outputValues[1] = new double [period]; + + // Accumulation Distribution + int expIndex = 0; + for( int index = inputValues[1].Length - period; index < inputValues[1].Length; index++ ) + { + // Set X values + outputValues[0][expIndex] = inputValues[0][index]; + + // Set Y values + if(startFromFirst) + { + // Number of items in all arays is the same and they are aligned by time. + outputValues[1][expIndex] = ExpAvg[expIndex] - ExpAvgDistribution[expIndex]; + } + else if( (expIndex + longPeriod - shortPeriod) < ExpAvg.Length) + { + // Number of items in MovingAverages arrays is different and requires adjustment. + outputValues[1][expIndex] = ExpAvg[expIndex + longPeriod - shortPeriod] - ExpAvgDistribution[expIndex]; + } + else + { + outputValues[1][expIndex] = Double.NaN; + } + expIndex++; + } + } + + /// + /// The Detrended Price Oscillator ("DPO") attempts to + /// eliminate the trend in prices. Detrended prices allow + /// you to more easily identify cycles and overbought/oversold + /// levels. To calculate the DPO, you specify a time period. + /// Cycles longer than this time period are removed from + /// prices, leaving the shorter-term cycles. + /// --------------------------------------------------------- + /// Input: + /// - 1 Y value ( Close ). + /// Output: + /// - 1 Y value Detrended Price Oscillator + /// Parameters: + /// - Period + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void DetrendedPriceOscillator(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 2 ) + { + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + } + + // Different number of x and y values + CheckNumOfValues( inputValues, 1 ); + + // Short Period for Exp moving average + int period; + try + {period = int.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture );} + catch( Exception e ) + { + if (e.Message == SR.ExceptionObjectReferenceIsNull) + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing); + else + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing + e.Message); + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + double [] outputAverage; + + // Moving Average + MovingAverage( inputValues[1], out outputAverage, period, false ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length - period*3/2]; + outputValues[1] = new double [inputValues[1].Length - period*3/2]; + + // Detrended Price Oscillator + for( int index = 0; index < outputValues[1].Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index + period + period/2]; + + // Set Y values + outputValues[1][index] = inputValues[1][index + period + period/2] - outputAverage[index]; + } + } + + /// + /// Chaikin's Volatility indicator compares the spread + /// between a security's high and low prices. + /// It quantifies volatility as a widening of the range + /// between the high and the low price. There are two ways + /// to interpret this measure of volatility. One method + /// assumes that market tops are generally accompanied by + /// increased volatility (as investors get nervous and + /// indecisive) and that the latter stages of a market + /// bottom are generally accompanied by decreased volatility + /// (as investors get bored). Another method (Mr. Chaikin's) + /// assumes that an increase in the Volatility indicator over + /// a relatively short time period indicates that a bottom is + /// near (e.g., a panic sell-off) and that a decrease in + /// volatility over a longer time period indicates an + /// approaching top (e.g., a mature bull market). As with + /// almost all experienced investors, Mr. Chaikin recommends + /// that you do not rely on any one indicator. He suggests + /// using a moving average ----ion or trading band system + /// to confirm this (or any) indicator. + /// --------------------------------------------------------- + /// Input: + /// - 2 Y values ( Hi, Low ). + /// Output: + /// - 1 Y value Volatility Chaikins + /// Parameters: + /// - Periods (default 10)- is used to specify the Shift days, By default this property is set to 10. + /// - SignalPeriod (default 10)- is used to calculate Exponential Moving Avg of the Signal line, By default this property is set to 10. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void VolatilityChaikins(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 3 ) + { + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + } + + // Different number of x and y values + CheckNumOfValues( inputValues, 2 ); + + // Period + int period; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out period)) + { + period = 10; + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionOscillatorNegativePeriodParameter); + + // Signal Period for Exp moving average + int signalPeriod; + if (parameterList.Length < 2 || + !int.TryParse(parameterList[1], NumberStyles.Any, CultureInfo.InvariantCulture, out signalPeriod)) + { + signalPeriod = 10; + } + + if( signalPeriod <= 0 ) + throw new InvalidOperationException(SR.ExceptionOscillatorNegativeSignalPeriod); + + double [] outputAverage; + + double [] hiLowInput = new double[inputValues[1].Length]; + + // Find Hi - Low + for( int index = 0; index < inputValues[1].Length; index++ ) + { + hiLowInput[index] = inputValues[1][index] - inputValues[2][index]; + } + + // Exponential Moving Average + ExponentialMovingAverage( hiLowInput, out outputAverage, signalPeriod, false ); + + outputValues = new double [2][]; + + outputValues[0] = new double [outputAverage.Length - period]; + outputValues[1] = new double [outputAverage.Length - period]; + + // Volatility Chaikins + for( int index = 0; index < outputValues[1].Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index + period + signalPeriod - 1]; + + // Set Y values + if( outputAverage[index] != 0.0 ) + outputValues[1][index] = ( outputAverage[index + period] - outputAverage[index] ) / outputAverage[index] * 100.0; + else + // Div with zero error. + outputValues[1][index] = 0.0; + } + } + + /// + /// The Volume Oscillator displays the difference between two + /// moving averages of a security's volume. The difference + /// between the moving averages can be expressed in either + /// points or percentages. You can use the difference between + /// two moving averages of volume to determine if the overall + /// volume trend is increasing or decreasing. When the Volume + /// Oscillator rises above zero, it signifies that the + /// shorter-term volume moving average has risen above + /// the longer-term volume moving average, and thus, that + /// the short-term volume trend is higher (i.e., more volume) + /// than the longer-term volume trend. + /// --------------------------------------------------------- + /// Input: + /// - 1 Y values ( Volume ). + /// Output: + /// - 1 Y value VolumeOscillator + /// Parameters: + /// - ShortPeriod (Default 5)= is used to configure the short period. + /// - LongPeriod (Default 10)= is used to configure the Int64 period. + /// - Percentage (Default true)= The Volume Oscillator can display the difference between the two moving averages as either points or percentages. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void VolumeOscillator(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 2 ) + { + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + } + + // Different number of x and y values + CheckNumOfValues( inputValues, 1 ); + + // Short Period + int shortPeriod; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out shortPeriod)) + { + shortPeriod = 5; + } + + // Int64 Period + int longPeriod; + if (parameterList.Length < 2 || + !int.TryParse(parameterList[1], NumberStyles.Any, CultureInfo.InvariantCulture, out longPeriod)) + { + longPeriod = 10; + } + + if( shortPeriod > longPeriod || longPeriod <= 0 || shortPeriod <= 0 ) + throw new ArgumentException(SR.ExceptionOscillatorObjectInvalidPeriod); + + // percentage + bool percentage; + if (parameterList.Length < 3 || + !bool.TryParse(parameterList[2], out percentage)) + { + percentage = true; + } + + double [] shortAverage; + double [] longAverage; + + // Find Short moving average + MovingAverage( inputValues[1], out shortAverage, shortPeriod, false ); + + // Find Int64 moving average + MovingAverage( inputValues[1], out longAverage, longPeriod, false ); + + outputValues = new double [2][]; + + outputValues[0] = new double [longAverage.Length]; + outputValues[1] = new double [longAverage.Length]; + + // Volume Oscillator + for( int index = 0; index < longAverage.Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index + longPeriod-1]; + + // Set Y values + outputValues[1][index] = shortAverage[index + shortPeriod] - longAverage[index]; + + // RecalculateAxesScale difference in % + if( percentage ) + { + // Div by zero error. + if( longAverage[index] == 0.0 ) + outputValues[1][index]=0.0; + else + outputValues[1][index] = outputValues[1][index] / shortAverage[index + shortPeriod] * 100; + } + } + } + + /// + /// The Stochastic Indicator is based on the observation that + /// as prices increase, closing prices tend to accumulate ever + /// closer to the highs for the period. Conversely, as prices + /// decrease, closing prices tend to accumulate ever closer to + /// the lows for the period. Trading decisions are made with + /// respect to divergence between % of "D" (one of the two + /// lines generated by the study) and the item's price. For + /// example, when a commodity or stock makes a high, reacts, + /// and subsequently moves to a higher high while corresponding + /// peaks on the % of "D" line make a high and then a lower + /// high, a bearish divergence is indicated. When a commodity + /// or stock has established a new low, reacts, and moves to a + /// lower low while the corresponding low points on the % of + /// "D" line make a low and then a higher low, a bullish + /// divergence is indicated. Traders act upon this divergence + /// when the other line generated by the study (K) crosses on + /// the right-hand side of the peak of the % of "D" line in the + /// case of a top, or on the right-hand side of the low point + /// of the % of "D" line in the case of a bottom. The Stochastic + /// Oscillator is displayed as two lines. The main line is + /// called "%K." The second line, called "%D," is a moving + /// average of %K. + /// --------------------------------------------------------- + /// Input: + /// - 3 Y values ( Hi, Low, Close ). + /// Output: + /// - 2 Y value ( %K, %D ) + /// Parameters: + /// - PeriodD (Default 10) = is used for %D calculation as SMA of %K. + /// - PeriodK (Default 10) = is used to calculate %K. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + internal void StochasticIndicator(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 4 ) + { + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresThreeArrays); + } + + // Different number of x and y values + CheckNumOfValues( inputValues, 3 ); + + // PeriodD for moving average + int periodD; + if (parameterList.Length < 2 || + !int.TryParse(parameterList[1], NumberStyles.Any, CultureInfo.InvariantCulture, out periodD)) + { + periodD = 10; + } + + if( periodD <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // PeriodK for moving average + int periodK; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out periodK)) + { + periodK = 10; + } + + if( periodK <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Output arrays + outputValues = new double [3][]; + + // X + outputValues[0] = new double [inputValues[0].Length - periodK - periodD + 2]; + + // K% + outputValues[1] = new double [inputValues[0].Length - periodK - periodD + 2]; + + // D% + outputValues[2] = new double [inputValues[0].Length - periodK - periodD + 2]; + + double [] K = new double [inputValues[0].Length - periodK + 1]; + + // Find K% + for( int index = periodK - 1; index < inputValues[0].Length; index++ ) + { + // Find Lowest Low and Highest High + double minLow = double.MaxValue; + double maxHi = double.MinValue; + for( int indexHL = index - periodK + 1; indexHL <= index; indexHL++ ) + { + if( minLow > inputValues[2][indexHL] ) + minLow = inputValues[2][indexHL]; + + if( maxHi < inputValues[1][indexHL] ) + maxHi = inputValues[1][indexHL]; + } + // Find K% + K[index - periodK + 1] = ( inputValues[3][index] - minLow ) / ( maxHi - minLow ) * 100; + + // Set X and Y K output + if( index >= periodK + periodD - 2 ) + { + outputValues[0][index - periodK - periodD + 2] = inputValues[0][index]; + outputValues[1][index - periodK - periodD + 2] = K[index - periodK + 1]; + } + } + + // Find D% + MovingAverage( K, out outputValues[2], periodD, false ); + } + + /// + /// Williams’ %R (pronounced "percent R") is a momentum + /// indicator that measures overbought/oversold levels. + /// Williams’ %R was developed by Larry Williams. The + /// interpretation of Williams' %R is very similar to that + /// of the Stochastic Oscillator except that %R is plotted + /// upside-down and the Stochastic Oscillator has internal + /// smoothing. To display the Williams’ %R indicator on an + /// upside-down scale, it is usually plotted using negative + /// values (e.g., -20%). Readings in the range of 80 to 100% + /// indicate that the security is oversold while readings in + /// the 0 to 20% range suggest that it is overbought. + /// As with all overbought/oversold indicators, it is best to + /// wait for the security's price to change direction before + /// placing your trades. For example, if an overbought/oversold + /// indicator (such as the Stochastic Oscillator or Williams' + /// %R) is showing an overbought condition, it is wise to wait + /// for the security's price to turn down before selling the + /// security. (The MovingAverageConvergenceDivergence is a good indicator to monitor change + /// in a security's price.) It is not unusual for + /// overbought/oversold indicators to remain in an + /// overbought/oversold condition for a long time period as + /// the security's price continues to climb/fall. Selling + /// simply because the security appears overbought may take + /// you out of the security long before its price shows signs + /// of deterioration. + /// --------------------------------------------------------- + /// Input: + /// - 3 Y values ( Hi, Low, Close ). + /// Output: + /// - 2 Y value ( %R ) + /// Parameters: + /// - Period (Default 14) = is used to configure the number of periods to calculate the WilliamsR + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + internal void WilliamsR(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 4 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresThreeArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 3 ); + + // PeriodD for moving average + int period; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out period)) + { + period = 14; + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Output arrays + outputValues = new double [2][]; + + // X + outputValues[0] = new double [inputValues[0].Length - period + 1]; + + // R% + outputValues[1] = new double [inputValues[0].Length - period + 1]; + + // Find R% + for( int index = period - 1; index < inputValues[0].Length; index++ ) + { + // Find Lowest Low and Highest High + double minLow = double.MaxValue; + double maxHi = double.MinValue; + for( int indexHL = index - period + 1; indexHL <= index; indexHL++ ) + { + if( minLow > inputValues[2][indexHL] ) + minLow = inputValues[2][indexHL]; + + if( maxHi < inputValues[1][indexHL] ) + maxHi = inputValues[1][indexHL]; + } + // Set X value + outputValues[0][index - period + 1] = inputValues[0][index]; + + // Find R% + outputValues[1][index - period + 1] = ( maxHi - inputValues[3][index] ) / ( maxHi - minLow ) * (-100.0); + } + } + + #endregion + + #region Methods + + /// + /// Constructor + /// + public Oscillators() + { + } + + + /// + /// The first method in the module, which converts a formula + /// name to the corresponding private method. + /// + /// String which represent a formula name + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Formula parameters + /// Array of strings - Extra Formula parameters from DataManipulator object + /// Array of strings - Used for Labels. Description for output results. + override public void Formula( string formulaName, double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList, out string [][] outLabels ) + { + string name; + outputValues = null; + + // Not used for these formulas. + outLabels = null; + + name = formulaName.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + try + { + switch( name ) + { + case "STOCHASTICINDICATOR": + StochasticIndicator( inputValues, out outputValues, parameterList ); + break; + case "CHAIKINOSCILLATOR": + ChaikinOscillator( inputValues, out outputValues, parameterList, extraParameterList ); + break; + case "DETRENDEDPRICEOSCILLATOR": + DetrendedPriceOscillator( inputValues, out outputValues, parameterList ); + break; + case "VOLATILITYCHAIKINS": + VolatilityChaikins( inputValues, out outputValues, parameterList ); + break; + case "VOLUMEOSCILLATOR": + VolumeOscillator( inputValues, out outputValues, parameterList ); + break; + case "WILLIAMSR": + WilliamsR( inputValues, out outputValues, parameterList ); + break; + default: + outputValues = null; + break; + } + } + catch( IndexOutOfRangeException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaInvalidPeriod( name ) ); + } + catch( OverflowException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaNotEnoughDataPoints( name ) ); + } + } + + #endregion + + } +} diff --git a/System.Web.DataVisualization/Common/Formulas/PriceIndicators.cs b/System.Web.DataVisualization/Common/Formulas/PriceIndicators.cs new file mode 100644 index 000000000..60dab3fdd --- /dev/null +++ b/System.Web.DataVisualization/Common/Formulas/PriceIndicators.cs @@ -0,0 +1,1174 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: PriceIndicators.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Formulas +// +// Classes: PriceIndicators +// +// Purpose: This class is used to calculate Price +// indicators used in Technical Analyses. +// +// Reviewed: GS - August 7, 2002 +// AG - August 7, 2002 +// +//=================================================================== + + +using System; + + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Formulas +#else + namespace System.Web.UI.DataVisualization.Charting.Formulas +#endif +{ + /// + /// Price indicator is module with mathematical calculations + /// that apply to a security's price. + /// + internal class PriceIndicators : IFormula + { + #region Error strings + + // Error strings + //internal string inputArrayStart = "Formula requires"; + //internal string inputArrayEnd = "arrays"; + //internal string SR.ExceptionPriceIndicatorsSameYNumber = "Formula requires the same number of Y values for each input data point"; + //internal string SR.ExceptionPriceIndicatorsFormulaRequiresFourArrays = "Formula requires the same number of X and Y values for each input data point"; + //internal string periodMissing = "Formula error - Period parameter is missing. "; + //internal string SR.ExceptionPriceIndicatorsFormulaRequiresFourArrays = "Formula error - There are not enough data points for the Period. "; + + #endregion + + #region Properties + + /// + /// Formula Module name + /// + virtual public string Name { get { return SR.FormulaNamePriceIndicators; } } + + #endregion + + #region Formulas + + /// + /// A Moving Average is an indicator that shows the average + /// value of a security's price over a period of time. When + /// calculating a moving average, a mathematical analysis of + /// the security's average value over a predetermined time + /// period is made. As the security's price changes, + /// its average price moves up or down. + /// A simple, or arithmetic, moving average is calculated by + /// adding the closing price of the security for a number of + /// time periods (e.g., 12 days) and then dividing this total + /// by the number of time periods. The result is the average + /// price of the security over the time period. Simple moving + /// averages give equal weight to each daily price. + /// --------------------------------------------------------- + /// Input: + /// - Y values. + /// Output: + /// - Moving Average. + /// Parameters: + /// - Period + /// Extra Parameters: + /// - Start from First + /// + /// + /// Array of doubles: Y values + /// Arrays of doubles: Moving average + /// Period + /// Start from first value + internal void MovingAverage(double [] inputValues, out double [] outputValues, int period, bool FromFirst ) + { + double [][] tempInput = new double [2][]; + double [][] tempOutput = new double [2][]; + string [] parList = new string [1]; + string [] extList = new string [1]; + + parList[0] = period.ToString(System.Globalization.CultureInfo.InvariantCulture); + extList[0] = FromFirst.ToString(System.Globalization.CultureInfo.InvariantCulture); + + tempInput[0] = new double[inputValues.Length]; + tempInput[1] = inputValues; + + MovingAverage( tempInput, out tempOutput, parList, extList ); + + outputValues = tempOutput[1]; + } + + /// + /// A Moving Average is an indicator that shows the average + /// value of a security's price over a period of time. When + /// calculating a moving average, a mathematical analysis of + /// the security's average value over a predetermined time + /// period is made. As the security's price changes, + /// its average price moves up or down. + /// A simple, or arithmetic, moving average is calculated by + /// adding the closing price of the security for a number of + /// time periods (e.g., 12 days) and then dividing this total + /// by the number of time periods. The result is the average + /// price of the security over the time period. Simple moving + /// averages give equal weight to each daily price. + /// --------------------------------------------------------- + /// Input: + /// - Y values. + /// Output: + /// - Moving Average. + /// Parameters: + /// - Period + /// Extra Parameters: + /// - Start from First + /// + /// + /// Arrays of doubles: 1. row - X values, 2. row - Y values + /// Arrays of doubles: 1. row - X values, 2. row - Moving average + /// Array of strings: 1. Period + /// Array of strings: 1. Start from zero + private void MovingAverage(double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList) + { + int length = inputValues.Length; + + // Period for moving average + int period; + try + {period = int.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture );} + catch( Exception e ) + { + if (e.Message == SR.ExceptionObjectReferenceIsNull) + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing); + else + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing + e.Message); + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Starting average from the first data point or after period. + bool startFromFirst = bool.Parse( extraParameterList[0]); + + // There is no enough series + if( length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + if( inputValues[0].Length != inputValues[1].Length ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsSameXYNumber); + + // Not enough values for moving average. + if( inputValues[0].Length < period ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsNotEnoughPoints); + + outputValues = new double [2][]; + + if( startFromFirst ) + { + // X values + outputValues[0] = new double [inputValues[0].Length]; + + // Y values + outputValues[1] = new double [inputValues[1].Length]; + + for( int point = 0; point < inputValues[0].Length; point++ ) + { + // Set X value + outputValues[0][point] = inputValues[0][point]; + + // Find sum of Y values + double sum = 0; + int startSum = 0; + + // Find the begining of the period + if( point - period + 1 > 0 ) + { + startSum = point - period + 1; + } + + // Find sum fro real period. + for( int pointSum = startSum; pointSum <= point; pointSum++ ) + { + sum += inputValues[1][pointSum]; + } + + // Find real period if start from first data point. + int realPeriod = period; + if( period > point + 1 ) + { + realPeriod = point + 1; + } + + outputValues[1][point] = sum / realPeriod; + } + } + else + { + // X values + outputValues[0] = new double [inputValues[0].Length - period + 1]; + + // Y values + outputValues[1] = new double [inputValues[1].Length - period + 1]; + + // Find sum of Y values for the period + double sum = 0; + for( int pointSum = 0; pointSum < period; pointSum++ ) + { + sum += inputValues[1][pointSum]; + } + + for( int point = 0; point < outputValues[0].Length; point++ ) + { + // Set X value + outputValues[0][point] = inputValues[0][point + period - 1]; + + outputValues[1][point] = sum / period; + + // Change Sum + if( point < outputValues[0].Length - 1 ) + { + sum -= inputValues[1][point]; + sum += inputValues[1][point + period]; + } + } + } + } + + /// + /// An exponential (or exponentially weighted) moving average + /// is calculated by applying a percentage of today’s closing + /// price to yesterday’s moving average value. Exponential + /// moving averages place more weight on recent prices. For + /// example, to calculate a 9% exponential moving average + /// of IBM, you would first take today’s closing price and + /// multiply it by 9%. Next, you would add this product to + /// the value of yesterday’s moving average multiplied by + /// 91% (100% - 9% = 91%). + /// --------------------------------------------------------- + /// Input: + /// - Y values. + /// Output: + /// - Exponential Moving Average. + /// Parameters: + /// - Period + /// Extra Parameters: + /// - Start from First + /// + /// + /// Array of doubles: Y values + /// Arrays of doubles: Exponential Moving average + /// Period + /// Start from first value + internal void ExponentialMovingAverage(double []inputValues, out double []outputValues, int period, bool startFromFirst) + { + double [][] tempInput = new double [2][]; + double [][] tempOutput = new double [2][]; + string [] parList = new string [1]; + string [] extList = new string [1]; + + parList[0] = period.ToString(System.Globalization.CultureInfo.InvariantCulture); + extList[0] = startFromFirst.ToString(System.Globalization.CultureInfo.InvariantCulture); + + tempInput[0] = new double[inputValues.Length]; + tempInput[1] = inputValues; + + ExponentialMovingAverage( tempInput, out tempOutput, parList, extList ); + + outputValues = tempOutput[1]; + } + + /// + /// An exponential (or exponentially weighted) moving average + /// is calculated by applying a percentage of today’s closing + /// price to yesterday’s moving average value. Exponential + /// moving averages place more weight on recent prices. For + /// example, to calculate a 9% exponential moving average + /// of IBM, you would first take today’s closing price and + /// multiply it by 9%. Next, you would add this product to + /// the value of yesterday’s moving average multiplied by + /// 91% (100% - 9% = 91%). + /// --------------------------------------------------------- + /// Input: + /// - Y values. + /// Output: + /// - Exponential Moving Average. + /// Parameters: + /// - Period + /// Extra Parameters: + /// - Start from First + /// + /// + /// Arrays of doubles: 1. row - X values, 2. row - Y values + /// Arrays of doubles: 1. row - X values, 2. row - Moving average + /// Array of strings: 1. Period + /// Array of strings: 1. Start from zero + private void ExponentialMovingAverage(double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList) + { + int length = inputValues.Length; + + // Period for moving average + int period; + try + {period = int.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture );} + catch( Exception e ) + { + if (e.Message == SR.ExceptionObjectReferenceIsNull) + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing); + else + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing + e.Message); + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Formula for converting period to percentage + double exponentialPercentage = 2.0 / ( period + 1.0 ); + + // Starting average from the first data point or after period. + bool startFromFirst = bool.Parse( extraParameterList[0] ); + + // There is no enough series + if( length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + if( inputValues[0].Length != inputValues[1].Length ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsSameXYNumber); + + // Not enough values for moving average. + if( inputValues[0].Length < period ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsNotEnoughPoints); + + outputValues = new double [2][]; + + if( startFromFirst ) + { + // X values + outputValues[0] = new double [inputValues[0].Length]; + + // Y values + outputValues[1] = new double [inputValues[1].Length]; + + for( int point = 0; point < inputValues[0].Length; point++ ) + { + // Set X value + outputValues[0][point] = inputValues[0][point]; + + // Find sum of Y values + double sum = 0; + int startSum = 0; + + if( point - period + 1 > 0 ) + { + startSum = point - period + 1; + } + + for( int pointSum = startSum; pointSum < point; pointSum++ ) + { + sum += inputValues[1][pointSum]; + } + + int realPeriod = period; + if( period > point + 1 ) + realPeriod = point + 1; + + double movingAvr; + + // Find real period if start from first data point. + if( realPeriod <= 1 ) + movingAvr = 0; + else + movingAvr = sum / ( realPeriod - 1 ); + + // Formula for converting period to percentage + exponentialPercentage = 2.0 / ( realPeriod + 1.0 ); + + // Exponential influence + outputValues[1][point] = movingAvr * (1 - exponentialPercentage ) + inputValues[1][point] * exponentialPercentage; + + } + } + else + { + // X values + outputValues[0] = new double [inputValues[0].Length - period + 1]; + + // Y values + outputValues[1] = new double [inputValues[1].Length - period + 1]; + + for( int point = 0; point < outputValues[0].Length; point++ ) + { + // Set X value + outputValues[0][point] = inputValues[0][point + period - 1]; + + double movingAvr; + // if point is less than period calulate simple moving average + if( point == 0 ) + { + // Find sum of Y values + double sum = 0; + for( int pointSum = point; pointSum < point + period; pointSum++ ) + { + sum += inputValues[1][pointSum]; + } + + movingAvr = sum / ( period ); + } + // else use previos day exponential moving average + else + movingAvr = outputValues[1][point-1]; + + // Exponential influence + outputValues[1][point] = movingAvr * (1 - exponentialPercentage ) + inputValues[1][point + period - 1] * exponentialPercentage; + + } + } + } + + /// + /// Triangular moving averages place the majority of the weight + /// on the middle portion of the price series. They are actually + /// double-smoothed simple moving averages. The periods used + /// in the simple moving averages varies depending on if you + /// specify an odd or even number of time periods. + /// --------------------------------------------------------- + /// Input: + /// - Y values. + /// Output: + /// - Moving Average. + /// Parameters: + /// - Period + /// Extra Parameters: + /// - Start from First + /// + /// + /// Arrays of doubles: 1. row - X values, 2. row - Y values + /// Arrays of doubles: 1. row - X values, 2. row - Moving average + /// Array of strings: 1. Period + /// Array of strings: 1. Start from zero + private void TriangularMovingAverage(double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList) + { + int length = inputValues.Length; + + // Period for moving average + int period; + try + {period = int.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture );} + catch( Exception e ) + { + if (e.Message == SR.ExceptionObjectReferenceIsNull) + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing); + else + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing + e.Message); + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Starting average from the first data point or after period. + bool startFromFirst = bool.Parse( extraParameterList[0] ); + + // There is no enough series + if( length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + if( inputValues[0].Length != inputValues[1].Length ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsSameXYNumber); + + // Not enough values for moving average. + if( inputValues[0].Length < period ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsNotEnoughPoints); + + outputValues = new double [2][]; + + // Find triangular period + double tempPeriod = ((double)period + 1.0) / 2.0; + tempPeriod = Math.Round(tempPeriod); + double [] tempOut; + double [] tempIn = inputValues[1]; + + // Call moving averages first time + MovingAverage( tempIn, out tempOut, (int)tempPeriod, startFromFirst ); + // Call moving averages second time (Moving average of moving average) + MovingAverage( tempOut, out tempOut, (int)tempPeriod, startFromFirst ); + + outputValues[1] = tempOut; + + // X values + outputValues[0] = new double [outputValues[1].Length]; + + // Set X values + if( startFromFirst ) + outputValues[0] = inputValues[0]; + else + { + for( int index = 0; index < outputValues[1].Length; index++ ) + outputValues[0][index] = inputValues[0][((int)(tempPeriod)-1) * 2 + index]; + } + } + + /// + /// A weighted moving average is designed to put more weight on + /// recent data and less weight on past data. A weighted moving + /// average is calculated by multiplying each of the previous + /// day’s data by a weight. The following table shows the calculation + /// of a 5-day weighted moving average. + /// --------------------------------------------------------- + /// Input: + /// - Y values. + /// Output: + /// - Moving Average. + /// Parameters: + /// - Period + /// Extra Parameters: + /// - Start from First + /// + /// + /// Arrays of doubles: 1. row - X values, 2. row - Y values + /// Arrays of doubles: 1. row - X values, 2. row - Moving average + /// Array of strings: 1. Period + /// Array of strings: 1. Start from zero + private void WeightedMovingAverage(double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList) + { + int length = inputValues.Length; + + // Period for moving average + int period; + try + {period = int.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture );} + catch( Exception e ) + { + if (e.Message == SR.ExceptionObjectReferenceIsNull) + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing); + else + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing + e.Message); + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Starting average from the first data point or after period. + bool startFromFirst = bool.Parse( extraParameterList[0] ); + + // There is no enough series + if( length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + if( inputValues[0].Length != inputValues[1].Length ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsSameXYNumber); + + // Not enough values for moving average. + if( inputValues[0].Length < period ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsNotEnoughPoints); + + outputValues = new double [2][]; + + if( startFromFirst ) + { + // X values + outputValues[0] = new double [inputValues[0].Length]; + + // Y values + outputValues[1] = new double [inputValues[1].Length]; + + for( int point = 0; point < inputValues[0].Length; point++ ) + { + // Set X value + outputValues[0][point] = inputValues[0][point]; + + // Find sum of Y values + double sum = 0; + int startSum = 0; + + if( point - period + 1 > 0 ) + { + startSum = point - period + 1; + } + + int index = 1; + int indexSum = 0; + for( int pointSum = startSum; pointSum <= point; pointSum++ ) + { + sum += inputValues[1][pointSum] * index; + indexSum += index; + index++; + } + + double movingAvr; + + // Avoid division by zero. + if( point == 0 ) + movingAvr = inputValues[1][0]; + else + movingAvr = sum / indexSum; + + // Weighted average + outputValues[1][point] = movingAvr; + + } + } + else + { + // X values + outputValues[0] = new double [inputValues[0].Length - period + 1]; + + // Y values + outputValues[1] = new double [inputValues[1].Length - period + 1]; + + for( int point = 0; point < outputValues[0].Length; point++ ) + { + // Set X value + outputValues[0][point] = inputValues[0][point + period - 1]; + + // Find sum of Y values + double sum = 0; + + int index = 1; + int indexSum = 0; + for( int pointSum = point; pointSum < point + period; pointSum++ ) + { + sum += inputValues[1][pointSum] * index; + indexSum += index; + index++; + } + + double movingAvr = sum / indexSum; + + // Weighted average + outputValues[1][point] = movingAvr; + + } + } + } + + /// + /// Bollinger Bands plot trading bands above and below + /// a simple moving average. The standard deviation of + /// closing prices for a period equal to the moving + /// average employed is used to determine the band width. + /// This causes the bands to tighten in quiet markets and + /// loosen in volatile markets. The bands can be used to + /// determine overbought and oversold levels, locate + /// reversal areas, project targets for market moves, and + /// determine appropriate stop levels. The bands are used + /// in conjunction with indicators such as RSI, MovingAverageConvergenceDivergence + /// histogram, CCI and Rate of Change. Divergences between + /// Bollinger bands and other indicators show potential + /// action points. + /// --------------------------------------------------------- + /// Input: + /// - 1 Y value. + /// Output: + /// - 2 Y values (Bollinger Band Hi and Low). + /// Parameters: + /// - period + /// Extra Parameters: + /// - startFromFirst + /// + /// + /// Arrays of doubles: 1. row - X values, 2. row - Y values + /// Arrays of doubles: 1. row - X values, 2. row - Bollinger Band Up, 3. row - Bollinger Band Down + /// Array of strings: 1. Period + /// Array of strings: 1. Start from zero + private void BollingerBands(double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList) + { + int length = inputValues.Length; + + // Period for moving average + int period; + try + {period = int.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture );} + catch( Exception e ) + { + if (e.Message == SR.ExceptionObjectReferenceIsNull) + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing); + else + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing + e.Message); + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Standard deviation + double deviation; + try + {deviation = double.Parse( parameterList[1], System.Globalization.CultureInfo.InvariantCulture );} + catch(System.Exception) + { throw new InvalidOperationException(SR.ExceptionIndicatorsDeviationMissing); } + + // Starting average from the first data point or after period. + bool startFromFirst = bool.Parse( extraParameterList[0] ); + + // There is no enough series + if( length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + if( inputValues[0].Length != inputValues[1].Length ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsSameXYNumber); + + // Not enough values for moving average. + if( inputValues[0].Length < period ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsNotEnoughPoints); + + outputValues = new double [3][]; + + if( startFromFirst ) + { + // X values + outputValues[0] = new double [inputValues[0].Length]; + + // Y values + outputValues[1] = new double [inputValues[1].Length]; + outputValues[2] = new double [inputValues[1].Length]; + + // average + double [] average = new double [inputValues[1].Length]; + + MovingAverage( inputValues[1], out average, period, true ); + + for( int point = 0; point < outputValues[0].Length; point++ ) + { + // Set X value + outputValues[0][point] = inputValues[0][point]; + + // Find sum of Y values + double sum = 0; + int startSum = 0; + + // Find the begining of the period + if( point - period + 1 > 0 ) + { + startSum = point - period + 1; + } + + for( int pointSum = startSum; pointSum <= point; pointSum++ ) + { + sum += ((inputValues[1][pointSum] - average[point])*(inputValues[1][pointSum] - average[point])); + } + + outputValues[1][point] = average[point] + Math.Sqrt(sum / period) * deviation; + outputValues[2][point] = average[point] - Math.Sqrt(sum / period) * deviation; + } + } + else + { + // X values + outputValues[0] = new double [inputValues[0].Length - period + 1]; + + // Y values + outputValues[1] = new double [inputValues[1].Length - period + 1]; + outputValues[2] = new double [inputValues[1].Length - period + 1]; + + // average + double [] average = new double [inputValues[1].Length - period + 1]; + + MovingAverage( inputValues[1], out average, period, false ); + + for( int point = 0; point < outputValues[0].Length; point++ ) + { + // Set X value + outputValues[0][point] = inputValues[0][point + period - 1]; + + // Find sum of Y values + double sum = 0; + + for( int pointSum = point; pointSum < point + period; pointSum++ ) + { + sum += ((inputValues[1][pointSum] - average[point])*(inputValues[1][pointSum] - average[point])); + } + + outputValues[1][point] = average[point] + Math.Sqrt(sum / period) * deviation; + outputValues[2][point] = average[point] - Math.Sqrt(sum / period) * deviation; + } + } + } + + /// + /// The Typical Price indicator is simply an average of each + /// day's price. The Median Price and Weighted Close are + /// similar indicators. The Typical Price indicator provides + /// a simple, single-line plot of the day's average price. + /// Some investors use the Typical Price rather than the + /// closing price when creating moving average ----ion + /// systems. + /// --------------------------------------------------------- + /// Input: + /// - 3 Y values ( Close, High, Low ). + /// Output: + /// - 1 Y value Weighted Close Indicator. + /// + /// Arrays of doubles: 1. row - X values, 2. row - Y values (Close), 3. row - Y values (High), 4. row - Y values (Low) + /// Arrays of doubles: 1. row - X values, 2. row - Weighted Close + private void TypicalPrice(double [][] inputValues, out double [][] outputValues) + { + int length = inputValues.Length; + + // There is no enough series + if( length != 4 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresThreeArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 3 ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length]; + outputValues[1] = new double [inputValues[1].Length]; + + for( int index = 0; index < inputValues[1].Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index]; + + // Set median price + outputValues[1][index] = (inputValues[1][index] + inputValues[2][index] + inputValues[3][index])/3.0; + } + + } + + /// + /// The Median Price indicator is simply the midpoint of each + /// day's price. The Typical Price and Weighted Close are + /// similar indicators. The Median Price indicator provides + /// a simple, single-line chart of the day's "average price." + /// This average price is useful when you want a simpler + /// scaleView of prices. + /// --------------------------------------------------------- + /// Input: + /// - 2 Y values ( High, Low ). + /// Output: + /// - 1 Y value Median Price Indicator. + /// + /// Arrays of doubles: 1. row - X values, 2. row - Y values (High), 3. row - Y values (Low) + /// Arrays of doubles: 1. row - X values, 2. row - Median Price + private void MedianPrice(double [][] inputValues, out double [][] outputValues) + { + int length = inputValues.Length; + + // There is no enough series + if( length != 3 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 2 ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length]; + outputValues[1] = new double [inputValues[1].Length]; + + for( int index = 0; index < inputValues[1].Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index]; + + // Set median price + outputValues[1][index] = (inputValues[1][index] + inputValues[2][index])/2.0; + } + + } + + /// + /// The Weighted Close indicator is simply an average of each day's + /// price. It gets its name from the fact that extra weight is + /// given to the closing price. The Median Price and Typical Price + /// are similar indicators. When plotting and back-testing moving + /// averages, indicators, trendlines, etc, some investors like + /// the simplicity that a line chart offers. However, line + /// charts that only show the closing price can be misleading + /// since they ignore the high and low price. A Weighted Close + /// chart combines the simplicity of the line chart with the + /// scope of a bar chart, by plotting a single point for each + /// day that includes the high, low, and closing price. + /// --------------------------------------------------------- + /// Input: + /// - 3 Y values ( Close, High, Low ). + /// Output: + /// - 1 Y value Weighted Close Indicator. + /// + /// Arrays of doubles: 1. row - X values, 2. row - Y values (Close), 3. row - Y values (High), 4. row - Y values (Low) + /// Arrays of doubles: 1. row - X values, 2. row - Weighted Close + private void WeightedClose(double [][] inputValues, out double [][] outputValues) + { + int length = inputValues.Length; + + // There is no enough series + if( length != 4 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresThreeArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 3 ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length]; + outputValues[1] = new double [inputValues[1].Length]; + + for( int index = 0; index < inputValues[1].Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index]; + + // Set median price + outputValues[1][index] = (inputValues[1][index] + inputValues[2][index] + inputValues[3][index] * 2)/4.0; + } + + } + + /// + /// An envelope is comprised of two moving averages. One moving + /// average is shifted upward and the second moving average + /// is shifted downward. Envelopes define the upper and lower + /// boundaries of a security's normal trading range. A sell + /// signal is generated when the security reaches the upper + /// band whereas a buy signal is generated at the lower band. + /// The optimum percentage shift depends on the volatility of + /// the security--the more volatile, the larger the percentage. + /// The logic behind envelopes is that overzealous buyers and + /// sellers push the price to the extremes (i.e., the upper + /// and lower bands), at which point the prices often stabilize + /// by moving to more realistic levels. This is similar to the + /// interpretation of Bollinger Bands. + /// --------------------------------------------------------- + /// Input: + /// - 1 Y value. + /// Output: + /// - 2 Y values (Envelope Hi and Low). + /// Parameters: + /// - period + /// - shift in percentages + /// Extra Parameters: + /// - startFromFirst + /// + /// + /// Arrays of doubles: 1. row - X values, 2. row - Y values + /// Arrays of doubles: 1. row - X values, 2. row - Envelopes Up, 3. row - Envelopes Down + /// Array of strings: parameters + /// Array of strings: Extra parameters + private void Envelopes(double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList) + { + int length = inputValues.Length; + + // Period for moving average + int period; + try + {period = int.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture );} + catch( Exception e ) + { + if (e.Message == SR.ExceptionObjectReferenceIsNull) + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing); + else + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing + e.Message); + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Shift + double shift; + try + {shift = double.Parse( parameterList[1], System.Globalization.CultureInfo.InvariantCulture );} + catch(System.Exception) + { throw new InvalidOperationException(SR.ExceptionPriceIndicatorsShiftParameterMissing); } + + // There is no enough series + if( length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + if( inputValues[0].Length != inputValues[1].Length ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsSameXYNumber); + + double [][] movingAverage; + + MovingAverage( inputValues, out movingAverage, parameterList, extraParameterList ); + + outputValues = new double[3][]; + outputValues[0] = new double[movingAverage[0].Length]; + outputValues[1] = new double[movingAverage[0].Length]; + outputValues[2] = new double[movingAverage[0].Length]; + + for( int index = 0; index < movingAverage[0].Length; index++ ) + { + outputValues[0][index] = movingAverage[0][index]; + outputValues[1][index] = movingAverage[1][index] + shift*movingAverage[1][index]/100.0; + outputValues[2][index] = movingAverage[1][index] - shift*movingAverage[1][index]/100.0; + + } + } + + /// + /// Standard Deviation is a statistical measure of volatility. + /// Standard Deviation is typically used as a component of + /// other indicators, rather than as a stand-alone indicator. + /// For example, Bollinger Bands are calculated by adding + /// a security's Standard Deviation to a moving average. + /// High Standard Deviation values occur when the data item + /// being analyzed (e.g., prices or an indicator) is changing + /// dramatically. Similarly, low Standard Deviation values + /// occur when prices are stable. + /// + /// Input Y values + /// Output standard deviation + /// Period + /// Start calculation from the first Y value + internal void StandardDeviation(double [] inputValues, out double [] outputValues, int period, bool startFromFirst ) + { + double [] movingOut; + + // Start calculation from the first Y value + if( startFromFirst ) + { + outputValues = new double[inputValues.Length]; + double sum; + MovingAverage( inputValues, out movingOut, period, startFromFirst ); + int outIndex = 0; + for( int index = 0; index < inputValues.Length; index++ ) + { + sum = 0; + int startSum = 0; + + // Find the begining of the period + if( index - period + 1 > 0 ) + { + startSum = index - period + 1; + } + for( int indexDev = startSum; indexDev <= index; indexDev++ ) + { + sum += (inputValues[indexDev] - movingOut[outIndex])*(inputValues[indexDev] - movingOut[outIndex]); + } + outputValues[outIndex] = Math.Sqrt( sum / period ); + outIndex++; + } + } + // Do not start calculation from the first Y value + else + { + outputValues = new double[inputValues.Length - period + 1]; + double sum; + MovingAverage( inputValues, out movingOut, period, startFromFirst ); + int outIndex = 0; + for( int index = period - 1; index < inputValues.Length; index++ ) + { + sum = 0; + for( int indexDev = index - period + 1; indexDev <= index; indexDev++ ) + { + sum += (inputValues[indexDev] - movingOut[outIndex])*(inputValues[indexDev] - movingOut[outIndex]); + } + outputValues[outIndex] = Math.Sqrt( sum / period ); + outIndex++; + } + } + } + + #endregion + + #region Methods + + /// + /// Default constructor + /// + public PriceIndicators() + { + } + + /// + /// This methods checks the number of X and Y values and + /// fire exception if the numbers are different. + /// + /// Input X and Y values + /// The number of Y values + public void CheckNumOfValues( double [][] inputValues, int numOfYValues ) + { + // Different number of x and y values + if( inputValues[0].Length != inputValues[1].Length ) + { + throw new ArgumentException(SR.ExceptionPriceIndicatorsSameXYNumber); + } + + // Different number of y values + for( int index = 1; index < numOfYValues; index++ ) + { + if( inputValues[index].Length != inputValues[index+1].Length ) + { + throw new ArgumentException( SR.ExceptionPriceIndicatorsSameYNumber ); + } + } + } + + /// + /// The first method in the module, which converts a formula + /// name to the corresponding private method. + /// + /// String which represent a formula name + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Formula parameters + /// Array of strings - Extra Formula parameters from DataManipulator object + /// Array of strings - Used for Labels. Description for output results. + virtual public void Formula( string formulaName, double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList, out string [][] outLabels ) + { + string name; + + name = formulaName.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + // Not used for these formulas. + outLabels = null; + + try + { + switch( name ) + { + case "MOVINGAVERAGE": + MovingAverage( inputValues, out outputValues, parameterList, extraParameterList ); + break; + case "EXPONENTIALMOVINGAVERAGE": + ExponentialMovingAverage( inputValues, out outputValues, parameterList, extraParameterList ); + break; + case "TRIANGULARMOVINGAVERAGE": + TriangularMovingAverage( inputValues, out outputValues, parameterList, extraParameterList ); + break; + case "WEIGHTEDMOVINGAVERAGE": + WeightedMovingAverage( inputValues, out outputValues, parameterList, extraParameterList ); + break; + case "BOLLINGERBANDS": + BollingerBands( inputValues, out outputValues, parameterList, extraParameterList ); + break; + case "MEDIANPRICE": + MedianPrice( inputValues, out outputValues ); + break; + case "TYPICALPRICE": + TypicalPrice( inputValues, out outputValues ); + break; + case "WEIGHTEDCLOSE": + WeightedClose( inputValues, out outputValues ); + break; + case "ENVELOPES": + Envelopes( inputValues, out outputValues, parameterList, extraParameterList ); + break; + default: + outputValues = null; + break; + } + } + catch( IndexOutOfRangeException ) + { + throw new InvalidOperationException(SR.ExceptionFormulaInvalidPeriod( name ) ); + } + catch( OverflowException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaNotEnoughDataPoints( name ) ); + } + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Formulas/StatisticalAnalysis.cs b/System.Web.DataVisualization/Common/Formulas/StatisticalAnalysis.cs new file mode 100644 index 000000000..579c7bc9c --- /dev/null +++ b/System.Web.DataVisualization/Common/Formulas/StatisticalAnalysis.cs @@ -0,0 +1,2189 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: StatisticalAnalysis.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Formulas +// +// Classes: StatisticalAnalysis +// +// Purpose: This class is used for Statistical Analysis +// +// Reviewed: AG - Apr 1, 2003 +// +//=================================================================== + + +using System; +using System.Collections; + + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Formulas +#else + namespace System.Web.UI.DataVisualization.Charting.Formulas +#endif +{ + /// + /// + /// + internal class StatisticalAnalysis : IFormula + { + + #region Error strings + + // Error strings + //internal string inputArrayStart = "Formula requires"; + //internal string inputArrayEnd = "arrays"; + + #endregion + + #region Parameters + + /// + /// Formula Module name + /// + virtual public string Name { get { return SR.FormulaNameStatisticalAnalysis; } } + + #endregion // Parameters + + #region Methods + + /// + /// Default constructor + /// + public StatisticalAnalysis() + { + } + + /// + /// The first method in the module, which converts a formula + /// name to the corresponding private method. + /// + /// String which represent a formula name + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Formula parameters + /// Array of strings - Extra Formula parameters from DataManipulator object + /// Array of strings - Used for Labels. Description for output results. + virtual public void Formula( string formulaName, double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList, out string [][] outLabels ) + { + string name; + + outLabels = null; + + name = formulaName.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + try + { + switch( name ) + { + case "TTESTEQUALVARIANCES": + TTest( inputValues, out outputValues, parameterList, out outLabels, true ); + break; + case "TTESTUNEQUALVARIANCES": + TTest( inputValues, out outputValues, parameterList, out outLabels, false ); + break; + case "TTESTPAIRED": + TTestPaired( inputValues, out outputValues, parameterList, out outLabels ); + break; + case "ZTEST": + ZTest( inputValues, out outputValues, parameterList, out outLabels ); + break; + case "FTEST": + FTest( inputValues, out outputValues, parameterList, out outLabels ); + break; + case "COVARIANCE": + Covariance( inputValues, out outputValues, out outLabels ); + break; + case "CORRELATION": + Correlation( inputValues, out outputValues, out outLabels ); + break; + case "ANOVA": + Anova( inputValues, out outputValues, parameterList, out outLabels ); + break; + case "TDISTRIBUTION": + TDistribution( out outputValues, parameterList, out outLabels ); + break; + case "FDISTRIBUTION": + FDistribution( out outputValues, parameterList, out outLabels ); + break; + case "NORMALDISTRIBUTION": + NormalDistribution( out outputValues, parameterList, out outLabels ); + break; + case "INVERSETDISTRIBUTION": + TDistributionInverse( out outputValues, parameterList, out outLabels ); + break; + case "INVERSEFDISTRIBUTION": + FDistributionInverse( out outputValues, parameterList, out outLabels ); + break; + case "INVERSENORMALDISTRIBUTION": + NormalDistributionInverse( out outputValues, parameterList, out outLabels ); + break; + case "MEAN": + Average( inputValues, out outputValues, out outLabels ); + break; + case "VARIANCE": + Variance( inputValues, out outputValues, parameterList, out outLabels ); + break; + case "MEDIAN": + Median( inputValues, out outputValues, out outLabels ); + break; + case "BETAFUNCTION": + BetaFunction( out outputValues, parameterList, out outLabels ); + break; + case "GAMMAFUNCTION": + GammaFunction( out outputValues, parameterList, out outLabels ); + break; + default: + outputValues = null; + break; + } + } + catch( IndexOutOfRangeException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaInvalidPeriod(name) ); + } + catch( OverflowException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaNotEnoughDataPoints(name) ); + } + } + + #endregion // Methods + + #region Statistical Tests + + /// + /// Anova test + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void Anova(double [][] inputValues, out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // There is no enough input series + if( inputValues.Length < 3 ) + throw new ArgumentException(SR.ExceptionStatisticalAnalysesNotEnoughInputSeries); + + outLabels = null; + + for( int index = 0; index < inputValues.Length - 1; index++ ) + { + if( inputValues[index].Length != inputValues[index+1].Length ) + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAnovaTest); + } + + // Alpha value + double alpha; + try + { + alpha = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + + if( alpha < 0 || alpha > 1 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [10]; + + // X + outputValues[0] = new double [10]; + + // Y + outputValues[1] = new double [10]; + + int m = inputValues.Length - 1; + int n = inputValues[0].Length; + + double [] average = new double[ m ]; + double [] variance = new double[ m ]; + + // Find averages + for( int group = 0; group < m; group++ ) + { + average[group] = Mean( inputValues[group+1] ); + } + + // Find variances + for( int group = 0; group < m; group++ ) + { + variance[group] = Variance( inputValues[group+1], true ); + } + + // Total Average ( for all groups ) + double averageTotal = Mean( average ); + + // Total Sample Variance + double totalS = 0; + foreach( double avr in average ) + { + totalS += ( avr - averageTotal ) * ( avr - averageTotal ); + } + + totalS /= ( m - 1 ); + + // Group Sample Variance + double groupS = Mean( variance ); + + // F Statistica + double f = totalS * ( n ) / groupS; + + // **************************************** + // Sum of Squares + // **************************************** + + // Grend Total Average + double grandTotalAverage = 0; + for( int group = 0; group < m; group++ ) + { + foreach( double point in inputValues[group+1] ) + { + grandTotalAverage += point; + } + } + + grandTotalAverage /= ( m * n ); + + // Treatment Sum of Squares + double trss = 0; + for( int group = 0; group < m; group++ ) + { + trss += ( average[group] - grandTotalAverage ) * ( average[group] - grandTotalAverage ); + } + + trss *= n; + + // Error Sum of Squares + double erss = 0; + for( int group = 0; group < m; group++ ) + { + foreach( double point in inputValues[group+1] ) + { + erss += ( point - average[group] ) * ( point - average[group] ); + } + } + + outLabels[0][0] = SR.LabelStatisticalSumOfSquaresBetweenGroups; + outputValues[0][0] = 1; + outputValues[1][0] = trss; + + outLabels[0][1] = SR.LabelStatisticalSumOfSquaresWithinGroups; + outputValues[0][1] = 2; + outputValues[1][1] = erss; + + outLabels[0][2] = SR.LabelStatisticalSumOfSquaresTotal; + outputValues[0][2] = 3; + outputValues[1][2] = trss + erss; + + outLabels[0][3] = SR.LabelStatisticalDegreesOfFreedomBetweenGroups; + outputValues[0][3] = 4; + outputValues[1][3] = m - 1; + + outLabels[0][4] = SR.LabelStatisticalDegreesOfFreedomWithinGroups; + outputValues[0][4] = 5; + outputValues[1][4] = m * ( n - 1 ); + + outLabels[0][5] = SR.LabelStatisticalDegreesOfFreedomTotal; + outputValues[0][5] = 6; + outputValues[1][5] = m * n - 1; + + outLabels[0][6] = SR.LabelStatisticalMeanSquareVarianceBetweenGroups; + outputValues[0][6] = 7; + outputValues[1][6] = trss / ( m - 1 ); + + outLabels[0][7] = SR.LabelStatisticalMeanSquareVarianceWithinGroups; + outputValues[0][7] = 8; + outputValues[1][7] = erss / ( m * ( n - 1 ) ); + + outLabels[0][8] = SR.LabelStatisticalFRatio; + outputValues[0][8] = 9; + outputValues[1][8] = f; + + outLabels[0][9] = SR.LabelStatisticalFCriteria; + outputValues[0][9] = 10; + outputValues[1][9] = FDistributionInverse( alpha, m - 1, m * ( n - 1 ) ); + + } + + + + + /// + /// Correlation measure the relationship between two data sets that + /// are scaled to be independent of the unit of measurement. The + /// population correlation calculation returns the covariance + /// of two data sets divided by the product of their standard + /// deviations: You can use the Correlation to determine whether two + /// ranges of data move together — that is, whether large values of + /// one set are associated with large values of the other + /// (positive correlation), whether small values of one set are + /// associated with large values of the other (negative correlation), + /// or whether values in both sets are unrelated (correlation + /// near zero). + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Used for Labels. Description for output results. + private void Correlation(double [][] inputValues, out double [][] outputValues, out string [][] outLabels ) + { + // There is no enough input series + if( inputValues.Length != 3 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + outLabels = null; + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + // Find Covariance. + double covar = Covar( inputValues[1], inputValues[2] ); + + double varianceX = Variance( inputValues[1], false ); + double varianceY = Variance( inputValues[2], false ); + + // Correlation + double correl = covar / Math.Sqrt( varianceX * varianceY ); + + outLabels[0][0] = SR.LabelStatisticalCorrelation; + outputValues[0][0] = 1; + outputValues[1][0] = correl; + + } + + /// + /// Returns covariance, the average of the products of deviations + /// for each data point pair. Use covariance to determine the + /// relationship between two data sets. For example, you can + /// examine whether greater income accompanies greater + /// levels of education. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Used for Labels. Description for output results. + private void Covariance(double [][] inputValues, out double [][] outputValues, out string [][] outLabels ) + { + // There is no enough input series + if( inputValues.Length != 3 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + outLabels = null; + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + // Find Covariance. + double covar = Covar( inputValues[1], inputValues[2] ); + + outLabels[0][0] = SR.LabelStatisticalCovariance; + outputValues[0][0] = 1; + outputValues[1][0] = covar; + + } + + /// + /// Returns the result of an F-test. An F-test returns the one-tailed + /// probability that the variances in array1 and array2 are not + /// significantly different. Use this function to determine + /// whether two samples have different variances. For example, + /// given test scores from public and private schools, you can + /// test whether these schools have different levels of diversity. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void FTest(double [][] inputValues, out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // There is no enough input series + if( inputValues.Length != 3 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + outLabels = null; + + double alpha; + + // The number of data points has to be > 1. + CheckNumOfPoints( inputValues ); + + // Alpha value + try + { + alpha = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + + if( alpha < 0 || alpha > 1 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [7]; + + // X + outputValues[0] = new double [7]; + + // Y + outputValues[1] = new double [7]; + + // Find Variance of the first group + double variance1 = Variance( inputValues[1], true ); + + // Find Variance of the second group + double variance2 = Variance( inputValues[2], true ); + + // Find Mean of the first group + double mean1 = Mean( inputValues[1] ); + + // Find Mean of the second group + double mean2 = Mean( inputValues[2] ); + + // F Value + double valueF = variance1 / variance2; + + if( variance2 == 0 ) + { + throw new InvalidOperationException(SR.ExceptionStatisticalAnalysesZeroVariance); + } + + // The way to find a left critical value is to reversed the degrees of freedom, + // look up the right critical value, and then take the reciprocal of this value. + // For example, the critical value with 0.05 on the left with 12 numerator and 15 + // denominator degrees of freedom is found of taking the reciprocal of the critical + // value with 0.05 on the right with 15 numerator and 12 denominator degrees of freedom. + // Avoiding Left Critical Values. Since the left critical values are a pain to calculate, + // they are often avoided altogether. This is the procedure followed in the textbook. + // You can force the F test into a right tail test by placing the sample with the large + // variance in the numerator and the smaller variance in the denominator. It does not + // matter which sample has the larger sample size, only which sample has the larger + // variance. The numerator degrees of freedom will be the degrees of freedom for + // whichever sample has the larger variance (since it is in the numerator) and the + // denominator degrees of freedom will be the degrees of freedom for whichever sample + // has the smaller variance (since it is in the denominator). + bool lessOneF = valueF <= 1; + + double fDistInv; + double fDist; + + if( lessOneF ) + { + fDistInv = FDistributionInverse( 1 - alpha, inputValues[1].Length - 1, inputValues[2].Length - 1 ); + fDist = 1 - FDistribution( valueF, inputValues[1].Length - 1, inputValues[2].Length - 1 ); + } + else + { + fDistInv = FDistributionInverse( alpha, inputValues[1].Length - 1, inputValues[2].Length - 1 ); + fDist = FDistribution( valueF, inputValues[1].Length - 1, inputValues[2].Length - 1 ); + } + + outLabels[0][0] = SR.LabelStatisticalTheFirstGroupMean; + outputValues[0][0] = 1; + outputValues[1][0] = mean1; + + outLabels[0][1] = SR.LabelStatisticalTheSecondGroupMean; + outputValues[0][1] = 2; + outputValues[1][1] = mean2; + + outLabels[0][2] = SR.LabelStatisticalTheFirstGroupVariance; + outputValues[0][2] = 3; + outputValues[1][2] = variance1; + + outLabels[0][3] = SR.LabelStatisticalTheSecondGroupVariance; + outputValues[0][3] = 4; + outputValues[1][3] = variance2; + + outLabels[0][4] = SR.LabelStatisticalFValue; + outputValues[0][4] = 5; + outputValues[1][4] = valueF; + + outLabels[0][5] = SR.LabelStatisticalPFLessEqualSmallFOneTail; + outputValues[0][5] = 6; + outputValues[1][5] = fDist; + + outLabels[0][6] = SR.LabelStatisticalFCriticalValueOneTail; + outputValues[0][6] = 7; + outputValues[1][6] = fDistInv; + } + + + /// + /// Returns the two-tailed P-value of a z-test. The z-test + /// generates a standard score for x with respect to the data set, + /// array, and returns the two-tailed probability for the + /// normal distribution. You can use this function to assess + /// the likelihood that a particular observation is drawn + /// from a particular population. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void ZTest(double [][] inputValues, out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // There is no enough input series + if( inputValues.Length != 3 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + // The number of data points has to be > 1. + CheckNumOfPoints( inputValues ); + + outLabels = null; + + double variance1; + double variance2; + double alpha; + double HypothesizedMeanDifference; + + // Find Hypothesized Mean Difference parameter + try + { + HypothesizedMeanDifference = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidMeanDifference); + } + + if( HypothesizedMeanDifference < 0.0 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesNegativeMeanDifference); + } + + // Find variance of the first group + try + { + variance1 = double.Parse( parameterList[1], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidVariance); + } + + // Find variance of the second group + try + { + variance2 = double.Parse( parameterList[2], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidVariance); + } + + // Alpha value + try + { + alpha = double.Parse( parameterList[3], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + + if( alpha < 0 || alpha > 1 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [9]; + + // X + outputValues[0] = new double [9]; + + // Y + outputValues[1] = new double [9]; + + // Find Mean of the first group + double mean1 = Mean( inputValues[1] ); + + // Find Mean of the second group + double mean2 = Mean( inputValues[2] ); + + double dev = Math.Sqrt( variance1 / inputValues[1].Length + variance2 / inputValues[2].Length ); + + // Z Value + double valueZ = ( mean1 - mean2 - HypothesizedMeanDifference ) / dev; + + double normalDistTwoInv = NormalDistributionInverse( 1 - alpha / 2 ); + double normalDistOneInv = NormalDistributionInverse( 1 - alpha); + double normalDistOne; + double normalDistTwo; + + if( valueZ < 0.0 ) + { + normalDistOne = NormalDistribution( valueZ ); + } + else + { + normalDistOne = 1.0 - NormalDistribution( valueZ ); + } + + normalDistTwo = 2.0 * normalDistOne; + + outLabels[0][0] = SR.LabelStatisticalTheFirstGroupMean; + outputValues[0][0] = 1; + outputValues[1][0] = mean1; + + outLabels[0][1] = SR.LabelStatisticalTheSecondGroupMean; + outputValues[0][1] = 2; + outputValues[1][1] = mean2; + + outLabels[0][2] = SR.LabelStatisticalTheFirstGroupVariance; + outputValues[0][2] = 3; + outputValues[1][2] = variance1; + + outLabels[0][3] = SR.LabelStatisticalTheSecondGroupVariance; + outputValues[0][3] = 4; + outputValues[1][3] = variance2; + + outLabels[0][4] = SR.LabelStatisticalZValue; + outputValues[0][4] = 5; + outputValues[1][4] = valueZ; + + outLabels[0][5] = SR.LabelStatisticalPZLessEqualSmallZOneTail; + outputValues[0][5] = 6; + outputValues[1][5] = normalDistOne; + + outLabels[0][6] = SR.LabelStatisticalZCriticalValueOneTail; + outputValues[0][6] = 7; + outputValues[1][6] = normalDistOneInv; + + outLabels[0][7] = SR.LabelStatisticalPZLessEqualSmallZTwoTail; + outputValues[0][7] = 8; + outputValues[1][7] = normalDistTwo; + + outLabels[0][8] = SR.LabelStatisticalZCriticalValueTwoTail; + outputValues[0][8] = 9; + outputValues[1][8] = normalDistTwoInv; + } + + /// + /// Returns the two-tailed P-value of a z-test. The z-test + /// generates a standard score for x with respect to the data set, + /// array, and returns the two-tailed probability for the + /// normal distribution. You can use this function to assess + /// the likelihood that a particular observation is drawn + /// from a particular population. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + /// True if Variances are equal. + private void TTest(double [][] inputValues, out double [][] outputValues, string [] parameterList, out string [][] outLabels, bool equalVariances ) + { + // There is no enough input series + if( inputValues.Length != 3 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + outLabels = null; + + double variance1; + double variance2; + double alpha; + double HypothesizedMeanDifference; + + // Find Hypothesized Mean Difference parameter + try + { + HypothesizedMeanDifference = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidMeanDifference); + } + + if( HypothesizedMeanDifference < 0.0 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesNegativeMeanDifference); + } + + // Alpha value + try + { + alpha = double.Parse( parameterList[1], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + + if( alpha < 0 || alpha > 1 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + + // The number of data points has to be > 1. + CheckNumOfPoints( inputValues ); + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [10]; + + // X + outputValues[0] = new double [10]; + + // Y + outputValues[1] = new double [10]; + + // Find Mean of the first group + double mean1 = Mean( inputValues[1] ); + + // Find Mean of the second group + double mean2 = Mean( inputValues[2] ); + + variance1 = Variance( inputValues[1], true ); + + variance2 = Variance( inputValues[2], true ); + + double s; + double T; + int freedom; + if( equalVariances ) + { + freedom = inputValues[1].Length + inputValues[2].Length - 2; + + // S value + s = ( ( inputValues[1].Length - 1 ) * variance1 + ( inputValues[2].Length - 1 ) * variance2 ) / ( inputValues[1].Length + inputValues[2].Length - 2 ); + + // T value + T = ( mean1 - mean2 - HypothesizedMeanDifference ) / ( Math.Sqrt( s * ( 1.0 / inputValues[1].Length + 1.0 / inputValues[2].Length ) ) ); + + } + else + { + double m = inputValues[1].Length; + double n = inputValues[2].Length; + double s1 = variance1; + double s2 = variance2; + double f = ( s1 / m + s2 / n ) * ( s1 / m + s2 / n ) / ( ( s1 / m ) * ( s1 / m ) / ( m - 1 ) + ( s2 / n ) * ( s2 / n ) / ( n - 1 ) ); + freedom = (int)Math.Round(f); + + s = Math.Sqrt( variance1 / inputValues[1].Length + variance2 / inputValues[2].Length ); + + // Z Value + T = ( mean1 - mean2 - HypothesizedMeanDifference ) / s; + } + + double TDistTwoInv = StudentsDistributionInverse( alpha , freedom ); + + bool more50 = alpha > 0.5; + + if( more50 ) + { + alpha = 1 - alpha; + } + + double TDistOneInv = StudentsDistributionInverse( alpha * 2.0, freedom ); + + if( more50 ) + { + TDistOneInv *= -1.0; + } + + double TDistTwo = StudentsDistribution( T, freedom, false ); + double TDistOne = StudentsDistribution( T, freedom, true ); + + outLabels[0][0] = SR.LabelStatisticalTheFirstGroupMean; + outputValues[0][0] = 1; + outputValues[1][0] = mean1; + + outLabels[0][1] = SR.LabelStatisticalTheSecondGroupMean; + outputValues[0][1] = 2; + outputValues[1][1] = mean2; + + outLabels[0][2] = SR.LabelStatisticalTheFirstGroupVariance; + outputValues[0][2] = 3; + outputValues[1][2] = variance1; + + outLabels[0][3] = SR.LabelStatisticalTheSecondGroupVariance; + outputValues[0][3] = 4; + outputValues[1][3] = variance2; + + outLabels[0][4] = SR.LabelStatisticalTValue; + outputValues[0][4] = 5; + outputValues[1][4] = T; + + outLabels[0][5] = SR.LabelStatisticalDegreeOfFreedom; + outputValues[0][5] = 6; + outputValues[1][5] = freedom; + + outLabels[0][6] = SR.LabelStatisticalPTLessEqualSmallTOneTail; + outputValues[0][6] = 7; + outputValues[1][6] = TDistOne; + + outLabels[0][7] = SR.LabelStatisticalSmallTCrititcalOneTail; + outputValues[0][7] = 8; + outputValues[1][7] = TDistOneInv; + + outLabels[0][8] = SR.LabelStatisticalPTLessEqualSmallTTwoTail; + outputValues[0][8] = 9; + outputValues[1][8] = TDistTwo; + + outLabels[0][9] = SR.LabelStatisticalSmallTCrititcalTwoTail; + outputValues[0][9] = 10; + outputValues[1][9] = TDistTwoInv; + } + + + /// + /// Returns the two-tailed P-value of a z-test. The z-test + /// generates a standard score for x with respect to the data set, + /// array, and returns the two-tailed probability for the + /// normal distribution. You can use this function to assess + /// the likelihood that a particular observation is drawn + /// from a particular population. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void TTestPaired(double [][] inputValues, out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // There is no enough input series + if( inputValues.Length != 3 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + if( inputValues[1].Length != inputValues[2].Length ) + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidVariableRanges); + + outLabels = null; + + double variance; + double alpha; + double HypothesizedMeanDifference; + int freedom; + + // Find Hypothesized Mean Difference parameter + try + { + HypothesizedMeanDifference = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidMeanDifference); + } + + if( HypothesizedMeanDifference < 0.0 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesNegativeMeanDifference); + } + + // Alpha value + try + { + alpha = double.Parse( parameterList[1], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + + if( alpha < 0 || alpha > 1 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + + // The number of data points has to be > 1. + CheckNumOfPoints( inputValues ); + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [10]; + + // X + outputValues[0] = new double [10]; + + // Y + outputValues[1] = new double [10]; + + double [] difference = new double[inputValues[1].Length]; + + for( int item = 0; item < inputValues[1].Length; item++ ) + { + difference[item] = inputValues[1][item] - inputValues[2][item]; + } + + // Find Mean of the second group + double mean = Mean( difference ); + + variance = Math.Sqrt( Variance( difference, true ) ); + + double T = ( Math.Sqrt( inputValues[1].Length ) * ( mean - HypothesizedMeanDifference ) ) / variance; + + freedom = inputValues[1].Length - 1; + + double TDistTwoInv = StudentsDistributionInverse( alpha , freedom ); + double TDistOneInv = alpha <= 0.5 ? StudentsDistributionInverse(2 * alpha, freedom) : double.NaN; + double TDistTwo = StudentsDistribution( T, freedom, false ); + double TDistOne = StudentsDistribution( T, freedom, true ); + + outLabels[0][0] = SR.LabelStatisticalTheFirstGroupMean; + outputValues[0][0] = 1; + outputValues[1][0] = Mean(inputValues[1]); + + outLabels[0][1] = SR.LabelStatisticalTheSecondGroupMean; + outputValues[0][1] = 2; + outputValues[1][1] = Mean(inputValues[2]); + + outLabels[0][2] = SR.LabelStatisticalTheFirstGroupVariance; + outputValues[0][2] = 3; + outputValues[1][2] = Variance(inputValues[1],true); + + outLabels[0][3] = SR.LabelStatisticalTheSecondGroupVariance; + outputValues[0][3] = 4; + outputValues[1][3] = Variance(inputValues[2],true); + + outLabels[0][4] = SR.LabelStatisticalTValue; + outputValues[0][4] = 5; + outputValues[1][4] = T; + + outLabels[0][5] = SR.LabelStatisticalDegreeOfFreedom; + outputValues[0][5] = 6; + outputValues[1][5] = freedom; + + outLabels[0][6] = SR.LabelStatisticalPTLessEqualSmallTOneTail; + outputValues[0][6] = 7; + outputValues[1][6] = TDistOne; + + outLabels[0][7] = SR.LabelStatisticalSmallTCrititcalOneTail; + outputValues[0][7] = 8; + outputValues[1][7] = TDistOneInv; + + outLabels[0][8] = SR.LabelStatisticalPTLessEqualSmallTTwoTail; + outputValues[0][8] = 9; + outputValues[1][8] = TDistTwo; + + outLabels[0][9] = SR.LabelStatisticalSmallTCrititcalTwoTail; + outputValues[0][9] = 10; + outputValues[1][9] = TDistTwoInv; + } + + + #endregion // Statistical Tests + + #region Public distributions + + /// + /// Returns the Percentage Points (probability) for the Student + /// t-distribution. The t-distribution is used in the hypothesis + /// testing of small sample data sets. Use this function in place + /// of a table of critical values for the t-distribution. + /// + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void TDistribution(out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // T value value + double tValue; + try + { + tValue = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidTValue); + } + + // DegreeOfFreedom + int freedom; + try + { + freedom = int.Parse( parameterList[1], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom); + } + + // One Tailed distribution + int oneTailed; + try + { + oneTailed = int.Parse( parameterList[2], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidTailedParameter); + } + + + outLabels = null; + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + outLabels[0][0] = SR.LabelStatisticalProbability; + outputValues[0][0] = 1; + outputValues[1][0] = StudentsDistribution( tValue, freedom, oneTailed == 1 ); + + } + + /// + /// Returns the F probability distribution. You can use + /// this function to determine whether two data sets have + /// different degrees of diversity. For example, you can + /// examine test scores given to men and women entering + /// high school and determine if the variability in the + /// females is different from that found in the males. + /// + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void FDistribution(out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // F value value + double fValue; + try + { + fValue = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidTValue); + } + + // Degree Of Freedom 1 + int freedom1; + try + { + freedom1 = int.Parse( parameterList[1], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom); + } + + // Degree Of Freedom 2 + int freedom2; + try + { + freedom2 = int.Parse( parameterList[2], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom); + } + + outLabels = null; + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + outLabels[0][0] = SR.LabelStatisticalProbability; + outputValues[0][0] = 1; + outputValues[1][0] = FDistribution( fValue, freedom1, freedom2 ); + } + + /// + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void NormalDistribution(out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // F value value + double zValue; + try + { + zValue = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidZValue); + } + + outLabels = null; + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + outLabels[0][0] = SR.LabelStatisticalProbability; + outputValues[0][0] = 1; + outputValues[1][0] = this.NormalDistribution( zValue ); + } + + /// + /// Returns the t-value of the Student's t-distribution + /// as a function of the probability and the degrees + /// of freedom. + /// + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void TDistributionInverse(out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // T value value + double probability; + try + { + probability = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidProbabilityValue); + } + + // DegreeOfFreedom + int freedom; + try + { + freedom = int.Parse( parameterList[1], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom); + } + + outLabels = null; + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + outLabels[0][0] = SR.LabelStatisticalProbability; + outputValues[0][0] = 1; + outputValues[1][0] = StudentsDistributionInverse( probability, freedom ); + + } + + /// + /// Returns the inverse of the F probability distribution. + /// If p = FDIST(x,...), then FINV(p,...) = x. The F distribution + /// can be used in an F-test that compares the degree of + /// variability in two data sets. For example, you can analyze + /// income distributions in the United States and Canada to + /// determine whether the two ---- have a similar degree + /// of diversity. + /// + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void FDistributionInverse(out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // Probability value value + double probability; + try + { + probability = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidProbabilityValue); + } + + // Degree Of Freedom 1 + int freedom1; + try + { + freedom1 = int.Parse( parameterList[1], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom); + } + + // Degree Of Freedom 2 + int freedom2; + try + { + freedom2 = int.Parse( parameterList[2], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom); + } + + outLabels = null; + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + outLabels[0][0] = SR.LabelStatisticalProbability; + outputValues[0][0] = 1; + outputValues[1][0] = FDistributionInverse( probability, freedom1, freedom2 ); + } + + /// + /// Returns the inverse of the standard normal + /// cumulative distribution. The distribution + /// has a mean of zero and a standard deviation + /// of one. + /// + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void NormalDistributionInverse(out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // Alpha value value + double alpha; + try + { + alpha = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + + outLabels = null; + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + outLabels[0][0] = SR.LabelStatisticalProbability; + outputValues[0][0] = 1; + outputValues[1][0] = this.NormalDistributionInverse( alpha ); + } + + #endregion + + #region Utility Statistical Functions + + + /// + /// Check number of data points. The number should be greater then 1. + /// + /// Input series + private void CheckNumOfPoints( double [][] inputValues ) + { + if( inputValues[1].Length < 2 ) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesNotEnoughDataPoints); + } + + if( inputValues.Length > 2 ) + { + if( inputValues[2].Length < 2 ) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesNotEnoughDataPoints); + } + } + } + + /// + /// Returns covariance, the average of the products of deviations + /// for each data point pair. Use covariance to determine the + /// relationship between two data sets. For example, you can + /// examine whether greater income accompanies greater + /// levels of education. + /// + /// First data set from X random variable. + /// Second data set from Y random variable. + /// Returns covariance + private double Covar( double [] arrayX, double [] arrayY ) + { + // Check the number of data points + if( arrayX.Length != arrayY.Length ) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesCovariance); + } + + double [] arrayXY = new double[arrayX.Length]; + + // Find XY + for( int index = 0; index < arrayX.Length; index++ ) + { + arrayXY[index] = arrayX[index] * arrayY[index]; + } + + // Find means + double meanXY = Mean( arrayXY ); + double meanX = Mean( arrayX ); + double meanY = Mean( arrayY ); + + // return covariance + return meanXY - meanX * meanY; + } + + /// + /// Returns the natural logarithm of the gamma function, G(x). + /// + /// The value for which you want to calculate gamma function. + /// Returns the natural logarithm of the gamma function. + private double GammLn( double n ) + { + double x; + double y; + double tmp; + double sum; + double [] cof = {76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5}; + + if( n < 0 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesGammaBetaNegativeParameters); + } + + // Iterative method for Gamma function + y = x = n; + tmp = x + 5.5; + tmp -= ( x + 0.5 ) * Math.Log( tmp ); + sum = 1.000000000190015; + for( int item = 0; item <=5; item++ ) + { + sum += cof[item] / ++y; + } + + return -tmp + Math.Log( 2.5066282746310005 * sum / x ); + } + + /// + /// Calculates Beta function + /// + /// First parameter for beta function + /// Second parameter for beta function + /// returns beta function + private double BetaFunction( double m, double n ) + { + return Math.Exp( GammLn( m ) + GammLn( n ) - GammLn( m + n ) ); + } + + /// + /// Used by betai: Evaluates continued fraction for + /// incomplete beta function by modified Lentz’s + /// + /// Beta incomplete parameter + /// Beta incomplete parameter + /// Beta incomplete parameter + /// Value used for Beta incomplete function + private double BetaCF( double a, double b, double x ) + { + int MAXIT = 100; + double EPS = 3.0e-7; + double FPMIN = 1.0e-30; + + int m,m2; + double aa,c,d,del,h,qab,qam,qap; + qab = a + b; + qap= a + 1.0; + qam = a - 1.0; + c = 1.0; + d = 1.0 - qab * x / qap; + if ( Math.Abs(d) < FPMIN ) d=FPMIN; + d = 1.0 / d; + h = d; + + // Numerical approximation for Beta incomplete function + for( m=1; m<=MAXIT; m++ ) + { + m2 = 2*m; + aa = m*(b-m)*x/((qam+m2)*(a+m2)); + + // Find d coeficient + d = 1.0 + aa*d; + if( Math.Abs(d) < FPMIN ) d=FPMIN; + + // Find c coeficient + c = 1.0 + aa / c; + if( Math.Abs(c) < FPMIN ) c = FPMIN; + + // Find d coeficient + d = 1.0 / d; + + // Find h coeficient + h *= d*c; + + aa = -(a+m)*(qab+m)*x/((a+m2)*(qap+m2)); + + // Recalc d coeficient + d=1.0+aa*d; + if (Math.Abs(d) < FPMIN) d=FPMIN; + + // Recalc c coeficient + c=1.0+aa/c; + if (Math.Abs(c) < FPMIN) c=FPMIN; + + // Recalc d coeficient + d=1.0/d; + del=d*c; + + // Recalc h coeficient + h *= del; + + if (Math.Abs(del-1.0) < EPS) + { + break; + } + } + + if (m > MAXIT) + { + throw new InvalidOperationException(SR.ExceptionStatisticalAnalysesIncompleteBetaFunction); + } + + return h; + } + + /// + /// Standard normal density function + /// + /// T Value + /// Standard normal density + private double NormalDistributionFunction(double t) + { + return 0.398942280401433 * Math.Exp( -t * t / 2 ); + } + + /// + /// Returns the incomplete beta function Ix(a, b). + /// + /// Beta incomplete parameter + /// Beta incomplete parameter + /// Beta incomplete parameter + /// Beta Incomplete value + private double BetaIncomplete( double a, double b, double x ) + { + double bt; + if (x < 0.0 || x > 1.0) + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidInputParameter); + if (x == 0.0 || x == 1.0) + { + bt = 0.0; + } + else + { // Factors in front of the continued fraction. + bt = Math.Exp(GammLn(a + b) - GammLn(a) - GammLn(b) + a * Math.Log(x) + b * Math.Log(1.0 - x)); + } + + if (x < (a + 1.0) / (a + b + 2.0)) + { //Use continued fraction directly. + return bt * BetaCF(a, b, x) / a; + } + else + { // Use continued fraction after making the symmetry transformation. + return 1.0 - bt * BetaCF(b, a, 1.0 - x) / b; + } + } + + + #endregion // Utility Statistical Functions + + #region Statistical Parameters + + /// + /// Returns the average (arithmetic mean) of the arguments. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Used for Labels. Description for output results. + private void Average(double [][] inputValues, out double [][] outputValues, out string [][] outLabels ) + { + + outLabels = null; + + // Invalid number of data series + if( inputValues.Length != 2 ) + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidSeriesNumber); + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + outLabels[0][0] = SR.LabelStatisticalAverage; + outputValues[0][0] = 1; + outputValues[1][0] = Mean( inputValues[1] ); + + } + + /// + /// Calculates variance + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void Variance(double [][] inputValues, out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + + // Sample Variance value + bool sampleVariance; + try + { + sampleVariance = bool.Parse( parameterList[0] ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidVariance); + } + + CheckNumOfPoints(inputValues); + + // Invalid number of data series + if( inputValues.Length != 2 ) + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidSeriesNumber); + + outLabels = null; + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + outLabels[0][0] = SR.LabelStatisticalVariance; + outputValues[0][0] = 1; + outputValues[1][0] = Variance( inputValues[1], sampleVariance ); + + } + + /// + /// Calculates Median + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Used for Labels. Description for output results. + private void Median(double [][] inputValues, out double [][] outputValues, out string [][] outLabels ) + { + + outLabels = null; + + // Invalid number of data series + if( inputValues.Length != 2 ) + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidSeriesNumber); + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + outLabels[0][0] = SR.LabelStatisticalMedian; + outputValues[0][0] = 1; + outputValues[1][0] = Median( inputValues[1] ); + + } + + /// + /// Calculates Beta Function + /// + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void BetaFunction(out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // Degree of freedom + double m; + try + { + m = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom); + } + + // Degree of freedom + double n; + try + { + n = double.Parse( parameterList[1], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom); + } + + outLabels = null; + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + outLabels[0][0] = SR.LabelStatisticalBetaFunction; + outputValues[0][0] = 1; + outputValues[1][0] = BetaFunction( m, n ); + + } + + /// + /// Calculates Gamma Function + /// + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Used for Labels. Description for output results. + private void GammaFunction(out double [][] outputValues, string [] parameterList, out string [][] outLabels ) + { + // Degree of freedom + double m; + try + { + m = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture ); + } + catch(System.Exception) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidInputParameter); + } + + if( m < 0 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesGammaBetaNegativeParameters); + } + + outLabels = null; + + // Output arrays + outputValues = new double [2][]; + + // Output Labels + outLabels = new string [1][]; + + // Parameters description + outLabels[0] = new string [1]; + + // X + outputValues[0] = new double [1]; + + // Y + outputValues[1] = new double [1]; + + outLabels[0][0] = SR.LabelStatisticalGammaFunction; + outputValues[0][0] = 1; + outputValues[1][0] = Math.Exp( GammLn( m ) ); + + } + + + /// + /// Sort array of double values. + /// + /// Array of doubles which should be sorted. + private void Sort( ref double [] values ) + { + + double tempValue; + for( int outLoop = 0; outLoop < values.Length; outLoop++ ) + { + for( int inLoop = outLoop + 1; inLoop < values.Length; inLoop++ ) + { + if( values[ outLoop ] > values[ inLoop ] ) + { + tempValue = values[ outLoop ]; + values[ outLoop ] = values[ inLoop ]; + values[ inLoop ] = tempValue; + } + } + } + } + + /// + /// Returns the median of the given numbers + /// + /// Array of double numbers + /// Median + private double Median( double [] values ) + { + // Exception for zero lenght of series. + if( values.Length == 0 ) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidMedianConditions); + } + + // Sort array + Sort( ref values ); + + int position = values.Length / 2; + + // if number of points is even + if( values.Length % 2 == 0 ) + { + return ( values[position-1] + values[position] ) / 2.0; + } + else + { + return values[position]; + } + } + + /// + /// Calculates a Mean for a series of numbers. + /// + /// series with double numbers + /// Returns Mean + private double Mean( double [] values ) + { + // Exception for zero lenght of series. + if( values.Length == 0 ) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidMeanConditions); + } + + // Find sum of values + double sum = 0; + foreach( double item in values ) + { + sum += item; + } + + // Calculate Mean + return sum / values.Length; + } + + /// + /// Calculates a Variance for a series of numbers. + /// + /// double values + /// If variance is calculated from sample sum has to be divided by n-1. + /// Variance + private double Variance( double [] values, bool sampleVariance ) + { + + // Exception for zero lenght of series. + if( values.Length < 1 ) + { + throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidVarianceConditions); + } + + // Find sum of values + double sum = 0; + double mean = Mean( values ); + foreach( double item in values ) + { + sum += (item - mean) * (item - mean); + } + + // Calculate Variance + if( sampleVariance ) + { + return sum / ( values.Length - 1 ); + } + else + { + return sum / values.Length; + } + } + + #endregion // Statistical Parameters + + # region Distributions + + /// + /// Calculates the Percentage Points (probability) for the Student + /// t-distribution. The t-distribution is used in the hypothesis + /// testing of small sample data sets. Use this function in place + /// of a table of critical values for the t-distribution. + /// + /// The numeric value at which to evaluate the distribution. + /// An integer indicating the number of degrees of freedom. + /// Specifies the number of distribution tails to return. + /// Returns the Percentage Points (probability) for the Student t-distribution. + private double StudentsDistribution( double tValue, int n, bool oneTailed ) + { + // Validation + tValue = Math.Abs( tValue ); + if( n > 300 ) + { + n = 300; + } + + if( n < 1 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesStudentsNegativeFreedomDegree); + } + + double result = 1 - BetaIncomplete( n / 2.0, 0.5, n / (n + tValue * tValue) ); + + if( oneTailed ) + return ( 1.0 - result ) / 2.0; + else + return 1.0 - result; + } + + /// + /// Returns the standard normal cumulative distribution + /// function. The distribution has a mean of 0 (zero) and + /// a standard deviation of one. Use this function in place + /// of a table of standard normal curve areas. + /// + /// The value for which you want the distribution. + /// Returns the standard normal cumulative distribution. + private double NormalDistribution( double zValue ) + { + + double [] a = {0.31938153,-0.356563782,1.781477937,-1.821255978,1.330274429}; + double result; + if (zValue<-7.0) + { + result = NormalDistributionFunction(zValue)/Math.Sqrt(1.0+zValue*zValue); + } + else if (zValue>7.0) + { + result = 1.0 - NormalDistribution(-zValue); + } + else + { + result = 0.2316419; + result=1.0/(1+result*Math.Abs(zValue)); + result=1-NormalDistributionFunction(zValue)*(result*(a[0]+result*(a[1]+result*(a[2]+result*(a[3]+result*a[4]))))); + if (zValue<=0.0) + result=1.0-result; + } + return result; + } + + private double FDistribution( double x, int freedom1, int freedom2 ) + { + if (x < 0) + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidTValue); + if (freedom1 <= 0) + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom); + if (freedom2 <= 0) + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom); + if (x == 0) + return 1; + if (x == double.PositiveInfinity) + return 0; + + return BetaIncomplete( freedom2 / 2.0, freedom1 / 2.0, freedom2 / ( freedom2 + freedom1 * x ) ); + } + + #endregion // Distributions + + # region Inverse Distributions + + /// + /// Calculates the t-value of the Student's t-distribution + /// as a function of the probability and the degrees of freedom. + /// + /// The probability associated with the two-tailed Student's t-distribution. + /// The number of degrees of freedom to characterize the distribution. + /// Returns the t-value of the Student's t-distribution. + private double StudentsDistributionInverse( double probability, int n ) + { + //Fix for boundary cases + if (probability == 0) + return double.PositiveInfinity; + else if (probability == 1) + return 0; + else if (probability < 0 || probability > 1) + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidProbabilityValue); + + int step = 0; + return StudentsDistributionSearch( probability, n, step, 0.0, 100000.0 ); + } + + /// + /// Method for calculation of Inverse T Distribution (Binary tree) + /// solution for non linear equations + /// + /// Probability value + /// Degree of freedom + /// Step for Numerical solution for non linear equations + /// Start for numerical process + /// End for numerical process + /// Returns F ditribution inverse + private double StudentsDistributionSearch( double probability, int n, int step, double start, double end ) + { + step++; + + double mid = ( start + end ) / 2.0; + double result = StudentsDistribution( mid, n, false ); + double resultX; + + if( step > 100 ) + { + return mid; + } + + if( result <= probability ) + { + resultX = StudentsDistributionSearch( probability, n, step, start, mid ); + } + else + { + resultX = StudentsDistributionSearch( probability, n, step, mid, end ); + } + + return resultX; + } + + /// + /// Returns the inverse of the standard normal cumulative distribution. + /// The distribution has a mean of zero and a standard deviation of one. + /// + /// A probability corresponding to the normal distribution. + /// Returns the inverse of the standard normal cumulative distribution. + private double NormalDistributionInverse( double probability ) + { + + // Validation + if( probability < 0.00001 || probability > 0.99999 ) + { + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesNormalInvalidProbabilityValue); + } + + double [] a = { 2.50662823884, -18.61500062529, 41.39119773534, -25.44106049637 }; + double [] b = { -8.47351093090, 23.08336743743, -21.06224101826, 3.13082909833 }; + double [] c = { 0.3374754822726147, 0.9761690190917186, 0.1607979714918209, 0.0276438810333863, 0.0038405729373609, 0.0003951896511919, 0.0000321767881768, 0.0000002888167364, 0.0000003960315187}; + + double x,r; + + // Numerical Integration + x = probability - 0.5; + + if ( Math.Abs(x) < 0.42 ) + { + r = x * x; + r = x * ( ( ( a[3] * r + a[2] ) * r + a[1] ) * r + a[0] ) / ( ( ( ( b[3] * r + b[2] ) * r + b[1] ) * r + b[0] ) * r + 1.0 ); + return( r ); + } + r= probability; + if( x > 0.0 ) + { + r = 1.0 - probability; + } + + r = Math.Log( -Math.Log( r ) ); + r = c[0] + r * ( c[1] + r * ( c[2] + r * ( c[3] + r * ( c[4] + r * ( c[5] + r * ( c[6] + r * ( c[7]+r * c[8] ) ) ) ) ) ) ); + if( x < 0.0 ) + { + r = -r; + } + + return r; + } + + /// + /// Calculates the inverse of the F probability distribution. + /// The F distribution can be used in an F-test that compares + /// the degree of variability in two data sets. + /// + /// A probability associated with the F cumulative distribution. + /// The numerator degrees of freedom. + /// The denominator degrees of freedom. + /// Returns the inverse of the F probability distribution. + private double FDistributionInverse( double probability, int m, int n ) + { + //Fix for boundary cases + if (probability == 0) + return double.PositiveInfinity; + else if (probability == 1) + return 0; + else if (probability < 0 || probability > 1) + throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidProbabilityValue); + + int step = 0; + return FDistributionSearch( probability, m, n, step, 0.0, 10000.0 ); + } + + /// + /// Method for calculation of Inverse F Distribution (Binary tree) + /// solution for non linear equations + /// + /// Probability value + /// Degree of freedom + /// Degree of freedom + /// Step for solution for non linear equations. + /// Start for numerical process + /// End for numerical process + /// Returns F ditribution inverse + private double FDistributionSearch( double probability, int m, int n, int step, double start, double end ) + { + step++; + + double mid = ( start + end ) / 2.0; + double result = FDistribution( mid, m, n ); + double resultX; + + if( step > 30 ) + { + return mid; + } + + if( result <= probability ) + { + resultX = FDistributionSearch( probability, m, n, step, start, mid ); + } + else + { + resultX = FDistributionSearch( probability, m, n, step, mid, end ); + } + + return resultX; + } + + + #endregion // Inverse Distributions + + } +} + + + diff --git a/System.Web.DataVisualization/Common/Formulas/TechGeneralIndicators.cs b/System.Web.DataVisualization/Common/Formulas/TechGeneralIndicators.cs new file mode 100644 index 000000000..b411be632 --- /dev/null +++ b/System.Web.DataVisualization/Common/Formulas/TechGeneralIndicators.cs @@ -0,0 +1,876 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: TechGeneralIndicators.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Formulas +// +// Classes: TechGeneralIndicators +// +// Purpose: This class is used for calculations of +// general technical analyses indicators. +// +// Reviewed: GS - August 7, 2002 +// AG - August 7, 2002 +// +//=================================================================== + + +using System; +using System.Globalization; + + + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Formulas +#else + namespace System.Web.UI.DataVisualization.Charting.Formulas +#endif +{ + /// + /// This class is used for calculations of general + /// technical analyses indicators. + /// + internal class GeneralTechnicalIndicators : PriceIndicators + { + #region Properties + + /// + /// Formula Module name + /// + override public string Name { get { return SR.FormulaNameGeneralTechnicalIndicators; } } + + #endregion + + #region Formulas + + /// + /// Standard Deviation is a statistical measure of volatility. + /// Standard Deviation is typically used as a component of + /// other indicators, rather than as a stand-alone indicator. + /// For example, Bollinger Bands are calculated by adding + /// a security's Standard Deviation to a moving average. + /// High Standard Deviation values occur when the data item + /// being analyzed (e.g., prices or an indicator) is changing + /// dramatically. Similarly, low Standard Deviation values + /// occur when prices are stable. + /// --------------------------------------------------------- + /// Input: + /// - 1 Y value. + /// Output: + /// - 1 Y value Standard Deviation + /// Parameters: + /// - Periods for standard deviation ( used for moving average ) + /// Extra Parameters: + /// - + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + /// Array of strings - Extra parameters + private void StandardDeviation(double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList) + { + int length = inputValues.Length; + + // Period for standard deviation ( used for moving average ) + int period; + try + {period = int.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture );} + catch( Exception e ) + { + if (e.Message == SR.ExceptionObjectReferenceIsNull) + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing); + else + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing + e.Message); + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Starting average from the first data point or after period. + bool startFromFirst = bool.Parse( extraParameterList[0] ); + + // There is no enough series + if( length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + if( inputValues[0].Length != inputValues[1].Length ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsSameXYNumber); + + // Not enough values for moving average in Standard deviation. + if( inputValues[0].Length < period ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsNotEnoughPoints); + + outputValues = new double [2][]; + + StandardDeviation( inputValues[1], out outputValues[1], period, startFromFirst ); + + // Set X values + outputValues[0] = new double [outputValues[1].Length]; + for( int index = 0; index < outputValues[1].Length; index++ ) + { + if( startFromFirst ) + outputValues[0][index] = inputValues[0][index]; + else + outputValues[0][index] = inputValues[0][index+period-1]; + } + } + + /// + /// The Average True Range ("ATR") is a measure of volatility. It was introduced + /// by Welles Wilder in his book, New Concepts in Technical Trading Systems, and + /// has since been used as a component of many indicators and trading systems. Wilder + /// has found that high ATR values often occur at market bottoms following a "panic" + /// sell-off. Low Average True Range values are often found during extended sideways + /// periods, such as those found at tops and after consolidation periods. The Average + /// True Range can be interpreted using the same techniques that are used with + /// the other volatility indicators. + /// --------------------------------------------------------- + /// Input: + /// - 3 Y values ( High, Low, Close ). + /// Output: + /// - 1 Y value AverageTrueRange + /// Parameters: + /// - Periods (Default 14) = is used to configure the number of periods to calculate the ATR + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void AverageTrueRange(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 4 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresThreeArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 3 ); + + // Period + int period; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out period)) + { + period = 14; + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // The distance from today's high to today's low + double distanceOne; + + // The distance from yesterday's close to today's high + double distanceTwo; + + // The distance from yesterday's close to today's low + double distanceTree; + + double [] trueRange = new double [inputValues[0].Length - 1]; + + // True Range + for( int index = 1; index < inputValues[0].Length; index++ ) + { + // The distance from today's high to today's low + distanceOne = Math.Abs( inputValues[1][index] - inputValues[2][index] ); + + // The distance from yesterday's close to today's high + distanceTwo = Math.Abs( inputValues[3][index-1] - inputValues[1][index] ); + + // The distance from yesterday's close to today's low + distanceTree = Math.Abs( inputValues[3][index-1] - inputValues[2][index] ); + + // True Range + trueRange[index-1] = Math.Max( Math.Max( distanceOne, distanceTwo ), distanceTree ); + } + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length-period]; + + // Moving average of true range + MovingAverage( trueRange, out outputValues[1], period, false ); + + // Set X values + for( int index = period; index < inputValues[0].Length; index++ ) + { + outputValues[0][index-period] = inputValues[0][index]; + } + } + + /// + /// The Ease of Movement indicator shows the relationship between volume and price + /// change. This indicator shows how much volume is required to move prices. The Ease + /// of Movement indicator was developed Richard W. Arms, Jr., the creator of Equivolume. + /// High Ease of Movement values occur when prices are moving upward on lightStyle volume. + /// Low Ease of Movement values occur when prices are moving downward on lightStyle volume. + /// If prices are not moving, or if heavy volume is required to move prices, then + /// indicator will also be near zero. + /// --------------------------------------------------------- + /// Input: + /// - 3 Y values ( High, Low, Volume ). + /// Output: + /// - 1 Y value Ease Of Movement + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + private void EaseOfMovement(double [][] inputValues, out double [][] outputValues) + { + // There is no enough input series + if( inputValues.Length != 4 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresThreeArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 3 ); + + double MidPointMove; + double BoxRattio; + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length - 1]; + outputValues[1] = new double [inputValues[0].Length - 1]; + + // Ease Of Movement + for( int index = 1; index < inputValues[0].Length; index++ ) + { + // Set X values + outputValues[0][index - 1] = inputValues[0][index]; + + // Calculate the Mid-point Move for each day: + MidPointMove = ( inputValues[1][index] + inputValues[2][index] ) / 2 - ( inputValues[1][index - 1] + inputValues[2][index - 1] ) / 2; + + // The Box Ratio determines the ratio between height and width of the Equivolume box: + BoxRattio = ( inputValues[3][index] ) / (( inputValues[1][index] - inputValues[2][index] ) ); + + // Ease of Movement is then calculated as: + outputValues[1][index - 1] = MidPointMove / BoxRattio; + } + } + + /// + /// The Mass Index was designed to identify trend reversals by measuring the narrowing + /// and widening of the range between the high and low prices. As this range widens, the + /// Mass Index increases; as the range narrows the Mass Index decreases. + /// The Mass Index was developed by Donald Dorsey. According to Mr. Dorsey, the most + /// significant pattern to watch for is a "reversal bulge." A reversal bulge occurs when + /// a 25-period Mass Index rises above 27.0 and subsequently falls below 26.5. A reversal + /// in price is then likely. The overall price trend (i.e., trending or trading range) + /// is unimportant. + /// --------------------------------------------------------- + /// Input: + /// - 2 Y values ( High, Low ). + /// Output: + /// - 1 Y value Mass Index + /// Parameters: + /// - Period = is used to calculate the accumulation, By default this property is set to 25. + /// - AveragePeriod = is used to calculate Simple Moving Avg, By default this property is set to 9. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void MassIndex(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 3 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 2 ); + + // Period + int period; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out period)) + { + period = 25; + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Average Period + int averagePeriod; + if (parameterList.Length < 2 || + !int.TryParse(parameterList[1], NumberStyles.Any, CultureInfo.InvariantCulture, out averagePeriod)) + { + averagePeriod = 9; + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodAverageParameterIsNegative); + + double [] highLow = new double [inputValues[0].Length]; + double [] average; + double [] secondAverage; + + for( int index = 0; index < inputValues[0].Length; index++ ) + { + highLow[index] = inputValues[1][index] - inputValues[2][index]; + } + + // Find exponential moving average + ExponentialMovingAverage( highLow, out average, averagePeriod, false ); + + // Find exponential moving average of exponential moving average + ExponentialMovingAverage( average, out secondAverage, averagePeriod, false ); + + outputValues = new double [2][]; + + outputValues[0] = new double [secondAverage.Length - period + 1]; + outputValues[1] = new double [secondAverage.Length - period + 1]; + + // Mass Index + int outIndex = 0; + double sum = 0; + for( int index = 2 * averagePeriod - 3 + period; index < inputValues[0].Length; index++ ) + { + // Set X values + outputValues[0][outIndex] = inputValues[0][index]; + + sum = 0; + for( int indexSum = index - period + 1; indexSum <= index; indexSum++ ) + { + sum += average[indexSum - averagePeriod + 1] / secondAverage[indexSum - 2 * averagePeriod + 2]; + } + + // Set Y values + outputValues[1][outIndex] = sum; + + outIndex++; + } + } + + /// + /// The Performance indicator displays a security's price performance as + /// a percentage. This is sometimes called a "normalized" chart. The + /// Performance indicator displays the percentage that the security + /// has increased since the first period displayed. For example, if + /// the Performance indicator is 10, it means that the security's + /// price has increased 10% since the first period displayed on the + /// left side of the chart. Similarly, a value of -10% means that + /// the security's price has fallen by 10% since the first period + /// displayed. + /// --------------------------------------------------------- + /// Input: + /// - 1 Y value ( Close ). + /// Output: + /// - 1 Y value Performance + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + private void Performance(double [][] inputValues, out double [][] outputValues) + { + // There is no enough input series + if( inputValues.Length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + CheckNumOfValues( inputValues, 1 ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length]; + outputValues[1] = new double [inputValues[0].Length]; + + // Performance indicator + for( int index = 0; index < inputValues[0].Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index]; + + // Set Y values + outputValues[1][index] = ( inputValues[1][index] - inputValues[1][0] ) / inputValues[1][0] * 100; + } + } + + /// + /// Rate of Change is used to monitor momentum by making direct comparisons between current + /// and past prices on a continual basis. The results can be used to determine the strength + /// of price trends. Note: This study is the same as the Momentum except that Momentum uses + /// subtraction in its calculations while Rate of Change uses division. The resulting lines + /// of these two studies operated over the same data will look exactly the same - only the + /// scale values will differ. The Price Rate-of-Change ("----") indicator displays the + /// difference between the current price and the price x-time periods ago. The difference + /// can be displayed in either points or as a percentage. The Momentum indicator displays + /// the same information, but expresses it as a ratio. When the Rate-of-Change displays + /// the price change in points, it subtracts the price x-time periods ago from today’s price. + /// When the Rate-of-Change displays the price change as a percentage, it divides + /// the price change by price x-time period’s ago. + /// --------------------------------------------------------- + /// Input: + /// - 1 Y value ( Close ). + /// Output: + /// - 1 Y value Rate of Change + /// Parameters: + /// - Periods = is used to configure the number of periods to calculate the rate of Change. By default the Periods property is set to 10. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void RateOfChange(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + CheckNumOfValues( inputValues, 1 ); + + // Period + int period; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out period)) + { + period = 10; + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length - period]; + outputValues[1] = new double [inputValues[0].Length - period]; + + // Rate Of Change + for( int index = period; index < inputValues[0].Length; index++ ) + { + // Set X values + outputValues[0][index - period] = inputValues[0][index]; + + // Set Y values + outputValues[1][index - period] = ( inputValues[1][index] - inputValues[1][index - period] ) / inputValues[1][index - period] * 100; + } + } + + /// + /// This indicator was developed by Welles Wilder Jr. Relative Strength is often + /// used to identify price tops and bottoms by keying on specific levels + /// (usually "30" and "70") on the RSI chart which is scaled from from 0-100. + /// The study is also useful to detect the following: + /// - Movement which might not be as readily apparent on the bar chart + /// - Failure swings above 70 or below 30 which can warn of coming reversals + /// - Support and resistance levels + /// - Divergence between the RSI and price which is often a useful reversal indicator + /// --------------------------------------------------------- + /// Input: + /// - 1 Y value ( Close ). + /// Output: + /// - 1 Y value RelativeStrengthIndex + /// Parameters: + /// - Periods = is used to configure the number of periods to calculate the RSI indicator. By default the Periods property is set to 10. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void RelativeStrengthIndex(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + CheckNumOfValues( inputValues, 1 ); + + // Period + int period; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out period)) + { + period = 10; + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + double [] upward = new double[inputValues[0].Length-1]; + double [] downward = new double[inputValues[0].Length-1]; + + for( int index = 1; index < inputValues[0].Length; index++ ) + { + // Upward - price is going up + if( inputValues[1][index - 1] < inputValues[1][index] ) + { + upward[index-1] = inputValues[1][index] - inputValues[1][index - 1]; + downward[index-1] = 0.0; + } + // Downward - price is going down + if( inputValues[1][index - 1] > inputValues[1][index] ) + { + upward[index-1] = 0.0; + downward[index-1] = inputValues[1][index - 1] - inputValues[1][index]; + } + } + + double [] averageUpward = new double[inputValues[0].Length]; + double [] averageDownward = new double[inputValues[0].Length]; + + ExponentialMovingAverage(downward, out averageDownward, period, false ); + ExponentialMovingAverage(upward, out averageUpward, period, false ); + + outputValues = new double [2][]; + + outputValues[0] = new double [averageDownward.Length]; + outputValues[1] = new double [averageDownward.Length]; + + // Find RSI + for( int index = 0; index < averageDownward.Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index + period]; + + // Calculate the Relative Strength Index (RSI): + outputValues[1][index] = 100 - 100 / ( 1 + averageUpward[index] / averageDownward[index] ); + } + } + + /// + /// TripleExponentialMovingAverage is a momentum indicator that displays the percent rate-of-change of a triple + /// exponentially smoothed moving average of the security's closing price. It is designed + /// to keep you in trends equal to or shorter than the number of periods you specify. + /// The TripleExponentialMovingAverage indicator oscillates around a zero line. Its triple exponential smoothing is + /// designed to filter out "insignificant" cycles (i.e., those that are shorter than + /// the number of periods you specify). Trades should be placed when the indicator changes + /// direction (i.e., buy when it turns up and sell when it turns down). You may want to + /// plot a 9-period moving average of the TripleExponentialMovingAverage to create a "signal" line (similar to the + /// MovingAverageConvergenceDivergence indicator, and then buy when the TripleExponentialMovingAverage rises above its signal, and sell when it + /// falls below its signal. Divergences between the security and the TripleExponentialMovingAverage can also help + /// identify turning points. + /// --------------------------------------------------------- + /// Input: + /// - 1 Y values ( Close ). + /// Output: + /// - 1 Y value ( TripleExponentialMovingAverage ). + /// Parameters: + /// - Period = is used to calculate the Exponential Moving Avg, By default this property is set to 12. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void Trix(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + CheckNumOfValues( inputValues, 1 ); + + // Period + int period; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out period)) + { + period = 12; + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + double [] exp1; // Exponential Moving average of input values + double [] exp2; // Exponential Moving average of exp1 + double [] exp3; // Exponential Moving average of exp2 + + // Find exponential moving average + ExponentialMovingAverage( inputValues[1], out exp1, period, false ); + + // Find exponential moving average + ExponentialMovingAverage( exp1, out exp2, period, false ); + + // Find exponential moving average + ExponentialMovingAverage( exp2, out exp3, period, false ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length - period * 3 + 2]; + outputValues[1] = new double [inputValues[0].Length - period * 3 + 2]; + + // Calculate TripleExponentialMovingAverage + int outIndex = 0; + for( int index = period * 3 - 2; index < inputValues[0].Length; index++ ) + { + // set X value + outputValues[0][outIndex] = inputValues[0][index]; + + // set Y value + outputValues[1][outIndex] = ( exp3[outIndex+1] - exp3[outIndex] ) / exp3[outIndex]; + + outIndex++; + } + } + + /// + /// The MovingAverageConvergenceDivergence is used to determine overbought or oversold conditions in the market. Written + /// for stocks and stock indices, MovingAverageConvergenceDivergence can be used for commodities as well. The MovingAverageConvergenceDivergence line + /// is the difference between the long and short exponential moving averages of the chosen + /// item. The signal line is an exponential moving average of the MovingAverageConvergenceDivergence line. Signals are + /// generated by the relationship of the two lines. As with RSI and Stochastics, + /// divergences between the MovingAverageConvergenceDivergence and prices may indicate an upcoming trend reversal. The MovingAverageConvergenceDivergence + /// is a trend following momentum indicator that shows the relationship between two + /// moving averages of prices. The MovingAverageConvergenceDivergence is the difference between a 26-day and 12-day + /// exponential moving average. A 9-day exponential moving average, called the "signal" + /// (or "trigger") line is plotted on top of the MovingAverageConvergenceDivergence to show buy/sell opportunities. The + /// MovingAverageConvergenceDivergence is calculated by subtracting the value of a 26-day exponential moving average + /// from a 12-day exponential moving average. A 9-day dotted exponential moving average of + /// the MovingAverageConvergenceDivergence (the "signal" line) is then plotted on top of the MovingAverageConvergenceDivergence. + /// --------------------------------------------------------- + /// Input: + /// - 1 Y value ( Close ). + /// Output: + /// - 1 Y value ( MovingAverageConvergenceDivergence ). + /// Parameters: + /// - ShortPeriod = is used to configure the short Exponential Moving Average, By default this property is set to 12. + /// - LongPeriod = is used to configure the Int64 Exponential Moving Average, By default this property is set to 26. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void Macd(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 2 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresOneArray); + + // Different number of x and y values + CheckNumOfValues( inputValues, 1 ); + + // Short Period + int shortPeriod; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out shortPeriod)) + { + shortPeriod = 12; + } + + if( shortPeriod <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodShortParameterIsNegative); + + // Int64 Period + int longPeriod; + if (parameterList.Length < 2 || + !int.TryParse(parameterList[1], NumberStyles.Any, CultureInfo.InvariantCulture, out longPeriod)) + { + longPeriod = 26; + } + + if( longPeriod <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodLongParameterIsNegative); + + if( longPeriod <= shortPeriod ) + throw new InvalidOperationException(SR.ExceptionIndicatorsLongPeriodLessThenShortPeriod); + + double [] longAverage; // Int64 Average + double [] shortAverage; // Short Average + + // Find Int64 exponential moving average + ExponentialMovingAverage( inputValues[1], out longAverage, longPeriod, false ); + + // Find Short exponential moving average + ExponentialMovingAverage( inputValues[1], out shortAverage, shortPeriod, false ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length - longPeriod + 1]; + outputValues[1] = new double [inputValues[0].Length - longPeriod + 1]; + + // Calculate MovingAverageConvergenceDivergence + int outIndex = 0; + for( int index = longPeriod - 1; index < inputValues[0].Length; index++ ) + { + // set X value + outputValues[0][outIndex] = inputValues[0][index]; + + // set Y value + outputValues[1][outIndex] = shortAverage[ outIndex + longPeriod - shortPeriod ] - longAverage[outIndex]; + + outIndex++; + } + } + + /// + /// The CCI is a timing system that is best applied to commodity contracts which + /// have cyclical or seasonal tendencies. CCI does not determine the length of + /// cycles - it is designed to detect when such cycles begin and end through + /// the use of a statistical analysis which incorporates a moving average and a divisor + /// reflecting both the possible and actual trading ranges. Although developed primarily + /// for commodities, the CCI could conceivably be used to analyze stocks as well. The + /// Commodity Channel Index ("CCI") measures the variation of a security’s price from + /// its statistical mean. High values show that prices are unusually high compared to + /// average prices whereas low values indicate that prices are unusually low. + /// 1. Calculate today's Typical Price (TP) = (H+L+C)/3 where H = high; L = low, and C = close. + /// 2. Calculate today's 20-day Simple Moving Average of the Typical Price (SMATP). + /// 3. Calculate today's Mean Deviation. First, calculate the absolute value of the difference + /// between today's SMATP and the typical price for each of the past 20 days. + /// Add all of these absolute values together and divide by 20 to find the Mean Deviation. + /// 4. The final step is to apply the Typical Price (TP), the Simple Moving Average of the + /// Typical Price (SMATP), the Mean Deviation and a Constant (.015). + /// --------------------------------------------------------- + /// Input: + /// - 3 Y values ( Hi, Low, Close ). + /// Output: + /// - 1 Y value ( CCI ). + /// Parameters: + /// - Periods = is used to configure the number of periods to calculate the CCI. By default the Periods property is set to 10. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void CommodityChannelIndex(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 4 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresThreeArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 3 ); + + // Period + int period; + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out period)) + { + period = 10; + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Typical Price + double [] typicalPrice = new double[inputValues[0].Length]; + + // Typical Price loop + for( int index = 0; index < inputValues[0].Length; index++ ) + { + typicalPrice[index] = ( inputValues[1][index] + inputValues[2][index] + inputValues[3][index] ) / 3.0; + } + + // Moving Average + double [] movingAverage; + + // Simple Moving Average of the Typical Price + MovingAverage( typicalPrice, out movingAverage, period, false ); + + // Calculate today's Mean Deviation. First, calculate the absolute value + // of the difference between today's SMATP and the typical price for each + // of the past 20 days. Add all of these absolute values together and + // divide by 20 to find the Mean Deviation. + + // Mean Deviation + double [] meanDeviation = new double[movingAverage.Length]; + + double sum =0; + for( int index = 0; index < movingAverage.Length; index++ ) + { + sum = 0; + for( int indexSum = index; indexSum < index + period; indexSum++ ) + { + sum += Math.Abs( movingAverage[index] - typicalPrice[indexSum] ); + } + meanDeviation[index] = sum / period; + } + + outputValues = new double [2][]; + + outputValues[0] = new double [meanDeviation.Length]; + outputValues[1] = new double [meanDeviation.Length]; + + + for( int index = 0; index < meanDeviation.Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index + period - 1]; + + // Set Y values + outputValues[1][index] = ( typicalPrice[index + period - 1] - movingAverage[index] ) / ( 0.015 * meanDeviation[index] ); + + } + } + + #endregion + + #region Methods + + /// + /// Default constructor + /// + public GeneralTechnicalIndicators() + { + } + + /// + /// The first method in the module, which converts a formula + /// name to the corresponding private method. + /// + /// String which represent a formula name + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Formula parameters + /// Array of strings - Extra Formula parameters from DataManipulator object + /// Array of strings - Used for Labels. Description for output results. + override public void Formula( string formulaName, double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList, out string [][] outLabels ) + { + string name; + outputValues = null; + + name = formulaName.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + // Not used for these formulas. + outLabels = null; + + try + { + switch( name ) + { + case "STANDARDDEVIATION": + StandardDeviation( inputValues, out outputValues, parameterList, extraParameterList ); + break; + case "AVERAGETRUERANGE": + AverageTrueRange( inputValues, out outputValues, parameterList ); + break; + case "EASEOFMOVEMENT": + EaseOfMovement( inputValues, out outputValues ); + break; + case "MASSINDEX": + MassIndex( inputValues, out outputValues, parameterList ); + break; + case "PERFORMANCE": + Performance( inputValues, out outputValues ); + break; + case "RATEOFCHANGE": + RateOfChange( inputValues, out outputValues, parameterList ); + break; + case "RELATIVESTRENGTHINDEX": + RelativeStrengthIndex( inputValues, out outputValues, parameterList ); + break; + case "TRIPLEEXPONENTIALMOVINGAVERAGE": + Trix( inputValues, out outputValues, parameterList ); + break; + case "MOVINGAVERAGECONVERGENCEDIVERGENCE": + Macd( inputValues, out outputValues, parameterList ); + break; + case "COMMODITYCHANNELINDEX": + CommodityChannelIndex( inputValues, out outputValues, parameterList ); + break; + default: + outputValues = null; + break; + } + } + catch( IndexOutOfRangeException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaInvalidPeriod( name ) ); + } + catch( OverflowException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaNotEnoughDataPoints( name ) ); + } + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Formulas/TimeSeriesAndForecasting.cs b/System.Web.DataVisualization/Common/Formulas/TimeSeriesAndForecasting.cs new file mode 100644 index 000000000..4af27bec5 --- /dev/null +++ b/System.Web.DataVisualization/Common/Formulas/TimeSeriesAndForecasting.cs @@ -0,0 +1,647 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: TimeSeriesAndForecasting.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Formulas +// +// Classes: TimeSeriesAndForecasting +// +// Purpose: This class is used for calculations of +// time series and forecasting +// +// Reviewed: GS - August 7, 2002 +// AG - August 7, 2002 +// +//=================================================================== + +using System; +using System.Globalization; + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Formulas +#else + namespace System.Web.UI.DataVisualization.Charting.Formulas +#endif +{ + /// + /// This class is used for calculations of + /// time series and forecasting + /// + internal class TimeSeriesAndForecasting : IFormula + { + #region Enumeration + + /// + /// AxisName of regression + /// + internal enum RegressionType + { + /// + /// Polynomial trend + /// + Polynomial, + + /// + /// IsLogarithmic trend + /// + Logarithmic, + + /// + /// Power trend + /// + Power, + + /// + /// Exponential trend + /// + Exponential + } + + #endregion + + #region Properties + + /// + /// Formula Module name + /// + virtual public string Name { get { return SR.FormulaNameTimeSeriesAndForecasting; } } + + #endregion + + #region Methods + + /// + /// Public constructor. + /// + public TimeSeriesAndForecasting() + { + + } + + /// + /// The first method in the module, which converts a formula + /// name to the corresponding private method. + /// + /// String which represent a formula name + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Formula parameters + /// Array of strings - Extra Formula parameters from DataManipulator object + /// Array of strings - Used for Labels. Description for output results. + virtual public void Formula( string formulaName, double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList, out string [][] outLabels ) + { + string name; + + name = formulaName.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + // Not used for these formulas. + outLabels = null; + + try + { + switch( name ) + { + case "FORECASTING": + Forecasting( inputValues, out outputValues, parameterList ); + break; + default: + outputValues = null; + break; + } + } + catch( IndexOutOfRangeException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaInvalidPeriod(name) ); + } + catch( OverflowException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaNotEnoughDataPoints( name ) ); + } + } + + #endregion + + #region Formulas + + /// + /// Forecasting formula predicts future values of the time series variable. + /// Multiple regressions are used for this forecasting model. Any method + /// of fitting equations to data may be called regression. Such equations + /// are valuable for at least two purposes: making predictions and judging + /// the strength of relationships. Of the various methods of performing + /// regression, Last Square is the most widely used. This formula returns + /// two more series, which represents upper and lower bond of error. Error + /// is based on standard deviation and represents a linear combination of + /// approximation error and forecasting error. + /// --------------------------------------------------------- + /// Input: + /// - Y values. + /// Output: + /// - Forecasting + /// - upper bond error + /// - lower bond error + /// Parameters: + /// - Polynomial degree (Default: 2 - Linear regression ) + /// - Forecasting period (Default: Half of the series length ) + /// - Returns Approximation error (Default: true) + /// - Returns Forecasting error (Default: true) + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + private void Forecasting(double[][] inputValues, out double[][] outputValues, string[] parameterList) + { + // Polynomial degree + int degree; + RegressionType regressionType = RegressionType.Polynomial; + + if (String.Equals(parameterList[0],"Exponential", StringComparison.OrdinalIgnoreCase)) + { + regressionType = RegressionType.Exponential; + degree = 2; + } + else if (String.Equals(parameterList[0],"Linear", StringComparison.OrdinalIgnoreCase)) + { + regressionType = RegressionType.Polynomial; + degree = 2; + } + else if (String.Equals(parameterList[0],"IsLogarithmic", StringComparison.OrdinalIgnoreCase) || + String.Equals(parameterList[0],"Logarithmic", StringComparison.OrdinalIgnoreCase)) + { + regressionType = RegressionType.Logarithmic; + degree = 2; + } + else if (String.Equals(parameterList[0],"Power", StringComparison.OrdinalIgnoreCase)) + { + regressionType = RegressionType.Power; + degree = 2; + } + else + { + if (parameterList.Length < 1 || + !int.TryParse(parameterList[0], NumberStyles.Any, CultureInfo.InvariantCulture, out degree)) + { + degree = 2; + } + } + + + if (degree > 5 || degree < 1) + throw new InvalidOperationException(SR.ExceptionForecastingDegreeInvalid); + + if (degree > inputValues[0].Length) + throw new InvalidOperationException(SR.ExceptionForecastingNotEnoughDataPoints(degree.ToString(System.Globalization.CultureInfo.InvariantCulture))); + + // Forecasting period + int period; + if (parameterList.Length < 2 || + !int.TryParse(parameterList[1], NumberStyles.Any, CultureInfo.InvariantCulture, out period)) + { + period = inputValues[0].Length / 2; + } + + // Approximation error + bool approximationError; + if (parameterList.Length < 3 || + !bool.TryParse(parameterList[2], out approximationError)) + { + approximationError = true; + } + + // Forecasting error + bool forecastingError; + if (parameterList.Length < 4 || + !bool.TryParse(parameterList[3], out forecastingError)) + { + forecastingError = true; + } + + double[][] tempOut; + // Find regresion + Regression(regressionType, inputValues, out tempOut, degree, period); + + // If error disabled get out from procedure + if (!forecastingError && !approximationError) + { + outputValues = tempOut; + return; + } + + double[][] inputErrorEst = new double[2][]; + double[][] outputErrorEst; + inputErrorEst[0] = new double[inputValues[0].Length / 2]; + inputErrorEst[1] = new double[inputValues[0].Length / 2]; + + for (int index = 0; index < inputValues[0].Length / 2; index++) + { + inputErrorEst[0][index] = inputValues[0][index]; + inputErrorEst[1][index] = inputValues[1][index]; + } + + Regression(regressionType, inputErrorEst, out outputErrorEst, degree, inputValues[0].Length / 2); + + // Find the average for forecasting error + double error = 0; + for (int index = inputValues[0].Length / 2; index < outputErrorEst[1].Length; index++) + { + error += (outputErrorEst[1][index] - inputValues[1][index]) * (outputErrorEst[1][index] - inputValues[1][index]); + } + error /= inputValues[0].Length - inputValues[0].Length / 2; + error = Math.Sqrt(error); + error /= (inputValues[0].Length / 4); + + // Find the standard deviation + double dev = 0; + for (int index = 0; index < inputValues[0].Length; index++) + { + dev += (tempOut[1][index] - inputValues[1][index]) * (tempOut[1][index] - inputValues[1][index]); + } + dev /= inputValues[0].Length; + dev = Math.Sqrt(dev); + + outputValues = new double[4][]; + outputValues[0] = tempOut[0]; + outputValues[1] = tempOut[1]; + outputValues[2] = new double[tempOut[0].Length]; + outputValues[3] = new double[tempOut[0].Length]; + + if (!approximationError) + dev = 0; + + if (!forecastingError) + error = 0; + + for (int index = 0; index < inputValues[0].Length; index++) + { + outputValues[2][index] = tempOut[1][index] + 2 * dev; + outputValues[3][index] = tempOut[1][index] - 2 * dev; + } + double sumError = 0; + for (int index = inputValues[0].Length; index < tempOut[0].Length; index++) + { + sumError += error; + outputValues[2][index] = tempOut[1][index] + sumError + 2 * dev; + outputValues[3][index] = tempOut[1][index] - sumError - 2 * dev; + } + } + + /// + /// Any method of fitting equations to data may be called regression. + /// Such equations are valuable for at least two purposes: making + /// predictions and judging the strength of relationships. Of the + /// various methods of performing regression, Last Square is the + /// most widely used. + /// + /// AxisName of regression Polynomial, exponential, etc. + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Polynomial degree (Default: 2 - Linear regression ) + /// Forecasting period (Default: Half of the series length ) + private void Regression( RegressionType regressionType, double [][] inputValues, out double [][] outputValues, int polynomialDegree, int forecastingPeriod ) + { + if( regressionType == RegressionType.Exponential ) + { + double [] oldYValues = new double[ inputValues[1].Length ]; + for( int index = 0; index < inputValues[1].Length; index++ ) + { + oldYValues[ index ] = inputValues[1][index]; + if( inputValues[1][index] <= 0 ) + { + throw new InvalidOperationException(SR.ExceptionForecastingExponentialRegressionHasZeroYValues); + } + inputValues[1][index] = Math.Log( inputValues[1][index] ); + } + + + + PolynomialRegression( regressionType, inputValues, out outputValues, 2, forecastingPeriod, 0 ); + + inputValues[1] = oldYValues; + } + else if( regressionType == RegressionType.Logarithmic ) + { + double interval; + double first = inputValues[0][0]; + + // Find Interval for X values + interval = Math.Abs( inputValues[0][0] - inputValues[0][inputValues[0].Length - 1] ) / ( inputValues[0].Length - 1 ); + + if( interval <= 0 ) + interval = 1; + + for( int index = 0; index < inputValues[0].Length; index++ ) + { + inputValues[0][index] = Math.Log( inputValues[0][index] ); + } + + PolynomialRegression( regressionType, inputValues, out outputValues, 2, forecastingPeriod, interval ); + + // Create Y values based on approximation. + for( int i = 0; i < outputValues[0].Length; i++ ) + { + // Set X value + outputValues[0][i] = first + i * interval; + } + } + else if( regressionType == RegressionType.Power ) + { + double [] oldYValues = new double[ inputValues[1].Length ]; + double interval; + double first = inputValues[0][0]; + + for( int index = 0; index < inputValues[1].Length; index++ ) + { + oldYValues[ index ] = inputValues[1][index]; + if( inputValues[1][index] <= 0 ) + { + throw new InvalidOperationException(SR.ExceptionForecastingPowerRegressionHasZeroYValues); + } + } + + // Find Interval for X values + interval = Math.Abs( inputValues[0][0] - inputValues[0][inputValues[0].Length - 1] ) / ( inputValues[0].Length - 1 ); + + if( interval <= 0 ) + interval = 1; + + PolynomialRegression( regressionType, inputValues, out outputValues, 2, forecastingPeriod, interval ); + + inputValues[1] = oldYValues; + + // Create Y values based on approximation. + for( int i = 0; i < outputValues[0].Length; i++ ) + { + // Set X value + outputValues[0][i] = first + i * interval; + } + } + else + { + PolynomialRegression( regressionType, inputValues, out outputValues, polynomialDegree, forecastingPeriod, 0 ); + } + } + + /// + /// Any method of fitting equations to data may be called regression. + /// Such equations are valuable for at least two purposes: making + /// predictions and judging the strength of relationships. Of the + /// various methods of performing regression, Last Square is the + /// most widely used. + /// + /// AxisName of regression Polynomial, exponential, etc. + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Polynomial degree (Default: 2 - Linear regression ) + /// Forecasting period (Default: Half of the series length ) + /// Interval for logarithmic scale + private void PolynomialRegression( RegressionType regressionType, double [][] inputValues, out double [][] outputValues, int polynomialDegree, int forecastingPeriod, double logInterval ) + { + double [] coefficients = new double [polynomialDegree]; + int size = inputValues[0].Length; + double minimumX = double.MaxValue; + double interval = 1.0; + + // Find Interval for X values + interval = Math.Abs( inputValues[0][0] - inputValues[0][inputValues[0].Length - 1] ) / ( inputValues[0].Length - 1 ); + + if( interval <= 0 ) + interval = 1; + + if( regressionType != RegressionType.Logarithmic ) + { + // Avoid Rounding error because of big X values. + // Find Minimum X value + for( int xIndex = 0; xIndex < inputValues[0].Length; xIndex++ ) + { + if( minimumX > inputValues[0][xIndex] ) + minimumX = inputValues[0][xIndex]; + } + + // Change X values. + for( int xIndex = 0; xIndex < inputValues[0].Length; xIndex++ ) + { + inputValues[0][xIndex] -= minimumX - 1; + } + } + + if( regressionType == RegressionType.Power ) + { + for( int index = 0; index < inputValues[0].Length; index++ ) + { + inputValues[0][index] = Math.Log( inputValues[0][index] ); + inputValues[1][index] = Math.Log( inputValues[1][index] ); + } + } + + double [][] mainDeterminant = new double [polynomialDegree][]; + for(int arrayIndex = 0; arrayIndex < polynomialDegree; arrayIndex++) + { + mainDeterminant[arrayIndex] = new double [polynomialDegree]; + } + + // Main determinant + for( int k = 0; k < polynomialDegree; k++ ) + { + for( int i = 0; i < polynomialDegree; i++ ) + { + mainDeterminant[i][k] = 0; + for( int j = 0; j < inputValues[0].Length; j++ ) + { + mainDeterminant[i][k] += (double)Math.Pow( inputValues[0][j], (i+k) ); + } + } + } + double mainValue = Determinant(mainDeterminant); + + // Coefficient determinant + for( int i = 0; i < polynomialDegree; i++ ) + { + double [][] coeffDeterminant = CopyDeterminant(mainDeterminant); + for( int k = 0; k < polynomialDegree; k++ ) + { + coeffDeterminant[i][k] = 0; + for( int j = 0; j < inputValues[0].Length; j++ ) + { + coeffDeterminant[i][k] += (double)inputValues[1][j] * (double)Math.Pow( inputValues[0][j], k ); + } + } + coefficients[i] = Determinant(coeffDeterminant) / mainValue; + } + + // Create output arrays for approximation and forecasting + outputValues = new double[2][]; + outputValues[0] = new double[size + forecastingPeriod]; + outputValues[1] = new double[size + forecastingPeriod]; + + if( regressionType == RegressionType.Polynomial ) + { + // Create Y values based on approximation. + for( int i = 0; i < size + forecastingPeriod; i++ ) + { + // Set X value + outputValues[0][i] = inputValues[0][0] + i * interval; + + outputValues[1][i] = 0; + for( int j = 0; j < polynomialDegree; j++ ) + { + outputValues[1][i]+= (double)coefficients[j]*Math.Pow(outputValues[0][i],j); + } + } + } + else if( regressionType == RegressionType.Exponential ) + { + // Create Y values based on approximation. + for( int i = 0; i < size + forecastingPeriod; i++ ) + { + // Set X value + outputValues[0][i] = inputValues[0][0] + i * interval; + + outputValues[1][i]= Math.Exp( coefficients[0] ) * Math.Exp( coefficients[1] * outputValues[0][i] ); + } + } + else if( regressionType == RegressionType.Logarithmic ) + { + // Create Y values based on approximation. + for( int i = 0; i < size + forecastingPeriod; i++ ) + { + // Set X value + outputValues[0][i] = Math.Exp( inputValues[0][0] ) + i * logInterval; + + outputValues[1][i]= coefficients[1] * Math.Log( outputValues[0][i] ) + coefficients[0]; + } + } + else if( regressionType == RegressionType.Power ) + { + // Create Y values based on approximation. + for( int i = 0; i < size + forecastingPeriod; i++ ) + { + // Set X value + outputValues[0][i] = Math.Exp( inputValues[0][0] ) + i * logInterval; + + outputValues[1][i]= Math.Exp( coefficients[0] ) * Math.Pow( outputValues[0][i], coefficients[1] ); + } + } + + if( regressionType != RegressionType.Logarithmic ) + { + // Return X values. + for( int xIndex = 0; xIndex < size + forecastingPeriod; xIndex++ ) + { + outputValues[0][xIndex] += minimumX - 1; + } + } + } + + /// + /// This method recalculates determinant. This method is used for + /// recursive calls for sub determinants too. + /// + /// Input determinant + /// Result of determinant + private double Determinant( double [][] inputDeterminant ) + { + double sum = 0; + double sign = 1.0; + + // Determinant is 2X2 - calculate value + if( inputDeterminant.Length == 2 ) + { + return inputDeterminant[0][0]*inputDeterminant[1][1] - inputDeterminant[0][1]*inputDeterminant[1][0]; + } + + // Determinant is biger than 2X2. Go to recursive + // call of Determinant method + for( int column = 0; column < inputDeterminant.GetLength(0); column++ ) + { + // Make sub determinant + double [][] newDeterminant = MakeSubDeterminant( inputDeterminant, column ); + + sum += sign * Determinant( newDeterminant ) * inputDeterminant[column][0]; + sign *= -1.0; + } + return sum; + } + + /// + /// This method will create a new determinant, which is + /// smaller by one rank (dimension). Specified column + /// and zero rows will be skipped. + /// + /// Input determinant + /// Position of column, which has to be skipped + /// New determinant + private double [][] MakeSubDeterminant( double [][] inputDeterminant, int columnPos ) + { + // Get Determinant Size + int size = inputDeterminant.GetLength(0); + + // Prepare sub Determinant + double [][] newDeterminant = new double [size - 1][]; + for(int arrayIndex = 0; arrayIndex < size - 1; arrayIndex++) + { + newDeterminant[arrayIndex] = new double [size - 1]; + } + + + int newColumn = 0; + // Copy columns + for( int column = 0; column < size; column++ ) + { + // Skeep this column + if( column == columnPos ) + continue; + + // Copy rows + for( int row = 1; row < size; row++ ) + { + newDeterminant[newColumn][row-1] = inputDeterminant[column][row]; + } + + // Go to new column for new determinant + newColumn++; + } + + // Return new determinant + return newDeterminant; + } + + /// + /// This method will copy determinant + /// + /// Input determinant + /// New determinant + private double [][] CopyDeterminant( double [][] inputDeterminant ) + { + // Get Determinant Size + int size = inputDeterminant.GetLength(0); + + // Prepare sub Determinant + double [][] newDeterminant = new double [size][]; + for(int arrayIndex = 0; arrayIndex < size; arrayIndex++) + { + newDeterminant[arrayIndex] = new double [size]; + } + + // Copy columns + for( int column = 0; column < size; column++ ) + { + // Copy rows + for( int row = 0; row < size; row++ ) + { + newDeterminant[column][row] = inputDeterminant[column][row]; + } + } + + // Return new determinant + return newDeterminant; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Formulas/VolumeIndicator.cs b/System.Web.DataVisualization/Common/Formulas/VolumeIndicator.cs new file mode 100644 index 000000000..b9450870d --- /dev/null +++ b/System.Web.DataVisualization/Common/Formulas/VolumeIndicator.cs @@ -0,0 +1,527 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: VolumeIndicator.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Formulas +// +// Classes: VolumeIndicators +// +// Purpose: This class is used for calculations of +// technical analyses volume indicators. +// +// Reviewed: GS - August 7, 2002 +// AG - August 7, 2002 +// +//=================================================================== + + +using System; + + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Formulas +#else + namespace System.Web.UI.DataVisualization.Charting.Formulas +#endif +{ + /// + /// This class is used for calculations of + /// technical analyses volume indicators. + /// + internal class VolumeIndicators : PriceIndicators + { + #region Properties + + /// + /// Formula Module name + /// + override public string Name { get { return SR.FormulaNameVolumeIndicators; } } + + #endregion + + #region Methods + + /// + /// Default Constructor + /// + public VolumeIndicators() + { + + } + + /// + /// The first method in the module, which converts a formula + /// name to the corresponding private method. + /// + /// String which represent a formula name + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Formula parameters + /// Array of strings - Extra Formula parameters from DataManipulator object + /// Array of strings - Used for Labels. Description for output results. + override public void Formula( string formulaName, double [][] inputValues, out double [][] outputValues, string [] parameterList, string [] extraParameterList, out string [][] outLabels ) + { + string name; + + name = formulaName.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + // Not used for these formulas. + outLabels = null; + + try + { + switch( name ) + { + case "MONEYFLOW": + MoneyFlow( inputValues, out outputValues, parameterList ); + break; + case "ONBALANCEVOLUME": + OnBalanceVolume( inputValues, out outputValues ); + break; + case "NEGATIVEVOLUMEINDEX": + NegativeVolumeIndex( inputValues, out outputValues, parameterList ); + break; + case "POSITIVEVOLUMEINDEX": + PositiveVolumeIndex( inputValues, out outputValues, parameterList ); + break; + case "PRICEVOLUMETREND": + PriceVolumeTrend( inputValues, out outputValues ); + break; + case "ACCUMULATIONDISTRIBUTION": + AccumulationDistribution( inputValues, out outputValues ); + break; + default: + outputValues = null; + break; + } + } + catch( IndexOutOfRangeException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaInvalidPeriod( name ) ); + } + catch( OverflowException ) + { + throw new InvalidOperationException( SR.ExceptionFormulaNotEnoughDataPoints( name ) ); + } + } + + #endregion + + #region Formulas + + /// + /// The Money Flow Index ("MFI") is a momentum indicator that + /// measures the strength of money flowing in and out of + /// a security. It is related to the Relative Strength Index, + /// but where the RSI only incorporates prices, the Money Flow + /// Index accounts for volume. + /// --------------------------------------------------------- + /// Input: + /// - 4 Y values ( High, Low, Close, Volume ). + /// Output: + /// - 1 Y value Money Flow Indicator. + /// Parameters: + /// - Period + /// + /// Arrays of doubles + /// Arrays of doubles + /// Array of strings + private void MoneyFlow(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + int length = inputValues.Length; + + // There is no enough series + if( length != 5 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresFourArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 4 ); + + // Period for moving average + int period; + try + {period = int.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture );} + catch( Exception e ) + { + if (e.Message == SR.ExceptionObjectReferenceIsNull) + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing); + else + throw new InvalidOperationException(SR.ExceptionPriceIndicatorsPeriodMissing + e.Message); + } + + if( period <= 0 ) + throw new InvalidOperationException(SR.ExceptionPeriodParameterIsNegative); + + // Not enough values for Money Flow. + if( inputValues[0].Length < period ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsNotEnoughPoints); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length - period + 1]; + outputValues[1] = new double [inputValues[0].Length - period + 1]; + double [] TypicalPrice = new double [inputValues[1].Length]; + double [] MoneyFlow = new double [inputValues[1].Length]; + double [] PositiveMoneyFlow = new double [inputValues[1].Length]; + double [] NegativeMoneyFlow = new double [inputValues[1].Length]; + + // Find Money Flow + for( int index = 0; index < inputValues[1].Length; index++ ) + { + // Find Typical Price + TypicalPrice[index] = (inputValues[1][index] + inputValues[2][index] + inputValues[3][index])/3.0; + // Find Money Flow + MoneyFlow[index] = (inputValues[1][index] + inputValues[2][index] + inputValues[3][index])/3.0 * inputValues[4][index]; + } + + // Find Money Flow + for( int index = 1; index < inputValues[1].Length; index++ ) + { + // Positive Typical Price + if( TypicalPrice[index] > TypicalPrice[index - 1] ) + { + PositiveMoneyFlow[index] = MoneyFlow[index]; + NegativeMoneyFlow[index] = 0; + } + // Negative Typical Price + if( TypicalPrice[index] < TypicalPrice[index - 1] ) + { + NegativeMoneyFlow[index] = MoneyFlow[index]; + PositiveMoneyFlow[index] = 0; + } + } + + double PosMoney = 0; + double NegMoney = 0; + for( int index = period - 1; index < inputValues[1].Length; index++ ) + { + PosMoney = 0; + NegMoney = 0; + // Find Money flow using period + for( int periodIndex = index - period + 1; periodIndex <= index; periodIndex++ ) + { + NegMoney += NegativeMoneyFlow[periodIndex]; + PosMoney += PositiveMoneyFlow[periodIndex]; + } + + // X value + outputValues[0][index - period + 1] = inputValues[0][index]; + + // Money Flow Index + outputValues[1][index - period + 1] = 100.0 - 100.0 / ( 1.0 + (PosMoney / NegMoney) ); + + } + } + + /// + /// The Price and Volume Trend ("PVT") is similar to + /// On Balance Volume ("OBV,") in that it is a cumulative + /// total of volume that is adjusted depending on changes + /// in closing prices. But where OBV adds all volume on days + /// when prices close higher and subtracts all volume on days + /// when prices close lower, the PVT adds/subtracts only + /// a portion of the daily volume. The amount of volume + /// added to the PVT is determined by the amount that prices + /// rose or fell relative to the previous day’s close. + /// The PVT is calculated by multiplying the day’s volume + /// by the percent that the security’s price changed, and + /// adding this value to a cumulative total. + /// --------------------------------------------------------- + /// Input: + /// - 2 Y values ( Close, Volume ). + /// Output: + /// - 1 Y value Price Volume Trend Indicator. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + private void PriceVolumeTrend(double [][] inputValues, out double [][] outputValues) + { + // There is no enough input series + if( inputValues.Length != 3 ) + throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 2 ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length]; + outputValues[1] = new double [inputValues[0].Length]; + + // Set X and Y zero values + outputValues[0][0] = inputValues[0][0]; + outputValues[1][0] = 0; + + double yesterdayClose; + double todayClose; + + // Price Volume Trend Indicator + for( int index = 1; index < inputValues[1].Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index]; + + // Set Y values + yesterdayClose = inputValues[1][index-1]; + todayClose = inputValues[1][index]; + + // Price Volume Trend for one point + outputValues[1][index] = ( todayClose - yesterdayClose ) / yesterdayClose * inputValues[2][index] + outputValues[1][index-1]; + } + } + + /// + /// On Balance Volume ("OBV") is a momentum indicator that + /// relates volume to price change. OBV is one of the most + /// popular volume indicators and was developed by + /// Joseph Granville. Constructing an OBV line is very + /// simple: The total volume for each day is assigned a + /// positive or negative value depending on whether prices + /// closed higher or lower that day. A higher close results + /// in the volume for that day to get a positive value, while + /// a lower close results in negative value. A running total + /// is kept by adding or subtracting each day's volume based + /// on the direction of the close. The direction of the OBV + /// line is the thing to watch, not the actual volume numbers. + /// --------------------------------------------------------- + /// Input: + /// - 2 Y values ( Close, Volume ). + /// Output: + /// - 1 Y value On Balance Volume Indicator. + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + private void OnBalanceVolume(double [][] inputValues, out double [][] outputValues) + { + // There is no enough input series + if( inputValues.Length != 3 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 2 ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length]; + outputValues[1] = new double [inputValues[0].Length]; + + outputValues[0][0] = inputValues[0][0]; + outputValues[1][0] = inputValues[2][0]; + + // Find On Balance Volume + for( int index = 1; index < inputValues[1].Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index]; + + // Set Y Values + // If today’s close is greater than yesterday’s close then + if( inputValues[1][index - 1] < inputValues[1][index] ) + outputValues[1][index] = outputValues[1][index - 1] + inputValues[2][index]; + // If today’s close is less than yesterday’s close then + else if( inputValues[1][index - 1] > inputValues[1][index] ) + outputValues[1][index] = outputValues[1][index - 1] - inputValues[2][index]; + // If today’s close is equal to yesterday’s close then + else + outputValues[1][index] = outputValues[1][index - 1]; + } + } + + /// + /// The Negative Volume Index ("NVI") focuses on days where + /// the volume decreases from the previous day. The premise + /// being that the "smart money" takes positions on days when + /// volume decreases. + /// --------------------------------------------------------- + /// Input: + /// - 2 Y values ( Close, Volume ). + /// Output: + /// - 1 Y value Negative Volume index. + /// Parameters: + /// - StartValue : double + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void NegativeVolumeIndex(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 3 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 2 ); + + // Start Value + double startValue; + try + {startValue = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture );} + catch(System.Exception) + { throw new InvalidOperationException(SR.ExceptionVolumeIndicatorStartValueMissing); } + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length]; + outputValues[1] = new double [inputValues[0].Length]; + + outputValues[0][0] = inputValues[0][0]; + outputValues[1][0] = startValue; + + // Find Negative Volume Index + for( int index = 1; index < inputValues[1].Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index]; + + // If today’s volume is less than yesterday’s volume then + if( inputValues[2][index] < inputValues[2][index-1] ) + { + double yesterdayClose = inputValues[1][index-1]; + double todayClose = inputValues[1][index]; + + outputValues[1][index] = ( todayClose - yesterdayClose ) / yesterdayClose * outputValues[1][index-1] + outputValues[1][index-1]; + } + // If today’s volume is greater than or equal to yesterday’s volume then: + else + outputValues[1][index] = outputValues[1][index-1]; + + } + } + + /// + /// The Positive Volume Index ("PVI") focuses on days where + /// the volume increased from the previous day. The premise + /// being that the "crowd" takes positions on days when + /// volume increases. Interpretation of the PVI assumes that + /// on days when volume increases, the crowd-following + /// "uninformed" investors are in the market. Conversely, on + /// days with decreased volume, the "smart money" is quietly + /// taking positions. Thus, the PVI displays what the + /// not-so-smart-money is doing. (The Negative Volume Index, + /// displays what the smart money is doing.) Note, however, + /// that the PVI is not a contrarian indicator. Even though + /// the PVI is supposed to show what the not-so-smart-money + /// is doing, it still trends in the same direction as prices. + /// --------------------------------------------------------- + /// Input: + /// - 2 Y values ( Close, Volume ). + /// Output: + /// - 1 Y value On Positive Volume index. + /// Parameters: + /// - StartValue : double + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + /// Array of strings - Parameters + private void PositiveVolumeIndex(double [][] inputValues, out double [][] outputValues, string [] parameterList) + { + // There is no enough input series + if( inputValues.Length != 3 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 2 ); + + // Start Value + double startValue; + try + {startValue = double.Parse( parameterList[0], System.Globalization.CultureInfo.InvariantCulture );} + catch(System.Exception) + { throw new InvalidOperationException(SR.ExceptionVolumeIndicatorStartValueMissing); } + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length]; + outputValues[1] = new double [inputValues[0].Length]; + + outputValues[0][0] = inputValues[0][0]; + outputValues[1][0] = startValue; + + // Find Negative Volume Index + for( int index = 1; index < inputValues[1].Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index]; + + // If today’s volume is greater than yesterday’s volume then + if( inputValues[2][index] > inputValues[2][index-1] ) + { + double yesterdayClose = inputValues[1][index-1]; + double todayClose = inputValues[1][index]; + + outputValues[1][index] = ( todayClose - yesterdayClose ) / yesterdayClose * outputValues[1][index-1] + outputValues[1][index-1]; + } + // If today’s volume is less than or equal to yesterday’s volume then: + else + outputValues[1][index] = outputValues[1][index-1]; + } + } + + /// + /// The Accumulation/Distribution is a momentum indicator that + /// associates changes in price and volume. The indicator is + /// based on the premise that the more volume that accompanies + /// a price move, the more significant the price move. A portion + /// of each day’s volume is added or subtracted from + /// a cumulative total. The nearer the closing price is to + /// the high for the day, the more volume added to + /// the cumulative total. The nearer the closing price is to + /// the low for the day, the more volume subtracted from the + /// cumulative total. If the close is exactly between the high + /// and low prices, nothing is added to the cumulative total. + /// --------------------------------------------------------- + /// Input: + /// - 4 Y values ( Hi, Low, Close, Volume ). + /// Output: + /// - 1 Y value Accumulation Distribution + /// + /// Arrays of doubles - Input values + /// Arrays of doubles - Output values + internal void AccumulationDistribution(double [][] inputValues, out double [][] outputValues) + { + // There is no enough input series + if( inputValues.Length != 5 ) + throw new ArgumentException( SR.ExceptionPriceIndicatorsFormulaRequiresFourArrays); + + // Different number of x and y values + CheckNumOfValues( inputValues, 4 ); + + outputValues = new double [2][]; + + outputValues[0] = new double [inputValues[0].Length]; + outputValues[1] = new double [inputValues[0].Length]; + + double [] distribution = new double [inputValues[0].Length]; + + // Set X and Y zero values + outputValues[0][0] = inputValues[0][0]; + outputValues[1][0] = 0; + + + // Accumulation Distribution + for( int index = 0; index < inputValues[1].Length; index++ ) + { + // Set X values + outputValues[0][index] = inputValues[0][index]; + + // Distribution {(Close - Low) - (High - Close)} / (High - Low) * Volume + distribution[index] = ((inputValues[3][index] - inputValues[2][index])-(inputValues[1][index] - inputValues[3][index]))/(inputValues[1][index] - inputValues[2][index])*inputValues[4][index]; + } + + // The Accumulation Distribution Index is calculated as a cumulative total of each day's reading + double sum = 0; + for( int index = 0; index < inputValues[1].Length; index++ ) + { + sum += distribution[index]; + outputValues[1][index] = sum; + } + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/Axis.cs b/System.Web.DataVisualization/Common/General/Axis.cs new file mode 100644 index 000000000..9b313d01e --- /dev/null +++ b/System.Web.DataVisualization/Common/General/Axis.cs @@ -0,0 +1,6508 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: Axis.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: Axis +// +// Purpose: Axis related properties and methods. Axis class gives +// information to Common.Chart series about +// position in the Common.Chart area and keeps all necessary +// information about axes. +// +// Reviewed: GS - August 6, 2002 +// AG - August 7, 2002 +// +//=================================================================== + +#region Used namespace +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +using System.Diagnostics.CodeAnalysis; +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Axis name enumeration + + /// + /// An enumeration of auto-fitting styles of the axis labels. + /// + [Flags] + public enum LabelAutoFitStyles + { + /// + /// No auto-fitting. + /// + None = 0, + /// + /// Allow font size increasing. + /// + IncreaseFont = 1, + /// + /// Allow font size decreasing. + /// + DecreaseFont = 2, + /// + /// Allow using staggered labels. + /// + StaggeredLabels = 4, + /// + /// Allow changing labels angle using values of 0, 30, 60 and 90 degrees. + /// + LabelsAngleStep30 = 8, + /// + /// Allow changing labels angle using values of 0, 45, 90 degrees. + /// + LabelsAngleStep45 = 16, + /// + /// Allow changing labels angle using values of 0 and 90 degrees. + /// + LabelsAngleStep90 = 32, + /// + /// Allow replacing spaces with the new line character. + /// + WordWrap = 64, + } + + /// + /// An enumeration of axis names. + /// + public enum AxisName + { + /// + /// Primary X Axis. + /// + + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "X")] + X = 0, + /// + /// Primary Y Axis. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Y")] + Y = 1, + /// + /// Secondary X Axis. + /// + X2 = 2, + /// + /// Secondary Y Axis. + /// + Y2 = 3 + } + + #endregion + + /// + /// The Axis class gives information to the Common.Chart series + /// about positions in the Common.Chart area and keeps all of + /// the data about the axis. + /// + [ + SRDescription("DescriptionAttributeAxis_Axis"), + DefaultProperty("Enabled"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif +#if Microsoft_CONTROL + public partial class Axis : ChartNamedElement +#else + public partial class Axis : ChartNamedElement, IChartMapArea +#endif + { + #region Axis fields + + /// + /// Plot area position + /// + internal ElementPosition PlotAreaPosition; + + // This field synchronies Store and Reset temporary values + private bool _storeValuesEnabled = true; + + private FontCache _fontCache = new FontCache(); + private Font _titleFont; + private Color _titleForeColor = Color.Black; + private StringAlignment _titleAlignment = StringAlignment.Center; + private string _title = ""; + private int _lineWidth = 1; + private ChartDashStyle _lineDashStyle = ChartDashStyle.Solid; + private Color _lineColor = Color.Black; + private bool _isLabelAutoFit = true; + private AxisArrowStyle _arrowStyle = AxisArrowStyle.None; + private StripLinesCollection _stripLines = null; + private bool _isMarksNextToAxis = true; + + // Default text orientation + private TextOrientation _textOrientation = TextOrientation.Auto; + + // Size of the axis elements in percentage + internal float titleSize = 0F; + internal float labelSize = 0F; + internal float labelNearOffset = 0F; + internal float labelFarOffset = 0F; + internal float unRotatedLabelSize = 0F; + internal float markSize = 0F; + internal float scrollBarSize = 0F; + internal float totlaGroupingLabelsSize = 0F; + internal float[] groupingLabelSizes = null; + internal float totlaGroupingLabelsSizeAdjustment = 0f; + private LabelAutoFitStyles _labelAutoFitStyle = LabelAutoFitStyles.DecreaseFont | + LabelAutoFitStyles.IncreaseFont | + LabelAutoFitStyles.LabelsAngleStep30 | + LabelAutoFitStyles.StaggeredLabels | + LabelAutoFitStyles.WordWrap; + + // Auto calculated font for labels + internal Font autoLabelFont = null; + internal int autoLabelAngle = -1000; + internal int autoLabelOffset = -1; + + // Labels auto fitting constants + private float _aveLabelFontSize = 10F; + private float _minLabelFontSize = 5F; + // Determines maximum label size of the chart area. + private float _maximumAutoSize = 75f; + + // Chart title position rectangle + private RectangleF _titlePosition = RectangleF.Empty; + + // Element spacing size + internal const float elementSpacing = 1F; + + // Maximum total size of the axis's elements in percentage + private const float maxAxisElementsSize = 75F; + + // Maximum size of the axis title in percentage + private const float maxAxisTitleSize = 20F; + + // Maximum size of the axis second row of labels in percentage + // of the total labels size + private const float maxAxisLabelRow2Size = 45F; + + // Maximum size of the axis tick marks in percentage + private const float maxAxisMarkSize = 20F; + + // Minimum cached value from data series. + internal double minimumFromData = double.NaN; + + // Maximum cached value from data series. + internal double maximumFromData = double.NaN; + + // Flag, which tells to Set Data method to take, again values from + // data source and not to use cached values. + internal bool refreshMinMaxFromData = true; + + // Flag, which tells to Set Data method to take, again values from + // data source and not to use cached values. + internal int numberOfPointsInAllSeries = 0; + + // Original axis scaleView position + private double _originalViewPosition = double.NaN; + + + /// + /// Indicates that isInterlaced strip lines will be displayed for the axis. + /// + private bool _isInterlaced = false; + + /// + /// Color used to draw isInterlaced strip lines for the axis. + /// + private Color _interlacedColor = Color.Empty; + + /// + /// Axis interval offset. + /// + private double _intervalOffset = 0; + + /// + /// Axis interval. + /// + internal double interval = 0; + + /// + /// Axis interval units type. + /// + internal DateTimeIntervalType intervalType = DateTimeIntervalType.Auto; + + /// + /// Axis interval offset units type. + /// + internal DateTimeIntervalType intervalOffsetType = DateTimeIntervalType.Auto; + + /// + /// Minimum font size that can be used by the labels auto-fitting algorithm. + /// + internal int labelAutoFitMinFontSize = 6; + + /// + /// Maximum font size that can be used by the labels auto-fitting algorithm. + /// + internal int labelAutoFitMaxFontSize = 10; + + /// + /// Axis tooltip + /// + private string _toolTip = String.Empty; + + /// + /// Axis HREF + /// + private string _url = String.Empty; + +#if !Microsoft_CONTROL + + + /// + /// Axis map area attributes + /// + private string _mapAreaAttributes = String.Empty; + + private string _postbackValue = String.Empty; + +#endif + + #endregion + + #region Axis constructor and initialization + + /// + /// Default constructor of Axis. + /// + public Axis() + : base(null, GetName(AxisName.X)) + { + Initialize(AxisName.X); + } + + /// + /// Axis constructor. + /// + /// The chart area the axis belongs to. + /// The type of the axis. + public Axis(ChartArea chartArea, AxisName axisTypeName) + : base(chartArea, GetName(axisTypeName)) + { + Initialize(axisTypeName); + } + + /// + /// Initialize axis class + /// + /// Name of the axis type. + private void Initialize(AxisName axisTypeName) + { + // DT: Axis could be already created. Don't recreate new labelstyle and other objects. + // Initialize axis labels + if (labelStyle == null) + { + labelStyle = new LabelStyle(this); + } + if (_customLabels == null) + { + _customLabels = new CustomLabelsCollection(this); + } + if (_scaleView == null) + { + // Create axis data scaleView object + _scaleView = new AxisScaleView(this); + } +#if Microsoft_CONTROL + if (scrollBar == null) + { + // Create axis croll bar class + scrollBar = new AxisScrollBar(this); + } +#endif // Microsoft_CONTROL + + this.axisType = axisTypeName; + + // Create grid & tick marks objects + if (minorTickMark == null) + { + minorTickMark = new TickMark(this, false); + } + if (majorTickMark == null) + { + majorTickMark = new TickMark(this, true); + majorTickMark.Interval = double.NaN; + majorTickMark.IntervalOffset = double.NaN; + majorTickMark.IntervalType = DateTimeIntervalType.NotSet; + majorTickMark.IntervalOffsetType = DateTimeIntervalType.NotSet; + } + if (minorGrid == null) + { + minorGrid = new Grid(this, false); + } + if (majorGrid == null) + { + majorGrid = new Grid(this, true); + majorGrid.Interval = double.NaN; + majorGrid.IntervalOffset = double.NaN; + majorGrid.IntervalType = DateTimeIntervalType.NotSet; + majorGrid.IntervalOffsetType = DateTimeIntervalType.NotSet; + } + if (this._stripLines == null) + { + this._stripLines = new StripLinesCollection(this); + } + + if (_titleFont == null) + { + _titleFont = _fontCache.DefaultFont; + } +#if SUBAXES + if(this.subAxes == null) + { + this.subAxes = new SubAxisCollection(this); + } +#endif // SUBAXES + +#if Microsoft_CONTROL + + // Initialize axis scroll bar class + this.ScrollBar.Initialize(); + +#endif // Microsoft_CONTROL + + // Create collection of scale segments + if (this.scaleSegments == null) + { + this.scaleSegments = new AxisScaleSegmentCollection(this); + } + + // Create scale break style + if (this.axisScaleBreakStyle == null) + { + this.axisScaleBreakStyle = new AxisScaleBreakStyle(this); + } + } + + /// + /// Initialize axis class + /// + /// Chart area that the axis belongs. + /// Axis type. + internal void Initialize(ChartArea chartArea, AxisName axisTypeName) + { + this.Initialize(axisTypeName); + this.Parent = chartArea; + this.Name = GetName(axisTypeName); + } + + /// + /// Set Axis Name + /// + internal static string GetName(AxisName axisName) + { + // Set axis name. + // NOTE: Strings below should neber be localized. Name properties in the chart are never localized + // and represent consisten object name in all locales. + switch (axisName) + { + case (AxisName.X): + return "X axis"; + case (AxisName.Y): + return "Y (Value) axis"; + case (AxisName.X2): + return "Secondary X axis"; + case (AxisName.Y2): + return "Secondary Y (Value) axis"; + } + return null; + } + + #endregion + + #region Axis properies + + // Internal + internal ChartArea ChartArea + { + get { return Parent as ChartArea; } + } + + /// + /// Text orientation. + /// + [ + SRCategory("CategoryAttributeTitle"), + Bindable(true), + DefaultValue(TextOrientation.Auto), + SRDescription("DescriptionAttribute_TextOrientation"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public TextOrientation TextOrientation + { + get + { + return this._textOrientation; + } + set + { + this._textOrientation = value; + this.Invalidate(); + } + } + + /// + /// Returns sub-axis name. + /// + virtual internal string SubAxisName + { + get + { + return string.Empty; + } + } + +#if SUBAXES + + /// + /// Indicates if this axis object present the main or sub axis. + /// + virtual internal bool IsSubAxis + { + get + { + return false; + } + } + + private SubAxisCollection subAxes = null; + + /// + /// Sub-axes collection. + /// + [ + SRCategory("CategoryAttributeSubAxes"), + Bindable(true), + SRDescription("DescriptionAttributeSubAxes"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base) + ] + virtual public SubAxisCollection SubAxes + { + get + { + return this.subAxes; + } + } + +#endif // SUBAXES + + /// + /// Gets or sets a flag which indicates whether interlaced strip lines will be displayed for the axis. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(false), + SRDescription("DescriptionAttributeInterlaced"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + NotifyParentPropertyAttribute(true), + ] + public bool IsInterlaced + { + get + { + return _isInterlaced; + } + set + { + _isInterlaced = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the color used to draw interlaced strip lines for the axis. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeInterlacedColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public Color InterlacedColor + { + get + { + return _interlacedColor; + } + set + { + _interlacedColor = value; + this.Invalidate(); + } + } + + /// + /// Axis name. This field is reserved for internal use only. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + Browsable(false), + DefaultValue(""), + SRDescription("DescriptionAttributeAxis_Name"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public override string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + + /// + /// Axis name. This field is reserved for internal use only. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + Browsable(false), + DefaultValue(""), + SRDescription("DescriptionAttributeType"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + virtual public AxisName AxisName + { + get + { + return axisType; + } + } + + /// + /// Gets or sets the arrow style used for the axis. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(AxisArrowStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeArrows"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public AxisArrowStyle ArrowStyle + { + get + { + return _arrowStyle; + } + set + { + _arrowStyle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the properties used for the major gridlines. + /// + [ + SRCategory("CategoryAttributeGridTickMarks"), + Bindable(true), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeMajorGrid"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] + public Grid MajorGrid + { + get + { + return majorGrid; + } + set + { + majorGrid = value; + majorGrid.Axis = this; + majorGrid.majorGridTick = true; + + if (!majorGrid.intervalChanged) + majorGrid.Interval = double.NaN; + if (!majorGrid.intervalOffsetChanged) + majorGrid.IntervalOffset = double.NaN; + if (!majorGrid.intervalTypeChanged) + majorGrid.IntervalType = DateTimeIntervalType.NotSet; + if (!majorGrid.intervalOffsetTypeChanged) + majorGrid.IntervalOffsetType = DateTimeIntervalType.NotSet; + + this.Invalidate(); + } + } + + /// + /// Gets or sets the properties used for the minor gridlines. + /// + [ + SRCategory("CategoryAttributeGridTickMarks"), + Bindable(true), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeMinorGrid"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] + public Grid MinorGrid + { + get + { + return minorGrid; + } + set + { + minorGrid = value; + minorGrid.Initialize(this, false); + this.Invalidate(); + } + } + + /// + /// Gets or sets the properties used for the major tick marks. + /// + [ + SRCategory("CategoryAttributeGridTickMarks"), + Bindable(true), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeMajorTickMark"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] + public TickMark MajorTickMark + { + get + { + return majorTickMark; + } + set + { + majorTickMark = value; + majorTickMark.Axis = this; + majorTickMark.majorGridTick = true; + + if (!majorTickMark.intervalChanged) + majorTickMark.Interval = double.NaN; + if (!majorTickMark.intervalOffsetChanged) + majorTickMark.IntervalOffset = double.NaN; + if (!majorTickMark.intervalTypeChanged) + majorTickMark.IntervalType = DateTimeIntervalType.NotSet; + if (!majorTickMark.intervalOffsetTypeChanged) + majorTickMark.IntervalOffsetType = DateTimeIntervalType.NotSet; + + this.Invalidate(); + } + } + + /// + /// Gets or sets the properties used for the minor tick marks. + /// + [ + SRCategory("CategoryAttributeGridTickMarks"), + Bindable(true), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeMinorTickMark"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] + public TickMark MinorTickMark + { + get + { + return minorTickMark; + } + set + { + minorTickMark = value; + minorTickMark.Initialize(this, false); + this.Invalidate(); + } + } + + /// + /// Gets or sets a flag which indicates whether auto-fitting of labels is enabled. + /// + [ + SRCategory("CategoryAttributeLabels"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeLabelsAutoFit"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public bool IsLabelAutoFit + { + get + { + return _isLabelAutoFit; + } + set + { + _isLabelAutoFit = value; + this.Invalidate(); + } + } + + + + /// + /// Gets or sets the minimum font size that can be used by + /// the label auto-fitting algorithm. + /// + [ + SRCategory("CategoryAttributeLabels"), + Bindable(true), + DefaultValue(6), + SRDescription("DescriptionAttributeLabelsAutoFitMinFontSize"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public int LabelAutoFitMinFontSize + { + get + { + return this.labelAutoFitMinFontSize; + } + set + { + // Font size cannot be less than 5 + if(value < 5) + { + throw (new InvalidOperationException(SR.ExceptionAxisLabelsAutoFitMinFontSizeValueInvalid)); + } + + this.labelAutoFitMinFontSize = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the maximum font size that can be used by + /// the label auto-fitting algorithm. + /// + [ + SRCategory("CategoryAttributeLabels"), + Bindable(true), + DefaultValue(10), + SRDescription("DescriptionAttributeLabelsAutoFitMaxFontSize"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public int LabelAutoFitMaxFontSize + { + get + { + return this.labelAutoFitMaxFontSize; + } + set + { + // Font size cannot be less than 5 + if(value < 5) + { + throw (new InvalidOperationException(SR.ExceptionAxisLabelsAutoFitMaxFontSizeInvalid)); + } + + this.labelAutoFitMaxFontSize = value; + this.Invalidate(); + } + } + + + + /// + /// Gets or sets the auto-fitting style used for the labels. + /// IsLabelAutoFit must be set to true. + /// + [ + SRCategory("CategoryAttributeLabels"), + Bindable(true), + DefaultValue(LabelAutoFitStyles.DecreaseFont | LabelAutoFitStyles.IncreaseFont | LabelAutoFitStyles.LabelsAngleStep30 | LabelAutoFitStyles.StaggeredLabels | LabelAutoFitStyles.WordWrap), + SRDescription("DescriptionAttributeLabelsAutoFitStyle"), + NotifyParentPropertyAttribute(true), + Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif +] + public LabelAutoFitStyles LabelAutoFitStyle + { + get + { + return this._labelAutoFitStyle; + } + set + { + this._labelAutoFitStyle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a flag which indicates whether + /// tick marks and labels move with the axis when + /// the crossing value changes. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeMarksNextToAxis"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + virtual public bool IsMarksNextToAxis + { + get + { + return _isMarksNextToAxis; + } + set + { + _isMarksNextToAxis = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the axis title. + /// + [ + SRCategory("CategoryAttributeTitle"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeTitle6"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public string Title + { + get + { + return _title; + } + set + { + _title = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the color of the axis title. + /// + [ + SRCategory("CategoryAttributeTitle"), + Bindable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeTitleColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public Color TitleForeColor + { + get + { + return _titleForeColor; + } + set + { + _titleForeColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the alignment of the axis title. + /// + [ + SRCategory("CategoryAttributeTitle"), + Bindable(true), + DefaultValue(typeof(StringAlignment), "Center"), + SRDescription("DescriptionAttributeTitleAlignment"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public StringAlignment TitleAlignment + { + get + { + return _titleAlignment; + } + set + { + _titleAlignment = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the font used for the axis title. + /// + [ + SRCategory("CategoryAttributeTitle"), + Bindable(true), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"), + SRDescription("DescriptionAttributeTitleFont"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public Font TitleFont + { + get + { + return _titleFont; + } + set + { + _titleFont = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the line color of the axis. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLineColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public Color LineColor + { + get + { + return _lineColor; + } + set + { + _lineColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the line width of the axis. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeLineWidth"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public int LineWidth + { + get + { + return _lineWidth; + } + set + { + if (value < 0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAxisWidthIsNegative)); + } + _lineWidth = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the line style of the axis. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeLineDashStyle"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public ChartDashStyle LineDashStyle + { + get + { + return _lineDashStyle; + } + set + { + _lineDashStyle = value; + this.Invalidate(); + } + } + + /// + /// The collection of strip lines of the axis. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeStripLines"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base) + ] + public StripLinesCollection StripLines + { + get + { + return _stripLines; + } + } + + + /// + /// Gets or sets the maximum size (in percentage) of the axis used in the automatic layout algorithm. + /// + /// + /// This property determines the maximum size of the axis, measured as a percentage of the chart area. + /// + [ + SRCategory("CategoryAttributeLabels"), + DefaultValue(75f), + SRDescription("DescriptionAttributeAxis_MaxAutoSize"), + ] + public float MaximumAutoSize + { + get + { + return this._maximumAutoSize; + } + set + { + if (value < 0f || value > 100f) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionValueMustBeInRange("MaximumAutoSize", "0", "100"))); + } + this._maximumAutoSize = value; + this.Invalidate(); + } + } + #endregion + + #region IMapAreaAttributes Properties implementation + + /// + /// Tooltip of the axis. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeToolTip"), + DefaultValue(""), + ] + public string ToolTip + { + set + { + this._toolTip = value; + } + get + { + return this._toolTip; + } + } + +#if !Microsoft_CONTROL + + /// + /// URL target of the axis. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeUrl"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base) + ] + public string Url + { + set + { + this._url = value; + } + get + { + return this._url; + } + } + + + /// + /// Gets or sets the map area attributes. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeMapAreaAttributes"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute) + ] + public string MapAreaAttributes + { + set + { + this._mapAreaAttributes = value; + } + get + { + return this._mapAreaAttributes; + } + } + + /// + /// Gets or sets the postback value which can be processed on click event. + /// + /// The value which is passed to click event as argument. + [DefaultValue("")] + [SRCategory(SR.Keys.CategoryAttributeMapArea)] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + public string PostBackValue + { + get + { + return this._postbackValue; + } + set + { + this._postbackValue = value; + } + } + + +#endif // !Microsoft_CONTROL + + + + #endregion + + #region Axis Interavl properies + + /// + /// Axis interval size. + /// + [ + SRCategory("CategoryAttributeInterval"), + Bindable(true), + DefaultValue(0.0), + SRDescription("DescriptionAttributeInterval4"), + RefreshPropertiesAttribute(RefreshProperties.All), + TypeConverter(typeof(AxisIntervalValueConverter)), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif +] + public double Interval + { + get + { + return interval; + } + set + { + // Axis interval properties must be set + if (double.IsNaN(value)) + { + interval = 0; + } + else + { + interval = value; + } + + // Reset initial values + majorGrid.interval = tempMajorGridInterval; + majorTickMark.interval = tempMajorTickMarkInterval; + minorGrid.interval = tempMinorGridInterval; + minorTickMark.interval = tempMinorTickMarkInterval; + labelStyle.interval = tempLabelInterval; + + this.Invalidate(); + } + } + + /// + /// Axis interval offset. + /// + [ + SRCategory("CategoryAttributeInterval"), + Bindable(true), + DefaultValue(0.0), + SRDescription("DescriptionAttributeIntervalOffset6"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + RefreshPropertiesAttribute(RefreshProperties.All), + TypeConverter(typeof(AxisIntervalValueConverter)) + ] + public double IntervalOffset + { + get + { + return _intervalOffset; + } + set + { + // Axis interval properties must be set + if (double.IsNaN(value)) + { + _intervalOffset = 0; + } + else + { + _intervalOffset = value; + } + + this.Invalidate(); + } + } + + /// + /// Axis interval type. + /// + [ + SRCategory("CategoryAttributeInterval"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeIntervalType4"), + RefreshPropertiesAttribute(RefreshProperties.All), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public DateTimeIntervalType IntervalType + { + get + { + return intervalType; + } + set + { + // Axis interval properties must be set + if (value == DateTimeIntervalType.NotSet) + { + intervalType = DateTimeIntervalType.Auto; + } + else + { + intervalType = value; + } + + // Reset initial values + majorGrid.intervalType = tempGridIntervalType; + majorTickMark.intervalType = tempTickMarkIntervalType; + labelStyle.intervalType = tempLabelIntervalType; + + this.Invalidate(); + } + } + + /// + /// Axis interval offset type. + /// + [ + SRCategory("CategoryAttributeInterval"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeIntervalOffsetType4"), + RefreshPropertiesAttribute(RefreshProperties.All), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public DateTimeIntervalType IntervalOffsetType + { + get + { + return intervalOffsetType; + } + set + { + // Axis interval properties must be set + if (value == DateTimeIntervalType.NotSet) + { + intervalOffsetType = DateTimeIntervalType.Auto; + } + else + { + intervalOffsetType = value; + } + + this.Invalidate(); + } + } + + #endregion + + #region Axis painting methods + + /// + /// Checks if Common.Chart axis title is drawn vertically. + /// Note: From the drawing perspective stacked text orientation is not vertical. + /// + /// True if text is vertical. + private bool IsTextVertical + { + get + { + TextOrientation currentTextOrientation = this.GetTextOrientation(); + return currentTextOrientation == TextOrientation.Rotated90 || currentTextOrientation == TextOrientation.Rotated270; + } + } + + /// + /// Returns axis title text orientation. If set to Auto automatically determines the + /// orientation based on the axis position. + /// + /// Current text orientation. + private TextOrientation GetTextOrientation() + { + if (this.TextOrientation == TextOrientation.Auto) + { + if (this.AxisPosition == AxisPosition.Left) + { + return TextOrientation.Rotated270; + } + else if (this.AxisPosition == AxisPosition.Right) + { + return TextOrientation.Rotated90; + } + return TextOrientation.Horizontal; + } + return this.TextOrientation; + } + + /// + /// Paint Axis elements on the back of the 3D scene. + /// + /// Reference to the Chart Graphics object + internal void PrePaint(ChartGraphics graph) + { + if (enabled != false) + { + // draw axis hot region + DrawAxisLineHotRegion(graph, true); + + // Paint Major Tick Marks + majorTickMark.Paint(graph, true); + + // Paint Minor Tick Marks + minorTickMark.Paint(graph, true); + + // Draw axis line + DrawAxisLine(graph, true); + + // Paint Labels + labelStyle.Paint(graph, true); + } + +#if SUBAXES + // Process all sub-axis + if(!ChartArea.Area3DStyle.Enable3D && + !ChartArea.chartAreaIsCurcular) + { + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.PrePaint( graph ); + } + } +#endif // SUBAXES + } + + /// + /// Paint Axis + /// + /// Reference to the Chart Graphics object + internal void Paint(ChartGraphics graph) + { + // Only Y axis is drawn in the circular Common.Chart area + if (ChartArea != null && ChartArea.chartAreaIsCurcular) + { + // Y circular axes + if (this.axisType == AxisName.Y && enabled != false) + { + ICircularChartType chartType = ChartArea.GetCircularChartType(); + if (chartType != null) + { + Matrix oldMatrix = graph.Transform; + float[] axesLocation = chartType.GetYAxisLocations(ChartArea); + bool drawLabels = true; + foreach (float curentSector in axesLocation) + { + // Set graphics rotation matrix + Matrix newMatrix = oldMatrix.Clone(); + newMatrix.RotateAt( + curentSector, + graph.GetAbsolutePoint(ChartArea.circularCenter)); + graph.Transform = newMatrix; + + // draw axis hot region + DrawAxisLineHotRegion(graph, false); + + // Paint Minor Tick Marks + minorTickMark.Paint(graph, false); + + // Paint Major Tick Marks + majorTickMark.Paint(graph, false); + + // Draw axis line + DrawAxisLine(graph, false); + + // Only first Y axis has labels + if (drawLabels) + { + drawLabels = false; + + // Save current font angle + int currentAngle = labelStyle.Angle; + + // Set labels text angle + if (labelStyle.Angle == 0) + { + if (curentSector >= 45f && curentSector <= 180f) + { + labelStyle.angle = -90; + } + else if (curentSector > 180f && curentSector <= 315f) + { + labelStyle.angle = 90; + } + } + + // Draw labels + labelStyle.Paint(graph, false); + + // Restore font angle + labelStyle.angle = currentAngle; + } + } + + graph.Transform = oldMatrix; + } + } + + // X circular axes + if (this.axisType == AxisName.X && enabled != false) + { + labelStyle.PaintCircular(graph); + } + + DrawAxisTitle(graph); + + return; + } + + // If axis is disabled draw only Title + if (enabled != false) + { + + // draw axis hot region + DrawAxisLineHotRegion(graph, false); + + // Paint Minor Tick Marks + minorTickMark.Paint(graph, false); + + // Paint Major Tick Marks + majorTickMark.Paint(graph, false); + + // Draw axis line + DrawAxisLine(graph, false); + + // Paint Labels + labelStyle.Paint(graph, false); + +#if Microsoft_CONTROL + + // Scroll bar is supoorted only in 2D charts + if (ChartArea != null && ChartArea.Area3DStyle.Enable3D == false) + { + // Draw axis scroll bar + ScrollBar.Paint(graph); + } +#endif // Microsoft_CONTROL + + } + + // Draw axis title + this.DrawAxisTitle(graph); + +#if SUBAXES + // Process all sub-axis + if(ChartArea.IsSubAxesSupported) + { + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.Paint( graph ); + } + } +#endif // SUBAXES + + // Reset temp axis offset for side-by-side charts like column + this.ResetTempAxisOffset(); + } + + + + /// + /// Paint Axis element when segmented axis scale feature is used. + /// + /// Reference to the Chart Graphics object + internal void PaintOnSegmentedScalePassOne( ChartGraphics graph ) + { + // If axis is disabled draw only Title + if( enabled != false ) + { + // Paint Minor Tick Marks + minorTickMark.Paint( graph, false ); + + // Paint Major Tick Marks + majorTickMark.Paint( graph, false ); + } + +#if SUBAXES + // Process all sub-axis + if(ChartArea.IsSubAxesSupported) + { + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.PaintOnSegmentedScalePassOne( graph ); + } + } +#endif // SUBAXES + + } + + /// + /// Paint Axis element when segmented axis scale feature is used. + /// + /// Reference to the Chart Graphics object + internal void PaintOnSegmentedScalePassTwo( ChartGraphics graph ) + { + // If axis is disabled draw only Title + if( enabled != false ) + { + // Draw axis line + DrawAxisLine( graph, false ); + + // Paint Labels + labelStyle.Paint( graph, false); + } + + // Draw axis title + this.DrawAxisTitle( graph ); + + // Reset temp axis offset for side-by-side charts like column + this.ResetTempAxisOffset(); + +#if SUBAXES + // Process all sub-axis + if(ChartArea.IsSubAxesSupported) + { + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.PaintOnSegmentedScalePassTwo( graph ); + } + } +#endif // SUBAXES + + } + + /// + /// Draw axis title + /// + /// Reference to the Chart Graphics object + private void DrawAxisTitle(ChartGraphics graph) + { + if (!this.enabled) + return; + + // Draw axis title + if (this.Title.Length > 0) + { + Matrix oldTransform = null; + + // Draw title in 3D + if (ChartArea.Area3DStyle.Enable3D && !ChartArea.chartAreaIsCurcular) + { + DrawAxis3DTitle(graph); + return; + } + + string axisTitle = this.Title; + + //****************************************************** + //** Check axis position + //****************************************************** + float axisPosition = (float)this.GetAxisPosition(); + if (this.AxisPosition == AxisPosition.Bottom) + { + if (!this.GetIsMarksNextToAxis()) + { + axisPosition = ChartArea.PlotAreaPosition.Bottom; + } + axisPosition = ChartArea.PlotAreaPosition.Bottom - axisPosition; + } + else if (this.AxisPosition == AxisPosition.Top) + { + if (!this.GetIsMarksNextToAxis()) + { + axisPosition = ChartArea.PlotAreaPosition.Y; + } + axisPosition = axisPosition - ChartArea.PlotAreaPosition.Y; + } + else if (this.AxisPosition == AxisPosition.Right) + { + if (!this.GetIsMarksNextToAxis()) + { + axisPosition = ChartArea.PlotAreaPosition.Right; + } + axisPosition = ChartArea.PlotAreaPosition.Right - axisPosition; + } + else if (this.AxisPosition == AxisPosition.Left) + { + if (!this.GetIsMarksNextToAxis()) + { + axisPosition = ChartArea.PlotAreaPosition.X; + } + axisPosition = axisPosition - ChartArea.PlotAreaPosition.X; + } + + //****************************************************** + //** Adjust axis elements size with axis position + //****************************************************** + // Calculate total size of axis elements + float axisSize = this.markSize + this.labelSize; + axisSize -= axisPosition; + if (axisSize < 0) + { + axisSize = 0; + } + // Set title alignment + using (StringFormat format = new StringFormat()) + { + format.Alignment = this.TitleAlignment; + format.Trimming = StringTrimming.EllipsisCharacter; + // VSTS #144398 + // We need to have the StringFormatFlags set to FitBlackBox as othwerwise axis titles using Fonts like + // "Algerian" or "Forte" are completly clipped (= not drawn) due to the fact that MeasureString returns + // a bounding rectangle that is too small. + format.FormatFlags |= StringFormatFlags.FitBlackBox; + + // Calculate title rectangle + _titlePosition = ChartArea.PlotAreaPosition.ToRectangleF(); + float titleSizeWithoutSpacing = this.titleSize - elementSpacing; + if (this.AxisPosition == AxisPosition.Left) + { + _titlePosition.X = ChartArea.PlotAreaPosition.X - titleSizeWithoutSpacing - axisSize; + _titlePosition.Y = ChartArea.PlotAreaPosition.Y; + + if (!this.IsTextVertical) + { + SizeF axisTitleSize = new SizeF(titleSizeWithoutSpacing, ChartArea.PlotAreaPosition.Height); + _titlePosition.Width = axisTitleSize.Width; + _titlePosition.Height = axisTitleSize.Height; + + format.Alignment = StringAlignment.Center; + if (this.TitleAlignment == StringAlignment.Far) + { + format.LineAlignment = StringAlignment.Near; + } + else if (this.TitleAlignment == StringAlignment.Near) + { + format.LineAlignment = StringAlignment.Far; + } + else + { + format.LineAlignment = StringAlignment.Center; + } + } + else + { + SizeF axisTitleSize = graph.GetAbsoluteSize(new SizeF(titleSizeWithoutSpacing, ChartArea.PlotAreaPosition.Height)); + axisTitleSize = graph.GetRelativeSize(new SizeF(axisTitleSize.Height, axisTitleSize.Width)); + + _titlePosition.Width = axisTitleSize.Width; + _titlePosition.Height = axisTitleSize.Height; + + _titlePosition.Y += ChartArea.PlotAreaPosition.Height / 2f - _titlePosition.Height / 2f; + _titlePosition.X += titleSizeWithoutSpacing / 2f - _titlePosition.Width / 2f; + + // Set graphics rotation transformation + oldTransform = this.SetRotationTransformation(graph, _titlePosition); + + // Set alignment + format.LineAlignment = StringAlignment.Center; + } + } + else if (this.AxisPosition == AxisPosition.Right) + { + _titlePosition.X = ChartArea.PlotAreaPosition.Right + axisSize; + _titlePosition.Y = ChartArea.PlotAreaPosition.Y; + + if (!this.IsTextVertical) + { + SizeF axisTitleSize = new SizeF(titleSizeWithoutSpacing, ChartArea.PlotAreaPosition.Height); + _titlePosition.Width = axisTitleSize.Width; + _titlePosition.Height = axisTitleSize.Height; + + format.Alignment = StringAlignment.Center; + if (this.TitleAlignment == StringAlignment.Far) + { + format.LineAlignment = StringAlignment.Near; + } + else if (this.TitleAlignment == StringAlignment.Near) + { + format.LineAlignment = StringAlignment.Far; + } + else + { + format.LineAlignment = StringAlignment.Center; + } + } + else + { + SizeF axisTitleSize = graph.GetAbsoluteSize(new SizeF(titleSizeWithoutSpacing, ChartArea.PlotAreaPosition.Height)); + axisTitleSize = graph.GetRelativeSize(new SizeF(axisTitleSize.Height, axisTitleSize.Width)); + + _titlePosition.Width = axisTitleSize.Width; + _titlePosition.Height = axisTitleSize.Height; + + _titlePosition.Y += ChartArea.PlotAreaPosition.Height / 2f - _titlePosition.Height / 2f; + _titlePosition.X += titleSizeWithoutSpacing / 2f - _titlePosition.Width / 2f; + + // Set graphics rotation transformation + oldTransform = this.SetRotationTransformation(graph, _titlePosition); + + // Set alignment + format.LineAlignment = StringAlignment.Center; + } + } + else if (this.AxisPosition == AxisPosition.Top) + { + _titlePosition.Y = ChartArea.PlotAreaPosition.Y - titleSizeWithoutSpacing - axisSize; + _titlePosition.Height = titleSizeWithoutSpacing; + _titlePosition.X = ChartArea.PlotAreaPosition.X; + _titlePosition.Width = ChartArea.PlotAreaPosition.Width; + + if (this.IsTextVertical) + { + // Set graphics rotation transformation + oldTransform = this.SetRotationTransformation(graph, _titlePosition); + } + + // Set alignment + format.LineAlignment = StringAlignment.Center; + } + else if (this.AxisPosition == AxisPosition.Bottom) + { + _titlePosition.Y = ChartArea.PlotAreaPosition.Bottom + axisSize; + _titlePosition.Height = titleSizeWithoutSpacing; + _titlePosition.X = ChartArea.PlotAreaPosition.X; + _titlePosition.Width = ChartArea.PlotAreaPosition.Width; + + if (this.IsTextVertical) + { + // Set graphics rotation transformation + oldTransform = this.SetRotationTransformation(graph, _titlePosition); + } + + // Set alignment + format.LineAlignment = StringAlignment.Center; + } + +#if DEBUG + // TESTING CODE: Shows labels rectangle position. + // RectangleF rr = graph.GetAbsoluteRectangle(_titlePosition); + // graph.DrawRectangle(Pens.Blue, rr.X, rr.Y, rr.Width, rr.Height); +#endif // DEBUG + + // Draw title + using (Brush brush = new SolidBrush(this.TitleForeColor)) + { + graph.DrawStringRel( + axisTitle.Replace("\\n", "\n"), + this.TitleFont, + brush, + _titlePosition, + format, + this.GetTextOrientation()); + } + } + + // Process selection regions + if (this.Common.ProcessModeRegions) + { + // NOTE: Solves Issue #4423 + // Transform title position coordinates using curent Graphics matrix + RectangleF transformedTitlePosition = graph.GetAbsoluteRectangle(_titlePosition); + PointF[] rectPoints = new PointF[] { + new PointF(transformedTitlePosition.X, transformedTitlePosition.Y), + new PointF(transformedTitlePosition.Right, transformedTitlePosition.Bottom) }; + graph.Transform.TransformPoints(rectPoints); + transformedTitlePosition = new RectangleF( + rectPoints[0].X, + rectPoints[0].Y, + rectPoints[1].X - rectPoints[0].X, + rectPoints[1].Y - rectPoints[0].Y); + if (transformedTitlePosition.Width < 0) + { + transformedTitlePosition.Width = Math.Abs(transformedTitlePosition.Width); + transformedTitlePosition.X -= transformedTitlePosition.Width; + } + if (transformedTitlePosition.Height < 0) + { + transformedTitlePosition.Height = Math.Abs(transformedTitlePosition.Height); + transformedTitlePosition.Y -= transformedTitlePosition.Height; + } + + // Add hot region + this.Common.HotRegionsList.AddHotRegion( + transformedTitlePosition, this, ChartElementType.AxisTitle, false, false); + } + + // Restore old transformation + if (oldTransform != null) + { + graph.Transform = oldTransform; + } + } + } + + /// + /// Helper method which sets 90 or -90 degrees transformation in the middle of the + /// specified rectangle. It is used to draw title text rotated 90 or 270 degrees. + /// + /// Chart graphics to apply transformation for. + /// Title position. + /// Old graphics transformation matrix. + private Matrix SetRotationTransformation(ChartGraphics graph, RectangleF titlePosition) + { + // Save old graphics transformation + Matrix oldTransform = graph.Transform.Clone(); + + // Rotate left tile 90 degrees at center + PointF center = PointF.Empty; + center.X = titlePosition.X + titlePosition.Width / 2F; + center.Y = titlePosition.Y + titlePosition.Height / 2F; + + // Create and set new transformation matrix + float angle = (this.GetTextOrientation() == TextOrientation.Rotated90) ? 90f : -90f; + Matrix newMatrix = graph.Transform.Clone(); + newMatrix.RotateAt(angle, graph.GetAbsolutePoint(center)); + graph.Transform = newMatrix; + + return oldTransform; + } + + + /// + /// Draws a radial line in circular Common.Chart area. + /// + /// Object requesting the painting. + /// Graphics path. + /// Line color. + /// Line width. + /// Line style. + /// X axis circular position. + internal void DrawRadialLine( + object obj, + ChartGraphics graph, + Color color, + int width, + ChartDashStyle style, + double position) + { + // Create circle position rectangle + RectangleF rect = ChartArea.PlotAreaPosition.ToRectangleF(); + rect = graph.GetAbsoluteRectangle(rect); + + // Make sure the rectangle width equals rectangle height for the circle + if (rect.Width != rect.Height) + { + if (rect.Width > rect.Height) + { + rect.X += (rect.Width - rect.Height) / 2f; + rect.Width = rect.Height; + } + else + { + rect.Y += (rect.Height - rect.Width) / 2f; + rect.Height = rect.Width; + } + } + + // Convert axis position to angle + float angle = ChartArea.CircularPositionToAngle(position); + + // Set clipping region to the polygon + Region oldRegion = null; + if (ChartArea.CircularUsePolygons) + { + oldRegion = graph.Clip; + graph.Clip = new Region(graph.GetPolygonCirclePath(rect, ChartArea.CircularSectorsNumber)); + } + + // Get center point + PointF centerPoint = graph.GetAbsolutePoint(ChartArea.circularCenter); + + // Set graphics rotation matrix + Matrix oldMatrix = graph.Transform; + Matrix newMatrix = oldMatrix.Clone(); + newMatrix.RotateAt( + angle, + centerPoint); + graph.Transform = newMatrix; + + // Draw Line + PointF endPoint = new PointF(rect.X + rect.Width / 2f, rect.Y); + graph.DrawLineAbs(color, width, style, centerPoint, endPoint); + + // Process selection regions + if (this.Common.ProcessModeRegions) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddLine(centerPoint, endPoint); + path.Transform(newMatrix); + try + { + using (Pen pen = new Pen(Color.Black, width + 2)) + { + path.Widen(pen); + this.Common.HotRegionsList.AddHotRegion(path, false, ChartElementType.Gridlines, obj); + } + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + } + } + + // Restore graphics + graph.Transform = oldMatrix; + newMatrix.Dispose(); + + // Restore clip region + if (ChartArea.CircularUsePolygons) + { + graph.Clip = oldRegion; + } + + } + + /// + /// Draws a circular line in circular Common.Chart area. + /// + /// Object requesting the painting. + /// Graphics path. + /// Line color. + /// Line width. + /// Line style. + /// Line position. + internal void DrawCircularLine( + object obj, + ChartGraphics graph, + Color color, + int width, + ChartDashStyle style, + float position + ) + { + // Create circle position rectangle + RectangleF rect = ChartArea.PlotAreaPosition.ToRectangleF(); + rect = graph.GetAbsoluteRectangle(rect); + + // Make sure the rectangle width equals rectangle height for the circle + if (rect.Width != rect.Height) + { + if (rect.Width > rect.Height) + { + rect.X += (rect.Width - rect.Height) / 2f; + rect.Width = rect.Height; + } + else + { + rect.Y += (rect.Height - rect.Width) / 2f; + rect.Height = rect.Width; + } + } + + // Inflate rectangle + PointF absPoint = graph.GetAbsolutePoint(new PointF(position, position)); + float rectInflate = absPoint.Y - rect.Top; + rect.Inflate(-rectInflate, -rectInflate); + + // Create circle pen + Pen circlePen = new Pen(color, width); + circlePen.DashStyle = graph.GetPenStyle(style); + + // Draw circle + if (ChartArea.CircularUsePolygons) + { + // Draw eaqula sides polygon + graph.DrawCircleAbs(circlePen, null, rect, ChartArea.CircularSectorsNumber, false); + } + else + { + graph.DrawEllipse(circlePen, rect); + } + + // Process selection regions + if (this.Common.ProcessModeRegions) + { + // Bounding rectangle must be more than 1 pixel by 1 pixel + if (rect.Width >= 1f && rect.Height > 1) + { + GraphicsPath path = null; + try + { + if (ChartArea.CircularUsePolygons) + { + path = graph.GetPolygonCirclePath(rect, ChartArea.CircularSectorsNumber); + } + else + { + path = new GraphicsPath(); + path.AddEllipse(rect); + } + circlePen.Width += 2; + path.Widen(circlePen); + this.Common.HotRegionsList.AddHotRegion(path, false, ChartElementType.Gridlines, obj); + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + finally + { + path.Dispose(); + } + } + } + + } + + /// + /// Draw axis title in 3D. + /// + /// Reference to the Chart Graphics object + private void DrawAxis3DTitle(ChartGraphics graph) + { + // Do not draw title if axis is not enabled + if (!this.enabled) + { + return; + } + + string axisTitle = this.Title; + + // Draw axis title + PointF rotationCenter = PointF.Empty; + int angle = 0; + + // Set title alignment + using (StringFormat format = new StringFormat()) + { + format.Alignment = this.TitleAlignment; + format.Trimming = StringTrimming.EllipsisCharacter; + format.FormatFlags |= StringFormatFlags.LineLimit; + + // Measure title size for non-centered aligment + SizeF realTitleSize = graph.MeasureString(axisTitle.Replace("\\n", "\n"), this.TitleFont, new SizeF(10000f, 10000f), format, this.GetTextOrientation()); + SizeF axisTitleSize = SizeF.Empty; + if (format.Alignment != StringAlignment.Center) + { + axisTitleSize = realTitleSize; + if (this.IsTextVertical) + { + // Switch height and width for vertical axis + float tempValue = axisTitleSize.Height; + axisTitleSize.Height = axisTitleSize.Width; + axisTitleSize.Width = tempValue; + } + + // Get relative size + axisTitleSize = graph.GetRelativeSize(axisTitleSize); + + // Change format aligment for the reversed mode + if (ChartArea.ReverseSeriesOrder) + { + if (format.Alignment == StringAlignment.Near) + { + format.Alignment = StringAlignment.Far; + } + else + { + format.Alignment = StringAlignment.Near; + } + } + } + + // Set text rotation angle based on the text orientation + if (this.GetTextOrientation() == TextOrientation.Rotated90) + { + angle = 90; + } + else if (this.GetTextOrientation() == TextOrientation.Rotated270) + { + angle = -90; + } + + // Calculate title center point on the axis + if (this.AxisPosition == AxisPosition.Left) + { + rotationCenter = new PointF(ChartArea.PlotAreaPosition.X, ChartArea.PlotAreaPosition.Y + ChartArea.PlotAreaPosition.Height / 2f); + if (format.Alignment == StringAlignment.Near) + { + rotationCenter.Y = ChartArea.PlotAreaPosition.Bottom - axisTitleSize.Height / 2f; + } + else if (format.Alignment == StringAlignment.Far) + { + rotationCenter.Y = ChartArea.PlotAreaPosition.Y + axisTitleSize.Height / 2f; + } + } + else if (this.AxisPosition == AxisPosition.Right) + { + rotationCenter = new PointF(ChartArea.PlotAreaPosition.Right, ChartArea.PlotAreaPosition.Y + ChartArea.PlotAreaPosition.Height / 2f); + if (format.Alignment == StringAlignment.Near) + { + rotationCenter.Y = ChartArea.PlotAreaPosition.Bottom - axisTitleSize.Height / 2f; + } + else if (format.Alignment == StringAlignment.Far) + { + rotationCenter.Y = ChartArea.PlotAreaPosition.Y + axisTitleSize.Height / 2f; + } + } + else if (this.AxisPosition == AxisPosition.Top) + { + rotationCenter = new PointF(ChartArea.PlotAreaPosition.X + ChartArea.PlotAreaPosition.Width / 2f, ChartArea.PlotAreaPosition.Y); + if (format.Alignment == StringAlignment.Near) + { + rotationCenter.X = ChartArea.PlotAreaPosition.X + axisTitleSize.Width / 2f; + } + else if (format.Alignment == StringAlignment.Far) + { + rotationCenter.X = ChartArea.PlotAreaPosition.Right - axisTitleSize.Width / 2f; + } + } + else if (this.AxisPosition == AxisPosition.Bottom) + { + rotationCenter = new PointF(ChartArea.PlotAreaPosition.X + ChartArea.PlotAreaPosition.Width / 2f, ChartArea.PlotAreaPosition.Bottom); + if (format.Alignment == StringAlignment.Near) + { + rotationCenter.X = ChartArea.PlotAreaPosition.X + axisTitleSize.Width / 2f; + } + else if (format.Alignment == StringAlignment.Far) + { + rotationCenter.X = ChartArea.PlotAreaPosition.Right - axisTitleSize.Width / 2f; + } + } + + // Transform center of title coordinates and calculate axis angle + bool isOnEdge = false; + float zPosition = this.GetMarksZPosition(out isOnEdge); + Point3D[] rotationCenterPoints = null; + float angleAxis = 0; + if (this.AxisPosition == AxisPosition.Top || this.AxisPosition == AxisPosition.Bottom) + { + rotationCenterPoints = new Point3D[] { + new Point3D(rotationCenter.X, rotationCenter.Y, zPosition), + new Point3D(rotationCenter.X - 20f, rotationCenter.Y, zPosition) }; + + // Transform coordinates of text rotation point + ChartArea.matrix3D.TransformPoints(rotationCenterPoints); + rotationCenter = rotationCenterPoints[0].PointF; + + // Get absolute coordinates + rotationCenterPoints[0].PointF = graph.GetAbsolutePoint(rotationCenterPoints[0].PointF); + rotationCenterPoints[1].PointF = graph.GetAbsolutePoint(rotationCenterPoints[1].PointF); + + // Calculate X axis angle + angleAxis = (float)Math.Atan( + (rotationCenterPoints[1].Y - rotationCenterPoints[0].Y) / + (rotationCenterPoints[1].X - rotationCenterPoints[0].X)); + } + else + { + rotationCenterPoints = new Point3D[] { + new Point3D(rotationCenter.X, rotationCenter.Y, zPosition), + new Point3D(rotationCenter.X, rotationCenter.Y - 20f, zPosition) }; + + // Transform coordinates of text rotation point + ChartArea.matrix3D.TransformPoints(rotationCenterPoints); + rotationCenter = rotationCenterPoints[0].PointF; + + // Get absolute coordinates + rotationCenterPoints[0].PointF = graph.GetAbsolutePoint(rotationCenterPoints[0].PointF); + rotationCenterPoints[1].PointF = graph.GetAbsolutePoint(rotationCenterPoints[1].PointF); + + // Calculate Y axis angle + if (rotationCenterPoints[1].Y != rotationCenterPoints[0].Y) + { + angleAxis = -(float)Math.Atan( + (rotationCenterPoints[1].X - rotationCenterPoints[0].X) / + (rotationCenterPoints[1].Y - rotationCenterPoints[0].Y)); + } + } + angle += (int)Math.Round(angleAxis * 180f / (float)Math.PI); + + + // Calculate title center offset from the axis line + float offset = this.labelSize + this.markSize + this.titleSize / 2f; + float dX = 0f, dY = 0f; + + + // Adjust center of title with labels, marker and title size + if (this.AxisPosition == AxisPosition.Left) + { + dX = (float)(offset * Math.Cos(angleAxis)); + rotationCenter.X -= dX; + } + else if (this.AxisPosition == AxisPosition.Right) + { + dX = (float)(offset * Math.Cos(angleAxis)); + rotationCenter.X += dX; + } + else if (this.AxisPosition == AxisPosition.Top) + { + dY = (float)(offset * Math.Cos(angleAxis)); + dX = (float)(offset * Math.Sin(angleAxis)); + rotationCenter.Y -= dY; + if (dY > 0) + { + rotationCenter.X += dX; + } + else + { + rotationCenter.X -= dX; + } + } + else if (this.AxisPosition == AxisPosition.Bottom) + { + dY = (float)(offset * Math.Cos(angleAxis)); + dX = (float)(offset * Math.Sin(angleAxis)); + rotationCenter.Y += dY; + if (dY > 0) + { + rotationCenter.X -= dX; + } + else + { + rotationCenter.X += dX; + } + } + + + // Always align text in the center + format.LineAlignment = StringAlignment.Center; + format.Alignment = StringAlignment.Center; + // SQL VSTS Fix #259954, Dev10: 591135 Windows 7 crashes on empty transformation. + if (rotationCenter.IsEmpty || float.IsNaN(rotationCenter.X) || float.IsNaN(rotationCenter.Y)) + { + return; + } + + // Draw 3D title + using (Brush brush = new SolidBrush(this.TitleForeColor)) + { + graph.DrawStringRel( + axisTitle.Replace("\\n", "\n"), + this.TitleFont, + brush, + rotationCenter, + format, + angle, + this.GetTextOrientation()); + } + + // Add hot region + if (Common.ProcessModeRegions) + { + using (GraphicsPath hotPath = graph.GetTranformedTextRectPath(rotationCenter, realTitleSize, angle)) + { + this.Common.HotRegionsList.AddHotRegion(hotPath, false, ChartElementType.AxisTitle, this); + } + } + } + + } + + /// + /// Select Axis line + /// + /// Reference to the Chart Graphics + /// Back elements of the axis should be drawn in 3D scene. + internal void DrawAxisLine(ChartGraphics graph, bool backElements) + { + Axis opositeAxis; + ArrowOrientation arrowOrientation = ArrowOrientation.Top; + PointF first = Point.Empty; + PointF second = Point.Empty; + + // Set the position of axis + switch (AxisPosition) + { + + case AxisPosition.Left: + + first.X = (float)GetAxisPosition(); + first.Y = PlotAreaPosition.Bottom; + second.X = (float)GetAxisPosition(); + second.Y = PlotAreaPosition.Y; + if (isReversed) + arrowOrientation = ArrowOrientation.Bottom; + else + arrowOrientation = ArrowOrientation.Top; + + break; + + case AxisPosition.Right: + + first.X = (float)GetAxisPosition(); + first.Y = PlotAreaPosition.Bottom; + second.X = (float)GetAxisPosition(); + second.Y = PlotAreaPosition.Y; + if (isReversed) + arrowOrientation = ArrowOrientation.Bottom; + else + arrowOrientation = ArrowOrientation.Top; + + break; + + case AxisPosition.Bottom: + + first.X = PlotAreaPosition.X; + first.Y = (float)GetAxisPosition(); + second.X = PlotAreaPosition.Right; + second.Y = (float)GetAxisPosition(); + if (isReversed) + arrowOrientation = ArrowOrientation.Left; + else + arrowOrientation = ArrowOrientation.Right; + + break; + + case AxisPosition.Top: + + first.X = PlotAreaPosition.X; + first.Y = (float)GetAxisPosition(); + second.X = PlotAreaPosition.Right; + second.Y = (float)GetAxisPosition(); + if (isReversed) + arrowOrientation = ArrowOrientation.Left; + else + arrowOrientation = ArrowOrientation.Right; + + break; + + } + + // Update axis line position for circular area + if (ChartArea.chartAreaIsCurcular) + { + first.Y = PlotAreaPosition.Y + PlotAreaPosition.Height / 2f; + } + + + if (Common.ProcessModePaint) + { + if (!ChartArea.Area3DStyle.Enable3D || ChartArea.chartAreaIsCurcular) + { + + // Start Svg/Flash Selection mode + graph.StartHotRegion( this._url, _toolTip ); + + // Draw the line + graph.DrawLineRel(_lineColor, _lineWidth, _lineDashStyle, first, second); + + // End Svg/Flash Selection mode + graph.EndHotRegion( ); + + // Opposite axis. Arrow uses this axis to find + // a shift from Common.Chart area border. This shift + // depend on Tick mark size. + switch (arrowOrientation) + { + case ArrowOrientation.Left: + opositeAxis = ChartArea.AxisX; + break; + case ArrowOrientation.Right: + opositeAxis = ChartArea.AxisX2; + break; + case ArrowOrientation.Top: + opositeAxis = ChartArea.AxisY2; + break; + case ArrowOrientation.Bottom: + opositeAxis = ChartArea.AxisY; + break; + default: + opositeAxis = ChartArea.AxisX; + break; + } + + // Draw arrow + PointF arrowPosition; + if (isReversed) + arrowPosition = first; + else + arrowPosition = second; + + // Draw Arrow + graph.DrawArrowRel(arrowPosition, arrowOrientation, _arrowStyle, _lineColor, _lineWidth, _lineDashStyle, opositeAxis.majorTickMark.Size, _lineWidth); + } + else + { + Draw3DAxisLine(graph, first, second, (this.AxisPosition == AxisPosition.Top || this.AxisPosition == AxisPosition.Bottom), backElements); + } + } + + } + + + /// + /// Draws the axis line hot region. + /// + /// The graph. + /// set to true if we draw back elements. + private void DrawAxisLineHotRegion(ChartGraphics graph, bool backElements) + { + if (Common.ProcessModeRegions) + { + //VSTS #229835: During the 3D rendering the axis is drawn twice: + //1. In PrePaint() both axis and backelements (labels) are drawn. + //2. In Paint() the axis is redrawn without labels and as a result it creates a second hot region which covered the labels' hotregions. + //In order to avoid this we have to suppress the hotregion drawing in the Paint using the backElements flag (it's false during the Paint) + //The circular charts and 2D charts are drawn only once in Paint() so we draw the hot regions. + if (backElements || !ChartArea.Area3DStyle.Enable3D || ChartArea.chartAreaIsCurcular) + { + DrawAxisLineHotRegion(graph); + } + } + + } + + /// + /// Adds the axis hot region + /// + /// The chart graphics instance. + private void DrawAxisLineHotRegion(ChartGraphics graph) + { + using (GraphicsPath path = new GraphicsPath()) + { + // Find the topLeft(first) and bottomRight(second) points of the hotregion rectangle + PointF first = PointF.Empty; + PointF second = PointF.Empty; + float axisPosition = (float)GetAxisPosition(); + + switch (this.AxisPosition) + { + case AxisPosition.Left: + first.X = axisPosition - (labelSize + markSize); + first.Y = PlotAreaPosition.Y; + second.X = axisPosition; + second.Y = PlotAreaPosition.Bottom; + break; + + case AxisPosition.Right: + first.X = axisPosition; + first.Y = PlotAreaPosition.Y; + second.X = axisPosition + labelSize + markSize; + second.Y = PlotAreaPosition.Bottom; + break; + + case AxisPosition.Bottom: + first.X = PlotAreaPosition.X; + first.Y = axisPosition; + second.X = PlotAreaPosition.Right; + second.Y = axisPosition + labelSize + markSize; + break; + + case AxisPosition.Top: + first.X = PlotAreaPosition.X; + first.Y = axisPosition - (labelSize + markSize); + second.X = PlotAreaPosition.Right; + second.Y = axisPosition; + break; + } + + // Update axis line position for circular area + if (ChartArea.chartAreaIsCurcular) + { + second.Y = PlotAreaPosition.Y + PlotAreaPosition.Height / 2f; + } + + // Create rectangle and inflate it + RectangleF rect = new RectangleF(first.X, first.Y, second.X - first.X, second.Y - first.Y); + SizeF size = graph.GetRelativeSize(new SizeF(3, 3)); + + if (AxisPosition == AxisPosition.Top || AxisPosition == AxisPosition.Bottom) + { + rect.Inflate(2, size.Height); + } + else + { + rect.Inflate(size.Width, 2); + } + + // Get the rectangle points + PointF[] points = new PointF[] { + new PointF(rect.Left, rect.Top), + new PointF(rect.Right, rect.Top), + new PointF(rect.Right, rect.Bottom), + new PointF(rect.Left, rect.Bottom)}; + + // If we are dealing with the 3D - transform the rectangle + if (ChartArea.Area3DStyle.Enable3D && !ChartArea.chartAreaIsCurcular) + { + Boolean axisOnEdge = false; + float zPositon = GetMarksZPosition(out axisOnEdge); + + // Convert points to 3D + Point3D[] points3D = new Point3D[points.Length]; + for (int i = 0; i < points.Length; i++) + { + points3D[i] = new Point3D(points[i].X, points[i].Y, zPositon); + } + + // Transform + ChartArea.matrix3D.TransformPoints(points3D); + + // Convert to 2D + for (int i = 0; i < points3D.Length; i++) + { + points[i] = points3D[i].PointF; + } + } + + // Transform points to absolute cooordinates + for (int i = 0; i < points.Length; i++) + { + points[i] = graph.GetAbsolutePoint(points[i]); + } + + // Add the points to the path + path.AddPolygon(points); + + +#if Microsoft_CONTROL + Common.HotRegionsList.AddHotRegion( + graph, + path, + false, + this._toolTip, + string.Empty, + string.Empty, + string.Empty, + this, + ChartElementType.Axis); +#else + Common.HotRegionsList.AddHotRegion( + graph, + path, + false, + this._toolTip, + this._url, + this._mapAreaAttributes, + this.PostBackValue, + this, + ChartElementType.Axis); +#endif + + } + } + + + /// + /// Draws axis line in 3D space. + /// + /// Reference to the Chart Graphics object. + /// First line point. + /// Second line point. + /// Indicates that tick mark line is horizontal + /// Only back elements of axis should be drawn. + private void Draw3DAxisLine( + ChartGraphics graph, + PointF point1, + PointF point2, + bool horizontal, + bool backElements + ) + { + // Check if axis is positioned on the plot area adge + bool onEdge = this.IsAxisOnAreaEdge; + + // Check if axis tick marks are drawn inside plotting area + bool tickMarksOnEdge = onEdge; + if (tickMarksOnEdge && + this.MajorTickMark.TickMarkStyle == TickMarkStyle.AcrossAxis || + this.MajorTickMark.TickMarkStyle == TickMarkStyle.InsideArea || + this.MinorTickMark.TickMarkStyle == TickMarkStyle.AcrossAxis || + this.MinorTickMark.TickMarkStyle == TickMarkStyle.InsideArea) + { + tickMarksOnEdge = false; + } + + // Make sure first point of axis coordinates has smaller values + if ((horizontal && point1.X > point2.X) || + (!horizontal && point1.Y > point2.Y)) + { + PointF tempPoint = new PointF(point1.X, point1.Y); + point1.X = point2.X; + point1.Y = point2.Y; + point2 = tempPoint; + } + + // Check if the front/back wall is on the top drawing layer + float zPositon = ChartArea.IsMainSceneWallOnFront() ? ChartArea.areaSceneDepth : 0f; + SurfaceNames surfName = ChartArea.IsMainSceneWallOnFront() ? SurfaceNames.Front : SurfaceNames.Back; + if (ChartArea.ShouldDrawOnSurface(SurfaceNames.Back, backElements, tickMarksOnEdge)) + { + + // Start Svg Selection mode + graph.StartHotRegion( this._url, _toolTip ); + + // Draw axis line on the back/front wall + graph.Draw3DLine( + ChartArea.matrix3D, + _lineColor, _lineWidth, _lineDashStyle, + new Point3D(point1.X, point1.Y, zPositon), + new Point3D(point2.X, point2.Y, zPositon), + Common, + this, + ChartElementType.Nothing + ); + + // End Svg Selection mode + graph.EndHotRegion(); + + } + + // Check if the back wall is on the top drawing layer + zPositon = ChartArea.IsMainSceneWallOnFront() ? 0f : ChartArea.areaSceneDepth; + surfName = ChartArea.IsMainSceneWallOnFront() ? SurfaceNames.Back : SurfaceNames.Front; + if (ChartArea.ShouldDrawOnSurface(surfName, backElements, tickMarksOnEdge)) + { + // Draw axis line on the front wall + if (!onEdge || + (this.AxisPosition == AxisPosition.Bottom && ChartArea.IsBottomSceneWallVisible()) || + (this.AxisPosition == AxisPosition.Left && ChartArea.IsSideSceneWallOnLeft()) || + (this.AxisPosition == AxisPosition.Right && !ChartArea.IsSideSceneWallOnLeft())) + { + + // Start Svg Selection mode + graph.StartHotRegion( this._url, _toolTip ); + + graph.Draw3DLine( + ChartArea.matrix3D, + _lineColor, _lineWidth, _lineDashStyle, + new Point3D(point1.X, point1.Y, zPositon), + new Point3D(point2.X, point2.Y, zPositon), + Common, + this, + ChartElementType.Nothing + ); + + // End Svg Selection mode + graph.EndHotRegion(); + + } + } + + // Check if the left/top wall is on the top drawing layer + SurfaceNames surfaceName = (this.AxisPosition == AxisPosition.Left || this.AxisPosition == AxisPosition.Right) ? SurfaceNames.Top : SurfaceNames.Left; + if (ChartArea.ShouldDrawOnSurface(surfaceName, backElements, tickMarksOnEdge)) + { + // Draw axis line on the left/top side walls + if (!onEdge || + (this.AxisPosition == AxisPosition.Bottom && (ChartArea.IsBottomSceneWallVisible() || ChartArea.IsSideSceneWallOnLeft())) || + (this.AxisPosition == AxisPosition.Left && ChartArea.IsSideSceneWallOnLeft()) || + (this.AxisPosition == AxisPosition.Right && !ChartArea.IsSideSceneWallOnLeft()) || + (this.AxisPosition == AxisPosition.Top && ChartArea.IsSideSceneWallOnLeft())) + { + + // Start Svg Selection mode + graph.StartHotRegion( this._url, _toolTip ); + + graph.Draw3DLine( + ChartArea.matrix3D, + _lineColor, _lineWidth, _lineDashStyle, + new Point3D(point1.X, point1.Y, ChartArea.areaSceneDepth), + new Point3D(point1.X, point1.Y, 0f), + Common, + this, + ChartElementType.Nothing + ); + + // End Svg Selection mode + graph.EndHotRegion( ); + + } + } + + // Check if the right/bottom wall is on the top drawing layer + surfaceName = (this.AxisPosition == AxisPosition.Left || this.AxisPosition == AxisPosition.Right) ? SurfaceNames.Bottom : SurfaceNames.Right; + if (ChartArea.ShouldDrawOnSurface(surfaceName, backElements, tickMarksOnEdge)) + { + // Draw axis line on the bottom/right side walls + if (!onEdge || + (this.AxisPosition == AxisPosition.Bottom && (ChartArea.IsBottomSceneWallVisible() || !ChartArea.IsSideSceneWallOnLeft())) || + (this.AxisPosition == AxisPosition.Left && (ChartArea.IsSideSceneWallOnLeft() || ChartArea.IsBottomSceneWallVisible())) || + (this.AxisPosition == AxisPosition.Right && (!ChartArea.IsSideSceneWallOnLeft() || ChartArea.IsBottomSceneWallVisible())) || + (this.AxisPosition == AxisPosition.Top && !ChartArea.IsSideSceneWallOnLeft()) + ) + { + + // Start Svg Selection mode + graph.StartHotRegion( this._url, _toolTip ); + + graph.Draw3DLine( + ChartArea.matrix3D, + _lineColor, _lineWidth, _lineDashStyle, + new Point3D(point2.X, point2.Y, ChartArea.areaSceneDepth), + new Point3D(point2.X, point2.Y, 0f), + Common, + this, + ChartElementType.Nothing + ); + + // End Svg Selection mode + graph.EndHotRegion(); + + } + } + + } + + /// + /// Gets Z position of axis tick marks and labels. + /// + /// Returns true if axis is on the edge. + /// Marks Z position. + internal float GetMarksZPosition(out bool axisOnEdge) + { + axisOnEdge = this.IsAxisOnAreaEdge; + if (!this.GetIsMarksNextToAxis()) + { + // Marks are forced to be on the area edge + axisOnEdge = true; + } + float wallZPosition = 0f; + if (this.AxisPosition == AxisPosition.Bottom && (ChartArea.IsBottomSceneWallVisible() || !axisOnEdge)) + { + wallZPosition = ChartArea.areaSceneDepth; + } + if (this.AxisPosition == AxisPosition.Left && (ChartArea.IsSideSceneWallOnLeft() || !axisOnEdge)) + { + wallZPosition = ChartArea.areaSceneDepth; + } + if (this.AxisPosition == AxisPosition.Right && (!ChartArea.IsSideSceneWallOnLeft() || !axisOnEdge)) + { + wallZPosition = ChartArea.areaSceneDepth; + } + if (this.AxisPosition == AxisPosition.Top && !axisOnEdge) + { + wallZPosition = ChartArea.areaSceneDepth; + } + + // Check if front wall is shown + if (ChartArea.IsMainSceneWallOnFront()) + { + // Switch Z position of tick mark + wallZPosition = (wallZPosition == 0f) ? ChartArea.areaSceneDepth : 0f; + } + + return wallZPosition; + } + + /// + /// Paint Axis Grid lines + /// + /// Reference to the Chart Graphics object + internal void PaintGrids(ChartGraphics graph) + { + object obj; + + PaintGrids(graph, out obj); + + } + + /// + /// Paint Axis Grid lines or + /// hit test function for grid lines + /// + /// Reference to the Chart Graphics object + /// Returns selected grid object + internal void PaintGrids(ChartGraphics graph, out object obj) + { + obj = null; + +#if SUBAXES + // Paint grids of sub-axis + if(!ChartArea.Area3DStyle.Enable3D && + !ChartArea.chartAreaIsCurcular) + { + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.PaintGrids( graph, out obj); + } + } +#endif // SUBAXES + + // Axis is disabled + if (enabled == false) + return; + + // Paint Minor grid lines + minorGrid.Paint(graph); + + // Paint Major grid lines + majorGrid.Paint(graph); + } + + /// + /// Paint Axis Strip lines + /// + /// Reference to the Chart Graphics object + /// Indicates if Lines or Stripes should be drawn. + internal void PaintStrips(ChartGraphics graph, bool drawLinesOnly) + { + object obj; + PaintStrips(graph, false, 0, 0, out obj, drawLinesOnly); + } + + /// + /// Paint Axis Strip lines or + /// hit test function for Strip lines + /// + /// Reference to the Chart Graphics object + /// The selection mode is active + /// X coordinate + /// Y coordinate + /// Returns selected grid object + /// Indicates if Lines or Stripes should be drawn. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "y"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "x"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "selectionMode")] + internal void PaintStrips(ChartGraphics graph, bool selectionMode, int x, int y, out object obj, bool drawLinesOnly) + { + obj = null; + +#if SUBAXES + // Paint strips of sub-axis + if(ChartArea.IsSubAxesSupported) + { + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.PaintStrips( graph, selectionMode, x, y, out obj, drawLinesOnly); + } + } +#endif // SUBAXES + + // Axis is disabled + if (enabled == false) + return; + + // Add axis isInterlaced strip lines into the collection + bool interlacedStripAdded = AddInterlacedStrip(); + + // Draw axis strips and lines + foreach (StripLine strip in this.StripLines) + { + strip.Paint(graph, this.Common, drawLinesOnly); + } + + // Remove axis isInterlaced strip line from the collection after drawing + if (interlacedStripAdded) + { + // Remove isInterlaced strips which always is the first strip line + this.StripLines.RemoveAt(0); + } + + } + + /// + /// Helper function which adds temp. strip lines into the collection + /// to display isInterlaced lines in axis. + /// + private bool AddInterlacedStrip() + { + bool addStrip = false; + if (this.IsInterlaced) + { + StripLine stripLine = new StripLine(); + stripLine.interlaced = true; + // VSTS fix of 164115 IsInterlaced StripLines with no border are rendered with black border, regression of VSTS 136763 + stripLine.BorderColor = Color.Empty; + + // Get interval from grid lines, tick marks or labels + if (this.MajorGrid.Enabled && this.MajorGrid.GetInterval() != 0.0) + { + addStrip = true; + stripLine.Interval = this.MajorGrid.GetInterval() * 2.0; + stripLine.IntervalType = this.MajorGrid.GetIntervalType(); + stripLine.IntervalOffset = this.MajorGrid.GetIntervalOffset(); + stripLine.IntervalOffsetType = this.MajorGrid.GetIntervalOffsetType(); + stripLine.StripWidth = this.MajorGrid.GetInterval(); + stripLine.StripWidthType = this.MajorGrid.GetIntervalType(); + } + else if (this.MajorTickMark.Enabled && this.MajorTickMark.GetInterval() != 0.0) + { + addStrip = true; + stripLine.Interval = this.MajorTickMark.GetInterval() * 2.0; + stripLine.IntervalType = this.MajorTickMark.GetIntervalType(); + stripLine.IntervalOffset = this.MajorTickMark.GetIntervalOffset(); + stripLine.IntervalOffsetType = this.MajorTickMark.GetIntervalOffsetType(); + stripLine.StripWidth = this.MajorTickMark.GetInterval(); + stripLine.StripWidthType = this.MajorTickMark.GetIntervalType(); + } + else if (this.LabelStyle.Enabled && this.LabelStyle.GetInterval() != 0.0) + { + addStrip = true; + stripLine.Interval = this.LabelStyle.GetInterval() * 2.0; + stripLine.IntervalType = this.LabelStyle.GetIntervalType(); + stripLine.IntervalOffset = this.LabelStyle.GetIntervalOffset(); + stripLine.IntervalOffsetType = this.LabelStyle.GetIntervalOffsetType(); + stripLine.StripWidth = this.LabelStyle.GetInterval(); + stripLine.StripWidthType = this.LabelStyle.GetIntervalType(); + } + + // Insert item into the strips collection + if (addStrip) + { + // Define stip color + if (this.InterlacedColor != Color.Empty) + { + stripLine.BackColor = this.InterlacedColor; + } + else + { + // If isInterlaced strips color is not set - use darker color of the area + if (ChartArea.BackColor == Color.Empty) + { + stripLine.BackColor = (ChartArea.Area3DStyle.Enable3D) ? Color.DarkGray : Color.LightGray; + } + else if (ChartArea.BackColor == Color.Transparent) + { + if (Common.Chart.BackColor != Color.Transparent && Common.Chart.BackColor != Color.Black) + { + stripLine.BackColor = ChartGraphics.GetGradientColor(Common.Chart.BackColor, Color.Black, 0.2); + } + else + { + stripLine.BackColor = Color.LightGray; + } + } + else + { + stripLine.BackColor = ChartGraphics.GetGradientColor(ChartArea.BackColor, Color.Black, 0.2); + } + } + + // Insert strip + this.StripLines.Insert(0, stripLine); + } + } + + return addStrip; + } + + #endregion + + #region Axis parameters recalculation and resizing methods + + /// + /// This method will calculate the maximum and minimum values + /// using interval on the X axis automatically. It will make a gap between + /// data points and border of the Common.Chart area. + /// Note that this method can only be called for primary or secondary X axes. + /// + public void RoundAxisValues() + { + this.roundedXValues = true; + } + + /// + /// RecalculateAxesScale axis. + /// + /// Plotting area position. + internal void ReCalc(ElementPosition position) + { + PlotAreaPosition = position; + +#if SUBAXES + + // Recalculate all sub-axis + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.ReCalc( position ); + } +#endif // SUBAXES + } + + /// + /// This method store Axis values as minimum, maximum, + /// crossing, etc. Axis auto algorithm changes these + /// values and they have to be set to default values + /// after painting. + /// + internal void StoreAxisValues() + { + tempLabels = new CustomLabelsCollection(this); + foreach (CustomLabel label in CustomLabels) + { + tempLabels.Add(label.Clone()); + } + + paintMode = true; + + // This field synchronies the Storing and + // resetting of temporary values + if (_storeValuesEnabled) + { + + tempMaximum = maximum; + tempMinimum = minimum; + tempCrossing = crossing; + tempAutoMinimum = _autoMinimum; + tempAutoMaximum = _autoMaximum; + + tempMajorGridInterval = majorGrid.interval; + tempMajorTickMarkInterval = majorTickMark.interval; + + tempMinorGridInterval = minorGrid.interval; + tempMinorTickMarkInterval = minorTickMark.interval; + + + tempGridIntervalType = majorGrid.intervalType; + tempTickMarkIntervalType = majorTickMark.intervalType; + + + tempLabelInterval = labelStyle.interval; + tempLabelIntervalType = labelStyle.intervalType; + + // Remember original ScaleView Position + this._originalViewPosition = this.ScaleView.Position; + + // This field synchronies the Storing and + // resetting of temporary values + _storeValuesEnabled = false; + } + +#if SUBAXES + + // Store values of all sub-axis + if(ChartArea.IsSubAxesSupported) + { + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.StoreAxisValues( ); + } + } +#endif // SUBAXES + + } + + + /// + /// This method reset Axis values as minimum, maximum, + /// crossing, etc. Axis auto algorithm changes these + /// values and they have to be set to default values + /// after painting. + /// + internal void ResetAxisValues() + { + // Paint mode is finished + paintMode = false; + +#if Microsoft_CONTROL + if(Common.Chart == null) + { +#if SUBAXES + else if(this is SubAxis) + { + if( ((SubAxis)this).parentAxis != null) + { + this.Common = ((SubAxis)this).parentAxis.Common; + Common.Chart = ((SubAxis)this).parentAxis.Common.Chart; + } + } +#endif // SUBAXES + } + if(Common.Chart != null && Common.Chart.Site != null && Common.Chart.Site.DesignMode) + { + ResetAutoValues(); + } +#else + ResetAutoValues(); +#endif + + // Reset back original custom labels + if (tempLabels != null) + { + CustomLabels.Clear(); + foreach (CustomLabel label in tempLabels) + { + CustomLabels.Add(label.Clone()); + } + + tempLabels = null; + } + +#if SUBAXES + + // Reset values of all sub-axis + if(ChartArea.IsSubAxesSupported) + { + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.ResetAxisValues( ); + } + } +#endif // SUBAXES + } + + + /// + /// Reset auto calculated axis values + /// + internal void ResetAutoValues() + { + refreshMinMaxFromData = true; + maximum = tempMaximum; + minimum = tempMinimum; + crossing = tempCrossing; + _autoMinimum = tempAutoMinimum; + _autoMaximum = tempAutoMaximum; + + majorGrid.interval = tempMajorGridInterval; + majorTickMark.interval = tempMajorTickMarkInterval; + + minorGrid.interval = tempMinorGridInterval; + minorTickMark.interval = tempMinorTickMarkInterval; + + + labelStyle.interval = tempLabelInterval; + majorGrid.intervalType = tempGridIntervalType; + majorTickMark.intervalType = tempTickMarkIntervalType; + labelStyle.intervalType = tempLabelIntervalType; + + // Restore original ScaleView Position + if (Common.Chart != null) + { + if (!Common.Chart.serializing) + { + this.ScaleView.Position = this._originalViewPosition; + } + } + + // This field synchronies the Storing and + // resetting of temporary values + _storeValuesEnabled = true; + +#if SUBAXES + + // Reset auto values of all sub-axis + if(ChartArea.IsSubAxesSupported) + { + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.ResetAutoValues( ); + } + } +#endif // SUBAXES + + } + + /// + /// Calculate size of the axis elements like title, labels and marks. + /// + /// Chart graphics object. + /// The Chart area position. + /// Plotting area size. + /// Number of axis of the same orientation. + /// Indicates that inner plot position is automatic. + virtual internal void Resize( + ChartGraphics chartGraph, + ElementPosition chartAreaPosition, + RectangleF plotArea, + float axesNumber, + bool autoPlotPosition) + { +#if SUBAXES + // Resize all sub-axis + if(ChartArea.IsSubAxesSupported) + { + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.Resize(chartGraph, chartAreaPosition, plotArea, axesNumber, autoPlotPosition); + } + } +#endif // SUBAXES + + +#if Microsoft_CONTROL + // Disable Common.Chart invalidation + bool oldDisableInvalidates = Common.Chart.disableInvalidates; + Common.Chart.disableInvalidates = true; +#endif //Microsoft_CONTROL + + // Set Common.Chart area position + PlotAreaPosition = chartAreaPosition; + + // Initialize plot area size + PlotAreaPosition.FromRectangleF(plotArea); + + //****************************************************** + //** Calculate axis title size + //****************************************************** + this.titleSize = 0F; + if (this.Title.Length > 0) + { + // Measure axis title + SizeF titleStringSize = chartGraph.MeasureStringRel(this.Title.Replace("\\n", "\n"), this.TitleFont, new SizeF(10000f, 10000f), StringFormat.GenericTypographic, this.GetTextOrientation()); + + // Switch Width & Heigth for vertical axes + // If axis is horizontal + float maxTitlesize = 0; + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + maxTitlesize = (plotArea.Height / 100F) * (Axis.maxAxisTitleSize / axesNumber); + if (this.IsTextVertical) + { + this.titleSize = Math.Min(titleStringSize.Width, maxTitlesize); + } + else + { + this.titleSize = Math.Min(titleStringSize.Height, maxTitlesize); + } + } + // If axis is vertical + else + { + titleStringSize = chartGraph.GetAbsoluteSize(titleStringSize); + titleStringSize = chartGraph.GetRelativeSize(new SizeF(titleStringSize.Height, titleStringSize.Width)); + maxTitlesize = (plotArea.Width / 100F) * (Axis.maxAxisTitleSize / axesNumber); + if (this.IsTextVertical) + { + this.titleSize = Math.Min(titleStringSize.Width, maxTitlesize); + } + else + { + this.titleSize = Math.Min(titleStringSize.Height, maxTitlesize); + } + } + } + if (this.titleSize > 0) + { + this.titleSize += elementSpacing; + } + + //********************************************************* + //** Get arrow size of the opposite axis + //********************************************************* + float arrowSize = 0F; + SizeF arrowSizePrimary = SizeF.Empty; + SizeF arrowSizeSecondary = SizeF.Empty; + ArrowOrientation arrowOrientation = ArrowOrientation.Bottom; + if (this.axisType == AxisName.X || this.axisType == AxisName.X2) + { + if (ChartArea.AxisY.ArrowStyle != AxisArrowStyle.None) + { + arrowSizePrimary = ChartArea.AxisY.GetArrowSize(out arrowOrientation); + if (!IsArrowInAxis(arrowOrientation, this.AxisPosition)) + { + arrowSizePrimary = SizeF.Empty; + } + } + + if (ChartArea.AxisY2.ArrowStyle != AxisArrowStyle.None) + { + arrowSizeSecondary = ChartArea.AxisY2.GetArrowSize(out arrowOrientation); + if (!IsArrowInAxis(arrowOrientation, this.AxisPosition)) + { + arrowSizeSecondary = SizeF.Empty; + } + } + } + else + { + if (ChartArea.AxisX.ArrowStyle != AxisArrowStyle.None) + { + arrowSizePrimary = ChartArea.AxisX.GetArrowSize(out arrowOrientation); + if (!IsArrowInAxis(arrowOrientation, this.AxisPosition)) + { + arrowSizePrimary = SizeF.Empty; + } + } + + if (ChartArea.AxisX2.ArrowStyle != AxisArrowStyle.None) + { + arrowSizeSecondary = ChartArea.AxisX2.GetArrowSize(out arrowOrientation); + if (!IsArrowInAxis(arrowOrientation, this.AxisPosition)) + { + arrowSizeSecondary = SizeF.Empty; + } + } + } + + // If axis is horizontal + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + arrowSize = Math.Max(arrowSizePrimary.Height, arrowSizeSecondary.Height); + } + // If axis is vertical + else + { + arrowSize = Math.Max(arrowSizePrimary.Width, arrowSizeSecondary.Width); + } + + //********************************************************* + //** Calculate axis tick marks, axis thickness, arrow size + //** and scroll bar size + //********************************************************* + this.markSize = 0F; + + // Get major and minor tick marks sizes + float majorTickSize = 0; + if (this.MajorTickMark.Enabled && this.MajorTickMark.TickMarkStyle != TickMarkStyle.None) + { + if (this.MajorTickMark.TickMarkStyle == TickMarkStyle.InsideArea) + { + majorTickSize = 0F; + } + else if (this.MajorTickMark.TickMarkStyle == TickMarkStyle.AcrossAxis) + { + majorTickSize = this.MajorTickMark.Size / 2F; + } + else if (this.MajorTickMark.TickMarkStyle == TickMarkStyle.OutsideArea) + { + majorTickSize = this.MajorTickMark.Size; + } + } + + float minorTickSize = 0; + if (this.MinorTickMark.Enabled && this.MinorTickMark.TickMarkStyle != TickMarkStyle.None && this.MinorTickMark.GetInterval() != 0) + { + if (this.MinorTickMark.TickMarkStyle == TickMarkStyle.InsideArea) + { + minorTickSize = 0F; + } + else if (this.MinorTickMark.TickMarkStyle == TickMarkStyle.AcrossAxis) + { + minorTickSize = this.MinorTickMark.Size / 2F; + } + else if (this.MinorTickMark.TickMarkStyle == TickMarkStyle.OutsideArea) + { + minorTickSize = this.MinorTickMark.Size; + } + } + + this.markSize += (float)Math.Max(majorTickSize, minorTickSize); + + + // Add axis line size + SizeF borderSize = chartGraph.GetRelativeSize(new SizeF(this.LineWidth, this.LineWidth)); + + // If axis is horizontal + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + this.markSize += borderSize.Height / 2f; + this.markSize = Math.Min(this.markSize, (plotArea.Height / 100F) * (Axis.maxAxisMarkSize / axesNumber)); + } + // If axis is vertical + else + { + this.markSize += borderSize.Width / 2f; + this.markSize = Math.Min(this.markSize, (plotArea.Width / 100F) * (Axis.maxAxisMarkSize / axesNumber)); + } + + // Add axis scroll bar size (if it's visible) + this.scrollBarSize = 0f; + +#if Microsoft_CONTROL + + if (this.ScrollBar.IsVisible && + (this.IsAxisOnAreaEdge || !this.IsMarksNextToAxis)) + { + if (this.ScrollBar.IsPositionedInside) + { + this.markSize += (float)this.ScrollBar.GetScrollBarRelativeSize(); + } + else + { + this.scrollBarSize = (float)this.ScrollBar.GetScrollBarRelativeSize(); + } + } + +#endif // Microsoft_CONTROL + + + //********************************************************* + //** Adjust mark size using area scene wall width + //********************************************************* + if (ChartArea.Area3DStyle.Enable3D && + !ChartArea.chartAreaIsCurcular && + ChartArea.BackColor != Color.Transparent && + ChartArea.Area3DStyle.WallWidth > 0) + { + SizeF areaWallSize = chartGraph.GetRelativeSize(new SizeF(ChartArea.Area3DStyle.WallWidth, ChartArea.Area3DStyle.WallWidth)); + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + this.markSize += areaWallSize.Height; + } + else + { + this.markSize += areaWallSize.Width; + } + + // Ignore Max marks size for the 3D wall size. + //this.markSize = Math.Min(this.markSize, (plotArea.Width / 100F) * (Axis.maxAxisMarkSize / axesNumber)); + } + + //********************************************************* + //** Adjust title size and mark size using arrow size + //********************************************************* + if (arrowSize > (this.markSize + this.scrollBarSize + this.titleSize)) + { + this.markSize = Math.Max(this.markSize, arrowSize - (this.markSize + this.scrollBarSize + this.titleSize)); + this.markSize = Math.Min(this.markSize, (plotArea.Width / 100F) * (Axis.maxAxisMarkSize / axesNumber)); + } + + //********************************************************* + //** Calculate max label size + //********************************************************* + float maxLabelSize = 0; + + if (!autoPlotPosition) + { + if (this.GetIsMarksNextToAxis()) + { + if (this.AxisPosition == AxisPosition.Top) + maxLabelSize = (float)GetAxisPosition() - ChartArea.Position.Y; + else if (this.AxisPosition == AxisPosition.Bottom) + maxLabelSize = ChartArea.Position.Bottom - (float)GetAxisPosition(); + if (this.AxisPosition == AxisPosition.Left) + maxLabelSize = (float)GetAxisPosition() - ChartArea.Position.X; + else if (this.AxisPosition == AxisPosition.Right) + maxLabelSize = ChartArea.Position.Right - (float)GetAxisPosition(); + } + else + { + if (this.AxisPosition == AxisPosition.Top) + maxLabelSize = plotArea.Y - ChartArea.Position.Y; + else if (this.AxisPosition == AxisPosition.Bottom) + maxLabelSize = ChartArea.Position.Bottom - plotArea.Bottom; + if (this.AxisPosition == AxisPosition.Left) + maxLabelSize = plotArea.X - ChartArea.Position.X; + else if (this.AxisPosition == AxisPosition.Right) + maxLabelSize = ChartArea.Position.Right - plotArea.Right; + } + + maxLabelSize *= 2F; + } + else + { + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + maxLabelSize = plotArea.Height * (_maximumAutoSize / 100f); + else + maxLabelSize = plotArea.Width * (_maximumAutoSize / 100f); + } + + + + //****************************************************** + //** First try to select the interval that will + //** generate best fit labels. + //****************************************************** + + + + // Make sure the variable interval mode is enabled and + // no custom label interval used. + if( this.Enabled != AxisEnabled.False && + this.LabelStyle.Enabled && + this.IsVariableLabelCountModeEnabled() ) + { + // Increase font by several points when height of the font is the most important + // dimension. Use original size whenwidth is the most important size. + float extraSize = 3f; + if( (this.AxisPosition == AxisPosition.Left || this.AxisPosition == AxisPosition.Right) && + (this.LabelStyle.Angle == 90 || this.LabelStyle.Angle == -90) ) + { + extraSize = 0f; + } + if( (this.AxisPosition == AxisPosition.Top || this.AxisPosition == AxisPosition.Bottom) && + (this.LabelStyle.Angle == 180 || this.LabelStyle.Angle == 0) ) + { + extraSize = 0f; + } + + // If 3D Common.Chart is used make the measurements with font several point larger + if(ChartArea.Area3DStyle.Enable3D) + { + extraSize += 1f; + } + + this.autoLabelFont = Common.Chart.chartPicture.FontCache.GetFont(this.LabelStyle.Font.FontFamily, + this.LabelStyle.Font.Size + extraSize, + this.LabelStyle.Font.Style, + GraphicsUnit.Point); + + // Reset angle and stagged flag used in the auto-fitting algorithm + this.autoLabelAngle = this.LabelStyle.Angle; + this.autoLabelOffset = (this.LabelStyle.IsStaggered) ? 1 : 0; + + // Adjust interval + this.AdjustIntervalToFitLabels(chartGraph, autoPlotPosition, false); + } + + + + //****************************************************** + //** Automatically calculate the best font size, angle + //** and try to use offset labels. + //****************************************************** + // Reset all automatic label properties + autoLabelFont = null; + autoLabelAngle = -1000; + autoLabelOffset = -1; + + // For circular Common.Chart area process auto-fitting for Y Axis only + if (this.IsLabelAutoFit && + this.LabelAutoFitStyle != LabelAutoFitStyles.None && + !ChartArea.chartAreaIsCurcular) + { + bool fitDone = false; + bool noWordWrap = false; + + // Set default font angle and labels offset flag + autoLabelAngle = 0; + autoLabelOffset = 0; + + // Original labels collection + CustomLabelsCollection originalLabels = null; + + // Pick up maximum font size + float size = 8f; + size = (float)Math.Max(this.LabelAutoFitMaxFontSize, this.LabelAutoFitMinFontSize); + _minLabelFontSize = Math.Min(this.LabelAutoFitMinFontSize, this.LabelAutoFitMaxFontSize); + _aveLabelFontSize = _minLabelFontSize + Math.Abs(size - _minLabelFontSize)/2f; + + + // Check if common font size should be used + if (ChartArea.IsSameFontSizeForAllAxes) + { + size = (float)Math.Min(size, ChartArea.axesAutoFontSize); + } + + //Set new font + autoLabelFont = Common.Chart.chartPicture.FontCache.GetFont(this.LabelStyle.Font.FontFamily, + size, + this.LabelStyle.Font.Style, + GraphicsUnit.Point + ); + + // Check if we allowed to increase font size while auto-fitting + if ((this.LabelAutoFitStyle & LabelAutoFitStyles.IncreaseFont) != LabelAutoFitStyles.IncreaseFont) + { + // Use axis labels font as starting point + autoLabelFont = this.LabelStyle.Font; + } + + // Loop while labels do not fit + float spacer = 0f; + while (!fitDone) + { + //****************************************************** + //** Check if labels fit + //****************************************************** + + // Check if grouping labels fit should be checked + bool checkLabelsFirstRowOnly = true; + if ((this.LabelAutoFitStyle & LabelAutoFitStyles.DecreaseFont) == LabelAutoFitStyles.DecreaseFont) + { + // Only check grouping labels if we can reduce fonts size + checkLabelsFirstRowOnly = false; + } + + // Check labels fit + fitDone = CheckLabelsFit( + chartGraph, + this.markSize + this.scrollBarSize + this.titleSize + spacer, + autoPlotPosition, + checkLabelsFirstRowOnly, + false); + + //****************************************************** + //** Adjust labels text properties to fit + //****************************************************** + if (!fitDone) + { + // If font is bigger than average try to make it smaller + if (autoLabelFont.SizeInPoints >= _aveLabelFontSize && + (this.LabelAutoFitStyle & LabelAutoFitStyles.DecreaseFont) == LabelAutoFitStyles.DecreaseFont) + { + //Clean up the old font + autoLabelFont = Common.Chart.chartPicture.FontCache.GetFont( + autoLabelFont.FontFamily, + autoLabelFont.SizeInPoints - 0.5f, + autoLabelFont.Style, + GraphicsUnit.Point); + } + + // Try to use offset labels (2D charts and non-circular arae only!!!) + else if (!ChartArea.Area3DStyle.Enable3D && + !ChartArea.chartAreaIsCurcular && + originalLabels == null && + autoLabelAngle == 0 && + autoLabelOffset == 0 && + (this.LabelAutoFitStyle & LabelAutoFitStyles.StaggeredLabels) == LabelAutoFitStyles.StaggeredLabels) + { + autoLabelOffset = 1; + } + + // Try to insert new line characters in labels text + else if (!noWordWrap && + (this.LabelAutoFitStyle & LabelAutoFitStyles.WordWrap) == LabelAutoFitStyles.WordWrap) + { + bool changed = false; + autoLabelOffset = 0; + + // Check if backup copy of the original lables was made + if (originalLabels == null) + { + // Copy current labels collection + originalLabels = new CustomLabelsCollection(this); + foreach (CustomLabel label in this.CustomLabels) + { + originalLabels.Add(label.Clone()); + } + } + + // Try to insert new line character into the longest label + changed = WordWrapLongestLabel(this.CustomLabels); + + // Word wrapping do not solve the labels overlapping issue + if (!changed) + { + noWordWrap = true; + + // Restore original labels + if (originalLabels != null) + { + this.CustomLabels.Clear(); + foreach (CustomLabel label in originalLabels) + { + this.CustomLabels.Add(label.Clone()); + } + + originalLabels = null; + } + + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + if ((spacer == 0 || + spacer == 30f || + spacer == 20f) && + ((this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep30) == LabelAutoFitStyles.LabelsAngleStep30 || + (this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep45) == LabelAutoFitStyles.LabelsAngleStep45 || + (this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep90) == LabelAutoFitStyles.LabelsAngleStep90)) + { + // Try to use 90 degrees angle + autoLabelAngle = 90; + noWordWrap = false; + + // Usually 55% of Common.Chart area size is allowed for labels + // Reduce that space. + if (spacer == 0f) + { + // 30 + spacer = 30f; + } + else if (spacer == 30f) + { + // 20 + spacer = 20f; + } + else if (spacer == 20f) + { + // 5 + spacer = 5f; + } + else + { + autoLabelAngle = 0; + noWordWrap = true; + } + + } + else + { + spacer = 0f; + } + } + } + } + + // Try to change font angle + else if (autoLabelAngle != 90 && + ((this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep30) == LabelAutoFitStyles.LabelsAngleStep30 || + (this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep45) == LabelAutoFitStyles.LabelsAngleStep45 || + (this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep90) == LabelAutoFitStyles.LabelsAngleStep90)) + { + spacer = 0f; + autoLabelOffset = 0; + + if ((this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep30) == LabelAutoFitStyles.LabelsAngleStep30) + { + // Increase angle by 45 degrees in 2D and 45 in 3D + autoLabelAngle += (ChartArea.Area3DStyle.Enable3D) ? 45 : 30; + } + else if ((this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep45) == LabelAutoFitStyles.LabelsAngleStep45) + { + // Increase angle by 45 degrees + autoLabelAngle += 45; + } + else if ((this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep90) == LabelAutoFitStyles.LabelsAngleStep90) + { + // Increase angle by 90 degrees + autoLabelAngle += 90; + } + } + + // Try to reduce font again + else if (autoLabelFont.SizeInPoints > _minLabelFontSize && + (this.LabelAutoFitStyle & LabelAutoFitStyles.DecreaseFont) == LabelAutoFitStyles.DecreaseFont) + { + //Clean up the old font + autoLabelAngle = 0; + autoLabelFont = Common.Chart.chartPicture.FontCache.GetFont( + autoLabelFont.FontFamily, + autoLabelFont.SizeInPoints - 0.5f, + autoLabelFont.Style, + GraphicsUnit.Point); + } + + // Failed to fit + else + { + // Use last font + if ((this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep30) == LabelAutoFitStyles.LabelsAngleStep30 || + (this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep45) == LabelAutoFitStyles.LabelsAngleStep45 || + (this.LabelAutoFitStyle & LabelAutoFitStyles.LabelsAngleStep90) == LabelAutoFitStyles.LabelsAngleStep90) + { + // Reset angle + if (this.AxisPosition == AxisPosition.Top || this.AxisPosition == AxisPosition.Bottom) + { + autoLabelAngle = 90; + } + else + { + autoLabelAngle = 0; + } + } + if ((this.LabelAutoFitStyle & LabelAutoFitStyles.StaggeredLabels) == LabelAutoFitStyles.StaggeredLabels) + { + // Reset offset labels + autoLabelOffset = 0; + } + fitDone = true; + } + } + else if (ChartArea.Area3DStyle.Enable3D && + !ChartArea.chartAreaIsCurcular && + autoLabelFont.SizeInPoints > _minLabelFontSize) + { + // Reduce auto-fit font by 1 for the 3D charts + autoLabelFont = Common.Chart.chartPicture.FontCache.GetFont( + autoLabelFont.FontFamily, + autoLabelFont.SizeInPoints - 0.5f, + autoLabelFont.Style, + GraphicsUnit.Point); + } + } + + // Change the auto-fit angle for top and bottom axes from 90 to -90 + if(this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + if(autoLabelAngle == 90) + { + autoLabelAngle = -90; + } + } + } + + //********************************************************* + //** Calculate overall labels size + //********************************************************* + this.labelSize = 0; + + // if labels are not enabled their size needs to remain zero + if (this.LabelStyle.Enabled) + { + //****************************************************** + //** Calculate axis second labels row size + //****************************************************** + this.labelSize = (maxAxisElementsSize) - this.markSize - this.scrollBarSize - this.titleSize; + if (this.labelSize > 0) + { + this.groupingLabelSizes = GetRequiredGroupLabelSize(chartGraph, (maxLabelSize / 100F) * maxAxisLabelRow2Size); + this.totlaGroupingLabelsSize = GetGroupLablesToatalSize(); + } + + //****************************************************** + //** Calculate axis labels size + //****************************************************** + this.labelSize -= this.totlaGroupingLabelsSize; + if (this.labelSize > 0) + { + // If axis is horizontal + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + this.labelSize = elementSpacing + GetRequiredLabelSize(chartGraph, + (maxLabelSize / 100F) * (maxAxisElementsSize - this.markSize - this.scrollBarSize - this.titleSize), out this.unRotatedLabelSize); + } + // If axis is horizontal + else + { + this.labelSize = elementSpacing + GetRequiredLabelSize(chartGraph, + (maxLabelSize / 100F) * (maxAxisElementsSize - this.markSize - this.scrollBarSize - this.titleSize), out this.unRotatedLabelSize); + } + + if (!this.LabelStyle.Enabled) + { + this.labelSize -= elementSpacing; + } + } + else + { + this.labelSize = 0; + } + + this.labelSize += this.totlaGroupingLabelsSize; + } + +#if SUBAXES + // Calculate offsets for all sub axes + if(!ChartArea.Area3DStyle.Enable3D && + !ChartArea.chartAreaIsCurcular) + { + float currentOffset = this.markSize + this.labelSize + this.titleSize + this.scrollBarSize; + foreach(SubAxis subAxis in this.SubAxes) + { + if(subAxis.Enabled != AxisEnabled.False) + { + currentOffset += (float)subAxis.LocationOffset; + subAxis.offsetFromParent = currentOffset; + currentOffset += subAxis.markSize + subAxis.labelSize + subAxis.titleSize; + } + } + } +#endif // SUBAXES + + +#if Microsoft_CONTROL + // Restore previous invalidation flag + Common.Chart.disableInvalidates = oldDisableInvalidates; +#endif //Microsoft_CONTROL + } + + /// + /// Calculates axis interval so that labels will fit most efficiently. + /// + /// Chart graphics. + /// True if plot position is auto calculated. + /// True if interval should only be increased. + private void AdjustIntervalToFitLabels(ChartGraphics chartGraph, bool autoPlotPosition, bool onlyIncreaseInterval) + { + // Calculates axis interval so that labels will fit most efficiently. + if(this.ScaleSegments.Count == 0) + { + this.AdjustIntervalToFitLabels(chartGraph, autoPlotPosition, null, onlyIncreaseInterval); + } + else + { + // Allow values to go outside the segment boundary + this.ScaleSegments.AllowOutOfScaleValues = true; + + // Adjust interval of each segment first + foreach(AxisScaleSegment axisScaleSegment in this.ScaleSegments) + { + this.AdjustIntervalToFitLabels(chartGraph, autoPlotPosition, axisScaleSegment, onlyIncreaseInterval); + } + + // Fill labels using new segment intervals + bool removeLabels = true; + int segmentIndex = 0; + ArrayList removedLabels = new ArrayList(); + ArrayList removedLabelsIndexes = new ArrayList(); + foreach(AxisScaleSegment scaleSegment in this.ScaleSegments) + { + scaleSegment.SetTempAxisScaleAndInterval(); + this.FillLabels(removeLabels); + removeLabels = false; + scaleSegment.RestoreAxisScaleAndInterval(); + + // Remove last label of all segmenst except of the last + if(segmentIndex < this.ScaleSegments.Count - 1 && + this.CustomLabels.Count > 0) + { + // Remove label and save it in the list + removedLabels.Add(this.CustomLabels[this.CustomLabels.Count - 1]); + removedLabelsIndexes.Add(this.CustomLabels.Count - 1); + this.CustomLabels.RemoveAt(this.CustomLabels.Count - 1); + } + + ++segmentIndex; + } + + // Check all previously removed last labels of each segment if there + // is enough space to fit them + int reInsertedLabelsCount = 0; + int labelIndex = 0; + foreach(CustomLabel label in removedLabels) + { + // Re-insert the label + int labelInsertIndex = (int)removedLabelsIndexes[labelIndex] + reInsertedLabelsCount; + if(labelIndex < this.CustomLabels.Count) + { + this.CustomLabels.Insert(labelInsertIndex, label); + } + else + { + this.CustomLabels.Add(label); + } + + // Check labels fit. Only horizontal or vertical fit is checked depending + // on the axis orientation. + ArrayList labelPositions = new ArrayList(); + bool fitDone = CheckLabelsFit( + chartGraph, + this.markSize + this.scrollBarSize + this.titleSize, + autoPlotPosition, + true, + false, + (this.AxisPosition == AxisPosition.Left || this.AxisPosition == AxisPosition.Right) ? false : true, + (this.AxisPosition == AxisPosition.Left || this.AxisPosition == AxisPosition.Right) ? true : false, + labelPositions); + + // If labels fit check if any of the label positions overlap + if(fitDone) + { + for(int index = 0; fitDone && index < labelPositions.Count; index++) + { + RectangleF rect1 = (RectangleF)labelPositions[index]; + for(int index2 = index + 1; fitDone && index2 < labelPositions.Count; index2++) + { + RectangleF rect2 = (RectangleF)labelPositions[index2]; + if(rect1.IntersectsWith(rect2)) + { + fitDone = false; + } + } + } + } + + // If labels do not fit or overlapp - remove completly + if(!fitDone) + { + this.CustomLabels.RemoveAt(labelInsertIndex); + } + else + { + ++reInsertedLabelsCount; + } + + ++labelIndex; + } + + // Make sure now values are rounded on segment boundary + this.ScaleSegments.AllowOutOfScaleValues = false; + } + } + + /// + /// Checks if variable count labels mode is enabled. + /// + /// True if variable count labels mode is enabled. + private bool IsVariableLabelCountModeEnabled() + { + // Make sure the variable interval mode is enabled and + // no custom label interval used. + if( (this.IntervalAutoMode == IntervalAutoMode.VariableCount || this.ScaleSegments.Count > 0) && + !this.IsLogarithmic && + (this.tempLabelInterval <= 0.0 || (double.IsNaN(this.tempLabelInterval) && this.Interval <= 0.0)) ) + { + // This feature is not supported for charts that do not + // require X and Y axes (Pie, Radar, ...) + if(!ChartArea.requireAxes) + { + return false; + } + // This feature is not supported if the axis doesn't have data range + if (Double.IsNaN(this.minimum) || Double.IsNaN(this.maximum)) + { + return false; + } + // Check if custom labels are used in the first row + bool customLabels = false; + foreach(CustomLabel label in this.CustomLabels) + { + if(label.customLabel && label.RowIndex == 0) + { + customLabels = true; + break; + } + } + + // Proceed only if no custom labels are used in the first row + if(!customLabels) + { + return true; + } + } + + return false; + } + + /// + /// Calculates axis interval so that labels will fit most efficiently. + /// + /// Chart graphics. + /// True if plot position is auto calculated. + /// Axis scale segment to process. + /// True if interval should only be increased. + private void AdjustIntervalToFitLabels( + ChartGraphics chartGraph, + bool autoPlotPosition, + AxisScaleSegment axisScaleSegment, + bool onlyIncreaseInterval) + { + // Re-fill the labels just for the scale segment provided + if(axisScaleSegment != null) + { + // Re-fill new axis labels + if(this.tempLabels != null) + { + this.CustomLabels.Clear(); + foreach( CustomLabel label in this.tempLabels ) + { + this.CustomLabels.Add(label.Clone()); + } + } + + // Fill labels just for the segment + axisScaleSegment.SetTempAxisScaleAndInterval(); + this.FillLabels( true ); + axisScaleSegment.RestoreAxisScaleAndInterval(); + } + + // Calculate minimum interval size + double minIntervalSzie = double.NaN; + ArrayList axisSeries = AxisScaleBreakStyle.GetAxisSeries(this); + foreach(Series series in axisSeries) + { + if(this.axisType == AxisName.X || this.axisType == AxisName.X2) + { + if(ChartHelper.IndexedSeries(series)) + { + minIntervalSzie = 1.0; + } + else if(series.XValueType == ChartValueType.String || + series.XValueType == ChartValueType.Int32 || + series.XValueType == ChartValueType.UInt32 || + series.XValueType == ChartValueType.UInt64 || + series.XValueType == ChartValueType.Int64 ) + { + minIntervalSzie = 1.0; + } + } + else + { + if(series.YValueType == ChartValueType.String || + series.YValueType == ChartValueType.Int32 || + series.YValueType == ChartValueType.UInt32 || + series.YValueType == ChartValueType.UInt64 || + series.YValueType == ChartValueType.Int64 ) + { + minIntervalSzie = 1.0; + } + } + } + + + // Iterate while interval is not found + bool firstIteration = true; + bool increaseNumberOfLabels = true; + double currentInterval = (axisScaleSegment == null) ? this.labelStyle.GetInterval() : axisScaleSegment.Interval; + DateTimeIntervalType currentIntervalType = (axisScaleSegment == null) ? this.labelStyle.GetIntervalType() : axisScaleSegment.IntervalType; + DateTimeIntervalType lastFitIntervalType = currentIntervalType; + double lastFitInterval = currentInterval; + ArrayList lastFitLabels = new ArrayList(); + bool intervalFound = false; + int iterationNumber = 0; + while(!intervalFound && iterationNumber <= 1000) + { + bool fillNewLabels = true; +#if DEBUG + if(iterationNumber >= 999) + { + throw (new InvalidOperationException(SR.ExceptionAxisDynamicIntervalCalculationFailed)); + } +#endif // DEBUG + + // Check labels fit. Only horizontal or vertical fit is checked depending + // on the axis orientation. + bool fitDone = CheckLabelsFit( + chartGraph, + this.markSize + this.scrollBarSize + this.titleSize, + autoPlotPosition, + true, + false, + (this.AxisPosition == AxisPosition.Left || this.AxisPosition == AxisPosition.Right) ? false : true, + (this.AxisPosition == AxisPosition.Left || this.AxisPosition == AxisPosition.Right) ? true : false, + null); + + // Check if we need to increase or reduce number of labels + if(firstIteration) + { + firstIteration = false; + increaseNumberOfLabels = (fitDone) ? true : false; + + // Check if we can decrease the interva; + if(onlyIncreaseInterval && increaseNumberOfLabels) + { + intervalFound = true; + continue; + } + } + + // Find new interval. Value 0.0 means that interval cannot be + // reduced/increased any more and current interval should be used + double newInterval = 0.0; + DateTimeIntervalType newIntervalType = DateTimeIntervalType.Number; + if(increaseNumberOfLabels) + { + if(fitDone) + { + // Make a copy of last interval and labels collection that previously fit + lastFitInterval = currentInterval; + lastFitIntervalType = currentIntervalType; + lastFitLabels.Clear(); + foreach(CustomLabel label in this.CustomLabels) + { + lastFitLabels.Add(label); + } + + newIntervalType = currentIntervalType; + newInterval = this.ReduceLabelInterval( + currentInterval, + minIntervalSzie, + ref newIntervalType); + } + else + { + newInterval = lastFitInterval; + newIntervalType = lastFitIntervalType; + intervalFound = true; + + // Reuse previously saved labels + fillNewLabels = false; + this.CustomLabels.Clear(); + foreach(CustomLabel label in lastFitLabels) + { + this.CustomLabels.Add(label); + } + + } + } + else + { + if(!fitDone && this.CustomLabels.Count > 1) + { + newIntervalType = currentIntervalType; + newInterval = this.IncreaseLabelInterval( + currentInterval, + ref newIntervalType); + } + else + { + intervalFound = true; + } + } + + // Set new interval + if(newInterval != 0.0) + { + currentInterval = newInterval; + currentIntervalType = newIntervalType; + + if(axisScaleSegment == null) + { + this.SetIntervalAndType(newInterval, newIntervalType); + } + else + { + axisScaleSegment.Interval = newInterval; + axisScaleSegment.IntervalType = newIntervalType; + } + + // Re-fill new axis labels + if(fillNewLabels) + { + if(this.tempLabels != null) + { + this.CustomLabels.Clear(); + foreach( CustomLabel label in this.tempLabels ) + { + CustomLabels.Add(label.Clone()); + } + } + + if(axisScaleSegment == null) + { + this.FillLabels(true); + } + else + { + axisScaleSegment.SetTempAxisScaleAndInterval(); + this.FillLabels( true ); + axisScaleSegment.RestoreAxisScaleAndInterval(); + } + } + } + else + { + intervalFound = true; + } + + ++iterationNumber; + } + } + + /// + /// Reduces current label interval, so that more labels can fit. + /// + /// An interval to reduce. + /// Minimum interval size. + /// Interval type. + /// New interval or 0.0 if interval cannot be reduced. + private double ReduceLabelInterval( + double oldInterval, + double minInterval, + ref DateTimeIntervalType axisIntervalType) + { + double newInterval = oldInterval; + + // Calculate rounded interval value + double range = this.maximum - this.minimum; + int iterationIndex = 0; + if( axisIntervalType == DateTimeIntervalType.Auto || + axisIntervalType == DateTimeIntervalType.NotSet || + axisIntervalType == DateTimeIntervalType.Number) + { + // Process numeric scale + double devider = 2.0; + do + { +#if DEBUG + if(iterationIndex >= 99) + { + throw (new InvalidOperationException(SR.ExceptionAxisIntervalDecreasingFailed)); + } +#endif // DEBUG + + newInterval = CalcInterval( range / (range / (newInterval / devider)) ); + if(newInterval == oldInterval) + { + devider *= 2.0; + } + + ++iterationIndex; + } while(newInterval == oldInterval && iterationIndex <= 100); + } + else + { + // Process date scale + if(oldInterval > 1.0 || oldInterval < 1.0) + { + if( axisIntervalType == DateTimeIntervalType.Minutes || + axisIntervalType == DateTimeIntervalType.Seconds) + { + if(oldInterval >= 60) + { + newInterval = Math.Round(oldInterval / 2.0); + } + else if(oldInterval >= 30.0) + { + newInterval = 15.0; + } + else if(oldInterval >= 15.0) + { + newInterval = 5.0; + } + else if(oldInterval >= 5.0) + { + newInterval = 1.0; + } + } + else + { + newInterval = Math.Round(oldInterval / 2.0); + } + if(newInterval < 1.0) + { + newInterval = 1.0; + } + } + if(oldInterval == 1.0) + { + if(axisIntervalType == DateTimeIntervalType.Years) + { + newInterval = 6.0; + axisIntervalType = DateTimeIntervalType.Months; + } + else if(axisIntervalType == DateTimeIntervalType.Months) + { + newInterval = 2.0; + axisIntervalType = DateTimeIntervalType.Weeks; + } + else if(axisIntervalType == DateTimeIntervalType.Weeks) + { + newInterval = 2.0; + axisIntervalType = DateTimeIntervalType.Days; + } + else if(axisIntervalType == DateTimeIntervalType.Days) + { + newInterval = 12.0; + axisIntervalType = DateTimeIntervalType.Hours; + } + else if(axisIntervalType == DateTimeIntervalType.Hours) + { + newInterval = 30.0; + axisIntervalType = DateTimeIntervalType.Minutes; + } + else if(axisIntervalType == DateTimeIntervalType.Minutes) + { + newInterval = 30.0; + axisIntervalType = DateTimeIntervalType.Seconds; + } + else if(axisIntervalType == DateTimeIntervalType.Seconds) + { + newInterval = 100.0; + axisIntervalType = DateTimeIntervalType.Milliseconds; + } + } + } + + + // Make sure interal is not less than min interval specified + if(!double.IsNaN(minInterval) && newInterval < minInterval) + { + newInterval = 0.0; + } + + return newInterval; + } + + /// + /// Increases current label interval, so that less labels fit. + /// + /// An interval to increase. + /// Interval type. + /// New interval or 0.0 if interval cannot be increased. + private double IncreaseLabelInterval( + double oldInterval, + ref DateTimeIntervalType axisIntervalType) + { + double newInterval = oldInterval; + + // Calculate rounded interval value + double range = this.maximum - this.minimum; + int iterationIndex = 0; + if( axisIntervalType == DateTimeIntervalType.Auto || + axisIntervalType == DateTimeIntervalType.NotSet || + axisIntervalType == DateTimeIntervalType.Number) + { + // Process numeric scale + double devider = 2.0; + do + { +#if DEBUG + if(iterationIndex >= 99) + { + throw (new InvalidOperationException(SR.ExceptionAxisIntervalIncreasingFailed)); + } +#endif // DEBUG + + newInterval = CalcInterval( range / (range / (newInterval * devider)) ); + if(newInterval == oldInterval) + { + devider *= 2.0; + } + ++iterationIndex; + } while(newInterval == oldInterval && iterationIndex <= 100); + } + else + { + // Process date scale + newInterval = oldInterval * 2.0; + if(axisIntervalType == DateTimeIntervalType.Years) + { + // Do nothing for years + } + else if(axisIntervalType == DateTimeIntervalType.Months) + { + if(newInterval >= 12.0) + { + newInterval = 1.0; + axisIntervalType = DateTimeIntervalType.Years; + } + } + else if(axisIntervalType == DateTimeIntervalType.Weeks) + { + if(newInterval >= 4.0) + { + newInterval = 1.0; + axisIntervalType = DateTimeIntervalType.Months; + } + } + else if(axisIntervalType == DateTimeIntervalType.Days) + { + if(newInterval >= 7.0) + { + newInterval = 1.0; + axisIntervalType = DateTimeIntervalType.Weeks; + } + } + else if(axisIntervalType == DateTimeIntervalType.Hours) + { + if(newInterval >= 60.0) + { + newInterval = 1.0; + axisIntervalType = DateTimeIntervalType.Days; + } + } + else if(axisIntervalType == DateTimeIntervalType.Minutes) + { + if(newInterval >= 60.0) + { + newInterval = 1.0; + axisIntervalType = DateTimeIntervalType.Hours; + } + } + else if(axisIntervalType == DateTimeIntervalType.Seconds) + { + if(newInterval >= 60.0) + { + newInterval = 1.0; + axisIntervalType = DateTimeIntervalType.Minutes; + } + } + else if(axisIntervalType == DateTimeIntervalType.Milliseconds) + { + if(newInterval >= 1000.0) + { + newInterval = 1.0; + axisIntervalType = DateTimeIntervalType.Seconds; + } + } + } + + return newInterval; + } + + /// + /// Finds the longest labels with the space and inserts the new line character. + /// + /// Labels collection. + /// True if collection was modified. + private bool WordWrapLongestLabel(CustomLabelsCollection labels) + { + bool changed = false; + + // Each label may contain several lines of text. + // Create a list that contains an array of text for each label. + ArrayList labelTextRows = new ArrayList(labels.Count); + foreach (CustomLabel label in labels) + { + labelTextRows.Add(label.Text.Split('\n')); + } + + // Find the longest label with a space + int longestLabelSize = 5; + int longestLabelIndex = -1; + int longestLabelRowIndex = -1; + int index = 0; + foreach (string[] textRows in labelTextRows) + { + for (int rowIndex = 0; rowIndex < textRows.Length; rowIndex++) + { + if (textRows[rowIndex].Length > longestLabelSize && textRows[rowIndex].Trim().IndexOf(' ') > 0) + { + longestLabelSize = textRows[rowIndex].Length; + longestLabelIndex = index; + longestLabelRowIndex = rowIndex; + } + } + ++index; + } + + // Longest label with a space was found + if (longestLabelIndex >= 0 && longestLabelRowIndex >= 0) + { + // Try to find a space and replace it with a new line + string newText = ((string[])labelTextRows[longestLabelIndex])[longestLabelRowIndex]; + for (index = 0; index < (newText.Length) / 2 - 1; index++) + { + if (newText[(newText.Length) / 2 - index] == ' ') + { + newText = + newText.Substring(0, (newText.Length) / 2 - index) + + "\n" + + newText.Substring((newText.Length) / 2 - index + 1); + changed = true; + } + else if (newText[(newText.Length) / 2 + index] == ' ') + { + newText = + newText.Substring(0, (newText.Length) / 2 + index) + + "\n" + + newText.Substring((newText.Length) / 2 + index + 1); + changed = true; + } + + if (changed) + { + ((string[])labelTextRows[longestLabelIndex])[longestLabelRowIndex] = newText; + break; + } + } + + // Update label text + if (changed) + { + // Construct label text from multiple rows separated by "\n" + CustomLabel label = labels[longestLabelIndex]; + label.Text = string.Empty; + for (int rowIndex = 0; rowIndex < ((string[])labelTextRows[longestLabelIndex]).Length; rowIndex++) + { + if (rowIndex > 0) + { + label.Text += "\n"; + } + label.Text += ((string[])labelTextRows[longestLabelIndex])[rowIndex]; + } + } + } + + return changed; + } + + /// + /// Calculates the auto-fit font for the circular Common.Chart area axis labels. + /// + /// Chart graphics object. + /// List of sector labels. + /// Circular labels style. + /// Plotting area position. + /// Chart area position. + /// Estimated size of labels. + internal void GetCircularAxisLabelsAutoFitFont( + ChartGraphics graph, + ArrayList axisList, + CircularAxisLabelsStyle labelsStyle, + RectangleF plotAreaRectAbs, + RectangleF areaRectAbs, + float labelsSizeEstimate) + { + // X axis settings defines if auto-fit font should be calculated + if (!this.IsLabelAutoFit || + this.LabelAutoFitStyle == LabelAutoFitStyles.None || + !this.LabelStyle.Enabled) + { + return; + } + + // Set minimum font size + _minLabelFontSize = Math.Min(this.LabelAutoFitMinFontSize, this.LabelAutoFitMaxFontSize); + + // Create new auto-fit font + this.autoLabelFont = Common.Chart.chartPicture.FontCache.GetFont( + this.LabelStyle.Font.FontFamily, + Math.Max(this.LabelAutoFitMaxFontSize, this.LabelAutoFitMinFontSize), + this.LabelStyle.Font.Style, + GraphicsUnit.Point); + + // Check if we allowed to increase font size while auto-fitting + if ((this.LabelAutoFitStyle & LabelAutoFitStyles.IncreaseFont) != LabelAutoFitStyles.IncreaseFont) + { + // Use axis labels font as starting point + this.autoLabelFont = this.LabelStyle.Font; + } + + // Loop while labels do not fit + bool fitDone = false; + while (!fitDone) + { + //****************************************************** + //** Check if labels fit + //****************************************************** + fitDone = CheckCircularLabelsFit( + graph, + axisList, + labelsStyle, + plotAreaRectAbs, + areaRectAbs, + labelsSizeEstimate); + + //****************************************************** + //** Adjust labels text properties to fit + //****************************************************** + if (!fitDone) + { + // Try to reduce font size + if (autoLabelFont.SizeInPoints > _minLabelFontSize && + (this.LabelAutoFitStyle & LabelAutoFitStyles.DecreaseFont) == LabelAutoFitStyles.DecreaseFont) + { + autoLabelFont = Common.Chart.chartPicture.FontCache.GetFont( + autoLabelFont.FontFamily, + autoLabelFont.SizeInPoints - 1, + autoLabelFont.Style, + GraphicsUnit.Point); + + } + + // Failed to fit + else + { + // Use last font with no angles + autoLabelAngle = 0; + autoLabelOffset = 0; + fitDone = true; + } + } + } + } + + /// + /// Checks id circular axis labels fits using current auto-fit font. + /// + /// Chart graphics object. + /// List of sector labels. + /// Circular labels style. + /// Plotting area position. + /// Chart area position. + /// Estimated size of labels. + /// True if labels fit. + internal bool CheckCircularLabelsFit( + ChartGraphics graph, + ArrayList axisList, + CircularAxisLabelsStyle labelsStyle, + RectangleF plotAreaRectAbs, + RectangleF areaRectAbs, + float labelsSizeEstimate) + { + bool labelsFit = true; + + // Get absolute center of the area + PointF areaCenterAbs = graph.GetAbsolutePoint(ChartArea.circularCenter); + + // Get absolute markers size and spacing + float spacing = graph.GetAbsolutePoint(new PointF(0, this.markSize + Axis.elementSpacing)).Y; + + //***************************************************************** + //** Loop through all axis labels + //***************************************************************** + RectangleF prevLabelPosition = RectangleF.Empty; + float prevLabelSideAngle = float.NaN; + foreach (CircularChartAreaAxis axis in axisList) + { + //***************************************************************** + //** Measure label text + //***************************************************************** + SizeF textSize = graph.MeasureString( + axis.Title.Replace("\\n", "\n"), + this.autoLabelFont); + + //***************************************************************** + //** Get circular style label position. + //***************************************************************** + if (labelsStyle == CircularAxisLabelsStyle.Circular || + labelsStyle == CircularAxisLabelsStyle.Radial) + { + // Swith text size for the radial style + if (labelsStyle == CircularAxisLabelsStyle.Radial) + { + float tempValue = textSize.Width; + textSize.Width = textSize.Height; + textSize.Height = tempValue; + } + + //***************************************************************** + //** Check overlapping with previous label + //***************************************************************** + + // Get radius of plot area + float plotAreaRadius = areaCenterAbs.Y - plotAreaRectAbs.Y; + plotAreaRadius -= labelsSizeEstimate; + plotAreaRadius += spacing; + + // Calculate angle on the side of the label + float leftSideAngle = (float)(Math.Atan((textSize.Width / 2f) / plotAreaRadius) * 180f / Math.PI); + float rightSideAngle = axis.AxisPosition + leftSideAngle; + leftSideAngle = axis.AxisPosition - leftSideAngle; + + // Check if label overlap the previous label + if (!float.IsNaN(prevLabelSideAngle)) + { + if (prevLabelSideAngle > leftSideAngle) + { + // Labels overlap + labelsFit = false; + break; + } + } + + // Remember label side angle + prevLabelSideAngle = rightSideAngle - 1; + + + //***************************************************************** + //** Check if label is inside the Common.Chart area + //***************************************************************** + + // Find the most outside point of the label + PointF outsidePoint = new PointF(areaCenterAbs.X, plotAreaRectAbs.Y); + outsidePoint.Y += labelsSizeEstimate; + outsidePoint.Y -= textSize.Height; + outsidePoint.Y -= spacing; + + PointF[] rotatedPoint = new PointF[] { outsidePoint }; + Matrix newMatrix = new Matrix(); + newMatrix.RotateAt(axis.AxisPosition, areaCenterAbs); + newMatrix.TransformPoints(rotatedPoint); + + // Check if rotated point is inside Common.Chart area + if (!areaRectAbs.Contains(rotatedPoint[0])) + { + // Label is not inside Common.Chart area + labelsFit = false; + break; + } + + } + + //***************************************************************** + //** Get horizontal style label position. + //***************************************************************** + else if (labelsStyle == CircularAxisLabelsStyle.Horizontal) + { + // Get text angle + float textAngle = axis.AxisPosition; + if (textAngle > 180f) + { + textAngle -= 180f; + } + + // Get label rotated position + PointF[] labelPosition = new PointF[] { new PointF(areaCenterAbs.X, plotAreaRectAbs.Y) }; + labelPosition[0].Y += labelsSizeEstimate; + labelPosition[0].Y -= spacing; + Matrix newMatrix = new Matrix(); + newMatrix.RotateAt(textAngle, areaCenterAbs); + newMatrix.TransformPoints(labelPosition); + + // Calculate label position + RectangleF curLabelPosition = new RectangleF( + labelPosition[0].X, + labelPosition[0].Y - textSize.Height / 2f, + textSize.Width, + textSize.Height); + if (textAngle < 5f) + { + curLabelPosition.X = labelPosition[0].X - textSize.Width / 2f; + curLabelPosition.Y = labelPosition[0].Y - textSize.Height; + } + if (textAngle > 175f) + { + curLabelPosition.X = labelPosition[0].X - textSize.Width / 2f; + curLabelPosition.Y = labelPosition[0].Y; + } + + // Decrease label rectangle + curLabelPosition.Inflate(0f, -curLabelPosition.Height * 0.15f); + + // Check if label position goes outside of the Common.Chart area. + if (!areaRectAbs.Contains(curLabelPosition)) + { + // Label is not inside Common.Chart area + labelsFit = false; + break; + } + + // Check if label position overlap previous label position. + if (!prevLabelPosition.IsEmpty && curLabelPosition.IntersectsWith(prevLabelPosition)) + { + // Label intersects with previous label + labelsFit = false; + break; + } + + // Set previous point position + prevLabelPosition = curLabelPosition; + } + } + + return labelsFit; + } + + #endregion + + #region Axis labels auto-fitting methods + + /// + /// Adjust labels font size at second pass of auto fitting. + /// + /// Chart graphics object. + /// Indicates that inner plot position is automatic. + internal void AdjustLabelFontAtSecondPass(ChartGraphics chartGraph, bool autoPlotPosition) + { +#if SUBAXES + // Process all sub-axis + if(!ChartArea.Area3DStyle.Enable3D && + !ChartArea.chartAreaIsCurcular) + { + foreach(SubAxis subAxis in this.SubAxes) + { + subAxis.AdjustLabelFontAtSecondPass(chartGraph, autoPlotPosition); + } + } +#endif //SUBAXES + + + //****************************************************** + //** First try to select the interval that will + //** generate best fit labels. + //****************************************************** + + + + // Make sure the variable interval mode is enabled + if( this.Enabled != AxisEnabled.False && + this.LabelStyle.Enabled && + this.IsVariableLabelCountModeEnabled() ) + { + // Set font for labels fitting + if(this.autoLabelFont == null) + { + this.autoLabelFont = this.LabelStyle.Font; + } + + // Reset angle and stagged flag used in the auto-fitting algorithm + if(this.autoLabelAngle < 0) + { + this.autoLabelAngle = this.LabelStyle.Angle; + } + if(this.autoLabelOffset < 0) + { + this.autoLabelOffset = (this.LabelStyle.IsStaggered) ? 1 : 0; + } + + // Check labels fit + bool fitDone = CheckLabelsFit( + chartGraph, + this.markSize + this.scrollBarSize + this.titleSize, + autoPlotPosition, + true, + true, + (this.AxisPosition == AxisPosition.Left || this.AxisPosition == AxisPosition.Right) ? false : true, + (this.AxisPosition == AxisPosition.Left || this.AxisPosition == AxisPosition.Right) ? true : false, + null); + + // If there is a problem fitting labels try to reduce number of labels by + // increasing of the interval. + if(!fitDone) + { + // Adjust interval + this.AdjustIntervalToFitLabels(chartGraph, autoPlotPosition, true); + } + } + + + + + //****************************************************** + //** If labels auto-fit is on try reducing font size. + //****************************************************** + + totlaGroupingLabelsSizeAdjustment = 0f; + if (this.IsLabelAutoFit && + this.LabelAutoFitStyle != LabelAutoFitStyles.None && + this.Enabled != AxisEnabled.False) + { + bool fitDone = false; + + if (autoLabelFont == null) + { + autoLabelFont = this.LabelStyle.Font; + } + + // Loop while labels do not fit + float oldLabelSecondRowSize = totlaGroupingLabelsSize; + while (!fitDone) + { + //****************************************************** + //** Check if labels fit + //****************************************************** + fitDone = CheckLabelsFit( + chartGraph, + this.markSize + this.scrollBarSize + this.titleSize, + autoPlotPosition, + true, + true); + + //****************************************************** + //** Adjust labels text properties to fit + //****************************************************** + if (!fitDone) + { + // Try to reduce font + if (autoLabelFont.SizeInPoints > _minLabelFontSize) + { + // Reduce auto fit font + if (ChartArea != null && ChartArea.IsSameFontSizeForAllAxes) + { + // Same font for all axes + foreach (Axis currentAxis in ChartArea.Axes) + { + if (currentAxis.enabled && currentAxis.IsLabelAutoFit && currentAxis.autoLabelFont != null) + { + currentAxis.autoLabelFont = Common.Chart.chartPicture.FontCache.GetFont( + currentAxis.autoLabelFont.FontFamily, + autoLabelFont.SizeInPoints - 1, + currentAxis.autoLabelFont.Style, + GraphicsUnit.Point); + } + } + } + else if ((this.LabelAutoFitStyle & LabelAutoFitStyles.DecreaseFont) == LabelAutoFitStyles.DecreaseFont) + { + autoLabelFont = Common.Chart.chartPicture.FontCache.GetFont( + autoLabelFont.FontFamily, + autoLabelFont.SizeInPoints - 1, + autoLabelFont.Style, + GraphicsUnit.Point); + } + else + { + // Failed to fit + fitDone = true; + } + } + else + { + // Failed to fit + fitDone = true; + } + } + } + + this.totlaGroupingLabelsSizeAdjustment = oldLabelSecondRowSize - totlaGroupingLabelsSize; + } + } + + /// + /// Check if axis is logarithmic + /// + /// Y value from data + /// Corected Y value if axis is logarithmic + internal double GetLogValue(double yValue) + { + // Check if axis is logarithmic + if (this.IsLogarithmic) + { + yValue = Math.Log(yValue, this.logarithmBase); + } + + return yValue; + } + + /// + /// Checks if labels fit using current auto fit properties + /// + /// Chart graphics object. + /// Axis title and marks size. + /// Indicates auto calculation of plotting area. + /// Labels fit is checked during the second pass. + /// Indicates second pass of labels fitting. + /// True if labels fit. + private bool CheckLabelsFit( + ChartGraphics chartGraph, + float otherElementsSize, + bool autoPlotPosition, + bool checkLabelsFirstRowOnly, + bool secondPass) + { + return this.CheckLabelsFit( + chartGraph, + otherElementsSize, + autoPlotPosition, + checkLabelsFirstRowOnly, + secondPass, + true, + true, + null); + } + + /// + /// Checks if labels fit using current auto fit properties + /// + /// Chart graphics object. + /// Axis title and marks size. + /// Indicates auto calculation of plotting area. + /// Labels fit is checked during the second pass. + /// Indicates second pass of labels fitting. + /// True if width should be checked. + /// True if height should be checked. + /// Returns an array of label positions. + /// True if labels fit. + private bool CheckLabelsFit( + ChartGraphics chartGraph, + float otherElementsSize, + bool autoPlotPosition, + bool checkLabelsFirstRowOnly, + bool secondPass, + bool checkWidth, + bool checkHeight, + ArrayList labelPositions) + { + // Reset list of label positions + if (labelPositions != null) + { + labelPositions.Clear(); + } + + // Label string drawing format + using (StringFormat format = new StringFormat()) + { + format.FormatFlags |= StringFormatFlags.LineLimit; + format.Trimming = StringTrimming.EllipsisCharacter; + + // Initialize all labels position rectangle + RectangleF rect = RectangleF.Empty; + + // Calculate max label size + float maxLabelSize = 0; + if (!autoPlotPosition) + { + if (this.GetIsMarksNextToAxis()) + { + if (this.AxisPosition == AxisPosition.Top) + maxLabelSize = (float)GetAxisPosition() - ChartArea.Position.Y; + else if (this.AxisPosition == AxisPosition.Bottom) + maxLabelSize = ChartArea.Position.Bottom - (float)GetAxisPosition(); + if (this.AxisPosition == AxisPosition.Left) + maxLabelSize = (float)GetAxisPosition() - ChartArea.Position.X; + else if (this.AxisPosition == AxisPosition.Right) + maxLabelSize = ChartArea.Position.Right - (float)GetAxisPosition(); + } + else + { + if (this.AxisPosition == AxisPosition.Top) + maxLabelSize = this.PlotAreaPosition.Y - ChartArea.Position.Y; + else if (this.AxisPosition == AxisPosition.Bottom) + maxLabelSize = ChartArea.Position.Bottom - this.PlotAreaPosition.Bottom; + if (this.AxisPosition == AxisPosition.Left) + maxLabelSize = this.PlotAreaPosition.X - ChartArea.Position.X; + else if (this.AxisPosition == AxisPosition.Right) + maxLabelSize = ChartArea.Position.Right - this.PlotAreaPosition.Right; + } + maxLabelSize *= 2F; + } + else + { + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + maxLabelSize = ChartArea.Position.Height; + else + maxLabelSize = ChartArea.Position.Width; + } + + // Loop through all grouping labels (all except first row) + this.totlaGroupingLabelsSize = 0; + + + // Get number of groups + int groupLabelLevelCount = GetGroupLabelLevelCount(); + + // Check ig grouping labels exist + if (groupLabelLevelCount > 0) + { + groupingLabelSizes = new float[groupLabelLevelCount]; + + // Loop through each level of grouping labels + bool fitResult = true; + for (int groupLevelIndex = 1; groupLevelIndex <= groupLabelLevelCount; groupLevelIndex++) + { + groupingLabelSizes[groupLevelIndex - 1] = 0f; + + // Loop through all labels in the level + foreach (CustomLabel label in this.CustomLabels) + { + // Skip if label middle point is outside current scaleView + if (label.RowIndex == 0) + { + double middlePoint = (label.FromPosition + label.ToPosition) / 2.0; + if (middlePoint < this.ViewMinimum || middlePoint > this.ViewMaximum) + { + continue; + } + } + + if (label.RowIndex == groupLevelIndex) + { + // Calculate label rect + double fromPosition = this.GetLinearPosition(label.FromPosition); + double toPosition = this.GetLinearPosition(label.ToPosition); + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + rect.Height = (maxLabelSize / 100F) * maxAxisLabelRow2Size / groupLabelLevelCount; + rect.X = (float)Math.Min(fromPosition, toPosition); + rect.Width = (float)Math.Max(fromPosition, toPosition) - rect.X; + } + else + { + rect.Width = (maxLabelSize / 100F) * maxAxisLabelRow2Size / groupLabelLevelCount; + rect.Y = (float)Math.Min(fromPosition, toPosition); + rect.Height = (float)Math.Max(fromPosition, toPosition) - rect.Y; + } + + // Measure string + SizeF axisLabelSize = chartGraph.MeasureStringRel(label.Text.Replace("\\n", "\n"), autoLabelFont); + + // Add image size + if (label.Image.Length > 0) + { + SizeF imageAbsSize = new SizeF(); + + if (this.Common.ImageLoader.GetAdjustedImageSize(label.Image, chartGraph.Graphics, ref imageAbsSize)) + { + SizeF imageRelSize = chartGraph.GetRelativeSize(imageAbsSize); + axisLabelSize.Width += imageRelSize.Width; + axisLabelSize.Height = Math.Max(axisLabelSize.Height, imageRelSize.Height); + } + } + + // Add extra spacing for the box marking of the label + if (label.LabelMark == LabelMarkStyle.Box) + { + // Get relative size from pixels and add it to the label size + SizeF spacerSize = chartGraph.GetRelativeSize(new SizeF(4, 4)); + axisLabelSize.Width += spacerSize.Width; + axisLabelSize.Height += spacerSize.Height; + } + + // Calculate max height of the second row of labels + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + groupingLabelSizes[groupLevelIndex - 1] = (float)Math.Max(groupingLabelSizes[groupLevelIndex - 1], axisLabelSize.Height); + } + else + { + axisLabelSize.Width = chartGraph.GetAbsoluteSize(new SizeF(axisLabelSize.Height, axisLabelSize.Height)).Height; + axisLabelSize.Width = chartGraph.GetRelativeSize(new SizeF(axisLabelSize.Width, axisLabelSize.Width)).Width; + groupingLabelSizes[groupLevelIndex - 1] = (float)Math.Max(groupingLabelSizes[groupLevelIndex - 1], axisLabelSize.Width); + } + + // Check if string fits + if (Math.Round(axisLabelSize.Width) >= Math.Round(rect.Width) && + checkWidth) + { + fitResult = false; + } + if (Math.Round(axisLabelSize.Height) >= Math.Round(rect.Height) && + checkHeight) + { + fitResult = false; + } + } + } + } + + this.totlaGroupingLabelsSize = this.GetGroupLablesToatalSize(); + if (!fitResult && !checkLabelsFirstRowOnly) + { + return false; + } + + } + + // Loop through all labels in the first row + float angle = autoLabelAngle; + int labelIndex = 0; + foreach (CustomLabel label in this.CustomLabels) + { + // Skip if label middle point is outside current scaleView + if (label.RowIndex == 0) + { + double middlePoint = (label.FromPosition + label.ToPosition) / 2.0; + if (middlePoint < this.ViewMinimum || middlePoint > this.ViewMaximum) + { + continue; + } + } + + if (label.RowIndex == 0) + { + + // Force which scale segment to use when calculating label position + if (labelPositions != null) + { + this.ScaleSegments.EnforceSegment(this.ScaleSegments.FindScaleSegmentForAxisValue((label.FromPosition + label.ToPosition) / 2.0)); + } + + + // Set label From and To coordinates + double fromPosition = this.GetLinearPosition(label.FromPosition); + double toPosition = this.GetLinearPosition(label.ToPosition); + + + // Reset scale segment to use when calculating label position + if (labelPositions != null) + { + this.ScaleSegments.EnforceSegment(null); + } + + + // Calculate single label position + rect.X = this.PlotAreaPosition.X; + rect.Y = (float)Math.Min(fromPosition, toPosition); + rect.Height = (float)Math.Max(fromPosition, toPosition) - rect.Y; + + float maxElementSize = maxAxisElementsSize; + if (maxAxisElementsSize - this.totlaGroupingLabelsSize > 55) + { + maxElementSize = 55 + this.totlaGroupingLabelsSize; + } + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + rect.Width = (maxLabelSize / 100F) * + (maxElementSize - this.totlaGroupingLabelsSize - otherElementsSize - elementSpacing); + } + else + { + rect.Width = (maxLabelSize / 100F) * + (maxElementSize - this.totlaGroupingLabelsSize - otherElementsSize - elementSpacing); + } + + // Adjust label From/To position if labels are displayed with offset + if (autoLabelOffset == 1) + { + rect.Y -= rect.Height / 2F; + rect.Height *= 2F; + rect.Width /= 2F; + } + + // If horizontal axis + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + // Switch rectangle sizes + float val = rect.Height; + rect.Height = rect.Width; + rect.Width = val; + + // Set vertical font for measuring + if (angle != 0) + { + format.FormatFlags |= StringFormatFlags.DirectionVertical; + } + } + else + { + // Set vertical font for measuring + if (angle == 90 || angle == -90) + { + angle = 0; + format.FormatFlags |= StringFormatFlags.DirectionVertical; + } + } + + // Measure label text size. Add the 'I' character to allow a little bit of spacing between labels. + SizeF axisLabelSize = chartGraph.MeasureStringRel( + label.Text.Replace("\\n", "\n") + "W", + autoLabelFont, + (secondPass) ? rect.Size : ChartArea.Position.ToRectangleF().Size, + format); + + // Width and height maybe zeros if rect is too small to fit the text and + // the LineLimit format flag is set. + if (label.Text.Length > 0 && + (axisLabelSize.Width == 0f || + axisLabelSize.Height == 0f)) + { + // Measure string without the LineLimit flag + format.FormatFlags ^= StringFormatFlags.LineLimit; + axisLabelSize = chartGraph.MeasureStringRel( + label.Text.Replace("\\n", "\n"), + autoLabelFont, + (secondPass) ? rect.Size : ChartArea.Position.ToRectangleF().Size, + format); + format.FormatFlags |= StringFormatFlags.LineLimit; + } + + + // Add image size + if (label.Image.Length > 0) + { + SizeF imageAbsSize = new SizeF(); + + if(this.Common.ImageLoader.GetAdjustedImageSize(label.Image, chartGraph.Graphics, ref imageAbsSize)) + { + SizeF imageRelSize = chartGraph.GetRelativeSize(imageAbsSize); + if ((format.FormatFlags & StringFormatFlags.DirectionVertical) == StringFormatFlags.DirectionVertical) + { + axisLabelSize.Height += imageRelSize.Height; + axisLabelSize.Width = Math.Max(axisLabelSize.Width, imageRelSize.Width); + } + else + { + axisLabelSize.Width += imageRelSize.Width; + axisLabelSize.Height = Math.Max(axisLabelSize.Height, imageRelSize.Height); + } + } + } + + // Add extra spacing for the box marking of the label + if (label.LabelMark == LabelMarkStyle.Box) + { + // Get relative size from pixels and add it to the label size + SizeF spacerSize = chartGraph.GetRelativeSize(new SizeF(4, 4)); + axisLabelSize.Width += spacerSize.Width; + axisLabelSize.Height += spacerSize.Height; + } + + + // Calculate size using label angle + float width = axisLabelSize.Width; + float height = axisLabelSize.Height; + if (angle != 0) + { + // Decrease label rectangle width by 3% + rect.Width *= 0.97f; + + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + width = (float)Math.Cos((Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Height; + width += (float)Math.Sin((Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Width; + + height = (float)Math.Sin((Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Height; + height += (float)Math.Cos((Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Width; + } + else + { + width = (float)Math.Cos((Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Width; + width += (float)Math.Sin((Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Height; + + height = (float)Math.Sin((Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Width; + height += (float)Math.Cos((Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Height; + } + } + + // Save label position + if (labelPositions != null) + { + RectangleF labelPosition = rect; + if (angle == 0F || angle == 90F || angle == -90F) + { + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + labelPosition.X = labelPosition.X + labelPosition.Width / 2f - width / 2f; + labelPosition.Width = width; + } + else + { + labelPosition.Y = labelPosition.Y + labelPosition.Height / 2f - height / 2f; + labelPosition.Height = height; + } + } + labelPositions.Add(labelPosition); + } + + // Check if string fits + if (angle == 0F) + { + if (width >= rect.Width && checkWidth) + { + return false; + } + if (height >= rect.Height && checkHeight) + { + return false; + } + } + if (angle == 90F || angle == -90F) + { + if (width >= rect.Width && checkWidth) + { + return false; + } + if (height >= rect.Height && checkHeight) + { + return false; + } + } + else + { + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + if (width >= rect.Width * 2F && checkWidth) + { + return false; + } + if (height >= rect.Height * 2F && checkHeight) + { + return false; + } + } + else + { + if (width >= rect.Width * 2F && checkWidth) + { + return false; + } + if (height >= rect.Height * 2F && checkHeight) + { + return false; + } + } + } + + ++labelIndex; + } + } + } + + return true; + } + + /// + /// Calculates the best size for labels area. + /// + /// Chart graphics object. + /// Maximum labels area size. + /// Label size without angle = 0. + private float GetRequiredLabelSize(ChartGraphics chartGraph, float maxLabelSize, out float resultSize) + { + float resultRotatedSize = 0F; + resultSize = 0F; + float angle = (autoLabelAngle < -90) ? this.LabelStyle.Angle : autoLabelAngle; + labelNearOffset = float.MaxValue; + labelFarOffset = float.MinValue; + + // Label string drawing format + using (StringFormat format = new StringFormat()) + { + format.FormatFlags |= StringFormatFlags.LineLimit; + format.Trimming = StringTrimming.EllipsisCharacter; + + // Initialize all labels position rectangle + RectangleF rectLabels = ChartArea.Position.ToRectangleF(); + + // Loop through all labels in the first row + foreach (CustomLabel label in this.CustomLabels) + { + // Skip if label middle point is outside current scaleView + if (label.RowIndex == 0) + { + decimal middlePoint = (decimal)(label.FromPosition + label.ToPosition) / (decimal)2.0; + if (middlePoint < (decimal)this.ViewMinimum || middlePoint > (decimal)this.ViewMaximum) + { + continue; + } + } + if (label.RowIndex == 0) + { + // Calculate single label position + RectangleF rect = rectLabels; + rect.Width = maxLabelSize; + + // Set label From and To coordinates + double fromPosition = this.GetLinearPosition(label.FromPosition); + double toPosition = this.GetLinearPosition(label.ToPosition); + rect.Y = (float)Math.Min(fromPosition, toPosition); + rect.Height = (float)Math.Max(fromPosition, toPosition) - rect.Y; + + // Adjust label From/To position if labels are displayed with offset + if ((autoLabelOffset == -1) ? this.LabelStyle.IsStaggered : (autoLabelOffset == 1)) + { + rect.Y -= rect.Height / 2F; + rect.Height *= 2F; + } + + // If horizontal axis + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + // Switch rectangle sizes + float val = rect.Height; + rect.Height = rect.Width; + rect.Width = val; + + // Set vertical font for measuring + if (angle != 0) + { + format.FormatFlags |= StringFormatFlags.DirectionVertical; + } + } + else + { + // Set vertical font for measuring + if (angle == 90 || angle == -90) + { + angle = 0; + format.FormatFlags |= StringFormatFlags.DirectionVertical; + } + } + + // Measure label text size + rect.Width = (float)Math.Ceiling(rect.Width); + rect.Height = (float)Math.Ceiling(rect.Height); + SizeF axisLabelSize = chartGraph.MeasureStringRel(label.Text.Replace("\\n", "\n"), + (autoLabelFont != null) ? autoLabelFont : this.LabelStyle.Font, + rect.Size, + format); + + // Width and height maybe zeros if rect is too small to fit the text and + // the LineLimit format flag is set. + if (axisLabelSize.Width == 0f || axisLabelSize.Height == 0f) + { + // Measure string without the LineLimit flag + format.FormatFlags ^= StringFormatFlags.LineLimit; + axisLabelSize = chartGraph.MeasureStringRel(label.Text.Replace("\\n", "\n"), + (autoLabelFont != null) ? autoLabelFont : this.LabelStyle.Font, + rect.Size, + format); + format.FormatFlags |= StringFormatFlags.LineLimit; + } + + + // Add image size + if (label.Image.Length > 0) + { + SizeF imageAbsSize = new SizeF(); + + if (this.Common.ImageLoader.GetAdjustedImageSize(label.Image, chartGraph.Graphics, ref imageAbsSize)) + { + SizeF imageRelSize = chartGraph.GetRelativeSize(imageAbsSize); + + if ((format.FormatFlags & StringFormatFlags.DirectionVertical) == StringFormatFlags.DirectionVertical) + { + axisLabelSize.Height += imageRelSize.Height; + axisLabelSize.Width = Math.Max(axisLabelSize.Width, imageRelSize.Width); + } + else + { + axisLabelSize.Width += imageRelSize.Width; + axisLabelSize.Height = Math.Max(axisLabelSize.Height, imageRelSize.Height); + } + } + } + + // Add extra spacing for the box marking of the label + if (label.LabelMark == LabelMarkStyle.Box) + { + // Get relative size from pixels and add it to the label size + SizeF spacerSize = chartGraph.GetRelativeSize(new SizeF(4, 4)); + axisLabelSize.Width += spacerSize.Width; + axisLabelSize.Height += spacerSize.Height; + } + + + // Calculate size using label angle + float width = axisLabelSize.Width; + float height = axisLabelSize.Height; + if (angle != 0) + { + width = (float)Math.Cos((90 - Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Width; + width += (float)Math.Cos((Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Height; + + height = (float)Math.Sin((Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Height; + height += (float)Math.Sin((90 - Math.Abs(angle)) / 180F * Math.PI) * axisLabelSize.Width; + } + + width = (float)Math.Ceiling(width) * 1.05f; + height = (float)Math.Ceiling(height) * 1.05f; + axisLabelSize.Width = (float)Math.Ceiling(axisLabelSize.Width) * 1.05f; + axisLabelSize.Height = (float)Math.Ceiling(axisLabelSize.Height) * 1.05f; + + + // If axis is horizontal + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + if (angle == 90 || angle == -90 || angle == 0) + { + resultSize = Math.Max(resultSize, axisLabelSize.Height); + resultRotatedSize = Math.Max(resultRotatedSize, axisLabelSize.Height); + + // Calculate the over hang of labels on the side + labelNearOffset = (float)Math.Min(labelNearOffset, (fromPosition + toPosition) / 2f - axisLabelSize.Width / 2f); + labelFarOffset = (float)Math.Max(labelFarOffset, (fromPosition + toPosition) / 2f + axisLabelSize.Width / 2f); + + } + else + { + resultSize = Math.Max(resultSize, axisLabelSize.Height); + resultRotatedSize = Math.Max(resultRotatedSize, height); + + // Calculate the over hang of labels on the side + if (angle > 0) + { + labelFarOffset = (float)Math.Max(labelFarOffset, (fromPosition + toPosition) / 2f + width * 1.1f); + } + else + { + labelNearOffset = (float)Math.Min(labelNearOffset, (fromPosition + toPosition) / 2f - width * 1.1f); + } + } + } + // If axis is vertical + else + { + if (angle == 90 || angle == -90 || angle == 0) + { + resultSize = Math.Max(resultSize, axisLabelSize.Width); + resultRotatedSize = Math.Max(resultRotatedSize, axisLabelSize.Width); + + // Calculate the over hang of labels on the side + labelNearOffset = (float)Math.Min(labelNearOffset, (fromPosition + toPosition) / 2f - axisLabelSize.Height / 2f); + labelFarOffset = (float)Math.Max(labelFarOffset, (fromPosition + toPosition) / 2f + axisLabelSize.Height / 2f); + } + else + { + resultSize = Math.Max(resultSize, axisLabelSize.Width); + resultRotatedSize = Math.Max(resultRotatedSize, width); + + // Calculate the over hang of labels on the side + if (angle > 0) + { + labelFarOffset = (float)Math.Max(labelFarOffset, (fromPosition + toPosition) / 2f + height * 1.1f); + } + else + { + labelNearOffset = (float)Math.Min(labelNearOffset, (fromPosition + toPosition) / 2f - height * 1.1f); + } + } + } + + // Check if we exceed the maximum value + if (resultSize > maxLabelSize) + { + resultSize = maxLabelSize; + } + } + } + } + + // Adjust results if labels are displayed with offset + if ((autoLabelOffset == -1) ? this.LabelStyle.IsStaggered : (autoLabelOffset == 1)) + { + resultSize *= 2F; + resultRotatedSize *= 2F; + + // Check if we exceed the maximum value + if (resultSize > maxLabelSize) + { + resultSize = maxLabelSize; + resultRotatedSize = maxLabelSize; + } + } + + // Adjust labels size for the 3D Common.Chart + if (ChartArea.Area3DStyle.Enable3D && !ChartArea.chartAreaIsCurcular) + { + // Increase labels size + resultSize *= 1.1f; + resultRotatedSize *= 1.1f; + } + + return resultRotatedSize; + } + + /// + /// Gets total size of all grouping labels. + /// + /// Total size of all grouping labels. + internal float GetGroupLablesToatalSize() + { + float size = 0f; + if (this.groupingLabelSizes != null && this.groupingLabelSizes.Length > 0) + { + foreach (float val in this.groupingLabelSizes) + { + size += val; + } + } + + return size; + } + + /// + /// Gets number of levels of the grouping labels. + /// + /// Number of levels of the grouping labels. + internal int GetGroupLabelLevelCount() + { + int groupLabelLevel = 0; + foreach (CustomLabel label in this.CustomLabels) + { + if (label.RowIndex > 0) + { + groupLabelLevel = Math.Max(groupLabelLevel, label.RowIndex); + } + } + + return groupLabelLevel; + } + + /// + /// Calculates the best size for axis labels for all rows except first one (grouping labels). + /// + /// Chart graphics object. + /// Maximum labels area size. + /// Array of grouping label sizes for each level. + private float[] GetRequiredGroupLabelSize(ChartGraphics chartGraph, float maxLabelSize) + { + float[] resultSize = null; + + // Get number of groups + int groupLabelLevelCount = GetGroupLabelLevelCount(); + + // Check ig grouping labels exist + if (groupLabelLevelCount > 0) + { + // Create result array + resultSize = new float[groupLabelLevelCount]; + + // Loop through each level of grouping labels + for (int groupLevelIndex = 1; groupLevelIndex <= groupLabelLevelCount; groupLevelIndex++) + { + resultSize[groupLevelIndex - 1] = 0f; + + // Loop through all labels in the level + foreach (CustomLabel label in this.CustomLabels) + { + // Skip if label middle point is outside current scaleView + if (label.RowIndex == 0) + { + double middlePoint = (label.FromPosition + label.ToPosition) / 2.0; + if (middlePoint < this.ViewMinimum || middlePoint > this.ViewMaximum) + { + continue; + } + } + + if (label.RowIndex == groupLevelIndex) + { + // Measure label text size + SizeF axisLabelSize = chartGraph.MeasureStringRel(label.Text.Replace("\\n", "\n"), (autoLabelFont != null) ? autoLabelFont : this.LabelStyle.Font); + axisLabelSize.Width = (float)Math.Ceiling(axisLabelSize.Width); + axisLabelSize.Height = (float)Math.Ceiling(axisLabelSize.Height); + + + // Add image size + if(label.Image.Length > 0) + { + SizeF imageAbsSize = new SizeF(); + + if(this.Common.ImageLoader.GetAdjustedImageSize(label.Image, chartGraph.Graphics, ref imageAbsSize)) + { + SizeF imageRelSize = chartGraph.GetRelativeSize(imageAbsSize); + axisLabelSize.Width += imageRelSize.Width; + axisLabelSize.Height = Math.Max(axisLabelSize.Height, imageRelSize.Height); + } + } + + // Add extra spacing for the box marking of the label + if(label.LabelMark == LabelMarkStyle.Box) + { + // Get relative size from pixels and add it to the label size + SizeF spacerSize = chartGraph.GetRelativeSize(new SizeF(4, 4)); + axisLabelSize.Width += spacerSize.Width; + axisLabelSize.Height += spacerSize.Height; + } + + + + // If axis is horizontal + if (this.AxisPosition == AxisPosition.Bottom || this.AxisPosition == AxisPosition.Top) + { + resultSize[groupLevelIndex - 1] = Math.Max(resultSize[groupLevelIndex - 1], axisLabelSize.Height); + } + // If axis is vertical + else + { + axisLabelSize.Width = chartGraph.GetAbsoluteSize(new SizeF(axisLabelSize.Height, axisLabelSize.Height)).Height; + axisLabelSize.Width = chartGraph.GetRelativeSize(new SizeF(axisLabelSize.Width, axisLabelSize.Width)).Width; + resultSize[groupLevelIndex - 1] = Math.Max(resultSize[groupLevelIndex - 1], axisLabelSize.Width); + } + + // Check if we exceed the maximum value + if (resultSize[groupLevelIndex - 1] > maxLabelSize / groupLabelLevelCount) + { + // NOTE: Group Labels size limitations are removed !!! + // resultSize[groupLevelIndex - 1] = maxLabelSize / groupLabelLevelCount; + // break; + } + } + } + } + } + + return resultSize; + } + + #endregion + + #region Axis helper methods + + + /// + /// Gets main or sub axis associated with this axis. + /// + /// Sub axis name or empty string to get the main axis. + /// Main or sub axis of the main axis. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "subAxisName")] + internal Axis GetSubAxis(string subAxisName) + { +#if SUBAXES + if(!this.IsSubAxis && subAxisName.Length > 0) + { + SubAxis subAxis = this.SubAxes.FindByName(subAxisName); + if(subAxis == null) + { + throw(new InvalidOperationException( SR.ExceptionSubAxisNameNotFoundShort( subAxisName ))); + } + return subAxis; + } +#endif // SUBAXES + return this; + } + + /// + /// Checks if axis marks should be next to the axis + /// + /// true if marks are next to axis. + internal bool GetIsMarksNextToAxis() + { + if (ChartArea != null && ChartArea.chartAreaIsCurcular) + { + return true; + } + return this.IsMarksNextToAxis; + } + + /// + /// Gets axis auto interval type. + /// + /// Axis interval type. + internal DateTimeIntervalType GetAxisIntervalType() + { + if(InternalIntervalType == DateTimeIntervalType.Auto) + { + if(GetAxisValuesType() == ChartValueType.DateTime || + GetAxisValuesType() == ChartValueType.Date || + GetAxisValuesType() == ChartValueType.Time || + GetAxisValuesType() == ChartValueType.DateTimeOffset) + { + return DateTimeIntervalType.Years; + } + + return DateTimeIntervalType.Number; + } + + return InternalIntervalType; + } + + /// + /// Gets axis values type depending on the series attached + /// + /// Axis values type. + internal ChartValueType GetAxisValuesType() + { + ChartValueType type = ChartValueType.Double; + + // Check all series in this Common.Chart area attached to this axis + if (this.Common != null && this.Common.DataManager.Series != null && ChartArea != null) + { + foreach (Series series in this.Common.DataManager.Series) + { + bool seriesAttached = false; + + // Check series name + if (series.ChartArea == ChartArea.Name && series.IsVisible()) + { + // Check if axis type of series match + if (this.axisType == AxisName.X && series.XAxisType == AxisType.Primary) + { +#if SUBAXES + if(((Axis)this).SubAxisName == series.XSubAxisName) +#endif // SUBAXES + { + seriesAttached = true; + } + } + else if (this.axisType == AxisName.X2 && series.XAxisType == AxisType.Secondary) + { +#if SUBAXES + if(((Axis)this).SubAxisName == series.XSubAxisName) +#endif // SUBAXES + { + seriesAttached = true; + } + } + else if (this.axisType == AxisName.Y && series.YAxisType == AxisType.Primary) + { +#if SUBAXES + if(((Axis)this).SubAxisName == series.YSubAxisName) +#endif // SUBAXES + { + seriesAttached = true; + } + } + else if (this.axisType == AxisName.Y2 && series.YAxisType == AxisType.Secondary) + { +#if SUBAXES + if(((Axis)this).SubAxisName == series.YSubAxisName) +#endif // SUBAXES + { + seriesAttached = true; + } + } + } + + // If series attached to this axes + if (seriesAttached) + { + if (this.axisType == AxisName.X || this.axisType == AxisName.X2) + { + type = series.XValueType; + } + else if (this.axisType == AxisName.Y || this.axisType == AxisName.Y2) + { + type = series.YValueType; + } + break; + } + } + } + return type; + } + + /// + /// Returns Arrow size + /// + /// Return arrow orientation. + /// Size of arrow + internal SizeF GetArrowSize(out ArrowOrientation arrowOrientation) + { + Axis opositeAxis; + double size; + double sizeOpposite; + arrowOrientation = ArrowOrientation.Top; + + // Set the position of axis + switch (AxisPosition) + { + case AxisPosition.Left: + + if (isReversed) + arrowOrientation = ArrowOrientation.Bottom; + else + arrowOrientation = ArrowOrientation.Top; + + break; + case AxisPosition.Right: + + if (isReversed) + arrowOrientation = ArrowOrientation.Bottom; + else + arrowOrientation = ArrowOrientation.Top; + + break; + case AxisPosition.Bottom: + + if (isReversed) + arrowOrientation = ArrowOrientation.Left; + else + arrowOrientation = ArrowOrientation.Right; + + break; + case AxisPosition.Top: + + if (isReversed) + arrowOrientation = ArrowOrientation.Left; + else + arrowOrientation = ArrowOrientation.Right; + + break; + } + + // Opposite axis. Arrow uses this axis to find + // a shift from Common.Chart area border. This shift + // depend on Tick mark size. + switch (arrowOrientation) + { + case ArrowOrientation.Left: + opositeAxis = ChartArea.AxisX; + break; + case ArrowOrientation.Right: + opositeAxis = ChartArea.AxisX2; + break; + case ArrowOrientation.Top: + opositeAxis = ChartArea.AxisY2; + break; + case ArrowOrientation.Bottom: + opositeAxis = ChartArea.AxisY; + break; + default: + opositeAxis = ChartArea.AxisX; + break; + } + + // Arrow size has to have the same shape when width and height + // are changed. When the picture is resized, width of the Common.Chart + // picture is used only for arrow size. + if (arrowOrientation == ArrowOrientation.Top || arrowOrientation == ArrowOrientation.Bottom) + { + size = _lineWidth; + sizeOpposite = (double)(_lineWidth) * Common.Width / Common.Height; + } + else + { + size = (double)(_lineWidth) * Common.Width / Common.Height; + sizeOpposite = _lineWidth; + } + + // Arrow is sharp triangle + if (_arrowStyle == AxisArrowStyle.SharpTriangle) + { + // Arrow direction is vertical + if (arrowOrientation == ArrowOrientation.Top || arrowOrientation == ArrowOrientation.Bottom) + return new SizeF((float)(size * 2), (float)(opositeAxis.MajorTickMark.Size + sizeOpposite * 4)); + else + // Arrow direction is horizontal + return new SizeF((float)(opositeAxis.MajorTickMark.Size + sizeOpposite * 4), (float)(size * 2)); + } + // There is no arrow + else if (_arrowStyle == AxisArrowStyle.None) + return new SizeF(0, 0); + else// Arrow is triangle or line type + { + // Arrow direction is vertical + if (arrowOrientation == ArrowOrientation.Top || arrowOrientation == ArrowOrientation.Bottom) + return new SizeF((float)(size * 2), (float)(opositeAxis.MajorTickMark.Size + sizeOpposite * 2)); + else + // Arrow direction is horizontal + return new SizeF((float)(opositeAxis.MajorTickMark.Size + sizeOpposite * 2), (float)(size * 2)); + } + } + + + /// + /// Checks if arrow with specified orientation will require space + /// in axis with specified position + /// + /// Arrow orientation. + /// Axis position. + /// True if arrow will be drawn in axis space + private bool IsArrowInAxis(ArrowOrientation arrowOrientation, AxisPosition axisPosition) + { + if (axisPosition == AxisPosition.Top && arrowOrientation == ArrowOrientation.Top) + return true; + else if (axisPosition == AxisPosition.Bottom && arrowOrientation == ArrowOrientation.Bottom) + return true; + if (axisPosition == AxisPosition.Left && arrowOrientation == ArrowOrientation.Left) + return true; + else if (axisPosition == AxisPosition.Right && arrowOrientation == ArrowOrientation.Right) + return true; + + return false; + } + + + /// + /// This function converts real Interval to + /// absolute Interval + /// + /// A interval represented as double value + /// A interval represented in pixels + internal float GetPixelInterval(double realInterval) + { + double chartAreaSize; + + // The Chart area pixel size as double + if (AxisPosition == AxisPosition.Top || AxisPosition == AxisPosition.Bottom) + { + chartAreaSize = PlotAreaPosition.Right - PlotAreaPosition.X; + } + else + { + chartAreaSize = PlotAreaPosition.Bottom - PlotAreaPosition.Y; + } + + // Avoid division by zero. + if (ViewMaximum - ViewMinimum == 0) + { + return (float)(chartAreaSize / realInterval); + } + + // The interval integer + return (float)(chartAreaSize / (ViewMaximum - ViewMinimum) * realInterval); + } + + /// + /// Find if axis is on the edge of the Common.Chart plot area + /// + internal bool IsAxisOnAreaEdge + { + get + { + double edgePosition = 0; + if (this.AxisPosition == AxisPosition.Bottom) + { + edgePosition = PlotAreaPosition.Bottom; + } + else if (this.AxisPosition == AxisPosition.Left) + { + edgePosition = PlotAreaPosition.X; + } + else if (this.AxisPosition == AxisPosition.Right) + { + edgePosition = PlotAreaPosition.Right; + } + else if (this.AxisPosition == AxisPosition.Top) + { + edgePosition = PlotAreaPosition.Y; + } + + // DT Fix : problems with values on edge ~0.0005 + if (Math.Abs(GetAxisPosition() - edgePosition) < 0.0015) + { + return true; + } + + return false; + } + } + + /// + /// Find axis position using crossing value. + /// + /// Relative position + internal double GetAxisPosition() + { + return GetAxisPosition(false); + } + + /// + /// Find axis position using crossing value. + /// + /// Axis crossing should be ignored. + /// Relative position + virtual internal double GetAxisPosition(bool ignoreCrossing) + { + Axis axisOpposite = GetOppositeAxis(); + + // Get axis position for circular Common.Chart area + if (ChartArea != null && ChartArea.chartAreaIsCurcular) + { + return PlotAreaPosition.X + PlotAreaPosition.Width / 2f; + } + + // Axis is not connected with any series. There is no maximum and minimum + if (axisOpposite.maximum == axisOpposite.minimum || + double.IsNaN(axisOpposite.maximum) || + double.IsNaN(axisOpposite.minimum) || + maximum == minimum || + double.IsNaN(maximum) || + double.IsNaN(minimum)) + { + switch (AxisPosition) + { + case AxisPosition.Top: + return PlotAreaPosition.Y; + case AxisPosition.Bottom: + return PlotAreaPosition.Bottom; + case AxisPosition.Right: + return PlotAreaPosition.Right; + case AxisPosition.Left: + return PlotAreaPosition.X; + } + } + + // Auto crossing enabled + if (Double.IsNaN(axisOpposite.crossing) || ignoreCrossing) + { + // Primary + if (axisType == AxisName.X || axisType == AxisName.Y) + return axisOpposite.GetLinearPosition(axisOpposite.ViewMinimum); + else // Secondary + return axisOpposite.GetLinearPosition(axisOpposite.ViewMaximum); + } + else // Auto crossing disabled + { + axisOpposite.crossing = axisOpposite.tempCrossing; + + if (axisOpposite.crossing < axisOpposite.ViewMinimum) + { + axisOpposite.crossing = axisOpposite.ViewMinimum; + } + else if (axisOpposite.crossing > axisOpposite.ViewMaximum) + { + axisOpposite.crossing = axisOpposite.ViewMaximum; + } + } + + return axisOpposite.GetLinearPosition(axisOpposite.crossing); + } + + #endregion + + #region Axis 3D helper methods + + /// + /// Returns angle between 2D axis line and it's 3D transformed projection. + /// + /// Axis projection angle. + internal double GetAxisProjectionAngle() + { + // Get Z position + bool axisOnEdge; + float zPosition = GetMarksZPosition(out axisOnEdge); + + // Get axis position + float axisPosition = (float)GetAxisPosition(); + + // Create two points on the sides of the axis + Point3D[] axisPoints = new Point3D[2]; + if (this.AxisPosition == AxisPosition.Top || this.AxisPosition == AxisPosition.Bottom) + { + axisPoints[0] = new Point3D(0f, axisPosition, zPosition); + axisPoints[1] = new Point3D(100f, axisPosition, zPosition); + } + else + { + axisPoints[0] = new Point3D(axisPosition, 0f, zPosition); + axisPoints[1] = new Point3D(axisPosition, 100f, zPosition); + } + + // Transform coordinates + ChartArea.matrix3D.TransformPoints(axisPoints); + + // Round result + axisPoints[0].X = (float)Math.Round(axisPoints[0].X, 4); + axisPoints[0].Y = (float)Math.Round(axisPoints[0].Y, 4); + axisPoints[1].X = (float)Math.Round(axisPoints[1].X, 4); + axisPoints[1].Y = (float)Math.Round(axisPoints[1].Y, 4); + + // Calculate angle + double angle = 0.0; + if (this.AxisPosition == AxisPosition.Top || this.AxisPosition == AxisPosition.Bottom) + { + angle = Math.Atan((axisPoints[1].Y - axisPoints[0].Y) / (axisPoints[1].X - axisPoints[0].X)); + } + else + { + angle = Math.Atan((axisPoints[1].X - axisPoints[0].X) / (axisPoints[1].Y - axisPoints[0].Y)); + } + + // Conver to degrees + return (angle * 180.0) / Math.PI; + } + + #endregion + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_fontCache != null) + { + _fontCache.Dispose(); + _fontCache = null; + } + + if (labelStyle != null) + { + labelStyle.Dispose(); + labelStyle = null; + } + + if (_stripLines != null) + { + _stripLines.Dispose(); + _stripLines = null; + } + if (_customLabels != null) + { + _customLabels.Dispose(); + _customLabels = null; + } + if (tempLabels != null) + { + tempLabels.Dispose(); + tempLabels = null; + } +#if Microsoft_CONTROL + if (this.scrollBar != null) + { + this.scrollBar.Dispose(); + this.scrollBar = null; + } +#endif // Microsoft_CONTROL + } + base.Dispose(disposing); + } + + + #endregion + + } +} diff --git a/System.Web.DataVisualization/Common/General/AxisLabels.cs b/System.Web.DataVisualization/Common/General/AxisLabels.cs new file mode 100644 index 000000000..859de283d --- /dev/null +++ b/System.Web.DataVisualization/Common/General/AxisLabels.cs @@ -0,0 +1,941 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: AxisLabels.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: AxisLabels +// +// Purpose: Base class for the Axis class which defines axis +// labels related properties and methods. +// +// Reviewed: GS - August 8, 2002 +// AG - August 8, 2002 +// +//=================================================================== + +#region Used namespaces +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// The Axis class provides functionality for + /// drawing axis labels. + /// + public partial class Axis + { + #region Fields + + // Custom Labels collection + private CustomLabelsCollection _customLabels = null; + + #endregion + + #region Axis labels properties + + /// + /// Gets or sets the style of the label. + /// + [ + SRCategory("CategoryAttributeLabels"), + Bindable(true), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeLabelStyle"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] + public LabelStyle LabelStyle + { + get + { + return labelStyle; + } + set + { + labelStyle = value; + labelStyle.Axis = (Axis)this; + this.Invalidate(); + } + } + + /// + /// Gets a collection of custom labels. + /// + [ + SRCategory("CategoryAttributeLabels"), + Bindable(true), + SRDescription("DescriptionAttributeCustomLabels"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base) + ] + public CustomLabelsCollection CustomLabels + { + get + { + return _customLabels; + } + } + + #endregion + + #region Axis labels methods + + /// + /// Indicates that custom grid lines should be painted. + /// + /// Indicates that custom grid lines should be painted. + internal bool IsCustomGridLines() + { + if(this.CustomLabels.Count > 0) + { + // Check if at least one custom label has a flag set + foreach(CustomLabel label in this.CustomLabels) + { + if((label.GridTicks & GridTickTypes.Gridline) == GridTickTypes.Gridline) + { + return true; + } + } + } + + return false; + } + + /// + /// Indicates that custom tick marks should be painted. + /// + /// Indicates that custom tick marks should be painted. + internal bool IsCustomTickMarks() + { + if(this.CustomLabels.Count > 0) + { + // Check if at least one custom label has a flag set + foreach(CustomLabel label in this.CustomLabels) + { + if((label.GridTicks & GridTickTypes.TickMark) == GridTickTypes.TickMark) + { + return true; + } + } + } + + return false; + } + + /// + /// Gets the type of the axis. + /// + /// The type of the axis. + internal AxisType GetAxisType() + { + if (this.axisType == AxisName.X || this.axisType == AxisName.Y) + { + return AxisType.Primary; + } + else + { + return AxisType.Secondary; + } + } + + /// + /// Gets the axis series. + /// + /// + internal ArrayList GetAxisSeries() + { + ArrayList dataSeries = new ArrayList(); + + // check for attached series. + foreach (string seriesName in this.ChartArea.Series) + { + Series series = this.Common.DataManager.Series[seriesName]; + if (this.axisType == AxisName.X || this.axisType == AxisName.X2) + { + if (series.XAxisType == this.GetAxisType()) + { + dataSeries.Add(series); + } + } + else + { + if (series.YAxisType == this.GetAxisType()) + { + dataSeries.Add(series); + } + } + } + return dataSeries; + } + + /// + /// Gets the other (primary/secondary) axis. + /// + /// + internal Axis GetOtherTypeAxis() + { + return ChartArea.GetAxis( + this.axisType, + this.GetAxisType() == AxisType.Primary ? AxisType.Secondary : AxisType.Primary, + String.Empty + ); + } + + /// + /// Checks if the other (primary/secondary) axis has custom labels labels. + /// These labels will be added if this axis has no series attached and no custom labels. + /// This works only on category axes. + /// + internal void PostFillLabels() + { + foreach (CustomLabel label in this.CustomLabels) + { + if (label.customLabel) + { + return; + } + } + + // Labels are disabled for this axis + if ( + !this.LabelStyle.Enabled || + !this.enabled || + !String.IsNullOrEmpty(((Axis)this).SubAxisName) || + this.axisType == AxisName.Y || + this.axisType == AxisName.Y2 + ) + { + return; + } + + // check if no series attached. + if (this.GetAxisSeries().Count > 0) + { + return; + } + this.CustomLabels.Clear(); + foreach (CustomLabel label in this.GetOtherTypeAxis().CustomLabels) + { + this.CustomLabels.Add(label.Clone()); + } + } + + /// + /// Fill labels from data from data manager or + /// from axis scale. + /// + /// True if first row of auto generated labels must be removed. + internal void FillLabels(bool removeFirstRow) + { +#if SUBAXES + // Process all sub-axis + foreach(SubAxis subAxis in ((Axis)this).SubAxes) + { + subAxis.FillLabels(true); + } +#endif // SUBAXES + + // Labels are disabled for this axis + if( !this.LabelStyle.Enabled || !this.enabled ) + { + return; + } + + // For circular chart area fill only Y axis labels + if(this.ChartArea != null && this.ChartArea.chartAreaIsCurcular) + { + if(this.axisType != AxisName.Y) + { + ICircularChartType type = this.ChartArea.GetCircularChartType(); + if(type == null || !type.XAxisLabelsSupported()) + { + return; + } + } + } + + // Check if the custom labels exist + bool customLabelsFlag = false; + foreach( CustomLabel lab in CustomLabels ) + { + if( lab.customLabel ) + { + if( lab.RowIndex == 0 || + this.ChartArea.chartAreaIsCurcular) + { + customLabelsFlag = true; + } + } + } + + + // Remove the first row of labels if custom labels not exist + if(removeFirstRow) + { + if( customLabelsFlag == false ) + { + for( int index = 0; index < CustomLabels.Count; index++ ) + { + if( CustomLabels[index].RowIndex == 0 ) + { + CustomLabels.RemoveAt( index ); + index = -1; + } + } + } + else + { + return; + } + } + + // Get data series for this axis. + List dataSeries = null; + switch( axisType ) + { + case AxisName.X: + dataSeries = ChartArea.GetXAxesSeries( AxisType.Primary, ((Axis)this).SubAxisName ); + break; + case AxisName.Y: + dataSeries = ChartArea.GetYAxesSeries( AxisType.Primary, ((Axis)this).SubAxisName ); + break; + case AxisName.X2: + dataSeries = ChartArea.GetXAxesSeries( AxisType.Secondary, ((Axis)this).SubAxisName ); + break; + case AxisName.Y2: + dataSeries = ChartArea.GetYAxesSeries( AxisType.Secondary, ((Axis)this).SubAxisName ); + break; + } + + // There aren't data series connected with this axis. + if( dataSeries.Count == 0 ) + { + return; + } + + //Let's convert the ArrayList of the series names into to string[] + string[] dataSeriesNames = new string[dataSeries.Count]; + for (int i = 0; i < dataSeries.Count; i++) + dataSeriesNames[i] = (string)dataSeries[i]; + + // Check if series X values all set to zeros + bool seriesXValuesZeros = ChartHelper.SeriesXValuesZeros(this.Common, dataSeriesNames); + + // Check if series is indexed (All X values zeros or IsXValueIndexed flag set) + bool indexedSeries = true; + if (!seriesXValuesZeros) + { + indexedSeries = ChartHelper.IndexedSeries(this.Common, dataSeriesNames); + } + + // Show End Labels + int endLabels = 0; + if( labelStyle.IsEndLabelVisible ) + { + endLabels = 1; + } + + // Get chart type of the first series + IChartType chartType = Common.ChartTypeRegistry.GetChartType( ChartArea.GetFirstSeries().ChartTypeName ); + bool fromSeries = false; + if( !chartType.RequireAxes ) + { + return; + } + else if( axisType == AxisName.Y || axisType == AxisName.Y2 ) + { + fromSeries = false; + } + else + { + fromSeries = true; + } + + // X values from data points are not 0. + if (fromSeries && !ChartHelper.SeriesXValuesZeros(this.Common, dataSeries.ToArray())) + { + fromSeries = false; + } + + // X values from data points are not 0. + if( fromSeries && ( labelStyle.GetIntervalOffset() != 0 || labelStyle.GetInterval() != 0 ) ) + { + fromSeries = false; + } + + // Get value type + ChartValueType valueType; + if( axisType == AxisName.X || axisType == AxisName.X2 ) + { + // If X value is indexed the type is always String. So we use indexed type instead + valueType = Common.DataManager.Series[dataSeries[0]].indexedXValueType; + } + else + { + valueType = Common.DataManager.Series[dataSeries[0]].YValueType; + } + + if( labelStyle.GetIntervalType() != DateTimeIntervalType.Auto && + labelStyle.GetIntervalType() != DateTimeIntervalType.Number ) + { + if (valueType != ChartValueType.Time && + valueType != ChartValueType.Date && + valueType != ChartValueType.DateTimeOffset) + { + valueType = ChartValueType.DateTime; + } + } + + // *********************************** + // Pre calculate some values + // *********************************** + double viewMaximum = this.ViewMaximum; + double viewMinimum = this.ViewMinimum; + + // *********************************** + // Labels are filled from data series. + // *********************************** + if( fromSeries ) + { + int numOfPoints; + numOfPoints = Common.DataManager.GetNumberOfPoints( dataSeries.ToArray() ); + + // Show end labels + if( endLabels == 1 ) + { + // min position + CustomLabels.Add( - 0.5, 0.5, ValueConverter.FormatValue( + this.Common.Chart, + this, + null, + 0.0, + this.LabelStyle.Format, + valueType, + ChartElementType.AxisLabels), + false); + } + + // Labels from point position + for( int point = 0; point < numOfPoints; point++ ) + { + CustomLabels.Add( ((double)point)+ 0.5, ((double)point)+ 1.5, + ValueConverter.FormatValue( + this.Common.Chart, + this, + null, + point + 1, + this.LabelStyle.Format, + valueType, + ChartElementType.AxisLabels), + false); + } + + // Show end labels + if( endLabels == 1 ) + { + // max position + CustomLabels.Add( ((double)numOfPoints)+ 0.5, ((double)numOfPoints)+ 1.5, + ValueConverter.FormatValue( + this.Common.Chart, + this, + null, + numOfPoints + 1, + this.LabelStyle.Format, + valueType, + ChartElementType.AxisLabels), + false); + } + + int pointIndx; + foreach( string seriesIndx in dataSeries ) + { + // End labels enabled + if( endLabels == 1 ) + pointIndx = 1; + else + pointIndx = 0; + + // Set labels from data points labels + foreach( DataPoint dataPoint in Common.DataManager.Series[ seriesIndx ].Points ) + { + // Find first row of labels + while( CustomLabels[pointIndx].RowIndex > 0 ) + { + pointIndx++; + } + + // Add X labels + if( axisType == AxisName.X || axisType == AxisName.X2 ) + { + if( dataPoint.AxisLabel.Length > 0 ) + { + CustomLabels[pointIndx].Text = dataPoint.AxisLabel; + } + } + + pointIndx++; + } + } + } + // *********************************** + // Labels are filled from axis scale. + // *********************************** + else + { + if( viewMinimum == viewMaximum ) + return; + + double labValue; // Value, which will be converted to text and used for, labels. + double beginPosition; // Begin position for a label + double endPosition; // End position for a label + double start; // Start position for all labels + + // Get first series attached to this axis + Series axisSeries = null; + if(axisType == AxisName.X || axisType == AxisName.X2) + { + List seriesArray = ChartArea.GetXAxesSeries((axisType == AxisName.X) ? AxisType.Primary : AxisType.Secondary, ((Axis)this).SubAxisName); + if(seriesArray.Count > 0) + { + axisSeries = Common.DataManager.Series[seriesArray[0]]; + if(axisSeries != null && !axisSeries.IsXValueIndexed) + { + axisSeries = null; + } + } + } + + // *********************************** + // Check if the AJAX zooming and scrolling mode is enabled. + // Labels are filled slightly different in this case. + // *********************************** + DateTimeIntervalType offsetType = (labelStyle.GetIntervalOffsetType() == DateTimeIntervalType.Auto) ? labelStyle.GetIntervalType() : labelStyle.GetIntervalOffsetType(); + + // By default start is equal to minimum + start = viewMinimum; + + // Adjust start position depending on the interval type + if(!this.ChartArea.chartAreaIsCurcular || + this.axisType == AxisName.Y || + this.axisType == AxisName.Y2 ) + { + start = ChartHelper.AlignIntervalStart(start, labelStyle.GetInterval(), labelStyle.GetIntervalType(), axisSeries); + } + + // Move start if there is start position + if( labelStyle.GetIntervalOffset() != 0 && axisSeries == null) + { + start += ChartHelper.GetIntervalSize(start, labelStyle.GetIntervalOffset(), + offsetType, axisSeries, 0, DateTimeIntervalType.Number, true, false); + } + + // *************************************** + // Date type + // *************************************** + if( valueType == ChartValueType.DateTime || + valueType == ChartValueType.Date || + valueType == ChartValueType.Time || + valueType == ChartValueType.DateTimeOffset || + axisSeries != null) + { + double position = start; + double dateInterval; + + // Too many labels + if ((viewMaximum - start) / ChartHelper.GetIntervalSize(start, labelStyle.GetInterval(), labelStyle.GetIntervalType(), axisSeries, 0, DateTimeIntervalType.Number, true) > ChartHelper.MaxNumOfGridlines) + return; + + int counter = 0; + double endLabelMaxPosition = viewMaximum - ChartHelper.GetIntervalSize(viewMaximum, labelStyle.GetInterval(), labelStyle.GetIntervalType(), axisSeries, labelStyle.GetIntervalOffset(), offsetType, true) / 2f; + double endLabelMinPosition = viewMinimum + ChartHelper.GetIntervalSize(viewMinimum, labelStyle.GetInterval(), labelStyle.GetIntervalType(), axisSeries, labelStyle.GetIntervalOffset(), offsetType, true) / 2f; + while( (decimal)position <= (decimal)viewMaximum ) + { + dateInterval = ChartHelper.GetIntervalSize(position, labelStyle.GetInterval(), labelStyle.GetIntervalType(), axisSeries, labelStyle.GetIntervalOffset(), offsetType, true); + labValue = position; + + // For IsLogarithmic axes + if( this.IsLogarithmic ) + { + labValue = Math.Pow( this.logarithmBase, labValue ); + } + + // Check if we do not exceed max number of elements + if (counter++ > ChartHelper.MaxNumOfGridlines) + { + break; + } + + if (endLabels == 0 && position >= endLabelMaxPosition) + { + break; + } + + beginPosition = position - dateInterval * 0.5; + endPosition = position + dateInterval * 0.5; + + if(endLabels == 0 && position <= endLabelMinPosition) + { + position += dateInterval; + continue; + } + + if( (decimal)beginPosition > (decimal)viewMaximum ) + { + position += dateInterval; + continue; + } + + // NOTE: Fixes issue #6466 + // Following code is removed due to the issues caused by the rounding error + + //if( (((decimal)beginPosition + (decimal)endPosition) / 2.0m) < (decimal)viewMinimum ) + //{ + // position += dateInterval; + // continue; + //} + //if ((decimal)viewMaximum < (((decimal)beginPosition + (decimal)endPosition) / 2m)) + //{ + // position += dateInterval; + // continue; + //} + + string pointLabel = GetPointLabel( dataSeries, labValue, !seriesXValuesZeros, indexedSeries ); + if( pointLabel.Length == 0 ) + { + // Do not draw last label for indexed series + if( position <= this.maximum ) + { + // Add a label to the collection + if( position != this.maximum || !Common.DataManager.Series[ dataSeries[0] ].IsXValueIndexed ) + { + CustomLabels.Add( beginPosition, + endPosition, + ValueConverter.FormatValue( + this.Common.Chart, + this, + null, + labValue, + this.LabelStyle.Format, + valueType, + ChartElementType.AxisLabels), + false); + } + } + } + else + { + // Add a label to the collection + CustomLabels.Add( beginPosition, + endPosition, + pointLabel, + false); + } + position += dateInterval; + } + } + else + { + // *************************************** + // Scale value type + // *************************************** + + // Show First label if Start Label position is used + if( start != viewMinimum ) + endLabels = 1; + + // Set labels + int labelCounter = 0; + for (double position = start - endLabels * labelStyle.GetInterval(); position < viewMaximum - 1.5 * labelStyle.GetInterval() * (1 - endLabels); position = (double)((decimal)position + (decimal)labelStyle.GetInterval())) + { + // Prevent endless loop that may be caused by very small interval + // and double/decimal rounding errors + ++labelCounter; + if(labelCounter > ChartHelper.MaxNumOfGridlines) + { + break; + } + + labValue = (double)((decimal)position + (decimal)labelStyle.GetInterval()); + + // This line is introduce because sometimes 0 value will appear as + // very small value close to zero. + double inter = Math.Log(labelStyle.GetInterval()); + double valu = Math.Log(Math.Abs(labValue)); + int digits = (int)Math.Abs(inter)+5; + + if( digits > 15 ) + { + digits = 15; + } + + if( Math.Abs(inter) < Math.Abs(valu)-5 ) + { + labValue = Math.Round(labValue,digits); + } + + // Too many labels + if( ( viewMaximum - start ) / labelStyle.GetInterval() > ChartHelper.MaxNumOfGridlines ) + { + return; + } + + // For IsLogarithmic axes + if( this.IsLogarithmic ) + labValue = Math.Pow( this.logarithmBase, labValue ); + + beginPosition = (double)((decimal)position + (decimal)labelStyle.GetInterval() * 0.5m); + endPosition = (double)((decimal)position + (decimal)labelStyle.GetInterval() * 1.5m); + + if( (decimal)beginPosition > (decimal)viewMaximum ) + { + continue; + } + + // Show End label if Start Label position is used + // Use decimal type to solve rounding issues + if( (decimal)(( beginPosition + endPosition )/2.0) > (decimal)viewMaximum ) + { + continue; + } + + string pointLabel = GetPointLabel( dataSeries, labValue, !seriesXValuesZeros, indexedSeries ); + if( pointLabel.Length > 15 && labValue < 0.000001) + { + labValue = 0.0; + } + + if( pointLabel.Length == 0 ) + { + // Do not draw last label for indexed series + if( !(Common.DataManager.Series[ dataSeries[0] ].IsXValueIndexed && position > this.maximum) ) + { + // Add a label to the collection + CustomLabels.Add( beginPosition, + endPosition, + ValueConverter.FormatValue( + this.Common.Chart, + this, + null, + labValue, + this.LabelStyle.Format, + valueType, + ChartElementType.AxisLabels), + false); + } + } + else + { + // Add a label to the collection + CustomLabels.Add( beginPosition, + endPosition, + pointLabel, + false); + } + } + } + } + } + + /// + /// This method checks if there is a data point which has value X equal + /// to valuePosition, and returns label from data point if such value exist. + /// If data point with this value not exists empty string will be returned. + /// If all data points have X value zero, index is used instead of X value. + /// + /// Data series + /// A value which should be found in data points x values + /// Series X values are not zeros. + /// Series is indexed. All X values are zeros or IsXValueIndexed flag set. + /// LabelStyle + private string GetPointLabel( + List series, + double valuePosition, + bool nonZeroXValues, + bool indexedSeries + ) + { + // Get max number of data points in the series + int maxPointCount = 0; + foreach (string seriesName in series) + { + Series ser = Common.DataManager.Series[seriesName]; + maxPointCount = Math.Max(maxPointCount, ser.Points.Count); + } + + // Check if axis only contains axis abels + bool allEmpty = true; + foreach( string seriesName in series ) + { + // Get series by name + Series ser = Common.DataManager.Series[ seriesName ]; + + // Check if series has axis labels set + if ((axisType == AxisName.X || axisType == AxisName.X2) && (margin != 0 || maxPointCount == 1 || !this._autoMinimum) && !ser.IsXValueIndexed) + { + if( ser.Points[ 0 ].AxisLabel.Length > 0 && ser.Points[ ser.Points.Count - 1 ].AxisLabel.Length > 0 ) + { + allEmpty = false; + } + } + + // Try getting label from the point + if(!ser.noLabelsInPoints || (nonZeroXValues && indexedSeries)) + { + string result = GetPointLabel( ser, valuePosition, nonZeroXValues, indexedSeries ); + if(!String.IsNullOrEmpty(result)) + { + return result; + } + } + + // VSTS 140676: Serach for IndexedSeriesLabelsSourceAttr attribute + // to find if we have indexed series as source of formula generated nonindexed series. + String labelSeriesName = ser[DataFormula.IndexedSeriesLabelsSourceAttr]; + if (!String.IsNullOrEmpty(labelSeriesName)) + { + Series labelsSeries = Common.DataManager.Series[labelSeriesName]; + if (labelsSeries != null) + { + string result = GetPointLabel(labelsSeries, valuePosition, nonZeroXValues, true); + if (!String.IsNullOrEmpty(result)) + { + return result; + } + } + } + + } + + if( !allEmpty ) + { + return " "; + } + else + { + return ""; + } + } + + /// + /// This method checks if there is a data point which has value X equal + /// to valuePosition, and returns label from data point if such value exist. + /// If data point with this value not exists empty string will be returned. + /// If all data points have X value zero, index is used instead of X value. + /// + /// Data series + /// A value which should be found in data points x values + /// Series X values are not zeros. + /// Series is indexed. All X values are zeros or IsXValueIndexed flag set. + /// LabelStyle + private string GetPointLabel( + Series series, + double valuePosition, + bool nonZeroXValues, + bool indexedSeries) + { + int pointIndx = 1; + + if( axisType == AxisName.Y || axisType == AxisName.Y2 ) + { + return ""; + } + + if( !(( axisType == AxisName.X && series.XAxisType == AxisType.Primary ) || ( axisType == AxisName.X2 && series.XAxisType == AxisType.Secondary )) ) + { +#if SUBAXES + if(series.XSubAxisName != ((Axis)this).SubAxisName) + { + return ""; + } +#endif // SUBAXES + return ""; + } + + // Loop through all series data points + foreach( DataPoint point in series.Points ) + { + // If series is indexed (all X values are zeros or IsXValueIndexed flag set) + if( indexedSeries ) + { + // If axis label position matches point index + if( valuePosition == pointIndx ) + { + // Use X value if axis label is not set and X values in series are not zeros + if(point.AxisLabel.Length == 0 && nonZeroXValues) + { + return ValueConverter.FormatValue( + this.Common.Chart, + this, + null, + point.XValue, + this.LabelStyle.Format, + series.XValueType, + ChartElementType.AxisLabels); + } + + // Return axis label from data point + return point.ReplaceKeywords(point.AxisLabel); + } + } + else + { + // Find x value using Data point X values + if( point.XValue == valuePosition ) + { + // Return label + return point.ReplaceKeywords(point.AxisLabel); + } + } + pointIndx++; + } + return ""; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/AxisScale.cs b/System.Web.DataVisualization/Common/General/AxisScale.cs new file mode 100644 index 000000000..7e7de6000 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/AxisScale.cs @@ -0,0 +1,2369 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: AxisScale.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: AxisScale +// +// Purpose: Base class for the Axis class which defines axis +// csale related properties and methods. +// +// Reviewed: GS Aug 8, 2002 +// AG Aug 8, 2002 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Collections.Generic; +#if Microsoft_CONTROL + + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; + +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Axis enumerations + + /// + /// An enumeration of the mode of automatically calculating intervals. + /// + public enum IntervalAutoMode + { + /// + /// Fixed number of intervals always created on the axis. + /// + FixedCount, + + /// + /// Number of axis intervals depends on the axis length. + /// + VariableCount + } + + + + /// + /// An enumeration of axis position. + /// + internal enum AxisPosition + { + /// + /// Left position + /// + Left, + + /// + /// Right position + /// + Right, + + /// + /// Top position + /// + Top, + + /// + /// Bottom position + /// + Bottom + } + + /// + /// An enumeration of axis arrow styles. + /// + public enum AxisArrowStyle + { + /// + /// No arrow + /// + None, + /// + /// Triangle type + /// + Triangle, + /// + /// Sharp triangle type + /// + SharpTriangle, + /// + /// Lines type + /// + Lines + } + + #endregion + + /// + /// The Axis class keeps information about minimum, maximum + /// and interval values and it is responsible for setting + /// these values automatically. It also handles + /// logarithmic and reversed axis. + /// + public partial class Axis + { + #region Axis scale fields + + // Represents the distance between the data points and its + // chart area margin, Measured as a percentage of default + // margin size. + internal double margin = 100.0; + internal double marginView = 0.0; + internal bool offsetTempSet = false; + + // Used for column chart margin + internal double marginTemp = 0.0; + private ArrayList _stripLineOffsets = new ArrayList(); + + + // Data members, which store properties values + private bool _isLogarithmic = false; + internal double logarithmBase = 10.0; + internal bool isReversed = false; + internal bool isStartedFromZero = true; + internal TickMark minorTickMark = null; + internal TickMark majorTickMark = null; + internal Grid minorGrid = null; + internal Grid majorGrid = null; + internal bool enabled = false; + internal bool autoEnabled = true; + internal LabelStyle labelStyle = null; + private DateTimeIntervalType _internalIntervalType = DateTimeIntervalType.Auto; + internal double maximum = Double.NaN; + internal double crossing = Double.NaN; + internal double minimum = Double.NaN; + + // Temporary Minimum and maximum values. + internal double tempMaximum = Double.NaN; + internal double tempMinimum = Double.NaN; + internal double tempCrossing = Double.NaN; + internal CustomLabelsCollection tempLabels; + internal bool tempAutoMaximum = true; + internal bool tempAutoMinimum = true; + internal double tempMajorGridInterval = Double.NaN; + internal double tempMinorGridInterval = 0.0; + internal double tempMajorTickMarkInterval = Double.NaN; + internal double tempMinorTickMarkInterval = 0.0; + internal double tempLabelInterval = Double.NaN; + internal DateTimeIntervalType tempGridIntervalType = DateTimeIntervalType.NotSet; + internal DateTimeIntervalType tempTickMarkIntervalType = DateTimeIntervalType.NotSet; + internal DateTimeIntervalType tempLabelIntervalType = DateTimeIntervalType.NotSet; + + // Paint mode + internal bool paintMode = false; + + // Axis type (X, Y, X2, Y2) + internal AxisName axisType = AxisName.X; + + // Automatic maximum value (from data point values). + private bool _autoMaximum = true; + + // Automatic minimum value (from data point values). + private bool _autoMinimum = true; + + /// + /// Axis position: Left, Right, Top Bottom + /// + private AxisPosition _axisPosition = AxisPosition.Left; + + /// + /// Opposite Axis for this Axis. Necessary for Crossing. + /// + internal Axis oppositeAxis = null; + + // Axis data scaleView + private AxisScaleView _scaleView = null; + +#if Microsoft_CONTROL + + // Axis scroll bar class + internal AxisScrollBar scrollBar = null; + +#endif // Microsoft_CONTROL + + // For scater chart X values could be rounded. + internal bool roundedXValues = false; + + // If Axis is logarithmic value shoud be converted to + // linear only once. + internal bool logarithmicConvertedToLinear = false; + + // IsLogarithmic minimum value + internal double logarithmicMinimum; + + // IsLogarithmic maximum value + internal double logarithmicMaximum; + + // Correction of interval because of + // 3D Rotation and perspective + internal double interval3DCorrection = Double.NaN; + + // Axis coordinate convertion optimization fields + internal bool optimizedGetPosition = false; + internal double paintViewMax = 0.0; + internal double paintViewMin = 0.0; + internal double paintRange = 0.0; + internal double valueMultiplier = 0.0; + internal RectangleF paintAreaPosition = RectangleF.Empty; + internal double paintAreaPositionBottom = 0.0; + internal double paintAreaPositionRight = 0.0; + internal double paintChartAreaSize = 0.0; + + + + // Determines how number of intervals automatically calculated + private IntervalAutoMode _intervalAutoMode = IntervalAutoMode.FixedCount; + + // True if scale segments are used + internal bool scaleSegmentsUsed = false; + + + + // Preffered number of intervals on the axis + internal int prefferedNumberofIntervals = 5; + + private Stack _intervalsStore = new Stack(); + + #endregion + + #region Axis scale properties + + /// + /// Axis position + /// + [ + Bindable(true), + DefaultValue(AxisPosition.Left), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeReverse"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + virtual internal AxisPosition AxisPosition + { + get + { + return this._axisPosition; + } + set + { + this._axisPosition = value; +#if SUBAXES + // Update axis position of the sub axis + if( !((Axis)this).IsSubAxis ) + { + foreach(SubAxis subAxis in ((Axis)this).SubAxes) + { + subAxis._axisPosition = value; + } + } + +#endif // SUBAXES + this.Invalidate(); + } + } + + + + /// + /// Gets or sets a flag which indicates whether the number of intervals + /// on the axis is fixed or varies with the axis size. + /// + [ + SRCategory("CategoryAttributeInterval"), + DefaultValue(IntervalAutoMode.FixedCount), + SRDescription("DescriptionAttributeIntervalAutoMode"), + ] + public IntervalAutoMode IntervalAutoMode + { + get + { + return this._intervalAutoMode; + } + set + { + this._intervalAutoMode = value; + this.Invalidate(); + } + } + + + + /// + /// Gets or sets a flag which indicates whether the axis is reversed. + /// If set to reversed, the values on the axis are in reversed sort order + /// and the direction of values on the axis is flipped. + /// + [ + SRCategory("CategoryAttributeScale"), + Bindable(true), + DefaultValue(false), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeReverse"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsReversed + { + get + { + return isReversed; + } + set + { + isReversed = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a flag which indicates whether the minimum value + /// of the axis will be automatically set to zero if all data point + /// values are positive. If there are negative data point values, + /// the minimum value of the data points will be used. + /// + [ + SRCategory("CategoryAttributeScale"), + Bindable(true), + DefaultValue(true), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeStartFromZero3"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsStartedFromZero + { + get + { + return isStartedFromZero; + } + set + { + isStartedFromZero = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a flag to add a margin to the axis. + /// If true, a space is added between the first/last data + /// point and the border of chart area. + /// + [ + SRCategory("CategoryAttributeScale"), + Bindable(true), + DefaultValue(true), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeMargin"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsMarginVisible + { + get + { + if( margin > 0 ) + return true; + else + return false; + } + set + { + if( value == true ) + margin = 100; + else + margin = 0; + + this.Invalidate(); + } + } + + /// + /// Date and time interval type. + /// + [ + SRCategory("CategoryAttributeScale"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeInternalIntervalType"), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + internal DateTimeIntervalType InternalIntervalType + { + get + { + return _internalIntervalType; + } + set + { + // Set intervals for labels, grids and tick marks. ( Auto interval type ) + if( tempMajorGridInterval <= 0.0 || + (double.IsNaN(tempMajorGridInterval) && ((Axis)this).Interval <= 0.0) ) + { + majorGrid.intervalType = value; + } + + if( this.tempMajorTickMarkInterval <= 0.0 || + (double.IsNaN(tempMajorTickMarkInterval) && ((Axis)this).Interval <= 0.0) ) + { + majorTickMark.intervalType = value; + } + + if( this.tempLabelInterval <= 0.0 || + (double.IsNaN(tempLabelInterval) && ((Axis)this).Interval <= 0.0) ) + { + labelStyle.intervalType = value; + } + + _internalIntervalType = value; + + this.Invalidate(); + } + } + + /// + /// Sets auto interval values to grids, tick marks + /// and labels + /// + internal double SetInterval + { + set + { + if( tempMajorGridInterval <= 0.0 || + (double.IsNaN(tempMajorGridInterval) && ((Axis)this).Interval <= 0.0) ) + { + majorGrid.interval = value; + } + + if( tempMajorTickMarkInterval <= 0.0 || + (double.IsNaN(tempMajorTickMarkInterval) && ((Axis)this).Interval <= 0.0) ) + { + majorTickMark.interval = value; + } + + if( tempLabelInterval <= 0.0 || + (double.IsNaN(tempLabelInterval) && ((Axis)this).Interval <= 0.0) ) + { + labelStyle.interval = value; + } + + this.Invalidate(); + } + } + + /// + /// Sets auto interval values to grids, tick marks + /// and labels + /// + internal void SetIntervalAndType(double newInterval, DateTimeIntervalType newIntervalType) + { + if( tempMajorGridInterval <= 0.0 || + (double.IsNaN(tempMajorGridInterval) && ((Axis)this).Interval <= 0.0) ) + { + majorGrid.interval = newInterval; + majorGrid.intervalType = newIntervalType; + } + + if( tempMajorTickMarkInterval <= 0.0 || + (double.IsNaN(tempMajorTickMarkInterval) && ((Axis)this).Interval <= 0.0) ) + { + majorTickMark.interval = newInterval; + majorTickMark.intervalType = newIntervalType; + } + + if( tempLabelInterval <= 0.0 || + (double.IsNaN(tempLabelInterval) && ((Axis)this).Interval <= 0.0) ) + { + labelStyle.interval = newInterval; + labelStyle.intervalType = newIntervalType; + } + + this.Invalidate(); + } + + + /// + /// Gets or sets the maximum axis value. + /// + [ + + SRCategory("CategoryAttributeScale"), + Bindable(true), + DefaultValue(Double.NaN), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeMaximum"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + TypeConverter(typeof(AxisMinMaxAutoValueConverter)) + ] + public double Maximum + { + get + { + // Get maximum + if (_isLogarithmic && logarithmicConvertedToLinear && !Double.IsNaN(maximum)) + return logarithmicMaximum; + else + return maximum; + } + set + { + // Split a value to maximum and auto maximum + if( Double.IsNaN(value) ) + { + _autoMaximum = true; + maximum = Double.NaN; + } + else + { + // Set maximum + maximum = value; + + // Set non linearized Maximum for logarithmic scale + logarithmicMaximum = value; + + _autoMaximum = false; + } + + // Reset original property value fields + ((Axis)this).tempMaximum = maximum; + + // This line is added because of Save ScaleView State August 29, 2003 + // in Web Forms. This place could cause problems with Reset Auto Values. + ((Axis)this).tempAutoMaximum = _autoMaximum; + + this.Invalidate(); + } + } + + /// + /// Gets or sets the minimum axis value + /// + [ + + SRCategory("CategoryAttributeScale"), + Bindable(true), + DefaultValue(Double.NaN), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeMinimum"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + TypeConverter(typeof(AxisMinMaxAutoValueConverter)) + ] + public double Minimum + { + get + { + // Get minimum + if (_isLogarithmic && logarithmicConvertedToLinear && !Double.IsNaN(maximum)) + return logarithmicMinimum; + else + return minimum; + } + set + { + // Split a value to minimum and auto minimum + if( Double.IsNaN(value) ) + { + _autoMinimum = true; + minimum = Double.NaN; + } + else + { + // Set maximum + minimum = value; + _autoMinimum = false; + + // Set non linearized Minimum for logarithmic scale + logarithmicMinimum = value; + } + + // Reset original property value fields + ((Axis)this).tempMinimum = minimum; + + // This line is added because of Save ScaleView State August 29, 2003 + // in Web Forms. This place could cause problems with Reset Auto Values. + ((Axis)this).tempAutoMinimum = _autoMinimum; + + this.Invalidate(); + } + } + + /// + /// Gets or sets the point where axis is crossed by another axis. + /// + [ + SRCategory("CategoryAttributeScale"), + Bindable(true), + DefaultValue(Double.NaN), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeCrossing"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + TypeConverter(typeof(AxisCrossingValueConverter)) + ] + virtual public double Crossing + { + get + { + if( paintMode ) + if (_isLogarithmic) + return Math.Pow( this.logarithmBase, GetCrossing() ); + else + return GetCrossing(); + else + return crossing; + } + set + { + crossing = value; + + // Reset original property value fields + ((Axis)this).tempCrossing = crossing; + + this.Invalidate(); + } + } + + + /// + /// Enables or disables the axis. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(typeof(AxisEnabled), "Auto"), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeEnabled7"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public AxisEnabled Enabled + { + get + { + // Take Enabled from two fields: enabled and auto enabled + if( autoEnabled ) + { + return AxisEnabled.Auto; + } + else if( enabled ) + { + return AxisEnabled.True; + } + else + { + return AxisEnabled.False; + } + } + set + { // Split Enabled to two fields: enabled and auto enabled + if( value == AxisEnabled.Auto ) + { + autoEnabled = true; + } + else if( value == AxisEnabled.True ) + { + enabled = true; + autoEnabled = false; + } + else + { + enabled = false; + autoEnabled = false; + } + + this.Invalidate(); + } + } + + /// + /// Gets or sets a flag which indicates whether the axis is logarithmic. + /// Zeros or negative data values are not allowed on logarithmic charts. + /// + [ + SRCategory("CategoryAttributeScale"), + Bindable(true), + DefaultValue(false), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeLogarithmic"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsLogarithmic + { + get + { + return _isLogarithmic; + } + set + { + _isLogarithmic = value; + this.Invalidate(); + } + } + + /// + /// Base of the logarithm used in logarithmic scale. + /// By default, this value is 10. + /// + [ + SRCategory("CategoryAttributeScale"), + Bindable(true), + DefaultValue(10.0), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeLogarithmBase"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public double LogarithmBase + { + get + { + return logarithmBase; + } + set + { + if( value < 2.0 ) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAxisScaleLogarithmBaseInvalid)); + } + + logarithmBase = value; + + this.Invalidate(); + } + } + + #endregion + + #region Axis Segments and Scale Breaks Properties + + + + // Field that stores Axis automatic scale breaks style. + internal AxisScaleBreakStyle axisScaleBreakStyle = null; + + /// + /// Gets or sets the style of scale breaks. + /// + [ + SRCategory("CategoryAttributeScale"), + SRDescription("DescriptionAttributeScaleBreakStyle"), + TypeConverter(typeof(NoNameExpandableObjectConverter)), + NotifyParentPropertyAttribute(true), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + ] + virtual public AxisScaleBreakStyle ScaleBreakStyle + { + get + { + return this.axisScaleBreakStyle; + } + set + { + this.axisScaleBreakStyle = value; + this.axisScaleBreakStyle.axis = (Axis)this; + //this.Invalidate(); + } + } + + // Field that stores axis scale segments + internal AxisScaleSegmentCollection scaleSegments = null; + + /// + /// Axis scale segment collection. + /// + [ + SRCategory("CategoryAttributeScale"), + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never), + SRDescription("DescriptionAttributeAxisScaleSegmentCollection_AxisScaleSegmentCollection"), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base) + ] + internal AxisScaleSegmentCollection ScaleSegments + { + get + { + return this.scaleSegments; + } + } + + #endregion // Axis Segments and Scale Breaks Properties + + #region Axis data scaleView properies and methods + + /// + /// Gets or sets the scale view settings of the axis. + /// + [ + SRCategory("CategoryAttributeDataView"), + Bindable(true), + SRDescription("DescriptionAttributeView"), + +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] + public AxisScaleView ScaleView + { + get + { + return _scaleView; + } + set + { + _scaleView = value; + _scaleView.axis = (Axis)this; + this.Invalidate(); + } + } + +#if Microsoft_CONTROL + + /// + /// Gets or sets the scroll bar settings of the axis. + /// + [ + SRCategory("CategoryAttributeDataView"), + Bindable(true), + SRDescription("DescriptionAttributeScrollBar"), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] + public AxisScrollBar ScrollBar + { + get + { + return scrollBar; + } + set + { + scrollBar = value; + scrollBar.axis = (Axis)this; + this.Invalidate(); + } + } + +#endif // Microsoft_CONTROL + + /// + /// Gets axis data scaleView minimum position. + /// + /// Axis data scaleView minimum position. + internal double ViewMinimum + { + get { return _scaleView.ViewMinimum; } + } + + /// + /// Gets axis data scaleView minimum position. + /// + /// Axis data scaleView minimum position. + internal double ViewMaximum + { + get { return _scaleView.ViewMaximum; } + } + + /// + /// Gets automatic maximum value (from data point values). + /// + internal bool AutoMaximum + { + get { return _autoMaximum; } + } + + /// + /// Gets automatic minimum value (from data point values). + /// + internal bool AutoMinimum + { + get { return _autoMinimum; } + } + + #endregion + + #region Axis position converters methos + + /// + /// This function converts axis value to relative position (0-100%). + /// If an axis has a logarithmic scale, the value is converted to a linear scale. + /// + /// Value from axis. + /// Relative position (0-100%). + public double GetPosition( double axisValue ) + { + // Adjust for the IsLogarithmic axis + if (_isLogarithmic && axisValue != 0.0) + { + axisValue = Math.Log( axisValue, this.logarithmBase ); + } + + // Get linear position + return GetLinearPosition(axisValue); + } + + /// + /// This function converts an axis value to relative position (0-100%). + /// If an axis has a logarithmic scale, the value is converted to a linear scale. + /// + /// Axis value. + /// Relative position (0-100%). + public double ValueToPosition( double axisValue ) + { + return GetPosition( axisValue ); + } + + /// + /// This function converts an axis value to a pixel position. + /// If an axis has a logarithmic scale, the value is converted to a linear scale. + /// + /// Value from axis. + /// Pixel position. + public double ValueToPixelPosition( double axisValue ) + { + // Get relative value + double val = ValueToPosition(axisValue); + + // Convert it to pixels + if( AxisPosition == AxisPosition.Top || AxisPosition == AxisPosition.Bottom ) + { + val *= (this.Common.ChartPicture.Width - 1) / 100F; + } + else + { + val *= (this.Common.ChartPicture.Height - 1) / 100F; + } + + return val; + } + + /// + /// This function converts a relative position to an axis value. + /// If an axis has a logarithmic scale, the value is converted to a linear scale. + /// + /// Relative position (0-100%). + /// Axis value. + public double PositionToValue( double position ) + { + return PositionToValue(position, true); + } + + /// + /// This function converts a relative position to an axis value. + /// If an axis has a logarithmic scale, the value is converted to a linear scale. + /// + /// Relative position (0-100%). + /// Indicates if input value range should be checked. + /// Axis value. + internal double PositionToValue( double position, bool validateInput) + { + // Check parameters + if(validateInput && + (position < 0 || position > 100) ) + { + throw (new ArgumentException(SR.ExceptionAxisScalePositionInvalid, "position")); + } + + // Check if plot area position was already calculated + if(PlotAreaPosition == null) + { + throw (new InvalidOperationException(SR.ExceptionAxisScalePositionToValueCallFailed)); + } + + // Convert chart picture position to plotting position + if( AxisPosition == AxisPosition.Top || AxisPosition == AxisPosition.Bottom ) + position = position - PlotAreaPosition.X; + else + position = PlotAreaPosition.Bottom - position; + + + // The Chart area size + double ChartArea; + if( AxisPosition == AxisPosition.Top || AxisPosition == AxisPosition.Bottom ) + ChartArea = PlotAreaPosition.Width; + else + ChartArea = PlotAreaPosition.Height; + + + // The Real range as double + double viewMax = ViewMaximum; + double viewMin = ViewMinimum; + double range = viewMax - viewMin; + + // Avoid division by zero + double axisValue = 0; + if( range != 0 ) + { + // Find axis value from position + axisValue = range / ChartArea * position; + } + + // Corrected axis value for reversed + if( isReversed ) + axisValue = viewMax - axisValue; + else + axisValue = viewMin + axisValue; + + return axisValue; + } + + /// + /// This function converts a pixel position to an axis value. + /// If an axis has a logarithmic scale, the value is converted to a linear scale. + /// + /// Pixel position. + /// Axis value. + public double PixelPositionToValue( double position ) + { + // Convert it to pixels + double val = position; + if( AxisPosition == AxisPosition.Top || AxisPosition == AxisPosition.Bottom ) + { + val *= 100F / ((float)(this.Common.ChartPicture.Width - 1)); + } + else + { + val *= 100F / ((float)(this.Common.ChartPicture.Height - 1)); + } + + // Get from relative position + return PositionToValue(val); + } + + #endregion + + #region Axis scale methods + + /// + /// Sets axis position. Axis position depends + /// on crossing and reversed value. + /// + internal void SetAxisPosition() + { + // Change position of the axis + if( GetOppositeAxis().isReversed ) + { + if( AxisPosition == AxisPosition.Left ) + AxisPosition = AxisPosition.Right; + else if( AxisPosition == AxisPosition.Right ) + AxisPosition = AxisPosition.Left; + else if( AxisPosition == AxisPosition.Top ) + AxisPosition = AxisPosition.Bottom; + else if( AxisPosition == AxisPosition.Bottom ) + AxisPosition = AxisPosition.Top; + } + } + + /// + /// Sets temporary offset value. + /// + internal void SetTempAxisOffset( ) + { + if (ChartArea.Series.Count == 0) + { + return; + } + // Conditions when this code changes margin size: Column chart, + // margin is turned off, Interval offset is not used for + // gridlines, tick marks and labels. + Series ser = ChartArea.GetFirstSeries(); + if( ( ser.ChartType == SeriesChartType.Column || + ser.ChartType == SeriesChartType.StackedColumn || + ser.ChartType == SeriesChartType.StackedColumn100 || + ser.ChartType == SeriesChartType.Bar || + + ser.ChartType == SeriesChartType.RangeBar || + ser.ChartType == SeriesChartType.RangeColumn || + + ser.ChartType == SeriesChartType.StackedBar || + ser.ChartType == SeriesChartType.StackedBar100 ) && + margin != 100.0 && !offsetTempSet && + this._autoMinimum) + { + + // Find offset correction for Column chart margin. + double offset; + marginTemp = margin; + + // Find point width + // Check if series provide custom value for point width + double pointWidthSize; + string strWidth = ser[CustomPropertyName.PointWidth]; + if(strWidth != null) + { + pointWidthSize = CommonElements.ParseDouble(strWidth); + } + else + { + pointWidthSize = 0.8; + } + + margin = ( pointWidthSize / 2 ) * 100; + offset = ( margin ) / 100; + double contraOffset = ( 100 - margin ) / 100; + + if (this._intervalsStore.Count == 0) + { + this._intervalsStore.Push(this.labelStyle.intervalOffset); + this._intervalsStore.Push(this.majorGrid.intervalOffset); + this._intervalsStore.Push(this.majorTickMark.intervalOffset); + this._intervalsStore.Push(this.minorGrid.intervalOffset); + this._intervalsStore.Push(this.minorTickMark.intervalOffset); + } + + this.labelStyle.intervalOffset = Double.IsNaN(this.labelStyle.intervalOffset) ? offset : this.labelStyle.intervalOffset + offset; + this.majorGrid.intervalOffset = Double.IsNaN(this.majorGrid.intervalOffset) ? offset : this.majorGrid.intervalOffset + offset; + this.majorTickMark.intervalOffset = Double.IsNaN(this.majorTickMark.intervalOffset) ? offset : this.majorTickMark.intervalOffset + offset; + this.minorGrid.intervalOffset = Double.IsNaN(this.minorGrid.intervalOffset) ? offset : this.minorGrid.intervalOffset + offset; + this.minorTickMark.intervalOffset = Double.IsNaN(this.minorTickMark.intervalOffset) ? offset : this.minorTickMark.intervalOffset + offset; + + foreach( StripLine strip in ((Axis)(this)).StripLines ) + { + _stripLineOffsets.Add( strip.IntervalOffset ); + strip.IntervalOffset -= contraOffset; + } + offsetTempSet = true; + } + } + + /// + /// Resets temporary offset value. + /// + internal void ResetTempAxisOffset( ) + { + if( this.offsetTempSet ) + { + System.Diagnostics.Debug.Assert(this._intervalsStore.Count == 5, "Fail in interval store count"); + + this.minorTickMark.intervalOffset = this._intervalsStore.Pop(); + this.minorGrid.intervalOffset = this._intervalsStore.Pop(); + this.majorTickMark.intervalOffset = this._intervalsStore.Pop(); + this.majorGrid.intervalOffset = this._intervalsStore.Pop(); + this.labelStyle.intervalOffset = this._intervalsStore.Pop(); + int index = 0; + foreach( StripLine strip in ((Axis)(this)).StripLines ) + { + if( _stripLineOffsets.Count > index ) + { + strip.IntervalOffset = (double)_stripLineOffsets[index]; + } + index++; + } + _stripLineOffsets.Clear(); + offsetTempSet = false; + margin = marginTemp; + } + } + + /// + /// This function will create auto maximum and minimum values + /// using the interval. This function will make a gap between + /// data points and border of the chart area. + /// + /// Interval + /// True if minimum scale value should start from zero. + /// Maximum is auto + /// Minimum is auto + /// Minimum value + /// Maximum value + /// Interval + internal double RoundedValues( + double inter, + bool shouldStartFromZero, + bool autoMax, + bool autoMin, + ref double min, + ref double max ) + { + // For X Axes + if( axisType == AxisName.X || axisType == AxisName.X2 ) + { + if( margin == 0.0 && !this.roundedXValues ) + { + return inter; + } + } + else // For Y Axes + { + // Avoid dividing with 0. There is no gap. + if( margin == 0.0 ) + { + return inter; + } + } + + if( autoMin ) + { // Set minimum value + if( min < 0.0 || ( !shouldStartFromZero && !ChartArea.stacked ) ) + { + min = (double)( ((decimal)Math.Ceiling( min / inter ) - 1m ) * (decimal)inter ); + } + else + { + min = 0.0; + } + } + if( autoMax ) + {// Set maximum value + if( max <= 0.0 && shouldStartFromZero ) + { + max = 0.0; + } + else + { + max = (double)( ((decimal)Math.Floor( max / inter ) + 1m ) * (decimal)inter ); + } + } + return inter; + } + + + /// + /// Recalculates an intelligent interval from real interval. + /// + /// Real interval. + /// Inteligent interval. + internal double CalcInterval( double diff ) + { + // If the interval is zero return error + if( diff == 0.0 ) + { + throw (new ArgumentOutOfRangeException("diff", SR.ExceptionAxisScaleIntervalIsZero)); + } + + // If the real interval is > 1.0 + double step = -1; + double temp = diff; + while( temp > 1.0 ) + { + step ++; + temp = temp / 10.0; + if( step > 1000 ) + { + throw (new InvalidOperationException(SR.ExceptionAxisScaleMinimumMaximumInvalid)); + } + } + + + // If the real interval is < 1.0 + temp = diff; + if( temp < 1.0 ) + { + step = 0; + } + + while( temp < 1.0 ) + { + step --; + temp = temp * 10.0; + if( step < -1000 ) + { + throw (new InvalidOperationException(SR.ExceptionAxisScaleMinimumMaximumInvalid)); + } + } + + double power = (this.IsLogarithmic) ? this.logarithmBase : 10.0; + double tempDiff = diff / Math.Pow( power, step ); + + if( tempDiff < 3 ) + tempDiff = 2; + else if( tempDiff < 7 ) + tempDiff = 5; + else + tempDiff = 10; + + // Make a correction of the real interval + return tempDiff * Math.Pow( power, step ); + } + + /// + /// Recalculates a intelligent interval from real interval + /// obtained from maximum and minimum values + /// + /// Minimum + /// Maximum + /// Auto Interval + private double CalcInterval( double min, double max ) + { + // Approximated interval value + return CalcInterval( ( max - min ) / 5 ); + } + + + /// + /// Recalculates a intelligent interval from real interval + /// obtained from maximum, minimum and date type if + /// the values is date-time value. + /// + /// Minimum value. + /// Maximum value. + /// True if date. + /// Date time interval type. + /// AxisName of date-time values. + /// Auto Interval. + internal double CalcInterval( + double min, + double max, + bool date, + out DateTimeIntervalType type, + ChartValueType valuesType) + { + // AxisName is date time + if( date ) + { + DateTime dateTimeMin = DateTime.FromOADate( min ); + DateTime dateTimeMax = DateTime.FromOADate( max ); + TimeSpan timeSpan = dateTimeMax.Subtract( dateTimeMin ); + + // Minutes + double inter = timeSpan.TotalMinutes; + + // For Range less than 60 seconds interval is 5 sec + if( inter <= 1.0 && valuesType != ChartValueType.Date) + { + // Milli Seconds + double mlSeconds = timeSpan.TotalMilliseconds; + if(mlSeconds <= 10) + { + type = DateTimeIntervalType.Milliseconds; + return 1; + } + if(mlSeconds <= 50) + { + type = DateTimeIntervalType.Milliseconds; + return 4; + } + if(mlSeconds <= 200) + { + type = DateTimeIntervalType.Milliseconds; + return 20; + } + if(mlSeconds <= 500) + { + type = DateTimeIntervalType.Milliseconds; + return 50; + } + + // Seconds + double seconds = timeSpan.TotalSeconds; + + if(seconds <= 7) + { + type = DateTimeIntervalType.Seconds; + return 1; + } + else if(seconds <= 15) + { + type = DateTimeIntervalType.Seconds; + return 2; + } + else if(seconds <= 30) + { + type = DateTimeIntervalType.Seconds; + return 5; + } + else if(seconds <= 60) + { + type = DateTimeIntervalType.Seconds; + return 10; + } + + }// For Range less than 120 seconds interval is 10 sec + else if( inter <= 2.0 && valuesType != ChartValueType.Date) + { + type = DateTimeIntervalType.Seconds; + return 20; + }// For Range less than 180 seconds interval is 30 sec + else if( inter <= 3.0 && valuesType != ChartValueType.Date) + { + type = DateTimeIntervalType.Seconds; + return 30; + } + + // For Range less than 10 minutes interval is 1 min + else if( inter <= 10 && valuesType != ChartValueType.Date) + { + type = DateTimeIntervalType.Minutes; + return 1; + } + // For Range less than 20 minutes interval is 1 min + else if( inter <= 20 && valuesType != ChartValueType.Date) + { + type = DateTimeIntervalType.Minutes; + return 2; + }// For Range less than 60 minutes interval is 5 min + else if( inter <= 60 && valuesType != ChartValueType.Date) + { + type = DateTimeIntervalType.Minutes; + return 5; + }// For Range less than 120 minutes interval is 10 min + else if( inter <= 120 && valuesType != ChartValueType.Date) + { + type = DateTimeIntervalType.Minutes; + return 10; + }// For Range less than 180 minutes interval is 30 min + else if( inter <= 180 && valuesType != ChartValueType.Date) + { + type = DateTimeIntervalType.Minutes; + return 30; + } + // For Range less than 12 hours interval is 1 hour + else if( inter <= 60*12 && valuesType != ChartValueType.Date) + { + type = DateTimeIntervalType.Hours; + return 1; + } + // For Range less than 24 hours interval is 4 hour + else if( inter <= 60*24 && valuesType != ChartValueType.Date) + { + type = DateTimeIntervalType.Hours; + return 4; + } + // For Range less than 2 days interval is 6 hour + else if( inter <= 60*24*2 && valuesType != ChartValueType.Date) + { + type = DateTimeIntervalType.Hours; + return 6; + } + // For Range less than 3 days interval is 12 hour + else if( inter <= 60*24*3 && valuesType != ChartValueType.Date) + { + type = DateTimeIntervalType.Hours; + return 12; + } + + // For Range less than 10 days interval is 1 day + else if( inter <= 60*24*10 ) + { + type = DateTimeIntervalType.Days; + return 1; + } + // For Range less than 20 days interval is 2 day + else if( inter <= 60*24*20 ) + { + type = DateTimeIntervalType.Days; + return 2; + } + // For Range less than 30 days interval is 3 day + else if( inter <= 60*24*30 ) + { + type = DateTimeIntervalType.Days; + return 3; + } + // For Range less than 2 months interval is 1 week + else if( inter <= 60*24*30.5*2 ) + { + type = DateTimeIntervalType.Weeks; + return 1; + } + // For Range less than 5 months interval is 2weeks + else if( inter <= 60*24*30.5*5 ) + { + type = DateTimeIntervalType.Weeks; + return 2; + } + // For Range less than 12 months interval is 1 month + else if( inter <= 60*24*30.5*12 ) + { + type = DateTimeIntervalType.Months; + return 1; + } + // For Range less than 24 months interval is 3 month + else if( inter <= 60*24*30.5*24 ) + { + type = DateTimeIntervalType.Months; + return 3; + } + // For Range less than 48 months interval is 6 months + else if( inter <= 60*24*30.5*48 ) + { + type = DateTimeIntervalType.Months; + return 6; + } + // For Range more than 48 months interval is year + else if( inter >= 60*24*30.5*48 ) + { + type = DateTimeIntervalType.Years; + return CalcYearInterval( inter / 60 / 24 / 365 ); + } + } + + // Else numbers + type = DateTimeIntervalType.Number; + return CalcInterval( min, max ); + + } + + /// + /// Recalculates a intelligent interval for years + /// + /// Number of years + /// Interval in years + private double CalcYearInterval( double years ) + { + // If the interval is zero return error + if( years <= 1.0 ) + { + throw (new ArgumentOutOfRangeException("years", SR.ExceptionAxisScaleIntervalIsLessThen1Year)); + } + + if( years < 5 ) + return 1; + else if( years < 10 ) + return 2; + + // Make a correction of the interval + return Math.Floor( years / 5 ); + } + + /// + /// This method returns the number of units + /// between min and max. + /// + /// Minimum. + /// Maximum. + /// Date type. + /// Number of units. + private int GetNumOfUnits( double min, double max, DateTimeIntervalType type ) + { + double current = ChartHelper.GetIntervalSize(min, 1, type); + return (int)Math.Round((max - min) / current); + } + + /// + /// This method checks if value type is date-time. + /// + /// Date-time type or Auto. + internal ChartValueType GetDateTimeType() + { + List list = null; + + ChartValueType dateType = ChartValueType.Auto; + + // Check if Value type is date from first series in the axis + if( axisType == AxisName.X ) + { + // Check X axes type + list = ChartArea.GetXAxesSeries( AxisType.Primary, ((Axis)this).SubAxisName ); + if( list.Count == 0 ) + { + return ChartValueType.Auto; + } + + if( Common.DataManager.Series[list[0]].IsXValueDateTime() ) + { + dateType = Common.DataManager.Series[list[0]].XValueType; + } + } + else if( axisType == AxisName.X2 ) + { + // Check X2 axes type + list = ChartArea.GetXAxesSeries( AxisType.Secondary, ((Axis)this).SubAxisName ); + if( list.Count == 0 ) + { + return ChartValueType.Auto; + } + + if( Common.DataManager.Series[list[0]].IsXValueDateTime() ) + { + dateType = Common.DataManager.Series[list[0]].XValueType; + } + } + else if( axisType == AxisName.Y ) + { + // Check Y axes type + list = ChartArea.GetYAxesSeries( AxisType.Primary, ((Axis)this).SubAxisName ); + if( list.Count == 0 ) + { + return ChartValueType.Auto; + } + + if( Common.DataManager.Series[list[0]].IsYValueDateTime() ) + { + dateType = Common.DataManager.Series[list[0]].YValueType; + } + } + else if( axisType == AxisName.Y2 ) + { + // Check Y2 axes type + list = ChartArea.GetYAxesSeries( AxisType.Secondary, ((Axis)this).SubAxisName ); + if( list.Count == 0 ) + { + return ChartValueType.Auto; + } + + if( Common.DataManager.Series[list[0]].IsYValueDateTime() ) + { + dateType = Common.DataManager.Series[list[0]].YValueType; + } + } + + return dateType; + } + + /// + /// This method removes "Auto", "min", "max" from crossing + /// value and creates a double value. + /// + /// Crossing value + private double GetCrossing() + { + if( Double.IsNaN(crossing) ) + { + if( Common.ChartTypeRegistry.GetChartType( (string)ChartArea.ChartTypes[0] ).ZeroCrossing ) + { + if( ViewMinimum > 0.0 ) + { + return ViewMinimum; + } + else if( ViewMaximum < 0.0 ) + { + return ViewMaximum; + } + else + { + return 0.0; + } + } + else + { + return ViewMinimum; + } + } + else if( crossing == Double.MaxValue ) + { + return ViewMaximum; + } + else if( crossing == Double.MinValue ) + { + return ViewMinimum; + } + + return crossing; + } + + /// + /// Set auto minimum number. The minimum number + /// which was sent to this function will be used to + /// estimate a rounded minimum. + /// + /// This value is a recommendation for the minimum value. + internal void SetAutoMinimum(double min) + { + // Set the minimum + if( _autoMinimum ) + { + minimum = min; + } + } + + /// + /// Set auto maximum number. The maximum number + /// which was sent to this function will be used to + /// estimate a rounded maximum. + /// + /// This value is a recommendation for the maximum value. + internal void SetAutoMaximum(double max) + { + // Set the maximum + if( _autoMaximum ) + { + maximum = max; + } + } + + /// + /// Find opposite axis of this axis. What is opposite + /// axis depend on first series in chart area and primary + /// and secondary X and Y axes for the first series. + /// + /// Opposite axis + internal Axis GetOppositeAxis() + { + // Oppoiste axis found + if (oppositeAxis != null) + { + return oppositeAxis; + } + + List list; + + switch( axisType ) + { + // X Axis + case AxisName.X: + list = ChartArea.GetXAxesSeries( AxisType.Primary, ((Axis)this).SubAxisName ); + // There aren't data series + if( list.Count == 0 ) + oppositeAxis = ChartArea.AxisY; + // Take opposite axis from the first series from chart area + else if( Common.DataManager.Series[list[0]].YAxisType == AxisType.Primary ) + oppositeAxis = ChartArea.AxisY.GetSubAxis(Common.DataManager.Series[list[0]].YSubAxisName); + else + oppositeAxis = ChartArea.AxisY2.GetSubAxis(Common.DataManager.Series[list[0]].YSubAxisName); + break; + // X2 Axis + case AxisName.X2: + list = ChartArea.GetXAxesSeries( AxisType.Secondary, ((Axis)this).SubAxisName ); + // There aren't data series + if( list.Count == 0 ) + oppositeAxis = ChartArea.AxisY2; + // Take opposite axis from the first series from chart area + else if( Common.DataManager.Series[list[0]].YAxisType == AxisType.Primary) + oppositeAxis = ChartArea.AxisY.GetSubAxis(Common.DataManager.Series[list[0]].YSubAxisName); + else + oppositeAxis = ChartArea.AxisY2.GetSubAxis(Common.DataManager.Series[list[0]].YSubAxisName); + break; + // Y Axis + case AxisName.Y: + list = ChartArea.GetYAxesSeries( AxisType.Primary, ((Axis)this).SubAxisName ); + // There aren't data series + if( list.Count == 0 ) + oppositeAxis = ChartArea.AxisX; + // Take opposite axis from the first series from chart area + else if( Common.DataManager.Series[list[0]].XAxisType == AxisType.Primary ) + oppositeAxis = ChartArea.AxisX.GetSubAxis(Common.DataManager.Series[list[0]].XSubAxisName); + else + oppositeAxis = ChartArea.AxisX2.GetSubAxis(Common.DataManager.Series[list[0]].XSubAxisName); + break; + // Y2 Axis + case AxisName.Y2: + list = ChartArea.GetYAxesSeries( AxisType.Secondary, ((Axis)this).SubAxisName ); + // There aren't data series + if( list.Count == 0 ) + oppositeAxis = ChartArea.AxisX2; + // Take opposite axis from the first series from chart area + else if( Common.DataManager.Series[list[0]].XAxisType == AxisType.Primary ) + oppositeAxis = ChartArea.AxisX.GetSubAxis(Common.DataManager.Series[list[0]].XSubAxisName); + else + oppositeAxis = ChartArea.AxisX2.GetSubAxis(Common.DataManager.Series[list[0]].XSubAxisName); + break; + } + return oppositeAxis; + } + + /// + /// This function converts Values from Axes to + /// linear relative positions. + /// + /// Value from axis. + /// Relative position. + internal double GetLinearPosition( double axisValue ) + { + bool circularArea = (ChartArea == null || !ChartArea.chartAreaIsCurcular) ? + false : true; + + // Check if some value calculation is optimized + if(!this.optimizedGetPosition) + { + paintViewMax = ViewMaximum; + paintViewMin = ViewMinimum; + paintRange = paintViewMax - paintViewMin; + paintAreaPosition = PlotAreaPosition.ToRectangleF(); + + // Update position for circular chart area + if(circularArea) + { + paintAreaPosition.Width /= 2.0f; + paintAreaPosition.Height /= 2.0f; + } + + paintAreaPositionBottom = paintAreaPosition.Y + paintAreaPosition.Height; + paintAreaPositionRight = paintAreaPosition.X + paintAreaPosition.Width; + + // The Chart area size + if( AxisPosition == AxisPosition.Top || AxisPosition == AxisPosition.Bottom ) + paintChartAreaSize = paintAreaPosition.Width; + else + paintChartAreaSize = paintAreaPosition.Height; + + valueMultiplier = 0.0; + if( paintRange != 0 ) + { + valueMultiplier = paintChartAreaSize / paintRange; + } + } + + // The Chart area pixel size + double position = valueMultiplier * ( axisValue - paintViewMin); + + + + // Check if axis scale segments are enabled + if(this.scaleSegmentsUsed) + { + AxisScaleSegment scaleSegment = this.ScaleSegments.FindScaleSegmentForAxisValue(axisValue); + if(scaleSegment != null) + { + double segmentSize = 0.0; + double segmentPosition = 0.0; + scaleSegment.GetScalePositionAndSize(paintChartAreaSize, out segmentPosition, out segmentSize); + + // Make sure value do not exceed max possible + if(!this.ScaleSegments.AllowOutOfScaleValues) + { + if(axisValue > scaleSegment.ScaleMaximum) + { + axisValue = scaleSegment.ScaleMaximum; + } + else if(axisValue < scaleSegment.ScaleMinimum) + { + axisValue = scaleSegment.ScaleMinimum; + } + } + + double segmentScaleRange = scaleSegment.ScaleMaximum - scaleSegment.ScaleMinimum; + + position = (segmentSize / segmentScaleRange) * (axisValue - scaleSegment.ScaleMinimum); + position += segmentPosition; + } + } + + + // Window position + // (Do Not use .Right or .Bottom methods below) - rounding issue! + if( isReversed ) + { + if( AxisPosition == AxisPosition.Top || AxisPosition == AxisPosition.Bottom ) + position = paintAreaPositionRight - position; + else + position = paintAreaPosition.Y + position; + } + else + { + if( AxisPosition == AxisPosition.Top || AxisPosition == AxisPosition.Bottom ) + position = paintAreaPosition.X + position; + else + position = paintAreaPositionBottom - position; + } + + return position; + } + + + #endregion + + #region Axis estimate axis methods + + /// + /// This function recalculates minimum maximum and interval. + /// The function uses current values for minimum and maximum to + /// find rounding values. If the value from the data source for the + /// maximum value is 376.5 this function will return 380. This function + /// also set interval type for date + /// + internal void EstimateAxis() + { + double axisInterval; + + // Check if veiw size specified without scaleView position + if(!Double.IsNaN(this.ScaleView.Size)) + { + // If size set only use axis minimum for scaleView position + if(Double.IsNaN(this.ScaleView.Position)) + { + this.ScaleView.Position = this.Minimum; + } + } + + // Zooming Mode + if( !Double.IsNaN(_scaleView.Position) && !Double.IsNaN(_scaleView.Size) ) + { + double viewMaximum = ViewMaximum; + double viewMinimum = ViewMinimum; + + // IsLogarithmic axes + if (this._isLogarithmic) + { + viewMaximum = Math.Pow( this.logarithmBase, viewMaximum ); + viewMinimum = Math.Pow( this.logarithmBase, viewMinimum ); + } + else + { + // Add rounding and gap for maximum and minimum + EstimateAxis( ref this.minimum, ref this.maximum, _autoMaximum, _autoMinimum ); + } + + // Find Interval for Zoom + axisInterval = EstimateAxis( ref viewMinimum, ref viewMaximum, true, true ); + } + else // No Zooming mode + { + // Estimate axis shoud be always called for non logarithmic axis + axisInterval = EstimateAxis( ref this.minimum, ref this.maximum, _autoMaximum, _autoMinimum ); + } + + // Set intervals for grids, tick marks and labels + if( axisInterval <= 0.0 ) + { + throw (new InvalidOperationException(SR.ExceptionAxisScaleAutoIntervalInvalid)); + } + else + { + // This code checks if all series in the chart area have “integer type” + // for specified axes, which means int, uint, long and ulong and rounds interval. +#if SUBAXES + if( ChartArea.SeriesIntegerType( this.axisType, ((Axis)this).SubAxisName ) ) +#else // SUBAXES + if ( ChartArea.SeriesIntegerType( this.axisType, string.Empty )) +#endif // SUBAXES + { + axisInterval = Math.Round( axisInterval ); + if( axisInterval == 0.0 ) + { + axisInterval = 1.0; + } + + // Round Minimum to floor value if type is integer + minimum = Math.Floor( minimum ); + } + + SetInterval = axisInterval; + } + } + + /// + /// This function recalculates minimum maximum and interval. + /// The function uses current values for minimum and maximum to + /// find rounding values. If the value from the data source for the + /// maximum value is 376.5 this function will return 380. This function + /// also set interval type for date + /// + /// Minimum + /// Maximum + /// Maximum value is Auto + /// Minimum value is Auto + /// Interval + internal double EstimateAxis( ref double minimumValue, ref double maximumValue, bool autoMaximum, bool autoMinimum ) + { + double axisInterval; + + // The axis minimum value is greater than the maximum value. + if( maximumValue < minimumValue ) + { + if(!this.Common.ChartPicture.SuppressExceptions) + { + throw (new InvalidOperationException(SR.ExceptionAxisScaleMinimumValueIsGreaterThenMaximumDataPoint)); + } + else + { + // Max axis scale should be always bigger + double tempValue = maximumValue; + maximumValue = minimumValue; + minimumValue = tempValue; + } + } + + // Take Value type + ChartValueType dateType = GetDateTimeType(); + + // Axis type is logarithmic + if (_isLogarithmic) + { + axisInterval = EstimateLogarithmicAxis( ref minimumValue, ref maximumValue, crossing, autoMaximum, autoMinimum ); + } + + // Axis type is date + else if( dateType != ChartValueType.Auto) + { + axisInterval = EstimateDateAxis( ref minimumValue, ref maximumValue, autoMaximum, autoMinimum, dateType ); + } + + // Axis type is number + else + { + axisInterval = EstimateNumberAxis( ref minimumValue, ref maximumValue, this.IsStartedFromZero, this.prefferedNumberofIntervals, autoMaximum, autoMinimum ); + } + + // Set intervals for grids, tick marks and labels + if( axisInterval <= 0.0 ) + { + throw (new InvalidOperationException(SR.ExceptionAxisScaleAutoIntervalInvalid)); + } + else + { + // Set interval for Grid lines Tick Marks and labels + SetInterval = axisInterval; + } + + return axisInterval; + + } + + /// + /// This function recalculates minimum maximum and interval for + /// logarithmic axis. The function uses current values for minimum and + /// maximum to find new rounding values. + /// + /// Current Minimum value + /// Current Maximum value + /// Crossing value + /// Maximum value is Auto + /// Minimum value is Auto + /// Interval + private double EstimateLogarithmicAxis( ref double minimumValue, ref double maximumValue, double crossingValue, bool autoMaximum, bool autoMinimum ) + { + double axisInterval; + + if( !logarithmicConvertedToLinear ) + { + // Remember values. Do not use POW function because of rounding. + this.logarithmicMinimum = this.minimum; + this.logarithmicMaximum = this.maximum; + } + + // For log axis margin always turn on. + margin = 100; + + // Supress zero and negative values with logarithmic axis exceptions + if(this.Common != null && this.Common.Chart != null && this.Common.Chart.chartPicture.SuppressExceptions) + { + if (minimumValue <= 0.0 ) + { + minimumValue = 1.0; + } + if (maximumValue <= 0.0 ) + { + maximumValue = 1.0; + } + if (crossingValue <= 0.0 && crossingValue != Double.MinValue ) + { + crossingValue = 1.0; + } + } + + // The logarithmic axes can not show negative values. + if( minimumValue <= 0.0 || maximumValue <= 0.0 || crossingValue <= 0.0 ) + { + if (minimumValue <= 0.0 ) + throw (new ArgumentOutOfRangeException("minimumValue", SR.ExceptionAxisScaleLogarithmicNegativeValues)); + if (maximumValue <= 0.0 ) + throw (new ArgumentOutOfRangeException("maximumValue", SR.ExceptionAxisScaleLogarithmicNegativeValues)); + } + + // Change crossing to linear scale + crossingValue = Math.Log( crossingValue, this.logarithmBase ); + + // Change minimum and maximum to linear scale + minimumValue = Math.Log( minimumValue, this.logarithmBase ); + maximumValue = Math.Log( maximumValue, this.logarithmBase ); + + logarithmicConvertedToLinear = true; + + // Find interval - Make approximately 5 grid lines and labels. + double diff = ( maximumValue - minimumValue ) / 5; + + // Make good interval for logarithmic scale + axisInterval = Math.Floor( diff ); + if( axisInterval == 0 ) axisInterval = 1; + + if( autoMinimum && autoMaximum ) + { + // The maximum and minimum rounding with interval + RoundedValues( axisInterval, this.IsStartedFromZero, autoMaximum, autoMinimum, ref minimumValue, ref maximumValue ); + } + + // Do not allow min/max values more than a hundred + if(ChartArea.hundredPercent) + { + if(autoMinimum) + { + if(minimumValue < 0) + minimumValue = 0; + } + + if(autoMaximum) + { + if(maximumValue > 2) + maximumValue = 2; + } + } + + // Set interval for Grid lines Tick Marks and labels + return axisInterval; + } + + /// + /// This function recalculates minimum maximum and interval for + /// Date axis. The function uses current values for minimum and + /// maximum to find new rounding values. + /// + /// Current Minimum value + /// Current Maximum value + /// Maximum value is Auto + /// Minimum value is Auto + /// AxisName of date-time values. + /// Interval + private double EstimateDateAxis( + ref double minimumValue, + ref double maximumValue, + bool autoMaximum, + bool autoMinimum, + ChartValueType valuesType) + { + double axisInterval; + + double min = minimumValue; + double max = maximumValue; + + // Find interval for this date type + axisInterval = CalcInterval(min, max, true, out _internalIntervalType, valuesType); + + + // For 3D Charts interval could be changed. After rotation + // projection of axis could be very small. + if( !double.IsNaN( this.interval3DCorrection ) && + ChartArea.Area3DStyle.Enable3D && + !ChartArea.chartAreaIsCurcular) + { + axisInterval = Math.Floor( axisInterval / this.interval3DCorrection ); + + this.interval3DCorrection = double.NaN; + } + + // Find number of units between minimum and maximum + int numberOfUnits = GetNumOfUnits( min, max, _internalIntervalType ); + + // Make a gap between max point and axis for Y axes + if( axisType == AxisName.Y || axisType == AxisName.Y2 ) + { + if (autoMinimum && minimumValue > ChartHelper.GetIntervalSize(min, axisInterval, _internalIntervalType)) + { + // Add gap to the minimum value from the series + // equal half of the interval + minimumValue += ChartHelper.GetIntervalSize( + min, + - (axisInterval / 2.0) * margin / 100, + _internalIntervalType, + null, + 0.0, + DateTimeIntervalType.Number, + false, + false); + + // Align minimum sacale value on the interval + minimumValue = ChartHelper.AlignIntervalStart( + minimumValue, + axisInterval * margin / 100, + _internalIntervalType); + } + + // Increase maximum if not zero. Make a space between chart type + // and the end of the chart area. + if( autoMaximum && max > 0 && margin != 0.0 ) + { + maximumValue = minimumValue + ChartHelper.GetIntervalSize( + minimumValue, + (double)((Math.Floor(numberOfUnits / axisInterval / margin * 100)+2) * axisInterval * margin / 100), + _internalIntervalType); + } + } + + InternalIntervalType = _internalIntervalType; + + // Set interval for Grid lines Tick Marks and labels + return axisInterval; + } + + /// + /// This function recalculates minimum maximum and interval for + /// number type axis. The function uses current values for minimum and + /// maximum to find new rounding values. + /// + /// Current Minimum value + /// Current Maximum value + /// Should start from zero flag. + /// Preferred number of intervals. Can be set to zero for dynamic mode. + /// Maximum value is Auto + /// Minimum value is Auto + /// Interval + internal double EstimateNumberAxis( + ref double minimumValue, + ref double maximumValue, + bool shouldStartFromZero, + int preferredNumberOfIntervals, + bool autoMaximum, + bool autoMinimum ) + { + double axisInterval; + double min = minimumValue; + double max = maximumValue; + double diff; + + if( !roundedXValues && ( axisType == AxisName.X || axisType == AxisName.X2 ) ) + { + diff = ChartArea.GetPointsInterval( false, 10 ); + if( diff == 0 || ( max - min ) / diff > 20 ) + { + diff = ( max - min ) / preferredNumberOfIntervals; + } + + } + else + { + diff = ( max - min ) / preferredNumberOfIntervals; + } + + // For 3D Charts interval could be changed. After rotation + // projection of axis could be very small. + if( !double.IsNaN( this.interval3DCorrection ) && + ChartArea.Area3DStyle.Enable3D && + !ChartArea.chartAreaIsCurcular) + { + diff = diff / this.interval3DCorrection; + + // Do not change minimum and maximum with 3D correction. + if( max - min < diff ) + { + diff = max - min; + } + + this.interval3DCorrection = double.NaN; + + if( diff != 0.0 ) + { + diff = CalcInterval( diff ); + } + } + + + if( autoMaximum || autoMinimum ) + { + if( diff == 0 ) + { + // Can not find interval. Minimum and maximum are same + + max = min + 1; + diff = 0.2; + axisInterval = 0.2; + } + else + { + axisInterval = CalcInterval( diff ); + } + } + else + { + axisInterval = diff; + } + + // Case when minimum or maximum is set and interval is > maximum. + // Reasons overflow exception. + if( ((Axis)this).interval != 0 && ((Axis)this).interval > axisInterval && minimumValue + ((Axis)this).interval > maximumValue ) + { + axisInterval = ((Axis)this).interval; + if( autoMaximum ) + { + maximumValue = minimumValue + axisInterval; + } + + if( autoMinimum ) + { + minimumValue = maximumValue - axisInterval; + } + } + + // The maximum and minimum rounding for Y Axes + if( axisType == AxisName.Y || axisType == AxisName.Y2 || ( roundedXValues && ( axisType == AxisName.X || axisType == AxisName.X2 ))) + { + // Start from zero for the 100% chart types + bool minIsZero = false; + bool maxIsZero = false; + if(ChartArea.hundredPercent) + { + minIsZero = (minimumValue == 0.0); + maxIsZero = (maximumValue == 0.0); + } + + // Round min/max values + RoundedValues( axisInterval, shouldStartFromZero, autoMaximum, autoMinimum, ref minimumValue, ref maximumValue ); + + // Do not allow min/max values more than a hundred + if(ChartArea.hundredPercent) + { + if(autoMinimum) + { + if(minimumValue < -100) + minimumValue = -100; + if(minIsZero) + minimumValue = 0; + } + + if(autoMaximum) + { + if(maximumValue > 100) + maximumValue = 100; + if(maxIsZero) + maximumValue = 0; + } + } + } + + // Set interval for Grid lines Tick Marks and labels + return axisInterval; + } + + #endregion + } +} + diff --git a/System.Web.DataVisualization/Common/General/AxisScaleBreaks.cs b/System.Web.DataVisualization/Common/General/AxisScaleBreaks.cs new file mode 100644 index 000000000..20306ff06 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/AxisScaleBreaks.cs @@ -0,0 +1,1108 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: AxisScaleBreaks.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: AxisScaleBreakStyle +// +// Purpose: Automatic scale breaks feature related classes. +// +// Reviewed: +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; + +#if Microsoft_CONTROL + + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; + +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Enumerations + + /// + /// An enumeration of line styles for axis scale breaks. + /// + public enum BreakLineStyle + { + /// + /// No scale break line visible. + /// + None, + + /// + /// Straight scale break. + /// + Straight, + + /// + /// Wave scale break. + /// + Wave, + + /// + /// Ragged scale break. + /// + Ragged, + } + + /// + /// An enumeration which indicates whether an axis segment should start + /// from zero when scale break is used. + /// + public enum StartFromZero + { + /// + /// Auto mode + /// + Auto, + + /// + /// Start the axis segment scale from zero. + /// + Yes, + + /// + /// Do not start the axis segment scale from zero. + /// + No + + }; + + #endregion // Enumerations + + /// + /// AxisScaleBreakStyle class represents the settings that control the scale break. + /// + [ + SRDescription("DescriptionAttributeAxisScaleBreakStyle_AxisScaleBreakStyle"), + DefaultProperty("Enabled"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class AxisScaleBreakStyle + { + #region Fields + + // Associated axis + internal Axis axis = null; + + // True if scale breaks are enabled + private bool _enabled = false; + + // AxisName of the break line + private BreakLineStyle _breakLineStyle = BreakLineStyle.Ragged; + + // Spacing between scale segments created by scale breaks + private double _segmentSpacing = 1.5; + + // Break line color + private Color _breakLineColor = Color.Black; + + // Break line width + private int _breakLineWidth = 1; + + // Break line style + private ChartDashStyle _breakLineDashStyle = ChartDashStyle.Solid; + + // Minimum segment size in axis length percentage + private double _minSegmentSize = 10.0; + + // Number of segments the axis is devided into to perform statistical analysis + private int _totalNumberOfSegments = 100; + + // Minimum "empty" size to be replace by the scale break + private int _minimumNumberOfEmptySegments = 25; + + // Maximum number of breaks + private int _maximumNumberOfBreaks = 2; + + // Indicates if scale segment should start from zero. + private StartFromZero _startFromZero = StartFromZero.Auto; + + #endregion // Fields + + #region Constructor + + /// + /// AxisScaleBreakStyle constructor. + /// + public AxisScaleBreakStyle() + { + } + + /// + /// AxisScaleBreakStyle constructor. + /// + /// Chart axis this class belongs to. + internal AxisScaleBreakStyle(Axis axis) + { + this.axis = axis; + } + + #endregion // Constructor + + #region Properties + + /// + /// Gets or sets a flag which indicates whether one of the axis segments should start its scale from zero + /// when scale break is used. + /// + /// + /// When property is set to StartFromZero.Auto, the range of the scale determines + /// if zero value should be included in the scale. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(StartFromZero.Auto), + SRDescription("DescriptionAttributeAxisScaleBreakStyle_StartFromZero"), + ] + public StartFromZero StartFromZero + { + get + { + return this._startFromZero; + } + set + { + this._startFromZero = value; + this.Invalidate(); + } + } + + /// + /// Maximum number of scale breaks that can be used. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(2), + SRDescription("DescriptionAttributeAxisScaleBreakStyle_MaxNumberOfBreaks"), + ] + public int MaxNumberOfBreaks + { + get + { + return this._maximumNumberOfBreaks; + } + set + { + if(value < 1 || value > 5) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAxisScaleBreaksNumberInvalid)); + } + this._maximumNumberOfBreaks = value; + this.Invalidate(); + } + } + + /// + /// Minimum axis scale region size, in percentage of the total axis length, + /// that can be collapsed with the scale break. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(25), + SRDescription("DescriptionAttributeAxisScaleBreakStyle_CollapsibleSpaceThreshold"), + ] + public int CollapsibleSpaceThreshold + { + get + { + return this._minimumNumberOfEmptySegments; + } + set + { + if(value < 10 || value > 90) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAxisScaleBreaksCollapsibleSpaceInvalid)); + } + this._minimumNumberOfEmptySegments = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a flag which determines if axis automatic scale breaks are enabled. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(false), + SRDescription("DescriptionAttributeAxisScaleBreakStyle_Enabled"), + ParenthesizePropertyNameAttribute(true), + ] + public bool Enabled + { + get + { + return this._enabled; + } + set + { + this._enabled = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the style of the scale break line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(BreakLineStyle.Ragged), + SRDescription("DescriptionAttributeAxisScaleBreakStyle_BreakLineType"), + ] + public BreakLineStyle BreakLineStyle + { + get + { + return this._breakLineStyle; + } + set + { + this._breakLineStyle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the spacing of the scale break. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(1.5), + SRDescription("DescriptionAttributeAxisScaleBreakStyle_Spacing"), + ] + public double Spacing + { + get + { + return this._segmentSpacing; + } + set + { + if(value < 0.0 || value > 10) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAxisScaleBreaksSpacingInvalid)); + } + this._segmentSpacing = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the color of the scale break line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLineColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + public Color LineColor + { + get + { + return this._breakLineColor; + } + set + { + this._breakLineColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the width of the scale break line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(1), + SRDescription("DescriptionAttributeLineWidth"), + ] + public int LineWidth + { + get + { + return this._breakLineWidth; + } + set + { + if(value < 1.0 || value > 10) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAxisScaleBreaksLineWidthInvalid)); + } + this._breakLineWidth = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the line style of the scale break line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeLineDashStyle"), + ] + public ChartDashStyle LineDashStyle + { + get + { + return this._breakLineDashStyle; + } + set + { + this._breakLineDashStyle = value; + this.Invalidate(); + } + } + + #endregion // Properties + + #region Helper Methods + + /// + /// Checks if automatic scale breaks are currently enabled. + /// + /// True if scale breaks are currently enabled. + internal bool IsEnabled() + { + // Axis scale breaks must be enabled AND supported by the axis. + if(this.Enabled && + this.CanUseAxisScaleBreaks()) + { + return true; + } + return false; + } + + /// + /// Checks if scale breaks can be used on specified axis. + /// + /// True if scale breaks can be used on this axis + internal bool CanUseAxisScaleBreaks() + { + // Check input parameters + if(this.axis == null || this.axis.ChartArea == null || this.axis.ChartArea.Common.Chart == null) + { + return false; + } + + // No scale breaks in 3D charts + if(this.axis.ChartArea.Area3DStyle.Enable3D) + { + return false; + } + + // Axis scale break can only be applied to the Y and Y 2 axis + if(this.axis.axisType == AxisName.X || this.axis.axisType == AxisName.X2) + { + return false; + } + + // No scale breaks for logarithmic axis + if(this.axis.IsLogarithmic) + { + return false; + } + + // No scale breaks if axis zooming is enabled + if(this.axis.ScaleView.IsZoomed) + { + return false; + } + + // Check series associated with this axis + ArrayList axisSeries = AxisScaleBreakStyle.GetAxisSeries(this.axis); + foreach(Series series in axisSeries) + { + + // Some special chart type are not supported + if(series.ChartType == SeriesChartType.Renko || + series.ChartType == SeriesChartType.PointAndFigure) + { + return false; + } + + + // Get chart type interface + IChartType chartType = this.axis.ChartArea.Common.ChartTypeRegistry.GetChartType(series.ChartTypeName); + if(chartType == null) + { + return false; + } + + // Circular and stacked chart types can not use scale breaks + if(chartType.CircularChartArea || + chartType.Stacked || + !chartType.RequireAxes) + { + return false; + } + } + + return true; + } + + /// + /// Gets a list of series objects attached to the specified axis. + /// + /// Axis to get the series for. + /// A list of series that are attached to the specified axis. + static internal ArrayList GetAxisSeries(Axis axis) + { + ArrayList seriesList = new ArrayList(); + if(axis != null && axis.ChartArea != null && axis.ChartArea.Common.Chart != null) + { + // Iterate through series in the chart + foreach(Series series in axis.ChartArea.Common.Chart.Series) + { + // Series should be on the same chart area and visible + if(series.ChartArea == axis.ChartArea.Name && + series.Enabled) + { + // Check primary/secondary axis + if( (axis.axisType == AxisName.Y && series.YAxisType == AxisType.Secondary) || + (axis.axisType == AxisName.Y2 && series.YAxisType == AxisType.Primary)) + { + continue; + } + + // Add series into the list + seriesList.Add(series); + } + } + } + return seriesList; + } + + /// + /// Invalidate chart control. + /// + private void Invalidate() + { + if(this.axis != null) + { + this.axis.Invalidate(); + } + } + + #endregion // Helper Methods + + #region Series StatisticFormula Methods + + /// + /// Get collection of axis segments to present scale breaks. + /// + /// Collection of axis scale segments. + internal void GetAxisSegmentForScaleBreaks(AxisScaleSegmentCollection axisSegments) + { + // Clear segment collection + axisSegments.Clear(); + + // Check if scale breaks are enabled + if(this.IsEnabled()) + { + // Fill collection of segments + this.FillAxisSegmentCollection(axisSegments); + + // Check if more than 1 segments were defined + if(axisSegments.Count >= 1) + { + // Get index of segment which scale should start from zero + int startFromZeroSegmentIndex = this.GetStartScaleFromZeroSegmentIndex(axisSegments); + + // Calculate segment interaval and round the scale + int index = 0; + foreach(AxisScaleSegment axisScaleSegment in axisSegments) + { + // Check if segment scale should start from zero + bool startFromZero = (index == startFromZeroSegmentIndex) ? true : false; + + // Calculate interval and round scale + double minimum = axisScaleSegment.ScaleMinimum; + double maximum = axisScaleSegment.ScaleMaximum; + axisScaleSegment.Interval = this.axis.EstimateNumberAxis( + ref minimum, ref maximum, startFromZero, this.axis.prefferedNumberofIntervals, true, true); + axisScaleSegment.ScaleMinimum = minimum; + axisScaleSegment.ScaleMaximum = maximum; + + // Make sure new scale break value range do not exceed axis current scale + if (axisScaleSegment.ScaleMinimum < this.axis.Minimum) + { + axisScaleSegment.ScaleMinimum = this.axis.Minimum; + } + if (axisScaleSegment.ScaleMaximum > this.axis.Maximum) + { + axisScaleSegment.ScaleMaximum = this.axis.Maximum; + } + + // Increase segment index + ++index; + } + + // Defined axis scale segments cannot overlap. + // Check for overlapping and join segments or readjust min/max. + bool adjustPosition = false; + AxisScaleSegment prevSegment = axisSegments[0]; + for (int segmentIndex = 1; segmentIndex < axisSegments.Count; segmentIndex++) + { + AxisScaleSegment currentSegment = axisSegments[segmentIndex]; + if (currentSegment.ScaleMinimum <= prevSegment.ScaleMaximum) + { + if (currentSegment.ScaleMaximum > prevSegment.ScaleMaximum) + { + // If segments are partially overlapping make sure the previous + // segment scale is extended + prevSegment.ScaleMaximum = currentSegment.ScaleMaximum; + } + + // Remove the overlapped segment + adjustPosition = true; + axisSegments.RemoveAt(segmentIndex); + --segmentIndex; + } + else + { + prevSegment = currentSegment; + } + } + + // Calculate the position of each segment + if (adjustPosition) + { + this.SetAxisSegmentPosition(axisSegments); + } + } + } + } + + /// + /// Gets index of segment that should be started from zero. + /// + /// Axis scale segment collection. + /// Index axis segment or -1. + private int GetStartScaleFromZeroSegmentIndex(AxisScaleSegmentCollection axisSegments) + { + if (this.StartFromZero == StartFromZero.Auto || + this.StartFromZero == StartFromZero.Yes) + { + int index = 0; + foreach(AxisScaleSegment axisScaleSegment in axisSegments) + { + // Check if zero value is already part of the scale + if(axisScaleSegment.ScaleMinimum < 0.0 && axisScaleSegment.ScaleMaximum > 0.0) + { + return -1; + } + + // As soon as we get first segment with positive minimum value or + // we reached last segment adjust scale to start from zero. + if(axisScaleSegment.ScaleMinimum > 0.0 || + index == (axisSegments.Count - 1) ) + { + // Check if setting minimum scale to zero will make the + // data points in the segment hard to read. This may hapen + // when the distance from zero to current minimum is + // significantly larger than current scale size. + if (this.StartFromZero == StartFromZero.Auto && + axisScaleSegment.ScaleMinimum > 2.0 * (axisScaleSegment.ScaleMaximum - axisScaleSegment.ScaleMinimum) ) + { + return -1; + } + + return index; + } + + // Increase segment index + ++index; + } + } + return -1; + } + + /// + /// Sets position of all scale segments in the axis. + /// + /// Collection of axis scale segments. + private void SetAxisSegmentPosition(AxisScaleSegmentCollection axisSegments) + { + // Calculate total number of points + int totalPointNumber = 0; + foreach(AxisScaleSegment axisScaleSegment in axisSegments) + { + if(axisScaleSegment.Tag is int) + { + totalPointNumber += (int)axisScaleSegment.Tag; + } + } + + // Calculate segment minimum size + double minSize = Math.Min(this._minSegmentSize, Math.Floor(100.0 / axisSegments.Count)); + + // Set segment position + double currentPosition = 0.0; + for(int index = 0; index < axisSegments.Count; index++) + { + axisSegments[index].Position = (currentPosition > 100.0) ? 100.0 : currentPosition; + axisSegments[index].Size = Math.Round(((int)axisSegments[index].Tag) / (totalPointNumber / 100.0),5); + if(axisSegments[index].Size < minSize) + { + axisSegments[index].Size = minSize; + } + + // Set spacing for all segments except the last one + if(index < (axisSegments.Count - 1) ) + { + axisSegments[index].Spacing = this._segmentSpacing; + } + + // Advance current position + currentPosition += axisSegments[index].Size; + } + + // Make sure we do not exceed the 100% axis length + double totalHeight = 0.0; + do + { + // Calculate total height + totalHeight = 0.0; + double maxSize = double.MinValue; + int maxSizeIndex = -1; + for(int index = 0; index < axisSegments.Count; index++) + { + totalHeight += axisSegments[index].Size; + if(axisSegments[index].Size > maxSize) + { + maxSize = axisSegments[index].Size; + maxSizeIndex = index; + } + } + + // If height is too large find largest segment + if(totalHeight > 100.0) + { + // Adjust segment size + axisSegments[maxSizeIndex].Size -= totalHeight - 100.0; + if(axisSegments[maxSizeIndex].Size < minSize) + { + axisSegments[maxSizeIndex].Size = minSize; + } + + // Adjust position of the next segment + double curentPosition = axisSegments[maxSizeIndex].Position + axisSegments[maxSizeIndex].Size; + for(int index = maxSizeIndex + 1; index < axisSegments.Count; index++) + { + axisSegments[index].Position = curentPosition; + curentPosition += axisSegments[index].Size; + } + } + + } while(totalHeight > 100.0); + + } + + /// + /// Fill collection of axis scale segments. + /// + /// Collection of axis segments. + private void FillAxisSegmentCollection(AxisScaleSegmentCollection axisSegments) + { + // Clear axis segments collection + axisSegments.Clear(); + + // Get statistics for the series attached to the axis + double minYValue = 0.0; + double maxYValue = 0.0; + double segmentSize = 0.0; + double[] segmentMaxValue = null; + double[] segmentMinValue = null; + int[] segmentPointNumber = GetSeriesDataStatistics( + this._totalNumberOfSegments, + out minYValue, + out maxYValue, + out segmentSize, + out segmentMaxValue, + out segmentMinValue); + if (segmentPointNumber == null) + { + return; + } + + // Calculate scale maximum and minimum + double minimum = minYValue; + double maximum = maxYValue; + this.axis.EstimateNumberAxis( + ref minimum, + ref maximum, + this.axis.IsStartedFromZero, + this.axis.prefferedNumberofIntervals, + true, + true); + + // Make sure max/min Y values are not the same + if (maxYValue == minYValue) + { + return; + } + + // Calculate the percentage of the scale range covered by the data range. + double dataRangePercent = (maxYValue - minYValue) / ((maximum - minimum) / 100.0); + + // Get sequences of empty segments + ArrayList emptySequences = new ArrayList(); + bool doneFlag = false; + while(!doneFlag) + { + doneFlag = true; + + // Get longest sequence of segments with no points + int startSegment = 0; + int numberOfSegments = 0; + this.GetLargestSequenseOfSegmentsWithNoPoints( + segmentPointNumber, + out startSegment, + out numberOfSegments); + + // Adjust minimum empty segments number depending on current segments + int minEmptySegments = (int)(this._minimumNumberOfEmptySegments * (100.0 / dataRangePercent)); + if(axisSegments.Count > 0 && numberOfSegments > 0) + { + // Find the segment which contain newly found empty segments sequence + foreach(AxisScaleSegment axisScaleSegment in axisSegments) + { + if(startSegment > 0 && (startSegment + numberOfSegments) <= segmentMaxValue.Length - 1) + { + if(segmentMaxValue[startSegment - 1] >= axisScaleSegment.ScaleMinimum && + segmentMinValue[startSegment + numberOfSegments] <= axisScaleSegment.ScaleMaximum) + { + // Get percentage of segment scale that is empty and suggested for collapsing + double segmentScaleRange = axisScaleSegment.ScaleMaximum - axisScaleSegment.ScaleMinimum; + double emptySpaceRange = segmentMinValue[startSegment + numberOfSegments] - segmentMaxValue[startSegment - 1]; + double emptySpacePercent = emptySpaceRange / (segmentScaleRange / 100.0); + emptySpacePercent = emptySpacePercent / 100 * axisScaleSegment.Size; + + if(emptySpacePercent > minEmptySegments && + numberOfSegments > this._minSegmentSize) + { + minEmptySegments = numberOfSegments; + } + } + } + } + } + + // Check if found sequence is long enough + if(numberOfSegments >= minEmptySegments) + { + doneFlag = false; + + // Store start segment and number of segments in the list + emptySequences.Add(startSegment); + emptySequences.Add(numberOfSegments); + + // Check if there are any emty segments sequence found + axisSegments.Clear(); + if(emptySequences.Count > 0) + { + double segmentFrom = double.NaN; + double segmentTo = double.NaN; + + // Based on the segments that need to be excluded create axis segments that + // will present on the axis scale. + int numberOfPoints = 0; + for(int index = 0; index < segmentPointNumber.Length; index++) + { + // Check if current segment is excluded + bool excludedSegment = this.IsExcludedSegment(emptySequences, index); + + // If not excluded segment - update from/to range if they were set + if(!excludedSegment && + !double.IsNaN(segmentMinValue[index]) && + !double.IsNaN(segmentMaxValue[index])) + { + // Calculate total number of points + numberOfPoints += segmentPointNumber[index]; + + // Set From/To of the visible segment + if(double.IsNaN(segmentFrom)) + { + segmentFrom = segmentMinValue[index]; + segmentTo = segmentMaxValue[index]; + } + else + { + segmentTo = segmentMaxValue[index]; + } + } + + // If excluded or last segment - add current visible segment range + if(!double.IsNaN(segmentFrom) && + (excludedSegment || index == (segmentPointNumber.Length - 1) )) + { + // Make sure To and From do not match + if(segmentTo == segmentFrom) + { + segmentFrom -= segmentSize; + segmentTo += segmentSize; + } + + // Add axis scale segment + AxisScaleSegment axisScaleSegment = new AxisScaleSegment(); + axisScaleSegment.ScaleMaximum = segmentTo; + axisScaleSegment.ScaleMinimum = segmentFrom; + axisScaleSegment.Tag = numberOfPoints; + axisSegments.Add(axisScaleSegment); + + // Reset segment range + segmentFrom = double.NaN; + segmentTo = double.NaN; + numberOfPoints = 0; + } + } + } + + // Calculate the position of each segment + this.SetAxisSegmentPosition(axisSegments); + } + + // Make sure we do not exceed specified number of breaks + if( (axisSegments.Count - 1) >= this._maximumNumberOfBreaks) + { + doneFlag = true; + } + } + + } + + /// + /// Check if segment was excluded. + /// + /// Array of segment indexes. + /// Index of the segment to check. + /// True if segment with specified index is marked as excluded. + private bool IsExcludedSegment(ArrayList excludedSegments, int segmentIndex) + { + for(int index = 0; index < excludedSegments.Count; index += 2) + { + if(segmentIndex >= (int)excludedSegments[index] && + segmentIndex < (int)excludedSegments[index] + (int)excludedSegments[index + 1]) + { + return true; + } + } + return false; + } + + /// + /// Collect statistical information about the series. + /// + /// Segment count. + /// Minimum Y value. + /// Maximum Y value. + /// Segment size. + /// Array of segment scale maximum values. + /// Array of segment scale minimum values. + /// + internal int[] GetSeriesDataStatistics( + int segmentCount, + out double minYValue, + out double maxYValue, + out double segmentSize, + out double[] segmentMaxValue, + out double[] segmentMinValue) + { + // Get all series associated with the axis + ArrayList axisSeries = AxisScaleBreakStyle.GetAxisSeries(this.axis); + + // Get range of Y values from axis series + minYValue = 0.0; + maxYValue = 0.0; + axis.Common.DataManager.GetMinMaxYValue(axisSeries, out minYValue, out maxYValue); + + int numberOfPoints = 0; + foreach (Series series in axisSeries) + { + numberOfPoints = Math.Max(numberOfPoints, series.Points.Count); + } + + if (axisSeries.Count == 0 || numberOfPoints == 0) + { + segmentSize = 0.0; + segmentMaxValue = null; + segmentMinValue = null; + return null; + } + + // Split range of values into predefined number of segments and calculate + // how many points will be in each segment. + segmentSize = (maxYValue - minYValue) / segmentCount; + int[] segmentPointNumber = new int[segmentCount]; + segmentMaxValue = new double[segmentCount]; + segmentMinValue = new double[segmentCount]; + for(int index = 0; index < segmentCount; index++) + { + segmentMaxValue[index] = double.NaN; + segmentMinValue[index] = double.NaN; + } + foreach(Series series in axisSeries) + { + // Get number of Y values to process + int maxYValueCount = 1; + IChartType chartType = this.axis.ChartArea.Common.ChartTypeRegistry.GetChartType(series.ChartTypeName); + if(chartType != null) + { + if(chartType.ExtraYValuesConnectedToYAxis && chartType.YValuesPerPoint > 1) + { + maxYValueCount = chartType.YValuesPerPoint; + } + } + + // Iterate throug all data points + foreach(DataPoint dataPoint in series.Points) + { + if(!dataPoint.IsEmpty) + { + // Iterate through all yValues + for(int yValueIndex = 0; yValueIndex < maxYValueCount; yValueIndex++) + { + // Calculate index of the scale segment + int segmentIndex = (int)Math.Floor((dataPoint.YValues[yValueIndex] - minYValue) / segmentSize); + if(segmentIndex < 0) + { + segmentIndex = 0; + } + if(segmentIndex > segmentCount - 1) + { + segmentIndex = segmentCount - 1; + } + + // Increase number points in that segment + ++segmentPointNumber[segmentIndex]; + + // Store Min/Max values for the segment + if(segmentPointNumber[segmentIndex] == 1) + { + segmentMaxValue[segmentIndex] = dataPoint.YValues[yValueIndex]; + segmentMinValue[segmentIndex] = dataPoint.YValues[yValueIndex]; + } + else + { + segmentMaxValue[segmentIndex] = Math.Max(segmentMaxValue[segmentIndex], dataPoint.YValues[yValueIndex]); + segmentMinValue[segmentIndex] = Math.Min(segmentMinValue[segmentIndex], dataPoint.YValues[yValueIndex]); + } + } + } + } + } + + return segmentPointNumber; + } + + /// + /// Gets largest segment with no points. + /// + /// Array that stores number of points for each segment. + /// Returns largest empty segment sequence starting index. + /// Returns largest empty segment sequence length. + /// True if long empty segment sequence was found. + internal bool GetLargestSequenseOfSegmentsWithNoPoints( + int[] segmentPointNumber, + out int startSegment, + out int numberOfSegments) + { + // Find the longest sequence of empty segments + startSegment = -1; + numberOfSegments = 0; + int currentSegmentStart = -1; + int currentNumberOfSegments = -1; + for(int index = 0; index < segmentPointNumber.Length; index++) + { + // Check for the segment with no points + if(segmentPointNumber[index] == 0) + { + if(currentSegmentStart == -1) + { + currentSegmentStart = index; + currentNumberOfSegments = 1; + } + else + { + ++currentNumberOfSegments; + } + } + + // Check if longest sequence found + if(currentNumberOfSegments > 0 && + (segmentPointNumber[index] != 0 || index == segmentPointNumber.Length - 1)) + { + if(currentNumberOfSegments > numberOfSegments) + { + startSegment = currentSegmentStart; + numberOfSegments = currentNumberOfSegments; + } + currentSegmentStart = -1; + currentNumberOfSegments = 0; + } + } + + // Store value of "-1" in found sequence + if(numberOfSegments != 0) + { + for(int index = startSegment; index < (startSegment + numberOfSegments); index++) + { + segmentPointNumber[index] = -1; + } + + return true; + } + + return false; + } + + #endregion // Series StatisticFormula Methods + } +} + + diff --git a/System.Web.DataVisualization/Common/General/AxisScaleSegments.cs b/System.Web.DataVisualization/Common/General/AxisScaleSegments.cs new file mode 100644 index 000000000..4a64ab836 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/AxisScaleSegments.cs @@ -0,0 +1,1014 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: AxisScaleSegments.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: AxisScaleSegment, AxisScaleSegmentCollection +// +// Purpose: +// +// Reviewed: +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +#if Microsoft_CONTROL + + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; + +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// AxisScaleSegment class represents a single segment of the axis with + /// it's own scale and intervals. + /// + [ + SRDescription("DescriptionAttributeAxisScaleSegment_AxisScaleSegment"), + ] + internal class AxisScaleSegment + { + #region Fields + + // Associated axis + internal Axis axis = null; + + // Axis segment position in percent of the axis size + private double _position = 0.0; + + // Axis segment size in percent of the axis size + private double _size = 0.0; + + // Axis segment spacing in percent of the axis size + private double _spacing = 0.0; + + // Axis segment scale minimum value + private double _scaleMinimum = 0.0; + + // Axis segment scale maximum value + private double _scaleMaximum = 0.0; + + // Axis segment interval offset. + private double _intervalOffset = 0; + + // Axis segment interval. + private double _interval = 0; + + // Axis segment interval units type. + private DateTimeIntervalType _intervalType = DateTimeIntervalType.Auto; + + // Axis segment interval offset units type. + private DateTimeIntervalType _intervalOffsetType = DateTimeIntervalType.Auto; + + // Object associated with the segment + private object _tag = null; + + // Stack used to save/load axis settings + private Stack _oldAxisSettings = new Stack(); + + #endregion // Fields + + #region Constructor + + /// + /// Default object constructor. + /// + public AxisScaleSegment() + { + } + + #endregion // Constructor + + #region Properties + + /// + /// Axis segment position in axis size percentage. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(0.0), + SRDescription("DescriptionAttributeAxisScaleSegment_Position"), + ] + public double Position + { + get + { + return this._position; + } + set + { + if(value < 0.0 || value > 100.0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAxisScaleSegmentsPositionInvalid)); + } + this._position = value; + } + } + + /// + /// Axis segment size in axis size percentage. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(0.0), + SRDescription("DescriptionAttributeAxisScaleSegment_Size"), + ] + public double Size + { + get + { + return this._size; + } + set + { + if(value < 0.0 || value > 100.0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAxisScaleSegmentsSizeInvalid)); + } + this._size = value; + } + } + + /// + /// Axis segment spacing in axis size percentage. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(0.0), + SRDescription("DescriptionAttributeAxisScaleSegment_Spacing"), + ] + public double Spacing + { + get + { + return this._spacing; + } + set + { + if(value < 0.0 || value > 100.0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAxisScaleSegmentsSpacingInvalid)); + } + this._spacing = value; + } + } + + /// + /// Axis segment scale maximum value. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(0.0), + SRDescription("DescriptionAttributeAxisScaleSegment_ScaleMaximum"), + ] + public double ScaleMaximum + { + get + { + return this._scaleMaximum; + } + set + { + this._scaleMaximum = value; + } + } + + /// + /// Axis segment scale minimum value. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(0.0), + SRDescription("DescriptionAttributeAxisScaleSegment_ScaleMinimum"), + ] + public double ScaleMinimum + { + get + { + return this._scaleMinimum; + } + set + { + this._scaleMinimum = value; + } + } + + + /// + /// Axis segment interval size. + /// + [ + SRCategory("CategoryAttributeInterval"), + DefaultValue(0.0), + SRDescription("DescriptionAttributeAxisScaleSegment_Interval"), + TypeConverter(typeof(AxisIntervalValueConverter)), + ] + public double Interval + { + get + { + return this._interval; + } + set + { + // Axis interval properties must be set + if(double.IsNaN(value)) + { + this._interval = 0; + } + else + { + this._interval = value; + } + } + } + + /// + /// Axis segment interval offset. + /// + [ + SRCategory("CategoryAttributeInterval"), + DefaultValue(0.0), + SRDescription("DescriptionAttributeAxisScaleSegment_IntervalOffset"), + TypeConverter(typeof(AxisIntervalValueConverter)) + ] + public double IntervalOffset + { + get + { + return _intervalOffset; + } + } + + /// + /// Axis segment interval type. + /// + [ + SRCategory("CategoryAttributeInterval"), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeAxisScaleSegment_IntervalType"), + ] + public DateTimeIntervalType IntervalType + { + get + { + return this._intervalType; + } + set + { + // Axis interval properties must be set + if(value == DateTimeIntervalType.NotSet) + { + this._intervalType = DateTimeIntervalType.Auto; + } + else + { + _intervalType = value; + } + } + } + + /// + /// Axis segment interval offset type. + /// + [ + SRCategory("CategoryAttributeInterval"), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeAxisScaleSegment_IntervalOffsetType"), + ] + public DateTimeIntervalType IntervalOffsetType + { + get + { + return this._intervalOffsetType; + } + } + + /// + /// Object associated with axis scale segment. + /// + [ + SRCategory("CategoryAttributeMisc"), + Browsable(false), + DefaultValue(null), + SRDescription("DescriptionAttributeAxisScaleSegment_Tag"), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SerializationVisibility(SerializationVisibility.Hidden), + ] + public object Tag + { + get + { + return this._tag; + } + set + { + this._tag = value; + } + } + + #endregion // Properties + + #region Break Line Painting Methods + + /// + /// Paints the axis break line. + /// + /// Chart graphics to use. + /// Axis scale segment next to current. + internal void PaintBreakLine(ChartGraphics graph, AxisScaleSegment nextSegment) + { + // Get break line position + RectangleF breakPosition = this.GetBreakLinePosition(graph, nextSegment); + + // Get top line graphics path + GraphicsPath breakLinePathTop = this.GetBreakLinePath(breakPosition, true); + GraphicsPath breakLinePathBottom = null; + + // Clear break line space using chart color behind the area + if(breakPosition.Width > 0f && breakPosition.Height > 0f) + { + // Get bottom line graphics path + breakLinePathBottom = this.GetBreakLinePath(breakPosition, false); + + // Clear plotting area background + using(GraphicsPath fillPath = new GraphicsPath()) + { + // Create fill path out of top and bottom break lines + fillPath.AddPath(breakLinePathTop, true); + fillPath.Reverse(); + fillPath.AddPath(breakLinePathBottom, true); + fillPath.CloseAllFigures(); + + // Use chart back color to fill the area + using(Brush fillBrush = this.GetChartFillBrush(graph)) + { + graph.FillPath(fillBrush, fillPath); + + // Check if shadow exsits in chart area + if( this.axis.ChartArea.ShadowOffset != 0 && !this.axis.ChartArea.ShadowColor.IsEmpty) + { + // Clear shadow + RectangleF shadowPartRect = breakPosition; + if( this.axis.AxisPosition == AxisPosition.Right || this.axis.AxisPosition == AxisPosition.Left ) + { + shadowPartRect.Y += this.axis.ChartArea.ShadowOffset; + shadowPartRect.Height -= this.axis.ChartArea.ShadowOffset; + shadowPartRect.X = shadowPartRect.Right - 1; + shadowPartRect.Width = this.axis.ChartArea.ShadowOffset + 2; + } + else + { + shadowPartRect.X += this.axis.ChartArea.ShadowOffset; + shadowPartRect.Width -= this.axis.ChartArea.ShadowOffset; + shadowPartRect.Y = shadowPartRect.Bottom - 1; + shadowPartRect.Height = this.axis.ChartArea.ShadowOffset + 2; + } + graph.FillRectangle(fillBrush, shadowPartRect); + + // Draw new shadow + using(GraphicsPath shadowPath = new GraphicsPath()) + { + shadowPath.AddPath(breakLinePathTop, false); + + // Define maximum size + float size = this.axis.ChartArea.ShadowOffset; + if( this.axis.AxisPosition == AxisPosition.Right || this.axis.AxisPosition == AxisPosition.Left ) + { + size = Math.Min(size, breakPosition.Height); + } + else + { + size = Math.Min(size, breakPosition.Width); + } + + // Define step to increase transperancy + int transparencyStep = (int)(this.axis.ChartArea.ShadowColor.A / size); + + // Set clip region to achieve spacing of the shadow + // Start with the plotting rectangle position + RectangleF clipRegion = graph.GetAbsoluteRectangle(this.axis.PlotAreaPosition.ToRectangleF()); + if( this.axis.AxisPosition == AxisPosition.Right || this.axis.AxisPosition == AxisPosition.Left ) + { + clipRegion.X += this.axis.ChartArea.ShadowOffset; + clipRegion.Width += this.axis.ChartArea.ShadowOffset; + } + else + { + clipRegion.Y += this.axis.ChartArea.ShadowOffset; + clipRegion.Height += this.axis.ChartArea.ShadowOffset; + } + graph.SetClip(graph.GetRelativeRectangle(clipRegion)); + + // Draw several lines to form shadow + for(int index = 0; index < size; index ++) + { + using(Matrix newMatrix = new Matrix()) + { + // Shift top break line by 1 pixel + if( this.axis.AxisPosition == AxisPosition.Right || this.axis.AxisPosition == AxisPosition.Left ) + { + newMatrix.Translate(0f, 1f); + } + else + { + newMatrix.Translate(1f, 0f); + } + shadowPath.Transform(newMatrix); + } + + // Get line color + Color color = Color.FromArgb( + this.axis.ChartArea.ShadowColor.A - transparencyStep * index, + this.axis.ChartArea.ShadowColor); + + using(Pen shadowPen = new Pen(color, 1)) + { + // Draw shadow + graph.DrawPath(shadowPen, shadowPath); + } + } + + graph.ResetClip(); + } + } + } + } + } + + // Draw Separator Line(s) + if(this.axis.ScaleBreakStyle.BreakLineStyle != BreakLineStyle.None) + { + using(Pen pen = new Pen(this.axis.ScaleBreakStyle.LineColor, this.axis.ScaleBreakStyle.LineWidth)) + { + // Set line style + pen.DashStyle = graph.GetPenStyle(this.axis.ScaleBreakStyle.LineDashStyle); + + // Draw break lines + graph.DrawPath(pen, breakLinePathTop); + if(breakPosition.Width > 0f && breakPosition.Height > 0f) + { + graph.DrawPath(pen, breakLinePathBottom); + } + } + } + + // Dispose break line paths + breakLinePathTop.Dispose(); + breakLinePathTop = null; + if(breakLinePathBottom != null) + { + breakLinePathBottom.Dispose(); + breakLinePathBottom = null; + } + + } + + /// + /// Get fill brush used to fill axis break lines spacing. + /// + /// chart graphics. + /// Fill brush. + private Brush GetChartFillBrush(ChartGraphics graph) + { + Chart chart = this.axis.ChartArea.Common.Chart; + Brush brush = null; + + if( chart.BackGradientStyle == GradientStyle.None ) + { + brush = new SolidBrush(chart.BackColor); + } + else + { + // If a gradient type is set create a brush with gradient + brush = graph.GetGradientBrush(new RectangleF(0, 0, chart.chartPicture.Width - 1, chart.chartPicture.Height - 1), chart.BackColor, chart.BackSecondaryColor, chart.BackGradientStyle); + } + + if( chart.BackHatchStyle != ChartHatchStyle.None ) + { + brush = graph.GetHatchBrush( chart.BackHatchStyle, chart.BackColor, chart.BackSecondaryColor ); + } + + if( chart.BackImage.Length > 0 && + chart.BackImageWrapMode != ChartImageWrapMode.Unscaled && + chart.BackImageWrapMode != ChartImageWrapMode.Scaled) + { + brush = graph.GetTextureBrush(chart.BackImage, chart.BackImageTransparentColor, chart.BackImageWrapMode, chart.BackColor ); + } + + return brush; + } + + /// + /// Gets a path of the break line for specified position. + /// + /// Break line position. + /// Indicates if top or bottom break line path should be retrieved. + /// Graphics path with break line path. + private GraphicsPath GetBreakLinePath(RectangleF breakLinePosition, bool top) + { + GraphicsPath path = new GraphicsPath(); + + if(this.axis.ScaleBreakStyle.BreakLineStyle == BreakLineStyle.Wave) + { + PointF[] points = null; + int pointNumber = 0; + if( this.axis.AxisPosition == AxisPosition.Right || this.axis.AxisPosition == AxisPosition.Left ) + { + float startX = breakLinePosition.X; + float endX = breakLinePosition.Right; + float y = (top) ? breakLinePosition.Y : breakLinePosition.Bottom; + pointNumber = ((int)(endX - startX) / 40) * 2 ; + if(pointNumber < 2) + { + pointNumber = 2; + } + float step = (endX - startX) / pointNumber; + points = new PointF[pointNumber + 1]; + for(int pointIndex = 1; pointIndex < pointNumber + 1; pointIndex++) + { + points[pointIndex] = new PointF( + startX + pointIndex * step, + y + ((pointIndex%2 == 0) ? -2f : 2f) ); + } + + points[0] = new PointF(startX, y); + points[points.Length - 1] = new PointF(endX, y); + } + else + { + float startY = breakLinePosition.Y; + float endY = breakLinePosition.Bottom; + float x = (top) ? breakLinePosition.X : breakLinePosition.Right; + pointNumber = ((int)(endY - startY) / 40) * 2 ; + if(pointNumber < 2) + { + pointNumber = 2; + } + float step = (endY - startY) / pointNumber; + points = new PointF[pointNumber + 1]; + for(int pointIndex = 1; pointIndex < pointNumber + 1; pointIndex++) + { + points[pointIndex] = new PointF( + x + ((pointIndex%2 == 0) ? -2f : 2f), + startY + pointIndex * step); + } + + points[0] = new PointF(x, startY); + points[points.Length - 1] = new PointF(x, endY); + } + + path.AddCurve(points, 0, pointNumber, 0.8f); + } + else if(this.axis.ScaleBreakStyle.BreakLineStyle == BreakLineStyle.Ragged) + { + PointF[] points = null; + Random rand = new Random(435657); + if( this.axis.AxisPosition == AxisPosition.Right || this.axis.AxisPosition == AxisPosition.Left ) + { + float startX = breakLinePosition.X; + float endX = breakLinePosition.Right; + float y = (top) ? breakLinePosition.Y : breakLinePosition.Bottom; + float step = 10f; + int pointNumber = (int)((endX - startX) / step); + if(pointNumber < 2) + { + pointNumber = 2; + } + points = new PointF[pointNumber]; + + for(int pointIndex = 1; pointIndex < pointNumber - 1; pointIndex++) + { + points[pointIndex] = new PointF( + startX + pointIndex * step, + y + rand.Next(-3, 3) ); + } + + points[0] = new PointF(startX, y); + points[points.Length - 1] = new PointF(endX, y); + } + else + { + float startY = breakLinePosition.Y; + float endY = breakLinePosition.Bottom; + float x = (top) ? breakLinePosition.X : breakLinePosition.Right; + float step = 10f; + int pointNumber = (int)((endY - startY) / step); + if(pointNumber < 2) + { + pointNumber = 2; + } + points = new PointF[pointNumber]; + + for(int pointIndex = 1; pointIndex < pointNumber - 1; pointIndex++) + { + points[pointIndex] = new PointF( + x + rand.Next(-3, 3), + startY + pointIndex * step ); + } + + points[0] = new PointF(x, startY); + points[points.Length - 1] = new PointF(x, endY); + } + + path.AddLines(points); + } + else + { + if( this.axis.AxisPosition == AxisPosition.Right || this.axis.AxisPosition == AxisPosition.Left ) + { + if(top) + { + path.AddLine(breakLinePosition.X, breakLinePosition.Y, breakLinePosition.Right, breakLinePosition.Y); + } + else + { + path.AddLine(breakLinePosition.X, breakLinePosition.Bottom, breakLinePosition.Right, breakLinePosition.Bottom); + } + } + else + { + if(top) + { + path.AddLine(breakLinePosition.X, breakLinePosition.Y, breakLinePosition.X, breakLinePosition.Bottom); + } + else + { + path.AddLine(breakLinePosition.Right, breakLinePosition.Y, breakLinePosition.Right, breakLinePosition.Bottom); + } + } + } + return path; + } + + /// + /// Gets position of the axis break line. Break line may be shown as a single + /// line or two lines separated with a spacing. + /// + /// Chart graphics. + /// Next segment reference. + /// Position of the axis break line in pixel coordinates. + internal RectangleF GetBreakLinePosition(ChartGraphics graph, AxisScaleSegment nextSegment) + { + // Start with the plotting rectangle position + RectangleF breakPosition = this.axis.PlotAreaPosition.ToRectangleF(); + + // Find maximum scale value of the current segment and minimuj of the next + double from = this.axis.GetLinearPosition(nextSegment.ScaleMinimum); + double to = this.axis.GetLinearPosition(this.ScaleMaximum); + if( this.axis.AxisPosition == AxisPosition.Right || this.axis.AxisPosition == AxisPosition.Left ) + { + breakPosition.Y = (float)Math.Min(from, to); + breakPosition.Height = (float)Math.Max(from, to); + } + else + { + breakPosition.X = (float)Math.Min(from, to); + breakPosition.Width = (float)Math.Max(from, to);; + } + + // Convert to pixels + breakPosition = Rectangle.Round(graph.GetAbsoluteRectangle(breakPosition)); + + // Add border width + if( this.axis.AxisPosition == AxisPosition.Right || this.axis.AxisPosition == AxisPosition.Left ) + { + breakPosition.Height = (float)Math.Abs(breakPosition.Y - breakPosition.Height); + breakPosition.X -= this.axis.ChartArea.BorderWidth; + breakPosition.Width += 2 * this.axis.ChartArea.BorderWidth; + } + else + { + breakPosition.Width = (float)Math.Abs(breakPosition.X - breakPosition.Width); + breakPosition.Y -= this.axis.ChartArea.BorderWidth; + breakPosition.Height += 2 * this.axis.ChartArea.BorderWidth; + } + + return breakPosition; + } + + #endregion // Break Line Painting Methods + + #region Helper Methods + + /// + /// Gets segment scale position and size in relative coordinates. + /// Method takes in consideration segment spacing and space required fro separatorType. + /// + /// Plotting area size in relative coordinates. + /// Returns scale position. + /// Returns scale size. + internal void GetScalePositionAndSize(double plotAreaSize, out double scalePosition, out double scaleSize) + { + scaleSize = (this.Size - this.Spacing) * (plotAreaSize / 100.0); + scalePosition = this.Position * (plotAreaSize / 100.0); + } + + /// + /// Saves axis settings and set them from the current segment. + /// + internal void SetTempAxisScaleAndInterval() + { + // Save current axis settings + if(_oldAxisSettings.Count == 0) + { + _oldAxisSettings.Push(this.axis.maximum); + _oldAxisSettings.Push(this.axis.minimum); + + _oldAxisSettings.Push(this.axis.majorGrid.interval); + _oldAxisSettings.Push(this.axis.majorGrid.intervalType); + _oldAxisSettings.Push(this.axis.majorGrid.intervalOffset); + _oldAxisSettings.Push(this.axis.majorGrid.intervalOffsetType); + + _oldAxisSettings.Push(this.axis.majorTickMark.interval); + _oldAxisSettings.Push(this.axis.majorTickMark.intervalType); + _oldAxisSettings.Push(this.axis.majorTickMark.intervalOffset); + _oldAxisSettings.Push(this.axis.majorTickMark.intervalOffsetType); + + _oldAxisSettings.Push(this.axis.LabelStyle.interval); + _oldAxisSettings.Push(this.axis.LabelStyle.intervalType); + _oldAxisSettings.Push(this.axis.LabelStyle.intervalOffset); + _oldAxisSettings.Push(this.axis.LabelStyle.intervalOffsetType); + } + + // Copy settings from the segment into the axis + this.axis.maximum = this.ScaleMaximum; + this.axis.minimum = this.ScaleMinimum; + + this.axis.majorGrid.interval = this.Interval; + this.axis.majorGrid.intervalType = this.IntervalType; + this.axis.majorGrid.intervalOffset = this.IntervalOffset; + this.axis.majorGrid.intervalOffsetType = this.IntervalOffsetType; + + this.axis.majorTickMark.interval = this.Interval; + this.axis.majorTickMark.intervalType = this.IntervalType; + this.axis.majorTickMark.intervalOffset = this.IntervalOffset; + this.axis.majorTickMark.intervalOffsetType = this.IntervalOffsetType; + + this.axis.LabelStyle.interval = this.Interval; + this.axis.LabelStyle.intervalType = this.IntervalType; + this.axis.LabelStyle.intervalOffset = this.IntervalOffset; + this.axis.LabelStyle.intervalOffsetType = this.IntervalOffsetType; + } + + /// + /// Restore previously saved axis settings. + /// + internal void RestoreAxisScaleAndInterval() + { + if(_oldAxisSettings.Count > 0) + { + this.axis.LabelStyle.intervalOffsetType = (DateTimeIntervalType)_oldAxisSettings.Pop(); + this.axis.LabelStyle.intervalOffset = (double)_oldAxisSettings.Pop(); + this.axis.LabelStyle.intervalType = (DateTimeIntervalType)_oldAxisSettings.Pop(); + this.axis.LabelStyle.interval = (double)_oldAxisSettings.Pop(); + + this.axis.majorTickMark.intervalOffsetType = (DateTimeIntervalType)_oldAxisSettings.Pop(); + this.axis.majorTickMark.intervalOffset = (double)_oldAxisSettings.Pop(); + this.axis.majorTickMark.intervalType = (DateTimeIntervalType)_oldAxisSettings.Pop(); + this.axis.majorTickMark.interval = (double)_oldAxisSettings.Pop(); + + this.axis.majorGrid.intervalOffsetType = (DateTimeIntervalType)_oldAxisSettings.Pop(); + this.axis.majorGrid.intervalOffset = (double)_oldAxisSettings.Pop(); + this.axis.majorGrid.intervalType = (DateTimeIntervalType)_oldAxisSettings.Pop(); + this.axis.majorGrid.interval = (double)_oldAxisSettings.Pop(); + + this.axis.minimum = (double)_oldAxisSettings.Pop(); + this.axis.maximum = (double)_oldAxisSettings.Pop(); + } + } + + #endregion // Helper Methods + + } + + /// + /// AxisScaleSegmentCollection is a class that stores collection of axis segments. + /// + [ + SRDescription("DescriptionAttributeAxisScaleSegmentCollection_AxisScaleSegmentCollection"), + ] + internal class AxisScaleSegmentCollection : CollectionBase + { + #region Fields + + // Axis this segment collection belongs to. + private Axis _axis = null; + + // Segment which is always used to convert scale values. + // This value is set tmporarly when only one segment has + // to handle all the values. + private AxisScaleSegment _enforcedSegment = null; + + // Indicates that values allowed to be outside of the scale segment. + // Otherwise they will be rounded to Min and Max values. + internal bool AllowOutOfScaleValues = false; + + #endregion // Fields + + #region Construction and Initialization + + /// + /// Default public constructor. + /// + /// + /// This constructor is for internal use and should not be part of documentation. + /// + public AxisScaleSegmentCollection() + { + } + + /// + /// Default public constructor. + /// + /// + /// This constructor is for internal use and should not be part of documentation. + /// + /// + /// Chart axis this collection belongs to + /// + internal AxisScaleSegmentCollection(Axis axis) + { + this._axis = axis; + } + + #endregion // Construction and Initialization + + #region Indexer + + /// + /// Axis scale segment collection indexer. + /// + /// + /// The AxisScaleSegment object index can be provided as a parameter. Returns the object. + /// + [ + SRDescription("DescriptionAttributeAxisScaleSegmentCollection_Item"), + ] + public AxisScaleSegment this[int index] + { + get + { + return (AxisScaleSegment)this.List[(int)index]; + } + } + + #endregion // Indexer + + #region Collection Add and Insert methods + + /// + /// Adds a segment to the end of the collection. + /// + /// + /// object to add. + /// + /// + /// Index of the newly added object. + /// + public int Add(AxisScaleSegment segment) + { + return this.List.Add(segment); + } + + + #endregion // Collection Add and Insert methods + + #region Items Inserting and Removing Notification methods + + /// + /// After new item inserted. + /// + /// Item index. + /// Item object. + /// + /// This is an internal method and should not be part of the documentation. + /// + protected override void OnInsertComplete(int index, object value) + { + ((AxisScaleSegment)value).axis = this._axis; + } + + /// + /// After items is set. + /// + /// The zero-based index at which oldValue can be found. + /// The value to replace with newValue. + /// The new value of the element at index. + /// + /// This is an internal method and should not be part of the documentation. + /// + protected override void OnSetComplete(int index, object oldValue, object newValue) + { + ((AxisScaleSegment)newValue).axis = this._axis; + } + + #endregion + + #region Helper Methods + + /// + /// Ensures that specified axis scale segment is used for all coordinate transformations. + /// Set tot NULL to reset. + /// + /// + internal void EnforceSegment(AxisScaleSegment segment) + { + this._enforcedSegment = segment; + } + + /// + /// Find axis scale segment that should be used to translate axis value to relative coordinates. + /// + /// Axis value to convert. + /// Scale segment to use for the convertion. + public AxisScaleSegment FindScaleSegmentForAxisValue(double axisValue) + { + // Check if no segments defined + if(this.List.Count == 0) + { + return null; + } + + // Check if segment enforcment is enabled + if(_enforcedSegment != null) + { + return _enforcedSegment; + } + + // Iterate through all segments + for(int index = 0; index < this.Count; index++) + { + if(axisValue < this[index].ScaleMinimum) + { + if(index == 0) + { + return this[index]; + } + else + { + // Find the segment which is "closer" to the value + if( Math.Abs(this[index].ScaleMinimum - axisValue) < Math.Abs(axisValue - this[index - 1].ScaleMaximum)) + { + return this[index]; + } + else + { + return this[index - 1]; + } + } + } + + if(axisValue <= this[index].ScaleMaximum) + { + return this[index]; + } + else if(index == this.Count - 1) + { + return this[index]; + } + } + + return null; + } + + #endregion // Helper Methods + } +} + diff --git a/System.Web.DataVisualization/Common/General/AxisScrollBar.cs b/System.Web.DataVisualization/Common/General/AxisScrollBar.cs new file mode 100644 index 000000000..cbb389e99 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/AxisScrollBar.cs @@ -0,0 +1,1952 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: AxisScrollBar.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: AxisScrollBar, ScrollBarEventArgs +// +// Purpose: AxisScrollBar class represent axis scroolbar. There +// is a big difference how this UI functionality +// implemented for Windows Forms and ASP.NET. For +// Windows Forms a custom drawn scrollbar control is +// drawn in the chart which reacts to the mouse input and +// changes current axis data scaleView. +// +// ASP.NET version uses client-side scripting and partial +// loading of data segment by segment. Due to the fact +// that scrollbar operates on the client side not all +// functionality of WindowsForms scrollbar is supported. +// +// Reviewed: AG - March 16, 2007 +// +//=================================================================== + +#if WINFORMS_CONTROL + +#region Used namespaces + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; +using System.Diagnostics.CodeAnalysis; + +#endregion + +namespace System.Windows.Forms.DataVisualization.Charting +{ + #region Scroll bar enumerations + + /// + /// An enumeration of scrollbar button types. + /// + public enum ScrollBarButtonType + { + /// + /// Thumb tracker button. + /// + ThumbTracker, + + /// + /// Scroll by substracting small distance. + /// + SmallDecrement, + + /// + /// Scroll by adding small distance. + /// + SmallIncrement, + + /// + /// Scroll by substracting large distance. + /// + LargeDecrement, + + /// + /// Scroll by adding large distance. + /// + LargeIncrement, + + /// + /// Zoom reset button. + /// + ZoomReset + } + + /// + /// An enumeration of scrollbar button style flags. + /// + [Flags] + public enum ScrollBarButtonStyles + { + /// + /// No buttons are shown. + /// + None = 0, + + /// + /// Small increment or decrement buttons are shown. + /// + SmallScroll = 1, + + /// + /// Reset zoom buttons are shown. + /// + ResetZoom = 2, + + /// + /// All buttons are shown. + /// + All = SmallScroll | ResetZoom + } + + #endregion + + /// + /// AxisScrollBar class represents the axis scrollbar. It is exposed as the + /// ScrollBar property of the Axis class. It contains scrollbar appearance + /// properties and drawing methods. + /// + public class AxisScrollBar : IDisposable + { + #region Scroll bar fields + + // Reference to the axis data scaleView class + internal Axis axis = null; + + // Indicates that scollbra will be drawn + private bool _enabled = true; + + // Axis data scaleView scroll bar style + private ScrollBarButtonStyles _scrollBarButtonStyle = ScrollBarButtonStyles.All; + + // Axis data scaleView scroll bar size + private double _scrollBarSize = 14.0; + + // Index of the pressed butoon in the scroll bar + private int _pressedButtonType = int.MaxValue; + + // Axis data scaleView scroll bar buttons color + private Color _buttonColor = Color.Empty; + + // Axis data scaleView scroll bar back color + private Color _backColor = Color.Empty; + + // Axis data scaleView scroll bar lines color + private Color _lineColor = Color.Empty; + + // Current scroll bar drawing colors + private Color _buttonCurrentColor = Color.Empty; + private Color _backCurrentColor = Color.Empty; + private Color _lineCurrentColor = Color.Empty; + + // Last mouse click mouse and scaleView position + private PointF _lastClickMousePosition = PointF.Empty; + private double _lastClickViewPosition = double.NaN; + + // Timer used to scroll the data while selecting + private System.Windows.Forms.Timer _scrollTimer = new System.Windows.Forms.Timer(); + + // Scroll size and direction when AutoScroll is set + private MouseEventArgs _mouseArguments = null; + + // Position of the scrollbar (true - edge of PlotArea, false - edge of chart area) + private bool _isPositionedInside = true; + + #endregion + + #region Scroll bar constructors and initialization + + /// + /// AxisScrollBar constructor. + /// + public AxisScrollBar() + { + } + + /// + /// Axis scroll bar constructor. + /// + /// Reference to the axis class. + internal AxisScrollBar(Axis axis) + { + // Save reference to the axis data scaleView + this.axis = axis; + } + + /// + /// Initialize axis scroll bar class. + /// + internal void Initialize() + { + } + + #endregion + +#region Scroll bar properties + + /// + /// Gets or sets a flag which indicates whether scroll bar is positioned inside or outside of chart area. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeAxisScrollBar_PositionInside") + ] + public bool IsPositionedInside + { + get + { + return _isPositionedInside; + } + set + { + if(_isPositionedInside != value) + { + _isPositionedInside = value; + if(axis != null) + { + axis.ChartArea.Invalidate(); + } + } + } + } + + + /// + /// Gets or sets a flag which indicates whether the scroll bar is enabled. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeAxisScrollBar_Enabled") + ] + public bool Enabled + { + get + { + return _enabled; + } + set + { + if(_enabled != value) + { + _enabled = value; + if(axis != null) + { + axis.ChartArea.Invalidate(); + } + } + } + } + + /// + /// Gets the ChartArea that contains this scrollbar. + /// + [ + Browsable(false), + Bindable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public ChartArea ChartArea + { + get + { + return this.axis.ChartArea; + } + } + + /// + /// Gets the Axis that contains this scrollbar. + /// + [ + Browsable(false), + Bindable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public Axis Axis + { + get + { + return this.axis; + } + } + + /// + /// Gets or sets the style of the scrollbar button. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), +#if WEB_OLAP + DefaultValue(ScrollBarButtonStyle.SmallScroll), +#else + DefaultValue(ScrollBarButtonStyles.All), +#endif + SRDescription("DescriptionAttributeAxisScrollBar_Buttons"), + Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base) + ] + public ScrollBarButtonStyles ButtonStyle + { + get + { + return _scrollBarButtonStyle; + } + set + { + if(_scrollBarButtonStyle != value) + { + _scrollBarButtonStyle = value; + if(axis != null) + { + axis.ChartArea.Invalidate(); + } + } + } + } + + /// + /// Gets or sets the size of the scrollbar. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(14.0), + SRDescription("DescriptionAttributeAxisScrollBar_Size"), + ] + public double Size + { + get + { + return _scrollBarSize; + } + set + { + if(_scrollBarSize != value) + { + // Check values range + if(value < 5.0 || value > 20.0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionScrollBarSizeInvalid)); + } + _scrollBarSize = value; + if(axis != null) + { + axis.ChartArea.Invalidate(); + } + } + } + } + + /// + /// Gets or sets the button color of the scrollbar. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeAxisScrollBar_ButtonColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + public Color ButtonColor + { + get + { + return _buttonColor; + } + set + { + if(_buttonColor != value) + { + _buttonColor = value; + if(axis != null) + { + axis.ChartArea.Invalidate(); + } + } + } + } + + /// + /// Gets or sets the line color of the scrollbar. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeLineColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + public Color LineColor + { + get + { + return _lineColor; + } + set + { + if(_lineColor != value) + { + _lineColor = value; + if(axis != null) + { + axis.ChartArea.Invalidate(); + } + } + } + } + + /// + /// Gets or sets the background color of the scrollbar. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base) + ] + public Color BackColor + { + get + { + return _backColor; + } + set + { + if(_backColor != value) + { + _backColor = value; + if(axis != null) + { + axis.ChartArea.Invalidate(); + } + } + } + } + +#endregion + +#region Scroll bar public methods + + /// + /// This method returns true if the scrollbar is visible. + /// + [Browsable(false)] + [Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)] + public bool IsVisible + { + get + { + // Check scroll bar enabled flag + if (!this.Enabled) + { + return false; + } + + // Do not show scroll bars while printing + if (this.axis == null || + this.axis.ChartArea == null || + this.axis.ChartArea.Common == null || + this.axis.ChartArea.Common.ChartPicture == null || + this.axis.ChartArea.Common.ChartPicture.isPrinting) + { + return false; + } + +#if SUBAXES + // Scrollbar is not supported on the sub axis + if(this.axis.IsSubAxis) + { + return false; + } +#endif // SUBAXES + + // Check if data scaleView size in percentage is less than 100% + return (GetDataViewPercentage() < 100.0) ? true : false; + } + } + +#endregion + +#region Scroll bar painting methods + + /// + /// Draws axis scroll bar. + /// + /// Reference to the Chart Graphics object. + internal void Paint( ChartGraphics graph ) + { + // Scroll bar border width + int borderWidth = 1; + + // Scroll bar should not be visible + if(!this.IsVisible) + { + return; + } + +#if SUBAXES + // Scrollbar not supported on sub axis + if( this.axis != null && this.axis.IsSubAxis) + { + return; + } +#endif //SUBAXES + + // Set current scroll bar colors + _buttonCurrentColor = this._buttonColor; + _backCurrentColor = this._backColor; + _lineCurrentColor = this._lineColor; + + // Make sure the current colors are not empty + if(_buttonCurrentColor == Color.Empty) + { + _buttonCurrentColor = this.axis.ChartArea.BackColor; + if(_buttonCurrentColor == Color.Empty) + { + _buttonCurrentColor = Color.DarkGray; + } + } + if(_backCurrentColor == Color.Empty) + { + _backCurrentColor = this.axis.ChartArea.BackColor; + if(_backCurrentColor == Color.Empty) + { + _backCurrentColor = Color.LightGray; + } + } + if(_lineCurrentColor == Color.Empty) + { + _lineCurrentColor = this.axis.LineColor; + if(_lineCurrentColor == Color.Empty) + { + _lineCurrentColor = Color.Black; + } + } + + // Get scroll bar rectangle + RectangleF scrollBarRect = this.GetScrollBarRect(); + + // Fill scroll bar background + graph.FillRectangleRel( + scrollBarRect, + _backCurrentColor, + ChartHatchStyle.None, + "", + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + _lineCurrentColor, + borderWidth, + ChartDashStyle.Solid, + Color.Empty, + 0, + PenAlignment.Outset ); + + // Fill rectangle between to neighbour scroll bars + PaintScrollBarConnectionRect(graph, scrollBarRect, borderWidth); + + // Get scroll bar client rectangle + SizeF borderRelativeSize = new SizeF(borderWidth, borderWidth); + borderRelativeSize = graph.GetRelativeSize(borderRelativeSize); + RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size); + scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height); + + // Draw all button types + foreach (ScrollBarButtonType buttonType in Enum.GetValues(typeof(ScrollBarButtonType))) + { + // Get button rectangle + RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)buttonType); + + // Paint button + if(!buttonRect.IsEmpty) + { + PaintScrollBar3DButton( + graph, + buttonRect, + ((ScrollBarButtonType)this._pressedButtonType) == (ScrollBarButtonType)buttonType, + (ScrollBarButtonType)buttonType); + } + } + + if( this.ChartArea.Common.ProcessModeRegions ) + { + SetHotRegionElement( this.ChartArea.Common ); + } + } + + /// + /// Fills a connection rectangle between two scoll bars. + /// + /// Chart graphics. + /// Scroll bar position. + /// Border width. + private void PaintScrollBarConnectionRect( + ChartGraphics graph, + RectangleF scrollBarRect, + int borderWidth) + { + // Do not draw anything if scroll bar is vertical + if(this.axis.AxisPosition == AxisPosition.Left || + this.axis.AxisPosition == AxisPosition.Right) + { + return; + } + + // Check if scoll bar is shown on the left/right sides of + // the plotting area and get their sizes in relative coordinates + float leftSize = 0f; + float rightSize = 0f; + + foreach(Axis a in this.axis.ChartArea.Axes) + { + if(a.AxisPosition == AxisPosition.Left && a.ScrollBar.IsVisible && a.ScrollBar.IsPositionedInside == this.axis.ScrollBar.IsPositionedInside) + { + leftSize = (float)a.ScrollBar.GetScrollBarRelativeSize(); + } + if(a.AxisPosition == AxisPosition.Right && a.ScrollBar.IsVisible && a.ScrollBar.IsPositionedInside == this.axis.ScrollBar.IsPositionedInside) + { + rightSize = (float)a.ScrollBar.GetScrollBarRelativeSize(); + } + } + + // Prepare generic rectangle coordinates + RectangleF connectorRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size); + + // Prepare coordinates and fill area to the left + if(leftSize > 0f) + { + connectorRect.X = scrollBarRect.X - leftSize; + connectorRect.Width = leftSize; + + // Fill background + graph.FillRectangleRel( + connectorRect, + _backCurrentColor, + ChartHatchStyle.None, + "", + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + _lineCurrentColor, + borderWidth, + ChartDashStyle.Solid, + Color.Empty, + 0, + PenAlignment.Outset ); + } + + // Prepare coordinates and fill area to the right + if(rightSize > 0f) + { + connectorRect.X = scrollBarRect.Right; + connectorRect.Width = rightSize; + + // Fill background + graph.FillRectangleRel( + connectorRect, + _backCurrentColor, + ChartHatchStyle.None, + "", + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + _lineCurrentColor, + borderWidth, + ChartDashStyle.Solid, + Color.Empty, + 0, + PenAlignment.Outset ); + } + + } + + /// + /// Draws 3D button in the scroll bar + /// + /// Chart graphics. + /// Button position. + /// Indicates that button is pressed. + /// Button type to draw. + internal void PaintScrollBar3DButton( + ChartGraphics graph, + RectangleF buttonRect, + bool pressedState, + ScrollBarButtonType buttonType) + { + // Page Up/Down buttons do not require drawing + if(buttonType == ScrollBarButtonType.LargeIncrement || buttonType == ScrollBarButtonType.LargeDecrement) + { + return; + } + + // Get 3 levels of colors for button drawing + Color darkerColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.Black, 0.5); + Color darkestColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.Black, 0.8); + Color lighterColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.White, 0.5); + + // Fill button rectangle background + graph.FillRectangleRel( + buttonRect, + _buttonCurrentColor, + ChartHatchStyle.None, + "", + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + darkerColor, + (pressedState) ? 1 : 0, + ChartDashStyle.Solid, + Color.Empty, + 0, + PenAlignment.Outset ); + + // Check if 2 or 1 pixel border will be drawn (if size too small) + bool singlePixelBorder = this.Size <= 12; + + // Draw 3D effect around the button when not pressed + if(!pressedState) + { + // Get relative size of 1 pixel + SizeF pixelRelativeSize = new SizeF(1, 1); + pixelRelativeSize = graph.GetRelativeSize(pixelRelativeSize); + + // Draw top/left border with button color + graph.DrawLineRel( + (singlePixelBorder) ? lighterColor : _buttonCurrentColor, 1, ChartDashStyle.Solid, + new PointF(buttonRect.X, buttonRect.Bottom), + new PointF(buttonRect.X, buttonRect.Top)); + graph.DrawLineRel( + (singlePixelBorder) ? lighterColor : _buttonCurrentColor, 1, ChartDashStyle.Solid, + new PointF(buttonRect.Left, buttonRect.Y), + new PointF(buttonRect.Right, buttonRect.Y)); + + // Draw right/bottom border with the darkest color + graph.DrawLineRel( + (singlePixelBorder) ? darkerColor : darkestColor, 1, ChartDashStyle.Solid, + new PointF(buttonRect.Right, buttonRect.Bottom), + new PointF(buttonRect.Right, buttonRect.Top)); + graph.DrawLineRel( + (singlePixelBorder) ? darkerColor : darkestColor, 1, ChartDashStyle.Solid, + new PointF(buttonRect.Left, buttonRect.Bottom), + new PointF(buttonRect.Right, buttonRect.Bottom)); + + if(!singlePixelBorder) + { + // Draw right/bottom border (offset 1) with the dark color + graph.DrawLineRel( + darkerColor, 1, ChartDashStyle.Solid, + new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height), + new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Top+pixelRelativeSize.Height)); + graph.DrawLineRel( + darkerColor, 1, ChartDashStyle.Solid, + new PointF(buttonRect.Left+pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height), + new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height)); + + // Draw top/left border (offset 1) with lighter color + graph.DrawLineRel( + lighterColor, 1, ChartDashStyle.Solid, + new PointF(buttonRect.X+pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height), + new PointF(buttonRect.X+pixelRelativeSize.Width, buttonRect.Top+pixelRelativeSize.Height)); + graph.DrawLineRel( + lighterColor, 1, ChartDashStyle.Solid, + new PointF(buttonRect.Left+pixelRelativeSize.Width, buttonRect.Y+pixelRelativeSize.Height), + new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Y+pixelRelativeSize.Height)); + } + } + + // Check axis orientation + bool verticalAxis = (this.axis.AxisPosition == AxisPosition.Left || + this.axis.AxisPosition == AxisPosition.Right) ? true : false; + + // Set graphics transformation for button pressed mode + float pressedShifting = (singlePixelBorder) ? 0.5f : 1f; + if(pressedState) + { + graph.TranslateTransform(pressedShifting, pressedShifting); + } + + // Draw button image + RectangleF buttonAbsRect = graph.GetAbsoluteRectangle(buttonRect); + float imageOffset = (singlePixelBorder) ? 2 : 3; + switch(buttonType) + { + case(ScrollBarButtonType.SmallDecrement): + { + // Calculate triangal points position + PointF[] points = new PointF[3]; + if(verticalAxis) + { + points[0].X = buttonAbsRect.X + imageOffset; + points[0].Y = buttonAbsRect.Y + (imageOffset + 1f); + points[1].X = buttonAbsRect.X + buttonAbsRect.Width/2f; + points[1].Y = buttonAbsRect.Bottom - imageOffset; + points[2].X = buttonAbsRect.Right - imageOffset; + points[2].Y = buttonAbsRect.Y + (imageOffset + 1f); + } + else + { + points[0].X = buttonAbsRect.X + imageOffset; + points[0].Y = buttonAbsRect.Y + buttonAbsRect.Height/2f; + points[1].X = buttonAbsRect.Right - (imageOffset + 1f); + points[1].Y = buttonAbsRect.Y + imageOffset; + points[2].X = buttonAbsRect.Right - (imageOffset + 1f); + points[2].Y = buttonAbsRect.Bottom - imageOffset; + } + + using (Brush brush = new SolidBrush(this._lineCurrentColor)) + { + graph.FillPolygon(brush, points); + } + break; + } + case(ScrollBarButtonType.SmallIncrement): + { + // Calculate triangal points position + PointF[] points = new PointF[3]; + if(verticalAxis) + { + points[0].X = buttonAbsRect.X + imageOffset; + points[0].Y = buttonAbsRect.Bottom - (imageOffset + 1f); + points[1].X = buttonAbsRect.X + buttonAbsRect.Width/2f; + points[1].Y = buttonAbsRect.Y + imageOffset; + points[2].X = buttonAbsRect.Right - imageOffset; + points[2].Y = buttonAbsRect.Bottom - (imageOffset + 1f); + } + else + { + points[0].X = buttonAbsRect.Right - imageOffset; + points[0].Y = buttonAbsRect.Y + buttonAbsRect.Height/2f; + points[1].X = buttonAbsRect.X + (imageOffset + 1f); + points[1].Y = buttonAbsRect.Y + imageOffset; + points[2].X = buttonAbsRect.X + (imageOffset + 1f); + points[2].Y = buttonAbsRect.Bottom - imageOffset; + } + + using (Brush brush = new SolidBrush(this._lineCurrentColor)) + { + graph.FillPolygon(brush, points); + } + break; + } + case(ScrollBarButtonType.ZoomReset): + { + // Draw circule with a minus sign + using (Pen pen = new Pen(this._lineCurrentColor, 1)) + { + graph.DrawEllipse(pen, buttonAbsRect.X + imageOffset - 0.5f, buttonAbsRect.Y + imageOffset - 0.5f, buttonAbsRect.Width - 2f * imageOffset, buttonAbsRect.Height - 2f * imageOffset); + graph.DrawLine(pen, buttonAbsRect.X + imageOffset + 1.5f, buttonAbsRect.Y + buttonAbsRect.Height / 2f - 0.5f, buttonAbsRect.Right - imageOffset - 2.5f, buttonAbsRect.Y + buttonAbsRect.Height / 2f - 0.5f); + } + break; + } + } + + // Reset graphics transformation for button pressed mode + if(pressedState) + { + graph.TranslateTransform(-pressedShifting, -pressedShifting); + } + } + +#endregion + +#region Mouse events handling for the Scroll Bar + + /// + /// Mouse down event handler. + /// + internal void ScrollBar_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) + { + // Process left mouse button + if(e.Button == MouseButtons.Left && this.IsVisible) + { + // Remember position where mouse was clicked + _lastClickMousePosition = new PointF(e.X, e.Y); + _lastClickViewPosition = this.axis.ScaleView.Position; + + // Check if button was pressed inside the scroll bar + ScrollBarButtonType buttonType; + if(GetElementByPixelPosition(e.X, e.Y, out buttonType)) + { + this.ButtonClicked(buttonType, e.X, e.Y); + } + } + } + + /// + /// Mouse up event handler. + /// + internal void ScrollBar_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) + { + // If scroll bar button was pressed + if(this._pressedButtonType != int.MaxValue) + { + // Check if button was unpressed inside the reset zoom button + ScrollBarButtonType buttonType; + if(GetElementByPixelPosition(e.X, e.Y, out buttonType)) + { + if(buttonType == ScrollBarButtonType.ZoomReset) + { + this.ButtonClicked(buttonType, e.X, e.Y); + } + } + + // Stop scrolling timer + _scrollTimer.Stop(); + _mouseArguments = null; + + // Clear pressed button state + this._pressedButtonType = int.MaxValue; + + // Invalidate chart + this.axis.Invalidate(); + } + } + + /// + /// Mouse move event handler. + /// + internal void ScrollBar_MouseMove(System.Windows.Forms.MouseEventArgs e, ref bool handled) + { + // If scroll bar button was pressed + if(this._pressedButtonType != int.MaxValue) + { + // Mouse move event should not be handled by any other chart elements + handled = true; + + // Check if tracking buton was pressed + if((ScrollBarButtonType)this._pressedButtonType == ScrollBarButtonType.ThumbTracker) + { + // Proceed if last clicked position is known + if(!_lastClickMousePosition.IsEmpty) + { + this.ButtonClicked(ScrollBarButtonType.ThumbTracker, e.X, e.Y); + } + } + + // Non tracking scroll bar button + else + { + // Check if mouse cursor is still in the pressed button's rectangle + bool inPressedButton = false; + ScrollBarButtonType buttonType; + if(GetElementByPixelPosition(e.X, e.Y, out buttonType)) + { + if(buttonType == (ScrollBarButtonType)this._pressedButtonType) + { + inPressedButton = true; + } + } + + // Clear pressed button state + if(!inPressedButton) + { + // Stop scrolling timer + _scrollTimer.Stop(); + _mouseArguments = null; + + // Clear pressed button state + this._pressedButtonType = int.MaxValue; + + // Invalidate chart + this.axis.Invalidate(); + } + } + } + } + + /// + /// Scroll bar button was clicked by the user. + /// + /// Button type. + /// X click position in pixels. + /// Y click position in pixels. + [SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Justification = "The timer is used for simulating scrolling behavior")] + private void ButtonClicked(ScrollBarButtonType buttonType, int x, int y) + { + // Call zoom reset on the second pass when button is released + if(buttonType != ScrollBarButtonType.ZoomReset || + (ScrollBarButtonType)this._pressedButtonType == buttonType) + { + + //************************************************** + //** Fire scroll bar button clicked event + //************************************************** + ScrollBarEventArgs eventArg = new ScrollBarEventArgs(this.axis, x, y, buttonType); + this.axis.ScaleView.GetChartObject().OnAxisScrollBarClicked(eventArg); + + // Check if event was handled by user + if(eventArg.IsHandled) + { + // Save type of the button pressed + this._pressedButtonType = (int)buttonType; + + return; + } + + //************************************************** + //** Scroll data scaleView + //************************************************** + switch(buttonType) + { + case(ScrollBarButtonType.SmallIncrement): + this.axis.ScaleView.Scroll(ScrollType.SmallIncrement, true); + break; + case(ScrollBarButtonType.SmallDecrement): + this.axis.ScaleView.Scroll(ScrollType.SmallDecrement, true); + break; + case(ScrollBarButtonType.LargeIncrement): + this.axis.ScaleView.Scroll(ScrollType.LargeIncrement, true); + break; + case(ScrollBarButtonType.LargeDecrement): + this.axis.ScaleView.Scroll(ScrollType.LargeDecrement, true); + break; + case(ScrollBarButtonType.ZoomReset): + this.axis.ScaleView.ZoomReset(1, true); + break; + case(ScrollBarButtonType.ThumbTracker): + { + if(!_lastClickMousePosition.IsEmpty && + !double.IsNaN(this._lastClickViewPosition) && + (_lastClickMousePosition.X != x || _lastClickMousePosition.Y != y)) + { + // Get scroll bar client rectangle + RectangleF scrollBarRect = this.GetScrollBarRect(); + SizeF borderRelativeSize = new SizeF(1, 1); + borderRelativeSize = this.GetRelativeSize(borderRelativeSize); + RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size); + scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height); + + // Check axis orientation + bool verticalAxis = (this.axis.AxisPosition == AxisPosition.Left || + this.axis.AxisPosition == AxisPosition.Right) ? true : false; + + // Get button relative size + SizeF buttonSize = new SizeF(scrollBarClientRect.Width, scrollBarClientRect.Height); + buttonSize = this.GetAbsoluteSize(buttonSize); + if(verticalAxis) + { + buttonSize.Height = buttonSize.Width; + } + else + { + buttonSize.Width = buttonSize.Height; + } + buttonSize = this.GetRelativeSize(buttonSize); + + // Calculate the distance in percentages the mouse was moved + // from it's original (clicked) position. + float distance = 0f; + double trackingAreaSize = 0f; + if(verticalAxis) + { + // Calculate max tracking size + trackingAreaSize = scrollBarClientRect.Height - this.GetButtonsNumberAll() * buttonSize.Height; + distance = _lastClickMousePosition.Y - y; + + // Convert to relative coordinates + distance = distance * 100F / ((float)(this.axis.Common.Height - 1)); + } + else + { + trackingAreaSize = scrollBarClientRect.Width - this.GetButtonsNumberAll() * buttonSize.Width; + distance = x - _lastClickMousePosition.X; + + // Convert to relative coordinates + distance = distance * 100F / ((float)(this.axis.Common.Width - 1)); + } + + // Convert to percentages from total tracking area + distance = (float)(distance / (trackingAreaSize / 100f)); + + // Get axis scale size without margins + double axisScaleSize = Math.Abs( + (this.axis.maximum - this.axis.marginView) - + (this.axis.minimum + this.axis.marginView)); + + // Calculate the same percentage using axis scale + distance = (float)(distance * (axisScaleSize/100f)); + + // Round the distance to the minimum scroll line size + if(!double.IsNaN(axis.ScaleView.SmallScrollMinSize) && axis.ScaleView.SmallScrollMinSize != 0.0) + { + double minSize = ChartHelper.GetIntervalSize(0, axis.ScaleView.SmallScrollMinSize, axis.ScaleView.SmallScrollMinSizeType); + + double rounder = (Math.Round(distance / minSize)); + distance = (float)(rounder * minSize); + } + + // Scroll scaleView into the new position + this.axis.ScaleView.Scroll(this._lastClickViewPosition + ((this.axis.IsReversed) ? -1 : 1) * distance, true); + } + break; + } + } + + //************************************************************ + //** Initialize timer for repeating scroll (if mouse is hold) + //************************************************************ + + // Reset mouse arguments + _mouseArguments = null; + + if(buttonType != ScrollBarButtonType.ThumbTracker && buttonType != ScrollBarButtonType.ZoomReset) + { + // Remember last mouse position + _mouseArguments = new MouseEventArgs(MouseButtons.Left, 1, x, y, 0); + + // Enable timer + if(!_scrollTimer.Enabled) + { + _scrollTimer.Tick += new EventHandler(ScrollingTimerEventProcessor); + _scrollTimer.Interval = 400; + _scrollTimer.Start(); + } + } + } + + //************************************************************ + //** Invalidate chart + //************************************************************ + + // Save type of the button pressed + this._pressedButtonType = (int)buttonType; + + // Invalidate + this.axis.Invalidate(); + } + + /// + /// This is the method to run when the timer is raised. + /// Used to repetedly scroll data scaleView while mouse button is pressed. + /// + /// Object. + /// Event arguments. + [SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Justification = "The timer is used for simulating scrolling behavior")] + private void ScrollingTimerEventProcessor(Object myObject, EventArgs myEventArgs) + { + // Simulate mouse move events + if(_mouseArguments != null) + { + _scrollTimer.Interval = 200; + this.ScrollBar_MouseDown(null, _mouseArguments); + } + } + + /// + /// This method fills hot region collection with scroll bar elements. + /// Possible elements are all scroll bar buttons and scroll bar background + /// which performs PgUp/PgDn action. + /// + /// Common Elements + private void SetHotRegionElement( CommonElements common ) + { + // Check if mouse button was clicked in the scroll bar + RectangleF scrollBarRect = this.GetScrollBarRect(); + + // Get scroll bar client rectangle + SizeF borderRelativeSize = new SizeF(1, 1); + borderRelativeSize = this.GetRelativeSize(borderRelativeSize); + RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size); + scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height); + + ChartElementType buttonType = ChartElementType.Nothing; + + // Fill collection with scroll buttons rectangles. + foreach(object type in Enum.GetValues(typeof(ScrollBarButtonType))) + { + + // Convert Scroll Bar Button type enum to Chart Element AxisName enum. + switch( (ScrollBarButtonType)type ) + { + case ScrollBarButtonType.SmallIncrement: + buttonType = ChartElementType.ScrollBarSmallIncrement; + break; + case ScrollBarButtonType.LargeIncrement: + buttonType = ChartElementType.ScrollBarLargeIncrement; + break; + case ScrollBarButtonType.LargeDecrement: + buttonType = ChartElementType.ScrollBarLargeDecrement; + break; + case ScrollBarButtonType.ThumbTracker: + buttonType = ChartElementType.ScrollBarThumbTracker; + break; + case ScrollBarButtonType.SmallDecrement: + buttonType = ChartElementType.ScrollBarSmallDecrement; + break; + case ScrollBarButtonType.ZoomReset: + buttonType = ChartElementType.ScrollBarZoomReset; + break; + } + + // Get button rectangle + RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)type); + + common.HotRegionsList.AddHotRegion( buttonRect, this, buttonType, true ); + + } + } + + /// + /// Detects the scroll bar elements by pixel position. + /// Possible elements are all scroll bar buttons and scroll bar background + /// which performs PgUp/PgDn action. + /// + /// X coordinate in pixels. + /// Y coordinate in pixels. + /// Return button type. + /// True if position is in the scroll bar. + private bool GetElementByPixelPosition(float x, float y, out ScrollBarButtonType buttonType) + { + // Set initial values + buttonType = ScrollBarButtonType.ThumbTracker; + + // Convert mouse click coordinates to relative + PointF position = new PointF(x, y); + position.X = x * 100F / ((float)(this.axis.Common.Width - 1)); + position.Y = y * 100F / ((float)(this.axis.Common.Height - 1)); + + // Check if mouse button was clicked in the scroll bar + RectangleF scrollBarRect = this.GetScrollBarRect(); + if(scrollBarRect.Contains(position)) + { + // Get scroll bar client rectangle + SizeF borderRelativeSize = new SizeF(1, 1); + borderRelativeSize = this.GetRelativeSize(borderRelativeSize); + RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size); + scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height); + + //****************************************************************** + //** Check if scroll bar button was clicked + //****************************************************************** + foreach(object type in Enum.GetValues(typeof(ScrollBarButtonType))) + { + // Get button rectangle + RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)type); + + // Check if position is inside the button + if(buttonRect.Contains(position)) + { + buttonType = (ScrollBarButtonType)type; + return true; + } + } + } + + // Pixel position is outside scroll bar area + return false; + } + +#endregion + +#region Scroll bar helper methods + + /// + /// Returns scroll bar button rectangle position in relative coordinates. + /// + /// Scroll bar client rectangle. + /// Scroll bar button type. + /// Scroll bar position. + internal RectangleF GetScrollBarButtonRect(RectangleF scrollBarClientRect, ScrollBarButtonType buttonType) + { + // Initialize button rectangle + RectangleF buttonRect = new RectangleF(scrollBarClientRect.Location, scrollBarClientRect.Size); + + // Check axis orientation + bool verticalAxis = (this.axis.AxisPosition == AxisPosition.Left || + this.axis.AxisPosition == AxisPosition.Right) ? true : false; + + // Get relative size of 1 pixel + SizeF pixelRelativeSize = new SizeF(1, 1); + pixelRelativeSize = this.GetRelativeSize(pixelRelativeSize); + + // Get button relative size + SizeF buttonSize = new SizeF(scrollBarClientRect.Width, scrollBarClientRect.Height); + buttonSize = this.GetAbsoluteSize(buttonSize); + if(verticalAxis) + { + buttonSize.Height = buttonSize.Width; + } + else + { + buttonSize.Width = buttonSize.Height; + } + buttonSize = this.GetRelativeSize(buttonSize); + + // Set common position sizes + buttonRect.Width = buttonSize.Width; + buttonRect.Height = buttonSize.Height; + if(verticalAxis) + { + buttonRect.X = scrollBarClientRect.X; + } + else + { + buttonRect.Y = scrollBarClientRect.Y; + } + + // Calculate scroll bar buttons position + switch(buttonType) + { + case(ScrollBarButtonType.LargeDecrement): + case(ScrollBarButtonType.LargeIncrement): + case(ScrollBarButtonType.ThumbTracker): + { + // Get tracker button position and size first + if(verticalAxis) + { + // Calculate tracker size + double trackingAreaSize = scrollBarClientRect.Height - this.GetButtonsNumberAll() * buttonSize.Height; + buttonRect.Height = (float)(this.GetDataViewPercentage() * (trackingAreaSize / 100f)); + + // Check if tracker size is too small + if(buttonRect.Height < pixelRelativeSize.Height * 6f) + { + buttonRect.Height = pixelRelativeSize.Height * 6f; + } + + // Calculate tracker position + if(!this.axis.IsReversed) + { + buttonRect.Y = scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - buttonRect.Height; + buttonRect.Y -= (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f)); + if(buttonRect.Y < scrollBarClientRect.Y + this.GetButtonsNumberTop()*buttonSize.Height + ((this.GetButtonsNumberTop() == 0) ? 0 : pixelRelativeSize.Height)) + { + buttonRect.Y = scrollBarClientRect.Y + this.GetButtonsNumberTop()*buttonSize.Height + ((this.GetButtonsNumberTop() == 0) ? 0 : pixelRelativeSize.Height); + } + } + else + { + buttonRect.Y = scrollBarClientRect.Top + this.GetButtonsNumberTop()*buttonSize.Height; + buttonRect.Y += (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f)); + if((buttonRect.Y + buttonRect.Height) > scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Height)) + { + buttonRect.Y = (scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height) - buttonRect.Height - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Height); + } + } + } + else + { + // Calculate tracker size + double trackingAreaSize = scrollBarClientRect.Width - this.GetButtonsNumberAll() * buttonSize.Width; + buttonRect.Width = (float)(this.GetDataViewPercentage() * (trackingAreaSize / 100f)); + + // Check if tracker size is too small + if(buttonRect.Width < pixelRelativeSize.Width * 6f) + { + buttonRect.Width = pixelRelativeSize.Width * 6f; + } + + // Calculate tracker position + if(!this.axis.IsReversed) + { + buttonRect.X = scrollBarClientRect.X + this.GetButtonsNumberTop() * buttonSize.Width; + buttonRect.X += (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f)); + if((buttonRect.X + buttonRect.Width) > scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width)) + { + buttonRect.X = (scrollBarClientRect.Right - buttonRect.Width) - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width); + } + } + else + { + buttonRect.X = scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width) - buttonRect.Width; + buttonRect.X -= (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f)); + if(buttonRect.X < scrollBarClientRect.X + this.GetButtonsNumberTop()*buttonSize.Width) + { + buttonRect.X = scrollBarClientRect.X + this.GetButtonsNumberTop()*buttonSize.Width; + } + } + + } + + // Get page up region rectangle depending on the tracker position + if(buttonType == ScrollBarButtonType.LargeDecrement) + { + if(verticalAxis) + { + buttonRect.Y = buttonRect.Bottom + pixelRelativeSize.Height; + buttonRect.Height = (scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - pixelRelativeSize.Height) - buttonRect.Y; + } + else + { + float x = scrollBarClientRect.X + + this.GetButtonsNumberTop() * buttonSize.Width + + pixelRelativeSize.Width; + + buttonRect.Width = buttonRect.X - x; + buttonRect.X = x; + } + } + + // Get page down region rectangle depending on the tracker position + else if(buttonType == ScrollBarButtonType.LargeIncrement) + { + if(verticalAxis) + { + float y = scrollBarClientRect.Y + + this.GetButtonsNumberTop() * buttonSize.Height + + pixelRelativeSize.Height; + + buttonRect.Height = buttonRect.Y - y; + buttonRect.Y = y; + } + else + { + buttonRect.X = buttonRect.Right + pixelRelativeSize.Width; + buttonRect.Width = (scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - pixelRelativeSize.Height) - buttonRect.X; + } + } + + break; + } + + case(ScrollBarButtonType.SmallDecrement): + if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All || + this._scrollBarButtonStyle == ScrollBarButtonStyles.SmallScroll) + { + if(verticalAxis) + { + buttonRect.Y = scrollBarClientRect.Bottom - buttonRect.Height; + } + else + { + buttonRect.X = scrollBarClientRect.X + (this.GetButtonsNumberTop()-1f)*buttonSize.Width; + buttonRect.X += (this.GetButtonsNumberTop() == 1) ? 0 : pixelRelativeSize.Width; + } + } + else + { + buttonRect = RectangleF.Empty; + } + break; + + case(ScrollBarButtonType.SmallIncrement): + if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All || + this._scrollBarButtonStyle == ScrollBarButtonStyles.SmallScroll) + { + if(verticalAxis) + { + buttonRect.Y = scrollBarClientRect.Y + (this.GetButtonsNumberTop()-1f) * buttonSize.Height; + buttonRect.Y += (this.GetButtonsNumberTop() == 1) ? 0 : pixelRelativeSize.Height; + } + else + { + buttonRect.X = scrollBarClientRect.Right - buttonRect.Width; + } + } + else + { + buttonRect = RectangleF.Empty; + } + break; + + case(ScrollBarButtonType.ZoomReset): + if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All || + this._scrollBarButtonStyle == ScrollBarButtonStyles.ResetZoom) + { + if(verticalAxis) + { + buttonRect.Y = scrollBarClientRect.Y; + } + else + { + buttonRect.X = scrollBarClientRect.X; + } + } + else + { + buttonRect = RectangleF.Empty; + } + break; + } + + return buttonRect; + } + + /// + /// Returns scroll bar rectangle position in relative coordinates. + /// + /// Scroll bar position. + internal RectangleF GetScrollBarRect() + { + // Get scroll bar relative size + float scrollBarSize = (float)this.GetScrollBarRelativeSize(); + + // Get relative size of the axis line (Note: Code removed for now. -- AG) + //SizeF axisLineSize = new SizeF(axis.LineWidth, axis.LineWidth); + //axisLineSize.Width = axisLineSize.Width * 100F / ((float)(this.axis.Common.Width - 1)); + //axisLineSize.Height = axisLineSize.Height * 100F / ((float)(this.axis.Common.Height - 1)); + + // Check if scroll bar is positioned next to PlotArea or ChartArea + RectangleF areaPosition = axis.PlotAreaPosition.ToRectangleF(); + if(!this.IsPositionedInside) + { + areaPosition = axis.ChartArea.Position.ToRectangleF(); + + // Reduce rectangle size by scroll bar size + foreach(Axis a in this.ChartArea.Axes) + { + if(a.ScrollBar.IsVisible && !a.ScrollBar.IsPositionedInside) + { + float size = (float)a.ScrollBar.GetScrollBarRelativeSize(); + switch( a.AxisPosition ) + { + case AxisPosition.Left: + areaPosition.X += size; + areaPosition.Width -= size; + break; + case AxisPosition.Right: + areaPosition.Width -= size; + break; + case AxisPosition.Bottom: + areaPosition.Height -= size; + break; + case AxisPosition.Top: + areaPosition.Y += size; + areaPosition.Height -= size; + break; + } + } + } + } + + // Get bar position depending on the axis type + RectangleF barPosition = RectangleF.Empty; + if(this.axis.PlotAreaPosition != null) + { + switch( axis.AxisPosition ) + { + case AxisPosition.Left: + barPosition.Y = areaPosition.Y; + barPosition.Height = areaPosition.Height; + barPosition.X = + ( (this.IsPositionedInside) ? (float)(axis.GetAxisPosition(true)) : areaPosition.X) - scrollBarSize;// - axisLineSize.Width / 2f; + barPosition.Width = scrollBarSize; + break; + case AxisPosition.Right: + barPosition.Y = areaPosition.Y; + barPosition.Height = areaPosition.Height; + barPosition.X = + (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Right;// + axisLineSize.Width / 2f; + barPosition.Width = scrollBarSize; + break; + case AxisPosition.Bottom: + barPosition.X = areaPosition.X; + barPosition.Width = areaPosition.Width; + barPosition.Y = + (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Bottom;// + axisLineSize.Height / 2f; + barPosition.Height = scrollBarSize; + break; + case AxisPosition.Top: + barPosition.X = areaPosition.X; + barPosition.Width = areaPosition.Width; + barPosition.Y = + ( (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Y) - scrollBarSize;// - axisLineSize.Height / 2f; + barPosition.Height = scrollBarSize; + break; + } + } + + return barPosition; + } + + /// + /// Internal helper method which returns the relative scroll bar size. + /// + /// Relative scroll bar size. + internal double GetScrollBarRelativeSize() + { + // Scroll bar is not shown in 3D + if(this.axis.ChartArea.Area3DStyle.Enable3D || this.axis.ChartArea.chartAreaIsCurcular) + { + return 0.0; + } + +#if SUBAXES + // Scrollbar not supported on sub axis + if( this.axis != null && this.axis.IsSubAxis) + { + return 0.0; + } +#endif //SUBAXES + + + // Get scroll bar relative size depending on the axis location + if(this.axis.AxisPosition == AxisPosition.Left || this.axis.AxisPosition == AxisPosition.Right) + { + return this._scrollBarSize * 100F / ((float)(this.axis.Common.Width - 1)); + } + else + { + return this._scrollBarSize * 100F / ((float)(this.axis.Common.Height - 1)); + } + } + + /// + /// Returns the percentage size (0-100%) of the data scaleView comparing to + /// the axis scale minimum and maximum values. + /// + /// Size of the data scaleView in percentage. + private double GetDataViewPercentage() + { + double viewPercentage = 100.0; + + // Check if axis data scaleView properties are set + if(this.axis != null && + !double.IsNaN(this.axis.ScaleView.Position) && + !double.IsNaN(this.axis.ScaleView.Size)) + { + // Get data scaleView size + double dataViewSize = ChartHelper.GetIntervalSize( + this.axis.ScaleView.Position, + this.axis.ScaleView.Size, + this.axis.ScaleView.SizeType); + + // Get axis scale size without margins + double minimum = this.axis.minimum + this.axis.marginView; + double maximum = this.axis.maximum - this.axis.marginView; + if(this.axis.ScaleView.Position < minimum) + { + minimum = this.axis.ScaleView.Position; + } + if((this.axis.ScaleView.Position + dataViewSize) > maximum) + { + maximum = this.axis.ScaleView.Position + dataViewSize; + } + double axisScaleSize = Math.Abs(minimum - maximum); + + // Check if data scaleView is smaller than axis scale and if it is find the pecentage + if(dataViewSize < axisScaleSize) + { + viewPercentage = dataViewSize / (axisScaleSize / 100.0); + } + } + + return viewPercentage; + } + + /// + /// Returns the the data scaleView position in percentage (0-100%) using + /// the axis scale minimum and maximum values. + /// + /// Data scaleView position in percentage. + private double GetDataViewPositionPercentage() + { + double viewPosition = 0.0; + + // Check if axis data scaleView properties are set + if(this.axis != null && + !double.IsNaN(this.axis.ScaleView.Position) && + !double.IsNaN(this.axis.ScaleView.Size)) + { + // Get data scaleView size + double dataViewSize = ChartHelper.GetIntervalSize( + this.axis.ScaleView.Position, + this.axis.ScaleView.Size, + this.axis.ScaleView.SizeType); + + // Get axis scale size without margins + double minimum = this.axis.minimum + this.axis.marginView; + double maximum = this.axis.maximum - this.axis.marginView; + if(this.axis.ScaleView.Position < minimum) + { + minimum = this.axis.ScaleView.Position; + } + if((this.axis.ScaleView.Position + dataViewSize) > maximum) + { + maximum = this.axis.ScaleView.Position + dataViewSize; + } + double axisScaleSize = Math.Abs(minimum - maximum); + + // Calculate data scaleView position in percentage + viewPosition = (this.axis.ScaleView.Position - (minimum)) / (axisScaleSize / 100.0); + } + + return viewPosition; + } + + /// + /// Get total number of buttons in the scroll bar (except tracker). + /// + /// Number of buttons. + private int GetButtonsNumberAll() + { + int buttonNumber = 0; + if((this._scrollBarButtonStyle & ScrollBarButtonStyles.ResetZoom) == ScrollBarButtonStyles.ResetZoom) + { + buttonNumber += 1; + } + if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll) + { + buttonNumber += 2; + } + + return buttonNumber; + } + + /// + /// Get number of buttons in the top (left) part of the scroll bar. + /// + /// Number of buttons. + private int GetButtonsNumberTop() + { + int buttonNumber = 0; + if((this._scrollBarButtonStyle & ScrollBarButtonStyles.ResetZoom) == ScrollBarButtonStyles.ResetZoom) + { + buttonNumber += 1; + } + if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll) + { + buttonNumber += 1; + } + + return buttonNumber; + } + + /// + /// Get number of buttons in the bottom (right) part of the scroll bar. + /// + /// Number of buttons. + private int GetButtonsNumberBottom() + { + int buttonNumber = 0; + if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll) + { + buttonNumber += 1; + } + + return buttonNumber; + } + +#endregion + +#region Coordinate convertion methods + + /// + /// Converts Relative size to Absolute size + /// + /// Relative size in % + /// Absolute size + internal SizeF GetAbsoluteSize( SizeF relative ) + { + SizeF absolute = SizeF.Empty; + + // Convert relative coordinates to absolute coordinates + absolute.Width = relative.Width * (this.axis.Common.Width - 1) / 100F; + absolute.Height = relative.Height * (this.axis.Common.Height - 1) / 100F; + + // Return Absolute coordinates + return absolute; + } + + /// + /// Converts Absolute size to Relative size + /// + /// Absolute size + /// Relative size + internal SizeF GetRelativeSize( SizeF size ) + { + SizeF relative = SizeF.Empty; + + // Convert absolute coordinates to relative coordinates + relative.Width = size.Width * 100F / ((float)(this.axis.Common.Width - 1)); + relative.Height = size.Height * 100F / ((float)(this.axis.Common.Height - 1)); + + // Return relative coordinates + return relative; + } + +#endregion + +#region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + // Dispose managed resources + if (this._scrollTimer != null) + { + this._scrollTimer.Dispose(); + this._scrollTimer = null; + } + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + } + + /// + /// The arguments for a scrollbar event. + /// + public class ScrollBarEventArgs : EventArgs + { +#region Private fields + + // Private fields for properties values storage + private Axis _axis = null; + private bool _isHandled = false; + private int _mousePositionX = 0; + private int _mousePositionY = 0; + private ScrollBarButtonType _buttonType = ScrollBarButtonType.ThumbTracker; + +#endregion + +#region Constructors + + /// + /// ScrollBarEventArgs constructor. + /// + /// Axis containing the scrollbar. + /// X position of mouse cursor. + /// Y position of mouse cursor. + /// Button type of the button clicked. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public ScrollBarEventArgs(Axis axis, int x, int y, ScrollBarButtonType buttonType) + { + this._axis = axis; + this._mousePositionX = x; + this._mousePositionY = y; + this._buttonType = buttonType; + } + +#endregion + +#region Properties + + /// + /// Axis containing the scrollbar of the event. + /// + [ + SRDescription("DescriptionAttributeAxis"), + ] + public Axis Axis + { + get + { + return _axis; + } + } + + /// + /// ChartArea containing the scrollbar of the event. + /// + [ + SRDescription("DescriptionAttributeChartArea"), + ] + public ChartArea ChartArea + { + get + { + return _axis.ChartArea; + } + } + + /// + /// Button type of the scrollbar button clicked. + /// + [ + SRDescription("DescriptionAttributeScrollBarEventArgs_ButtonType"), + ] + public ScrollBarButtonType ButtonType + { + get + { + return _buttonType; + } + } + + /// + /// Indicates if the event is handled by the user and no further processing is required. + /// + [ + SRDescription("DescriptionAttributeScrollBarEventArgs_Handled"), + ] + public bool IsHandled + { + get + { + return _isHandled; + } + set + { + _isHandled = value; + } + } + + /// + /// X position of mouse cursor. + /// + [ + SRDescription("DescriptionAttributeScrollBarEventArgs_MousePositionX"), + ] + public int MousePositionX + { + get + { + return _mousePositionX; + } + } + + /// + /// Y position of mouse cursor. + /// + [ + SRDescription("DescriptionAttributeScrollBarEventArgs_MousePositionY"), + ] + public int MousePositionY + { + get + { + return _mousePositionY; + } + } + +#endregion + } +} + +#endif // #if WINFORMS_CONTROL \ No newline at end of file diff --git a/System.Web.DataVisualization/Common/General/AxisScrollZoom.cs b/System.Web.DataVisualization/Common/General/AxisScrollZoom.cs new file mode 100644 index 000000000..981fd8127 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/AxisScrollZoom.cs @@ -0,0 +1,1770 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: AxisScrollZoom.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: AxisScaleView, ViewEventArgs, DoubleNanValueConverter +// +// Purpose: AxisScaleView class represents a data scaleView, and is +// exposed using the Axis.ScaleView property. A data scaleView is +// a "scaleView" of data that has a start position (represented +// by the Position property) and a size (represented by +// the Size property). +// +// Axis data scaleView is used in zooming and scrolling when +// only part of the data must be visible. Views always +// belong to an axis, and a scaleView can result from either +// user interaction or by calling the Zoom or Scroll +// methods. User interaction, accomplished using range +// selection along an axis using the mouse, is possible +// if the IsUserSelectionEnabled property of the chart area' +// s cursor property is set to true. The end-user selects +// a range by left-clicking the mouse and dragging the +// mouse, and when the mouse button is released the +// selected range is then displayed as a scaleView. +// +// Reviewed: AG - Microsoft 16, 2007 +// +//=================================================================== + +#region Used namespace + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel; +using System.Collections; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +using System.Diagnostics.CodeAnalysis; + + +#else + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + + #region Scrolling enumerations + +#if Microsoft_CONTROL + + /// + /// Scrolling type enumeration. + /// + public enum ScrollType + { + /// + /// Scrolls by substracting one small size. + /// + SmallDecrement, + /// + /// Scrolls by adding one small size. + /// + SmallIncrement, + /// + /// Scrolls by substracting one scaleView size. + /// + LargeDecrement, + /// + /// Scrolls by adding one scaleView size. + /// + LargeIncrement, + /// + /// Scrolls to the first scaleView. + /// + First, + /// + /// Scrolls to the last scaleView. + /// + Last + } + +#endif // Microsoft_CONTROL + + #endregion + + /// + /// AxisScaleView class represents a scale view which allows to display + /// only part of the available data. + /// + [ + SRDescription("DescriptionAttributeAxisDataView_AxisDataView"), + DefaultProperty("Position"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class AxisScaleView + { + #region Fields + + // Reference to the axis object + internal Axis axis = null; + + // Axis data scaleView position + private double _position = double.NaN; + + // Axis data scaleView size + private double _size = double.NaN; + + // Axis data scaleView size units type + private DateTimeIntervalType _sizeType = DateTimeIntervalType.Auto; + +#if Microsoft_CONTROL + + // Axis data scaleView minimum scaleView/scrolling size + private double _minSize = double.NaN; + + // Axis data scaleView minimum scaleView/scrolling size units type + private DateTimeIntervalType _minSizeType = DateTimeIntervalType.Auto; + + // Axis data scaleView zooming UI interface enabled flag + private bool _zoomable = true; + + // Axis data scaleView scroll line size + private double _smallScrollSize = double.NaN; + + // Axis data scaleView scroll line size units type + private DateTimeIntervalType _smallScrollSizeType = DateTimeIntervalType.Auto; + + // Axis data scaleView scroll line minimum size + private double _smallScrollMinSize = 1.0; + + // Axis data scaleView scroll line minimum size units type + private DateTimeIntervalType _smallScrollMinSizeType = DateTimeIntervalType.Auto; + + // Axis data scaleView scroll line minimum size + private double _currentSmallScrollSize = double.NaN; + + // Axis data scaleView scroll line minimum size units type + private DateTimeIntervalType _currentSmallScrollSizeType = DateTimeIntervalType.Auto; + + // Storage for the saved data scaleView states (position/size/sizetype) + internal ArrayList dataViewStates = null; + +#endif + + // Ignore validation flag + private bool _ignoreValidation = false; + + #endregion + + #region Constructor + + /// + /// Default constructor + /// + public AxisScaleView() + { + this.axis = null; + } + + /// + /// Internal constructor. + /// + /// Data scaleView axis. + internal AxisScaleView(Axis axis) + { + this.axis = axis; + } + + #endregion + + #region Axis data scaleView properties + + /// + /// Gets or sets the position of the AxisScaleView. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(Double.NaN), + SRDescription("DescriptionAttributeAxisDataView_Position"), + TypeConverter(typeof(DoubleDateNanValueConverter)), + ParenthesizePropertyNameAttribute(true) + ] + public double Position + { + get + { + // Axis scaleView is not supported in circular chrt areas + if(this.axis != null && this.axis.ChartArea != null && this.axis.ChartArea.chartAreaIsCurcular) + { + return Double.NaN; + } + return _position; + } + set + { + // Axis scaleView is not supported in circular chrt areas + if(this.axis != null && this.axis.ChartArea != null && this.axis.ChartArea.chartAreaIsCurcular) + { + return; + } + + if(_position != value) + { + // Set new position + _position = value; + + // Align scaleView in connected areas + if(this.axis != null && this.axis.ChartArea != null && this.axis.Common != null && this.axis.Common.ChartPicture != null) + { + if(!this.axis.ChartArea.alignmentInProcess) + { + AreaAlignmentOrientations orientation = (this.axis.axisType == AxisName.X || this.axis.axisType== AxisName.X2) ? + AreaAlignmentOrientations.Vertical : AreaAlignmentOrientations.Horizontal; + this.axis.Common.ChartPicture.AlignChartAreasAxesView(this.axis.ChartArea, orientation); + } + } + + // Validate chart + if(!_ignoreValidation && axis != null) + { + axis.Invalidate(); + } + } + } + } + + /// + /// Gets or sets the size of the AxisScaleView + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(Double.NaN), + SRDescription("DescriptionAttributeAxisDataView_Size"), + TypeConverter(typeof(DoubleNanValueConverter)), + ParenthesizePropertyNameAttribute(true) + ] + public double Size + { + get + { + // Axis scaleView is not supported in circular chrt areas + if(this.axis != null && this.axis.ChartArea != null && this.axis.ChartArea.chartAreaIsCurcular) + { + return Double.NaN; + } + + return _size; + } + set + { + // Axis scaleView is not supported in circular chrt areas + if(this.axis != null && this.axis.ChartArea != null && this.axis.ChartArea.chartAreaIsCurcular) + { + return; + } + + if(_size != value) + { + // Set size value + _size = value; + + + // Align scaleView in connected areas + if(this.axis != null && this.axis.ChartArea != null && this.axis.Common != null && this.axis.Common.ChartPicture != null) + { + if(!this.axis.ChartArea.alignmentInProcess) + { + AreaAlignmentOrientations orientation = (this.axis.axisType == AxisName.X || this.axis.axisType== AxisName.X2) ? + AreaAlignmentOrientations.Vertical : AreaAlignmentOrientations.Horizontal; + this.axis.Common.ChartPicture.AlignChartAreasAxesView(this.axis.ChartArea, orientation); + } + } +#if Microsoft_CONTROL + // Reset current scrolling line size + this._currentSmallScrollSize = double.NaN; +#endif //Microsoft_CONTROL + // Validate chart + if(!_ignoreValidation && axis != null) + { + axis.Invalidate(); + } + } + } + } + + /// + /// Gets or sets the unit of measurement of the Size property. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeAxisDataView_SizeType"), + ParenthesizePropertyNameAttribute(true) + ] + public DateTimeIntervalType SizeType + { + get + { + return _sizeType; + } + set + { + if(_sizeType != value) + { + // Set size type + _sizeType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto; + + // Align scaleView in connected areas + if(this.axis != null && this.axis.ChartArea != null && this.axis.Common != null && this.axis.Common.ChartPicture != null) + { + if(!this.axis.ChartArea.alignmentInProcess) + { + AreaAlignmentOrientations orientation = (this.axis.axisType == AxisName.X || this.axis.axisType== AxisName.X2) ? + AreaAlignmentOrientations.Vertical : AreaAlignmentOrientations.Horizontal; + this.axis.Common.ChartPicture.AlignChartAreasAxesView(this.axis.ChartArea, orientation); + } + } + + // Validate chart + if(!_ignoreValidation && axis != null) + { + axis.Invalidate(); + } + } + } + } + + /// + /// Indicates if axis is zoomed-in. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(false), + Browsable(false), + SRDescription("DescriptionAttributeAxisDataView_IsZoomed"), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SerializationVisibility(SerializationVisibility.Hidden), + ] + public bool IsZoomed + { + get + { + return ( + !double.IsNaN(this.Size) && + this.Size != 0.0 && + !double.IsNaN(this.Position)); + } + } + +#if Microsoft_CONTROL + + /// + /// Gets or sets the minimum size of the AxisScaleView. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(Double.NaN), + SRDescription("DescriptionAttributeAxisDataView_MinSize"), + TypeConverter(typeof(DoubleNanValueConverter)) + ] + public double MinSize + { + get + { + return _minSize; + } + set + { + _minSize = value; + } + } + + /// + /// Gets or sets the unit of measurement of the MinSize property. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeAxisDataView_MinSizeType"), + ] + public DateTimeIntervalType MinSizeType + { + get + { + return _minSizeType; + } + set + { + _minSizeType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto; + } + } + + /// + /// Gets or sets a flag which indicates whether the zooming user interface is enabled. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeAxisDataView_Zoomable"), + SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification="'Zoomable' is a commonly used term and generally well understood"), + ] + public bool Zoomable + { + get + { + return _zoomable; + } + set + { + _zoomable = value; + } + } + + /// + /// Gets or sets the small scrolling size. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(Double.NaN), + SRDescription("DescriptionAttributeAxisDataView_SmallScrollSize"), + TypeConverter(typeof(AxisMinMaxAutoValueConverter)) + ] + public double SmallScrollSize + { + get + { + return _smallScrollSize; + } + set + { + if(_smallScrollSize != value) + { + // Set size value + _smallScrollSize = value; + + // Validate chart + if(!_ignoreValidation && axis != null) + { + axis.Invalidate(); + } + } + } + } + + /// + /// Gets or sets the unit of measurement for the SmallScrollMinSize property + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeAxisDataView_SmallScrollSizeType"), + ] + public DateTimeIntervalType SmallScrollSizeType + { + get + { + return _smallScrollSizeType; + } + set + { + if(_smallScrollSizeType != value) + { + // Set size type + _smallScrollSizeType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto; + + // Validate chart + if(!_ignoreValidation && axis != null) + { + axis.Invalidate(); + } + } + } + } + + /// + /// Gets or sets the minimum small scrolling size. + /// Only used if the small scrolling size is not set. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(1.0), + SRDescription("DescriptionAttributeAxisDataView_SmallScrollMinSize") + ] + public double SmallScrollMinSize + { + get + { + return _smallScrollMinSize; + } + set + { + if(_smallScrollMinSize != value) + { + // Set size value + _smallScrollMinSize = value; + + _currentSmallScrollSize = double.NaN; + + // Validate chart + if(!_ignoreValidation && axis != null) + { + axis.Invalidate(); + } + } + } + } + + /// + /// Gets or sets the unit of measurement for the SmallScrollMinSize property. + /// + [ + SRCategory("CategoryAttributeAxisView"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeAxisDataView_SmallScrollMinSizeType"), + ] + public DateTimeIntervalType SmallScrollMinSizeType + { + get + { + return _smallScrollMinSizeType; + } + set + { + if(_smallScrollMinSizeType != value) + { + // Set size type + _smallScrollMinSizeType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto; + + _currentSmallScrollSize = double.NaN; + + // Validate chart + if(!_ignoreValidation && axis != null) + { + axis.Invalidate(); + } + } + } + } + +#endif // Microsoft_CONTROL + + #endregion + + #region ScaleView position internal methods + + /// + /// Call this method to get the minimum axis value of a data view. + /// + /// The minimum axis value for the data view. + [Browsable(false)] + [Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)] + public double ViewMinimum + { + get + { + // If zooming is enabled + if (!Double.IsNaN(this.Size)) + { + // If size set only use axis minimum for scaleView position + if (Double.IsNaN(this.Position)) + { + this.Position = this.axis.Minimum; + } + // Check if scaleView position and size are set + else + { + // Calculate and add axis side margin + if (this.Position <= axis.minimum) + { + return this.Position; + } + else // Add a margin only if scaleView is inside data point scaleView + { + return this.Position - axis.marginView; + } + } + } + + // Return axis scale minimum value if scaleView position is not set + return axis.minimum; + } + } + + /// + /// Maximum axis value of a data view. + /// + /// The maximum axis value for the data view. + [Browsable(false)] + [Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)] + public double ViewMaximum + { + get + { + // If zooming is enabled + if (!Double.IsNaN(this.Size)) + { + // If size set only use axis minimum for scaleView position + if (Double.IsNaN(this.Position)) + { + this.Position = this.axis.Minimum; + } + + // Check if scaleView position and size are set + else + { + // Get axis interval + double viewSize = ChartHelper.GetIntervalSize(this.Position, this.Size, this.SizeType); + + // Calculate and add axis side margin + if (this.Position + viewSize >= axis.maximum) + { + return this.Position + viewSize; + } + else // Add a margin only if scaleView is inside data point scaleView + { + return this.Position + viewSize + axis.marginView; + } + } + } + + // Return axis scale maximum value if scaleView position is not set + return axis.maximum; + } + } + + #endregion + + #region Scrolling methods + +#if Microsoft_CONTROL + + /// + /// Call this method to scroll to a specified position along an axis. + /// + /// Direction and size to scroll. + public void Scroll(ScrollType scrollType) + { + this.Scroll(scrollType, false); + } + + /// + /// Scrolls axis data scaleView from current position. + /// + /// Direction and size to scroll. + /// Fire scaleView position events from this method. + internal void Scroll(ScrollType scrollType, bool fireChangeEvents) + { + // Adjust current position depending on the scroll type + double newPosition = this._position; + switch(scrollType) + { + case(ScrollType.SmallIncrement): + newPosition += ((axis.IsReversed) ? -1 : 1) * ChartHelper.GetIntervalSize(this._position, this.GetScrollingLineSize(), this.GetScrollingLineSizeType()); + break; + case(ScrollType.SmallDecrement): + newPosition -= ((axis.IsReversed) ? -1 : 1) * ChartHelper.GetIntervalSize(this._position, this.GetScrollingLineSize(), this.GetScrollingLineSizeType()); + break; + case(ScrollType.LargeIncrement): + newPosition += ((axis.IsReversed) ? -1 : 1) * ChartHelper.GetIntervalSize(this._position, this.Size, this.SizeType); + break; + case(ScrollType.LargeDecrement): + newPosition -= ((axis.IsReversed) ? -1 : 1) * ChartHelper.GetIntervalSize(this._position, this.Size, this.SizeType); + break; + case(ScrollType.First): + if(!axis.IsReversed) + { + newPosition = (axis.minimum + axis.marginView); + } + else + { + newPosition = (axis.maximum - axis.marginView); + } + break; + case(ScrollType.Last): + { + double viewSize = ChartHelper.GetIntervalSize(newPosition, this.Size, this.SizeType); + if(!axis.IsReversed) + { + newPosition = (axis.maximum - axis.marginView - viewSize); + } + else + { + newPosition = (axis.minimum + axis.marginView + viewSize); + } + break; + } + } + + // Scroll to the new position + this.Scroll(newPosition, fireChangeEvents); + } + + /// + /// Call this method to scroll to a specified position along an axis. + /// + /// New position. + public void Scroll(double newPosition) + { + this.Scroll(newPosition, false); + } + + /// + /// Call this method to scroll to a specified position along an axis. + /// + /// New position. + public void Scroll(DateTime newPosition) + { + this.Scroll(newPosition.ToOADate(), false); + } + + /// + /// Internal helper method for scrolling into specified position. + /// + /// New data scaleView position. + /// Fire scaleView position events from this method. + internal void Scroll(double newPosition, bool fireChangeEvents) + { + // Get current scaleView size + double viewSize = ChartHelper.GetIntervalSize(newPosition, this.Size, this.SizeType); + + // Validate new scaleView position + if(newPosition < (axis.minimum + axis.marginView)) + { + newPosition = (axis.minimum + axis.marginView); + } + else if(newPosition > (axis.maximum - axis.marginView - viewSize)) + { + newPosition = (axis.maximum - axis.marginView - viewSize); + } + + // Fire scaleView position changing events + ViewEventArgs arguments = new ViewEventArgs(this.axis, newPosition, this.Size, this.SizeType); + if(fireChangeEvents && GetChartObject() != null) + { + GetChartObject().OnAxisViewChanging(arguments); + newPosition = arguments.NewPosition; + } + + // Check if data scaleView position and size is different from current + if(newPosition == this.Position) + { + return; + } + + // Change scaleView position + this.Position = newPosition; + + // Fire scaleView position changed events + if(fireChangeEvents && GetChartObject() != null) + { + GetChartObject().OnAxisViewChanged(arguments); + } + } + +#endif + #endregion + + #region Zooming and ZoomResetting methods + +#if Microsoft_CONTROL + + /// + /// Sets a new axis data view/position based on the start and end dates specified. + /// + /// New start position for the axis scale view. + /// New size for the axis scale view. + /// New unit of measurement of the size. + /// Indicates whether the current size/position needs to be saved. + public void Zoom(double viewPosition, double viewSize, DateTimeIntervalType viewSizeType, bool saveState) + { + this.Zoom(viewPosition, viewSize, viewSizeType, false, saveState); + } + + /// + /// Sets a new axis data view/position based on the specified start and end values. + /// + /// New start position for the axis scale view. + /// New end position for the axis scale view. + public void Zoom(double viewStart, double viewEnd) + { + this.Zoom(viewStart, viewEnd - viewStart, DateTimeIntervalType.Number, false, false); + } + + /// + /// Sets a new axis data view/position based on the start and end dates specified. + /// + /// New start position for the axis scale view. + /// New size for the axis scale view. + /// New unit of measurement of the size. + public void Zoom(double viewPosition, double viewSize, DateTimeIntervalType viewSizeType) + { + this.Zoom(viewPosition, viewSize, viewSizeType, false, false); + } + + /// + /// Reset the specified number of zooming operations by restoring axis data view. + /// + /// Number of zoom operations to reset. Zero for all. + public void ZoomReset(int numberOfViews) + { + this.LoadDataViewState(numberOfViews, false); + } + + /// + /// Reset one zooming operation by restoring axis data view. + /// + public void ZoomReset() + { + this.LoadDataViewState(1, false); + } + + /// + /// Reset several zooming operation by restoring data scaleView size/position. + /// + /// How many scaleView zoom operations to reset. Zero for all. + /// Fire scaleView position events from this method. + internal void ZoomReset(int numberOfViews, bool fireChangeEvents) + { + this.LoadDataViewState(numberOfViews, fireChangeEvents); + } + + /// + /// Internal helper zooming method. + /// + /// New data scaleView start posiion. + /// New data scaleView size. + /// New data scaleView size units type. + /// Fire scaleView position events from this method. + /// Indicates that current scaleView size/position must be save, so it can be restored later. + /// True if zoom operation was made. + internal bool Zoom( + double viewPosition, + double viewSize, + DateTimeIntervalType viewSizeType, + bool fireChangeEvents, + bool saveState) + { + // Validate new scaleView position and size + ValidateViewPositionSize(ref viewPosition, ref viewSize, ref viewSizeType); + + // Fire scaleView position/size changing events + ViewEventArgs arguments = new ViewEventArgs(this.axis, viewPosition, viewSize, viewSizeType); + if(fireChangeEvents && GetChartObject() != null) + { + GetChartObject().OnAxisViewChanging(arguments); + viewPosition = arguments.NewPosition; + viewSize = arguments.NewSize; + viewSizeType = arguments.NewSizeType; + } + + // Check if data scaleView position and size is different from current + if(viewPosition == this.Position && + viewSize == this.Size && + viewSizeType == this.SizeType) + { + return false; + } + + // Save current data scaleView state, so it can be restored + if(saveState) + { + SaveDataViewState(); + } + + // Change scaleView position/size + this._ignoreValidation = true; + this.Position = viewPosition; + this.Size = viewSize; + this.SizeType = viewSizeType; + this._ignoreValidation = false; + + // Reset current scrolling line size + this._currentSmallScrollSize = double.NaN; + + // Invalidate chart + axis.Invalidate(); + + // Fire scaleView position/size changed events + if(fireChangeEvents && GetChartObject() != null) + { + GetChartObject().OnAxisViewChanged(arguments); + } + + return true; + } + +#endif + + #endregion + + #region Data scaleView state saving/restoring methods + +#if Microsoft_CONTROL + + /// + /// Saves current data scaleView position/size/sizetype, so + /// it can be restored later. + /// + /// Number of time to reset zoom. Zero for all. + /// Fire scaleView position events from this method. + private void LoadDataViewState(int numberOfViews, bool fireChangeEvents) + { + // Check parameters + if(numberOfViews < 0) + { + throw (new ArgumentOutOfRangeException("numberOfViews", SR.ExceptionScrollBarZoomResetsNumberInvalid)); + } + // Check if storage was created + if(dataViewStates != null && dataViewStates.Count >= 3) + { + // Find starting index of restoring state + int dataStartIndex = 0; + if(numberOfViews > 0) + { + dataStartIndex = dataViewStates.Count - numberOfViews * 3; + if(dataStartIndex < 0) + { + dataStartIndex = 0; + } + } + + + // Fire scaleView position/size changing events + ViewEventArgs arguments = new ViewEventArgs( + this.axis, + (double)dataViewStates[dataStartIndex], + (double)dataViewStates[dataStartIndex + 1], + (DateTimeIntervalType)dataViewStates[dataStartIndex + 2]); + if(fireChangeEvents && GetChartObject() != null) + { + GetChartObject().OnAxisViewChanging(arguments); + } + + // Restore data + this.Position = arguments.NewPosition; + this.Size = arguments.NewSize; + this.SizeType = arguments.NewSizeType; + + // Fire scaleView position/size changed events + if(fireChangeEvents && GetChartObject() != null) + { + GetChartObject().OnAxisViewChanged(arguments); + } + + // Clear data + int itemsToRemove = numberOfViews * 3; + if (itemsToRemove > (dataViewStates.Count - dataStartIndex)) + { + itemsToRemove = dataViewStates.Count - dataStartIndex; + } + dataViewStates.RemoveRange(dataStartIndex, itemsToRemove); + + + // clean up the history state when the numberOfViews == 0 (reset all by docs) + if ( numberOfViews == 0 ) + { + dataViewStates.Clear(); + } + if (Double.IsNaN(this.Position) || Double.IsNaN(this.Size)) + { + this.Position = Double.NaN; + this.Size = Double.NaN; + } + + } + + // Nothing to restore - just disable the data scaleView + else + { + // Fire scaleView position/size changing events + ViewEventArgs arguments = new ViewEventArgs( + this.axis, + double.NaN, + double.NaN, + DateTimeIntervalType.Auto); + + if(fireChangeEvents && GetChartObject() != null) + { + GetChartObject().OnAxisViewChanging(arguments); + } + + // Restore data + this.Position = arguments.NewPosition; + this.Size = arguments.NewSize; + this.SizeType = arguments.NewSizeType; + + // Fire scaleView position/size changed events + if(fireChangeEvents && GetChartObject() != null) + { + GetChartObject().OnAxisViewChanged(arguments); + } + } + // clear cached chart areas and bitmap buffers + GetChartObject().Refresh(); + } + + /// + /// Saves current data scaleView position/size/sizetype, so + /// it can be restored later. + /// + private void SaveDataViewState() + { + // Create storage array + if(dataViewStates == null) + { + dataViewStates = new ArrayList(); + } + + // Save data scaleView state + dataViewStates.Add(this.Position); + dataViewStates.Add(this.Size); + dataViewStates.Add(this.SizeType); + } +#endif + + #endregion + + #region Helper methods + +#if Microsoft_CONTROL + /// + /// Initialize internal scrolling line size variables for later use. + /// This size is used in to scroll chart one line up or down. + /// + private void GetCurrentViewSmallScrollSize() + { + //************************************************************************** + //** Check if current scrolling line size was not already calculated + //************************************************************************** + if(double.IsNaN(_currentSmallScrollSize)) + { + //************************************************************************** + //** Calculate line size depending on the current scaleView size + //************************************************************************** + if(this.SizeType == DateTimeIntervalType.Auto || this.SizeType == DateTimeIntervalType.Number) + { + // Set line size type + _currentSmallScrollSizeType = DateTimeIntervalType.Number; + + // Devide scaleView by 20 to find the scrolling line size + double newSize = this.Size / 20.0; + + // Make sure that current line size is even with minimum value + if(!double.IsNaN(this.SmallScrollMinSize) && this.SmallScrollMinSize != 0.0) + { + double rounder = (Math.Round(newSize / this.SmallScrollMinSize)); + if(rounder < 0) + { + rounder = 1; + } + newSize = rounder * this.SmallScrollMinSize; + } + + // Set new current line size + this._currentSmallScrollSize = newSize; + } + else + { + // Calculate line size for date/time + double viewEndPosition = this.Position + ChartHelper.GetIntervalSize(this.Position, this.Size, this.SizeType); + _currentSmallScrollSize = axis.CalcInterval( + this.Position, + viewEndPosition, + true, + out _currentSmallScrollSizeType, + ChartValueType.Auto); + } + + //************************************************************************** + //** Make sure calculated scroll line size is not smaller than the minimum + //************************************************************************** + if(!double.IsNaN(this.SmallScrollMinSize) && this.SmallScrollMinSize != 0.0) + { + double newLineSize = ChartHelper.GetIntervalSize(this.Position, _currentSmallScrollSize, _currentSmallScrollSizeType); + double minLineSize = ChartHelper.GetIntervalSize(this.Position, this.SmallScrollMinSize, this.SmallScrollMinSizeType); + if(newLineSize < minLineSize) + { + _currentSmallScrollSize = SmallScrollMinSize; + _currentSmallScrollSizeType = SmallScrollMinSizeType; + } + } + } + } + + /// + /// Returns the scroll line size. + /// + /// Scroll line size. + internal double GetScrollingLineSize() + { + // Scroll line size/type is specificly set by user + if(!double.IsNaN(this.SmallScrollSize)) + { + return this.SmallScrollSize; + } + + // Calcualte scroll line size depending on the current scaleView size + GetCurrentViewSmallScrollSize(); + + // Return line size + return _currentSmallScrollSize; + } + + /// + /// Returns the scroll line size units type. + /// + /// Scroll line size units type. + internal DateTimeIntervalType GetScrollingLineSizeType() + { + // Scroll line size/type is specificly set by user + if(!double.IsNaN(this.SmallScrollSize)) + { + return this.SmallScrollSizeType; + } + + // Calcualte scroll line size depending on the current scaleView size + GetCurrentViewSmallScrollSize(); + + // Return line size units type + return _currentSmallScrollSizeType; + } + + /// + /// Helper method, which validates the axis data scaleView position and size. + /// Returns adjusted scaleView position and size. + /// + /// ScaleView position. + /// ScaleView size. + /// ScaleView size units type. + private void ValidateViewPositionSize(ref double viewPosition, ref double viewSize, ref DateTimeIntervalType viewSizeType) + { + //**************************************************************** + //** Check if new scaleView position is inside axis scale + //** minimum/maximum without margin. + //**************************************************************** + if(viewPosition < (axis.minimum + axis.marginView)) + { + if(viewSizeType == DateTimeIntervalType.Auto || viewSizeType == DateTimeIntervalType.Number) + { + viewSize -= (axis.minimum + axis.marginView) - viewPosition; + } + viewPosition = (axis.minimum + axis.marginView); + } + else if(viewPosition > (axis.maximum - axis.marginView)) + { + if(viewSizeType == DateTimeIntervalType.Auto || viewSizeType == DateTimeIntervalType.Number) + { + viewSize -= viewPosition - (axis.maximum - axis.marginView); + } + viewPosition = (axis.maximum - axis.marginView); + } + + //**************************************************************** + //** Check if new scaleView size is not smaller than minimum size + //** set by the user + //**************************************************************** + double newViewSize = ChartHelper.GetIntervalSize(viewPosition, viewSize, viewSizeType); + double minViewSize = ChartHelper.GetIntervalSize(viewPosition, 1, this.MinSizeType); + if(!double.IsNaN(this.MinSize)) + { + minViewSize = ChartHelper.GetIntervalSize(viewPosition, this.MinSize, this.MinSizeType); + if(newViewSize < minViewSize) + { + viewSize = (double.IsNaN(this.MinSize)) ? 1 : this.MinSize; + viewSizeType = this.MinSizeType; + newViewSize = ChartHelper.GetIntervalSize(viewPosition, viewSize, viewSizeType); + } + } + + //**************************************************************** + //** Check if new scaleView size is smaller than (0.000000001) + //**************************************************************** + if(newViewSize < 0.000000001) + { + viewSize = 0.000000001; + viewSizeType = DateTimeIntervalType.Number; + newViewSize = ChartHelper.GetIntervalSize(viewPosition, viewSize, viewSizeType); + } + + //**************************************************************** + //** Check if new scaleView end position (position + size) is inside + //** axis scale minimum/maximum without margin. + //**************************************************************** + while( (viewPosition + newViewSize) > (axis.maximum - axis.marginView) ) + { + double currentSize = viewSize; + DateTimeIntervalType currentSizeType = viewSizeType; + + // Try to reduce the scaleView size + if(newViewSize > minViewSize) + { + // Try to adjust the scaleView size + if(viewSize > 1) + { + --viewSize; + } + else if(viewSizeType == DateTimeIntervalType.Years) + { + viewSize = 11; + viewSizeType = DateTimeIntervalType.Months; + } + else if(viewSizeType == DateTimeIntervalType.Months) + { + viewSize = 4; + viewSizeType = DateTimeIntervalType.Weeks; + } + else if(viewSizeType == DateTimeIntervalType.Weeks) + { + viewSize = 6; + viewSizeType = DateTimeIntervalType.Days; + } + else if(viewSizeType == DateTimeIntervalType.Days) + { + viewSize = 23; + viewSizeType = DateTimeIntervalType.Hours; + } + else if(viewSizeType == DateTimeIntervalType.Hours) + { + viewSize = 59; + viewSizeType = DateTimeIntervalType.Minutes; + } + else if(viewSizeType == DateTimeIntervalType.Minutes) + { + viewSize = 59; + viewSizeType = DateTimeIntervalType.Seconds; + } + else if(viewSizeType == DateTimeIntervalType.Seconds) + { + viewSize = 999; + viewSizeType = DateTimeIntervalType.Milliseconds; + } + else + { + viewPosition = (axis.maximum - axis.marginView) - minViewSize; + break; + } + + // Double check that scaleView size is not smaller than min size + newViewSize = ChartHelper.GetIntervalSize(viewPosition, viewSize, viewSizeType); + if(newViewSize < minViewSize) + { + // Can't adjust size no more (restore prev. value) + viewSize = currentSize; + viewSizeType = currentSizeType; + + // Adjust the start position + viewPosition = (axis.maximum - axis.marginView) - minViewSize; + break; + } + } + else + { + // Adjust the start position + viewPosition = (axis.maximum - axis.marginView) - newViewSize; + break; + } + } + } + + /// + /// Helper function which returns a reference to the chart object. + /// + /// Chart object reference. + internal Chart GetChartObject() + { + if(this.axis != null && this.axis.Common!=null) + { + return this.axis.Common.Chart; + } + + return null; + } +#endif //Microsoft_CONTROL + + #endregion + } + +#if Microsoft_CONTROL + + /// + /// This class is used as a parameter object in the AxisViewChanged and AxisViewChanging events of the root Chart object. + /// + public class ViewEventArgs : EventArgs + { + #region Private fields + + // Private fields for properties values storage + private Axis _axis = null; + private double _newPosition = double.NaN; + private double _newSize = double.NaN; + private DateTimeIntervalType _newSizeType = DateTimeIntervalType.Auto; + + #endregion + + #region Constructors + + /// + /// ViewEventArgs constructor. + /// + /// Axis of the scale view. + /// New scale view start position. + public ViewEventArgs(Axis axis, double newPosition) + { + this._axis = axis; + this._newPosition = newPosition; + } + + /// + /// ViewEventArgs constructor. + /// + /// Axis of the scale view. + /// New scale view start position. + /// New scale view size. + /// New unit of measurement of the size. + public ViewEventArgs(Axis axis, double newPosition, double newSize, DateTimeIntervalType newSizeType) + { + this._axis = axis; + this._newPosition = newPosition; + this._newSize = newSize; + this._newSizeType = newSizeType; + } + + #endregion + + #region Properties + + /// + /// Axis of the event. + /// + [ + SRDescription("DescriptionAttributeAxis"), + ] + public Axis Axis + { + get + { + return _axis; + } + } + + /// + /// ChartArea of the event. + /// + [ + SRDescription("DescriptionAttributeChartArea"), + ] + public ChartArea ChartArea + { + get + { + return _axis.ChartArea; + } + } + + /// + /// New scale view start position. + /// + [ + SRDescription("DescriptionAttributeViewEventArgs_NewPosition"), + ] + public double NewPosition + { + get + { + return _newPosition; + } + set + { + _newPosition = value; + } + } + + /// + /// New scale view size. + /// + [ + SRDescription("DescriptionAttributeViewEventArgs_NewSize"), + ] + public double NewSize + { + get + { + return _newSize; + } + set + { + _newSize = value; + } + } + + /// + /// New unit of measurement of the scale view. + /// + [ + SRDescription("DescriptionAttributeViewEventArgs_NewSizeType"), + ] + public DateTimeIntervalType NewSizeType + { + get + { + return _newSizeType; + } + set + { + _newSizeType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto; + } + } + + #endregion + } + +#endif // #if Microsoft_CONTROL +} + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif +{ + /// + /// Designer converter class + /// Converts Double.NaN values to/from "Not set". + /// + internal class DoubleNanValueConverter : DoubleConverter + { + #region Converter methods + + /// + /// Standard values supported. This method always return true. + /// + /// Descriptor context. + /// True. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standard values are not exclusive. This method always return false. + /// + /// Descriptor context. + /// False. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Get in the collection of standard values. + /// + /// Descriptor context. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + values.Add(Double.NaN); + + return new StandardValuesCollection(values); + } + + /// + /// Convert double.NaN to string "Not set" + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Conversion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + double doubleValue = (double)value; + if (destinationType == typeof(string)) + { + if(Double.IsNaN(doubleValue)) + { + return Constants.NotSetValue; + } + } + + // Call base class + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// Convert minimum or maximum values from string. + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + // If converting from string value + string crossingValue = value as string; + if (crossingValue != null) + { + if (String.Compare(crossingValue, Constants.NotSetValue, StringComparison.OrdinalIgnoreCase) == 0) + { + return Double.NaN; + } + } + + // Call base converter + return base.ConvertFrom(context, culture, value); + } + + #endregion + } + + /// + /// Designer converter class + /// Converts Double.NaN values to/from "Not set". + /// Converts value to/from date strings. + /// + internal class DoubleDateNanValueConverter : DoubleConverter + { + #region Converter methods + + /// + /// Standard values supported - return true + /// + /// Descriptor context. + /// Standard values supported. + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + /// + /// Standard values are not exclusive - return false + /// + /// Descriptor context. + /// Non exclusive standard values. + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return false; + } + + /// + /// Fill in the list of predefined values. + /// + /// Descriptor context. + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + ArrayList values = new ArrayList(); + values.Add(Double.NaN); + + return new StandardValuesCollection(values); + } + + /// + /// Convert values to string if step type is set to one of the DateTime type + /// + /// Descriptor context. + /// Culture information. + /// Value to convert. + /// Conversion destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + // Check for NaN + if (destinationType == typeof(string)) + { + if(Double.IsNaN((double)value)) + { + return Constants.NotSetValue; + } + } + + if (context != null && context.Instance != null) + { + // Get access to the Axis object + Axis axis = null; + if(context.Instance is AxisScaleView) + { + axis = ((AxisScaleView)context.Instance).axis; + } + +#if Microsoft_CONTROL + + else if(context.Instance is Cursor) + { + axis = ((Cursor)context.Instance).GetAxis(); + } +#endif // Microsoft_CONTROL + + if (axis != null && destinationType == typeof(string)) + { + string strValue = ConvertDateTimeToString( + (double)value, + axis.GetAxisValuesType(), + axis.InternalIntervalType); + + if (strValue != null) + return strValue; + } + + } + return base.ConvertTo(context, culture, value, destinationType); + } + + public static string ConvertDateTimeToString( + double dtValue, + ChartValueType axisValuesType, + DateTimeIntervalType dtIntervalType) + { + string strValue = null; + // Use axis values types if interval is automatic + if (dtIntervalType == DateTimeIntervalType.Auto) + { + if (axisValuesType == ChartValueType.DateTime || + axisValuesType == ChartValueType.Time || + axisValuesType == ChartValueType.Date || + axisValuesType == ChartValueType.DateTimeOffset) + { + strValue = DateTime.FromOADate(dtValue).ToString("g", System.Globalization.CultureInfo.CurrentCulture); + } + } + else + { + if (dtIntervalType != DateTimeIntervalType.Number) + { + // Covert value to date/time + if (dtIntervalType < DateTimeIntervalType.Hours) + { + strValue = DateTime.FromOADate(dtValue).ToShortDateString(); + } + else + { + strValue = DateTime.FromOADate(dtValue).ToString("g", System.Globalization.CultureInfo.CurrentCulture); + } + } + } + + if (axisValuesType == ChartValueType.DateTimeOffset && strValue != null) + strValue += " +0"; + + return strValue; + } + + /// + /// Convert Min and Max values from string if step type is set to one of the DateTime type + /// + /// Descriptor context. + /// Culture information. + /// Value to convert from. + /// Converted object. + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + object result = null; + bool convertFromDate = false; + + // If converting from string value + string crossingValue = value as string; + if (crossingValue != null) + { + if (String.Compare(crossingValue, Constants.NotSetValue, StringComparison.OrdinalIgnoreCase) == 0) + { + return Double.NaN; + } + } + + // If context interface provided check if we are dealing with DateTime values + if (context != null && context.Instance != null && context.Instance is Axis) + { + + // Get axis object + Axis axis = null; + if(context.Instance is AxisScaleView) + { + axis = ((AxisScaleView)context.Instance).axis; + } + +#if Microsoft_CONTROL + else if(context.Instance is Cursor) + { + axis = ((Cursor)context.Instance).GetAxis(); + } +#endif // Microsoft_CONTROL + + if (axis != null && crossingValue != null) + { + if(axis.InternalIntervalType == DateTimeIntervalType.Auto) + { + if(axis.GetAxisValuesType() == ChartValueType.DateTime || + axis.GetAxisValuesType() == ChartValueType.Date || + axis.GetAxisValuesType() == ChartValueType.Time || + axis.GetAxisValuesType() == ChartValueType.DateTimeOffset) + { + convertFromDate = true; + } + } + else + { + if(axis.InternalIntervalType != DateTimeIntervalType.Number) + { + convertFromDate = true; + } + } + } + } + + // Try to convert from double string + try + { + result = base.ConvertFrom(context, culture, value); + } + catch (ArgumentException) + { + result = null; + } + catch (NotSupportedException) + { + result = null; + } + + // Try to convert from date/time string + if (crossingValue != null && (convertFromDate || result == null)) + { + DateTime valueAsDate; + bool parseSucceed = DateTime.TryParse(crossingValue, CultureInfo.InvariantCulture, DateTimeStyles.None, out valueAsDate); + + if (parseSucceed) + { + return valueAsDate.ToOADate(); + } + } + + // Call base converter + return base.ConvertFrom(context, culture, value); + } + + #endregion + } + +} + + diff --git a/System.Web.DataVisualization/Common/General/BaseClasses.cs b/System.Web.DataVisualization/Common/General/BaseClasses.cs new file mode 100644 index 000000000..610b0e74e --- /dev/null +++ b/System.Web.DataVisualization/Common/General/BaseClasses.cs @@ -0,0 +1,403 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant, victark + +using System; +using System.Text; +using System.Globalization; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + + /// + /// ChartElement is the most basic element of the chart element hierarchy. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public abstract class ChartElement : IChartElement, IDisposable + { + #region Member variables + + private IChartElement _parent = null; + private CommonElements _common = null; + private object _tag = null; + + #endregion + + #region Properties + + /// + /// Gets or sets an object associated with this chart element. + /// + /// + /// An associated with this chart element. + /// + /// + /// This property may be used to store additional data with this chart element. + /// + [ + Browsable(false), + DefaultValue(null), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + Utilities.SerializationVisibilityAttribute(Utilities.SerializationVisibility.Hidden) + ] + public object Tag + { + get { return _tag; } + set { _tag = value; } + } + + /// + /// Gets or sets the parent chart element or collection. + /// + /// The parent chart element or collection. + internal virtual IChartElement Parent + { + get { return _parent; } + set { _parent = value; } + } + + /// + /// Gets a shortcut to Common intance providing access to the various chart related services. + /// + /// The Common instance. + internal CommonElements Common + { + get + { + if (_common == null && _parent != null) + { + _common = _parent.Common; + } + return _common; + } + set + { + _common = value; + } + } + + /// + /// Gets the chart. + /// + /// The chart. + internal Chart Chart + { + get + { + if (Common != null) + return Common.Chart; + else + return null; + } + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + protected ChartElement() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The parent chart element or collection. + internal ChartElement(IChartElement parent) + { + _parent = parent; + } + + #endregion + + #region Methods + + /// + /// Invalidates this chart element. + /// + internal virtual void Invalidate() + { + if (_parent != null) + _parent.Invalidate(); + } + + #endregion + + #region IChartElement Members + + + IChartElement IChartElement.Parent + { + get { return _parent; } + set { this.Parent = value; } + } + + void IChartElement.Invalidate() + { + this.Invalidate(); + } + + CommonElements IChartElement.Common + { + get{ return this.Common; } + } + + #endregion + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + } + + /// + /// Performs freeing, releasing, or resetting managed resources. + /// + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + + #region Methods + + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + /// For internal use. + internal virtual string ToStringInternal() + { + return GetType().Name; + } + + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + public override string ToString() + { + return this.ToStringInternal(); + } + + /// + /// Determines whether the specified is equal to the current . + /// + /// The to compare with the current . + /// + /// true if the specified is equal to the current ; otherwise, false. + /// + /// The parameter is null. + /// For internal use. + internal virtual bool EqualsInternal(object obj) + { + return base.Equals(obj); + } + + /// + /// Determines whether the specified is equal to the current . + /// + /// The to compare with the current . + /// + /// true if the specified is equal to the current ; otherwise, false. + /// + /// The parameter is null. + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + public override bool Equals(object obj) + { + return this.EqualsInternal(obj); + } + + /// + /// Serves as a hash function for a particular type. + /// + /// + /// A hash code for the current . + /// + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #endregion + + } + + /// + /// ChartNamedElement is a base class for most chart elements. Series, ChartAreas, Legends and other chart elements have a Name and reuse the unique name generation and validation logic provided by the ChartNamedElementCollection. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public abstract class ChartNamedElement : ChartElement + { + #region Member variables + + private string _name = String.Empty; + + #endregion + + #region Properties + + /// + /// Gets or sets the name of the chart element. + /// + /// The name. + [DefaultValue("")] + public virtual string Name + { + get { return _name; } + set + { + if (_name != value) + { + if (Parent is INameController) + { + INameController nameController = Parent as INameController; + + if (!nameController.IsUniqueName(value)) + throw new ArgumentException(SR.ExceptionNameAlreadyExistsInCollection(value, nameController.GetType().Name)); + + // Fire the name change events in case when the old name is not empty + NameReferenceChangedEventArgs args = new NameReferenceChangedEventArgs(this, _name, value); + nameController.OnNameReferenceChanging(args); + _name = value; + nameController.OnNameReferenceChanged(args); + } + else + { + _name = value; + } + Invalidate(); + } + } + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + protected ChartNamedElement() + : base() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The name of the new chart element. + protected ChartNamedElement(string name) + : base() + { + _name = name; + } + + /// + /// Initializes a new instance of the class. + /// + /// The parent chart element. + /// The name of the new chart element. + internal ChartNamedElement(IChartElement parent, string name) : base(parent) + { + _name = name; + } + + #endregion + + #region Methods + + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + internal override string ToStringInternal() + { + string typeName = GetType().Name; + return (string.IsNullOrEmpty(_name)) ? typeName : typeName + '-' + _name; + } + + #endregion + + } + + + /// + /// NameReferenceChanged events help chart maintain referencial integrity. + /// + internal class NameReferenceChangedEventArgs : EventArgs + { + #region MemberValiables + + ChartNamedElement _oldElement; + string _oldName; + string _newName; + + #endregion + + #region Properties + public ChartNamedElement OldElement + { + get { return _oldElement; } + } + public string OldName + { + get { return _oldName; } + } + public string NewName + { + get { return _newName; } + } + #endregion + + #region Constructor + public NameReferenceChangedEventArgs(ChartNamedElement oldElement, ChartNamedElement newElement) + { + _oldElement = oldElement; + _oldName = oldElement!=null ? oldElement.Name : string.Empty; + _newName = newElement!=null ? newElement.Name : string.Empty; + } + public NameReferenceChangedEventArgs(ChartNamedElement oldElement, string oldName, string newName) + { + _oldElement = oldElement; + _oldName = oldName; + _newName = newName; + } + #endregion + } + +} diff --git a/System.Web.DataVisualization/Common/General/BaseCollections.cs b/System.Web.DataVisualization/Common/General/BaseCollections.cs new file mode 100644 index 000000000..7fae321d4 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/BaseCollections.cs @@ -0,0 +1,619 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant, victark + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; +using System.Collections; + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + + /// + /// Base class for all chart element collections + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public abstract class ChartElementCollection : Collection, IChartElement, IDisposable + where T : ChartElement + { + #region Member variables + + private IChartElement _parent = null; + private CommonElements _common = null; + internal int _suspendUpdates = 0; + #endregion + + #region Properties + + /// + /// Gets or sets the parent. + /// + internal IChartElement Parent + { + get { return _parent; } + set + { + _parent = value; + Invalidate(); + } + } + /// + /// Gets the CommonElements of the chart. + /// + internal CommonElements Common + { + get + { + if (_common == null && _parent != null) + { + _common = _parent.Common; + } + return _common; + } + } + + /// + /// Gets the chart. + /// + internal Chart Chart + { + get + { + if (Common != null) + return Common.Chart; + else + return null; + } + } + + /// + /// Gets the items as List<T>. Use this property to perform advanced List specific operations (Sorting, etc) + /// + internal List ItemList + { + get { return Items as List; } + } + + internal bool IsSuspended + { + get { return _suspendUpdates > 0; } + } + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The parent chart element. + internal ChartElementCollection(IChartElement parent) + { + _parent = parent; + } + + #endregion + + #region Methods + + /// + /// Forces the invalidation of the parent chart element + /// + public virtual void Invalidate() + { + if (_parent != null && !IsSuspended) + _parent.Invalidate(); + } + + /// + /// Suspends invalidation + /// + public virtual void SuspendUpdates() + { + _suspendUpdates++; + } + + /// + /// Resumes invalidation. + /// + public virtual void ResumeUpdates() + { + if (_suspendUpdates>0) + _suspendUpdates--; + + if (_suspendUpdates==0) + this.Invalidate(); + } + + /// + /// Removes all elements from the . + /// + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + protected override void ClearItems() + { + SuspendUpdates(); + while (this.Count > 0) + { + this.RemoveItem(0); + } + ResumeUpdates(); + } + + /// + /// Deinitializes the specified item. + /// + /// The item. + internal virtual void Deinitialize( T item) + { + + } + + /// + /// Initializes the specified item. + /// + /// The item. + internal virtual void Initialize(T item) + { + + } + + /// + /// Removes the element at the specified index of the . + /// + /// The zero-based index of the element to remove. + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + protected override void RemoveItem(int index) + { + this.Deinitialize(this[index]); + this[index].Parent = null; + base.RemoveItem(index); + Invalidate(); + } + + /// + /// Inserts an element into the at the specified index. + /// + /// The zero-based index at which should be inserted. + /// The object to insert. The value can be null for reference types. + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + protected override void InsertItem(int index, T item) + { + this.Initialize(item); + item.Parent = this; + base.InsertItem(index, item); + Invalidate(); + } + + /// + /// Replaces the element at the specified index. + /// + /// The zero-based index of the element to replace. + /// The new value for the element at the specified index. The value can be null for reference types. + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + protected override void SetItem(int index, T item) + { + this.Initialize(item); + item.Parent = this; + base.SetItem(index, item); + Invalidate(); + } + + #endregion + + #region IChartElement Members + + IChartElement IChartElement.Parent + { + get { return this.Parent; } + set { this.Parent = value; } + } + + void IChartElement.Invalidate() + { + this.Invalidate(); + } + + CommonElements IChartElement.Common + { + get{ return this.Common; } + } + + #endregion + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + // Dispose managed resources + foreach (T element in this) + { + element.Dispose(); + } + } + } + + /// + /// Performs freeing, releasing, or resetting managed resources. + /// + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + + } + + /// + /// Base class for all collections of named chart elements. Performs the name management and enforces the uniquness of the names + /// + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public abstract class ChartNamedElementCollection : ChartElementCollection, INameController + where T : ChartNamedElement + { + + #region Fields + private List _cachedState = null; + private int _disableDeleteCount = 0; + #endregion + + #region Properties + + /// + /// Gets the name prefix that is used to create unique chart element names. + /// + /// The default name prefix of the chart elements stored in the collection. + protected virtual string NamePrefix + { + get { return typeof(T).Name; } + } + + /// + /// Gets or sets the chart element with the specified name. + /// + /// + public T this[string name] + { + get + { + int index = this.IndexOf(name); + if (index != -1) + { + return this[index]; + } + throw new ArgumentException(SR.ExceptionNameNotFound(name, this.GetType().Name)); + } + set + { + int nameIndex = this.IndexOf(name); + int itemIndex = this.IndexOf(value); + bool nameFound = nameIndex > -1; + bool itemFound = itemIndex > -1; + + if (!nameFound && !itemFound) + this.Add(value); + + else if (nameFound && !itemFound) + this[nameIndex] = value; + + else if (!nameFound && itemFound) + throw new ArgumentException(SR.ExceptionNameAlreadyExistsInCollection(name, this.GetType().Name)); + + else if (nameFound && itemFound && nameIndex != itemIndex) + throw new ArgumentException(SR.ExceptionNameAlreadyExistsInCollection(name, this.GetType().Name)); + + } + } + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The parent chart element. + internal ChartNamedElementCollection(IChartElement parent) + : base(parent) + { + } + + #endregion + + #region Events + + internal event EventHandler NameReferenceChanged; + internal event EventHandler NameReferenceChanging; + + #endregion + + #region Methods + + /// + /// Determines whether the chart element with the specified name already exists in the collection. + /// + /// The new chart element name. + /// + /// true if new chart element name is unique; otherwise, false. + /// + public virtual bool IsUniqueName(string name) + { + return FindByName(name)==null; + } + + /// + /// Finds the unique name for a new element being added to the collection + /// + /// Next unique chart element name + public virtual string NextUniqueName() + { + // Find unique name + string result = string.Empty; + string prefix = this.NamePrefix; + for (int i = 1; i < System.Int32.MaxValue; i++) + { + result = prefix + i.ToString(CultureInfo.InvariantCulture); + // Check whether the name is unique + if (IsUniqueName(result)) + { + break; + } + } + return result; + } + + /// + /// Indexes the of chart element with the specified name. + /// + /// The name. + /// + public int IndexOf(string name) + { + int i = 0; + foreach (T namedObj in this) + { + if (namedObj.Name == name) + return i; + i++; + } + return -1; + } + + /// + /// Verifies the name reference to a chart named element stored in this collection and throws the argument exception if its not valid. + /// + /// Chart element name. + internal void VerifyNameReference(string name) + { + if (Chart!=null && !Chart.serializing && !IsNameReferenceValid(name)) + throw new ArgumentException(SR.ExceptionNameNotFound(name, this.GetType().Name)); + } + + /// + /// Verifies the name reference to a chart named element stored in this collection. + /// + /// Chart element name. + internal bool IsNameReferenceValid(string name) + { + return String.IsNullOrEmpty(name) || + name == Constants.NotSetValue || + IndexOf(name) >= 0; + } + + /// + /// Finds the chart element by the name. + /// + /// The name. + /// + public virtual T FindByName(string name) + { + foreach (T namedObj in this) + { + if (namedObj.Name == name) + return namedObj; + } + return null; + } + + /// + /// Inserts the specified item in the collection at the specified index. + /// + /// The zero-based index where the item is to be inserted. + /// The object to insert. + protected override void InsertItem(int index, T item) + { + if (String.IsNullOrEmpty(item.Name)) + item.Name = this.NextUniqueName(); + else if (!IsUniqueName(item.Name)) + throw new ArgumentException(SR.ExceptionNameAlreadyExistsInCollection(item.Name, this.GetType().Name)); + + //If the item references other named references we might need to fix the references + FixNameReferences(item); + + base.InsertItem(index, item); + + if (this.Count == 1 && item != null) + { + // First element is added to the list -> fire the NameReferenceChanged event to update all the dependent elements + ((INameController)this).OnNameReferenceChanged(new NameReferenceChangedEventArgs(null, item)); + } + } + + /// + /// Replaces the element at the specified index. + /// + /// The zero-based index of the element to replace. + /// The new value for the element at the specified index. + protected override void SetItem(int index, T item) + { + if (String.IsNullOrEmpty(item.Name)) + item.Name = this.NextUniqueName(); + else if (!IsUniqueName(item.Name) && IndexOf(item.Name) != index) + throw new ArgumentException(SR.ExceptionNameAlreadyExistsInCollection(item.Name, this.GetType().Name)); + + //If the item references other named references we might need to fix the references + FixNameReferences(item); + + // Remember the removedElement + ChartNamedElement removedElement = index + /// Removes the element at the specified index of the collection. + /// + /// The zero-based index of the element to remove. + protected override void RemoveItem(int index) + { + // Remember the removedElement + ChartNamedElement removedElement = index < Count ? this[index] : null; + if (_disableDeleteCount == 0) + { + ((INameController)this).OnNameReferenceChanged(new NameReferenceChangedEventArgs(removedElement, null)); + } + base.RemoveItem(index); + if (_disableDeleteCount == 0) + { + // All elements referencing the removed element will be redirected to the first element in collection + // Fire the NameReferenceChanged event to update all the dependent elements + ChartNamedElement defaultElement = this.Count > 0 ? this[0] : null; + ((INameController)this).OnNameReferenceChanged(new NameReferenceChangedEventArgs(removedElement, defaultElement)); + } + } + + /// + /// Fixes the name references of the item. + /// + internal virtual void FixNameReferences(T item) + { + //Nothing to fix at the base class... + } + + #endregion + + #region INameController Members + + /// + /// Determines whether is the name us unique. + /// + /// The name. + /// + /// true if is the name us unique; otherwise, false. + /// + bool INameController.IsUniqueName(string name) + { + return this.IsUniqueName(name); + } + + /// + /// Gets or sets a value indicating whether this instance is in edit mode by collecrtion editor. + /// + /// + /// true if this instance the colection is editing; otherwise, false. + /// + bool INameController.IsColectionEditing + { + get + { + return _disableDeleteCount == 0; + } + set + { + _disableDeleteCount += value ? 1 : -1; + } + } + + /// + /// Raises the event. + /// + /// The instance containing the event data. + void INameController.OnNameReferenceChanging(NameReferenceChangedEventArgs e) + { + if (!IsSuspended) + { + if (this.NameReferenceChanging != null) + this.NameReferenceChanging(this, e); + } + } + + /// + /// Raises the event. + /// + /// The instance containing the event data. + void INameController.OnNameReferenceChanged(NameReferenceChangedEventArgs e) + { + if (!IsSuspended) + { + if (this.NameReferenceChanged != null) + this.NameReferenceChanged(this, e); + } + } + + /// + /// Does the snapshot of collection items. + /// + /// if set to true collection items will be saved. + /// The changing callback. + /// The changed callback. + void INameController.DoSnapshot(bool save, + EventHandler changingCallback, + EventHandler changedCallback) + { + if (save) + { + _cachedState = new List(this); + if (changingCallback != null) this.NameReferenceChanging += changingCallback; + if (changedCallback != null) this.NameReferenceChanged += changedCallback; + } + else + { + if (changingCallback != null) this.NameReferenceChanging -= changingCallback; + if (changedCallback != null) this.NameReferenceChanged -= changedCallback; + _cachedState.Clear(); + _cachedState = null; + } + } + + /// + /// Gets the snapshot of saved collection items. + /// + /// The snapshot. + IList INameController.Snapshot + { + get { return _cachedState; } + } + + + #endregion + + + } + +} diff --git a/System.Web.DataVisualization/Common/General/BaseInterfaces.cs b/System.Web.DataVisualization/Common/General/BaseInterfaces.cs new file mode 100644 index 000000000..db61a2899 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/BaseInterfaces.cs @@ -0,0 +1,80 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant, victark + +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; + +#if WINFORMS_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + /// + /// IChartElement is implemented by both ChartElements and ChartElementCollection to provide a unified access to Parent/Common elements. + /// + internal interface IChartElement + { + //Properties + IChartElement Parent { get; set; } + CommonElements Common { get; } + + //Methods + void Invalidate(); + } + + + /// + /// Named controller interface allows ChartNamedElements to check the uniqueness of their names + /// + internal interface INameController + { + + /// + /// Determines whether is the name us unique. + /// + /// The name. + /// + /// true if is the name us unique; otherwise, false. + /// + bool IsUniqueName(string name); + /// + /// Gets or sets a value indicating whether this instance is in edit mode by collecrtion editor. + /// + /// + /// true if this instance the colection is editing; otherwise, false. + /// + bool IsColectionEditing { get; set; } + /// + /// Does the snapshot of collection items. + /// + /// if set to true collection items will be saved. + /// The changing callback. + /// The changed callback. + void DoSnapshot(bool save, + EventHandler changingCallback, + EventHandler changedCallback); + /// + /// Gets the snapshot of saved collection items. + /// + /// The snapshot. + IList Snapshot {get;} + /// + /// Raises the event. + /// + /// The instance containing the event data. + void OnNameReferenceChanged(NameReferenceChangedEventArgs e); + /// + /// Raises the event. + /// + /// The instance containing the event data. + void OnNameReferenceChanging(NameReferenceChangedEventArgs e); + } + +} diff --git a/System.Web.DataVisualization/Common/General/Chart.cs b/System.Web.DataVisualization/Common/General/Chart.cs new file mode 100644 index 000000000..a83a2fb71 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/Chart.cs @@ -0,0 +1,4361 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: Chart.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ChartImage, ChartPicture, ChartPaintEventArgs +// +// Purpose: This file contains classes, which are used for Image +// creation and chart painting. This file has also a +// class, which is used for Paint events arguments. +// +// Reviewed: GS - August 2, 2002 +// AG - August 8, 2002 +// AG - Microsoft 16, 2007 +// +//=================================================================== + +#region Used Namespaces + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Design; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Resources; +using System.Reflection; +using System.IO; +using System.Data; +using System.Collections; +using System.Drawing.Imaging; +using System.Drawing.Text; +using System.Xml; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; +using System.Diagnostics; +using System.Security; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +#if Microsoft_CONTROL + + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web; + using System.Web.UI; + using System.Net; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Enumerations + +#if !Microsoft_CONTROL + + /// + /// An enumeration of supported image types + /// + public enum ChartImageType + { + /// + /// BMP image format + /// + Bmp, + /// + /// Jpeg image format + /// + Jpeg, + + /// + /// Png image format + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Png")] + Png, + + /// + /// Enhanced Meta File (Emf) image format. + /// + Emf, + + }; +#endif + + + #endregion + + /// + /// ChartImage class adds image type and data binding functionality to + /// the base ChartPicture class. + /// + internal class ChartImage : ChartPicture + { + #region Fields + + // Private data members, which store properties values + private int _compression = 0; + + // Chart data source object + private object _dataSource = null; + + // Indicates that control was bound to the data source + internal bool boundToDataSource = false; + +#if !Microsoft_CONTROL + private ChartImageType imageType = ChartImageType.Png; +#endif + + #endregion + + #region Constructor + + /// + /// Chart internal constructor. + /// + /// Service container + internal ChartImage(IServiceContainer container) + : base(container) + { + } + + #endregion // Constructor + + #region Properties + + /// + /// Gets or sets the data source for the Chart object. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeDataSource"), + DefaultValue(null), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public object DataSource + { + get + { + return _dataSource; + } + set + { + if(_dataSource != value) + { + _dataSource = value; + this.boundToDataSource = false; + } + } + } + +#if !Microsoft_CONTROL + + /// + /// Image type (Jpeg, BMP, Png) + /// + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(ChartImageType.Png), + SRDescription("DescriptionAttributeImageType"), + PersistenceMode(PersistenceMode.Attribute) + ] + public ChartImageType ImageType + { + get + { + return imageType; + } + set + { + imageType = value; + } + } + +#endif + + /// + /// Image compression value + /// + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributeChartImage_Compression"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int Compression + { + get + { + return _compression; + } + set + { + if(value < 0 || value > 100) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionChartCompressionInvalid)); + } + _compression = value; + } + } + + #endregion + + #region Methods + + #region Image Manipulation + + + /// + /// Saves image into the metafile stream. + /// + /// Image stream. + /// Image stream. + [SecuritySafeCritical] + public void SaveIntoMetafile(Stream imageStream, EmfType emfType) + { + // Check arguments + if (imageStream == null) + throw new ArgumentNullException("imageStream"); + + // Create temporary Graphics object for metafile + using (Bitmap bitmap = new Bitmap(this.Width, this.Height)) + { + using (Graphics newGraphics = Graphics.FromImage(bitmap)) + { + IntPtr hdc = IntPtr.Zero; + try + { + System.Security.Permissions.SecurityPermission securityPermission = new System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode); + securityPermission.Demand(); + + hdc = newGraphics.GetHdc(); + + + // Create metafile object to record. + using (Metafile metaFile = new Metafile( + imageStream, + hdc, + new Rectangle(0, 0, this.Width, this.Height), + MetafileFrameUnit.Pixel, + emfType)) + { + + // Create graphics object to record metaFile. + using (Graphics metaGraphics = Graphics.FromImage(metaFile)) + { + + // Note: Fix for issue #3674. Some 3D borders shadows may be drawn outside + // of image boundaries. This causes issues when generated EMF file + // is placed in IE. Image looks shifted down and hot areas do not align. + if (this.BorderSkin.SkinStyle != BorderSkinStyle.None) + { + metaGraphics.Clip = new Region(new Rectangle(0, 0, this.Width, this.Height)); + } + + // Draw chart in the metafile + this.ChartGraph.IsMetafile = true; + this.Paint(metaGraphics, false); + this.ChartGraph.IsMetafile = false; + + } + } + } + finally + { + if (hdc != IntPtr.Zero) + { + newGraphics.ReleaseHdc(hdc); + } + } + } + } + } + + public Bitmap GetImage() + { + return this.GetImage(96); + } + /// + /// Create Image and draw chart picture + /// + public Bitmap GetImage(float resolution) + { + // Create a new bitmap + + Bitmap image = null; + + while (image == null) + { + bool failed = true; + try + { + image = new Bitmap(Math.Max(1,Width), Math.Max(1,Height)); + image.SetResolution(resolution, resolution); + failed = false; + } + catch (ArgumentException) + { + failed = true; + } + catch (OverflowException) + { + failed = true; + } + catch (InvalidOperationException) + { + failed = true; + } + catch (ExternalException) + { + failed = true; + } + + if (failed) + { + // if failed to create the image, decrease the size and the resolution of the chart + image = null; + float newResolution = Math.Max(resolution / 2, 96); + Width = (int)Math.Ceiling(Width * newResolution / resolution); + Height = (int)Math.Ceiling(Height * newResolution / resolution); + resolution = newResolution; + } + } + + // Creates a new Graphics object from the + // specified Image object. + Graphics offScreen = Graphics.FromImage( image ); + + + + Color backGroundColor; + + if (this.BackColor != Color.Empty) + backGroundColor = this.BackColor; + else + backGroundColor = Color.White; + + // Get the page color if border skin is visible. + if (GetBorderSkinVisibility() && + this.BorderSkin.PageColor != Color.Empty) + { + backGroundColor = this.BorderSkin.PageColor; + } + + // draw a rctangle first with the size of the control, this prevent strange behavior when printing in the reporting services, + // without this rectangle, the printed picture is blurry + Pen pen = new Pen(backGroundColor); + offScreen.DrawRectangle(pen, 0, 0, Width, Height); + pen.Dispose(); + + // Paint the chart + Paint( offScreen , false); + + // Dispose Graphic object + offScreen.Dispose(); + + // Return reference to the image + return image; + } + + #endregion // Image Manipulation + + #region Data Binding + + /// + /// Checks if the type of the data source is valid. + /// + /// Data source object to test. + /// True if valid data source object. + static internal bool IsValidDataSource(object dataSource) + { + if( null != dataSource && + ( + dataSource is IEnumerable || + dataSource is DataSet || + dataSource is DataView || + dataSource is DataTable || + dataSource is System.Data.OleDb.OleDbCommand || + dataSource is System.Data.SqlClient.SqlCommand || + dataSource is System.Data.OleDb.OleDbDataAdapter || + dataSource is System.Data.SqlClient.SqlDataAdapter || + // ADDED: for VS2005 compatibility, DT Nov 25, 2005 + dataSource.GetType().GetInterface("IDataSource") != null + // END ADDED + ) + ) + { + return true; + } + + return false; + } + + + + /// + /// Gets an list of the data source member names. + /// + /// Data source object to get the members for. + /// Indicates that member will be used for Y values. + /// List of member names. + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", + Justification = "Too large of a code change to justify making this change")] + static internal ArrayList GetDataSourceMemberNames(object dataSource, bool usedForYValue) + { + ArrayList names = new ArrayList(); + if (dataSource != null) + { + // ADDED: for VS2005 compatibility, DT Nov 25, 2004 + if (dataSource.GetType().GetInterface("IDataSource") != null) + { + try + { + MethodInfo m = dataSource.GetType().GetMethod("Select"); + if (m != null) + { + if (m.GetParameters().Length == 1) + { + // SQL derived datasource + Type selectArgsType = dataSource.GetType().Assembly.GetType("System.Web.UI.DataSourceSelectArguments", true); + ConstructorInfo ci = selectArgsType.GetConstructor(new Type[] { }); + dataSource = m.Invoke(dataSource, new object[] { ci.Invoke(new object[] { }) }); + } + else + { + // object data source + dataSource = m.Invoke(dataSource, new object[] { }); + } + } + } + catch (TargetException) + { + } + catch (TargetInvocationException) + { + } + } + // END ADDED + + // Check all DataTable based data souces + DataTable dataTable = null; + + if (dataSource is DataTable) + { + dataTable = (DataTable)dataSource; + } + else if (dataSource is DataView) + { + dataTable = ((DataView)dataSource).Table; + } + else if (dataSource is DataSet && ((DataSet)dataSource).Tables.Count > 0) + { + dataTable = ((DataSet)dataSource).Tables[0]; + } + else if (dataSource is System.Data.OleDb.OleDbDataAdapter) + { + dataTable = new DataTable(); + dataTable.Locale = CultureInfo.CurrentCulture; + dataTable = ((System.Data.OleDb.OleDbDataAdapter)dataSource).FillSchema(dataTable, SchemaType.Mapped); + } + else if (dataSource is System.Data.SqlClient.SqlDataAdapter) + { + dataTable = new DataTable(); + dataTable.Locale = CultureInfo.CurrentCulture; + dataTable = ((System.Data.SqlClient.SqlDataAdapter)dataSource).FillSchema(dataTable, SchemaType.Mapped); + } + else if (dataSource is System.Data.OleDb.OleDbDataReader) + { + // Add table columns names + for (int fieldIndex = 0; fieldIndex < ((System.Data.OleDb.OleDbDataReader)dataSource).FieldCount; fieldIndex++) + { + if (!usedForYValue || ((System.Data.OleDb.OleDbDataReader)dataSource).GetFieldType(fieldIndex) != typeof(string)) + { + names.Add(((System.Data.OleDb.OleDbDataReader)dataSource).GetName(fieldIndex)); + } + } + } + else if (dataSource is System.Data.SqlClient.SqlDataReader) + { + // Add table columns names + for (int fieldIndex = 0; fieldIndex < ((System.Data.SqlClient.SqlDataReader)dataSource).FieldCount; fieldIndex++) + { + if (!usedForYValue || ((System.Data.SqlClient.SqlDataReader)dataSource).GetFieldType(fieldIndex) != typeof(string)) + { + names.Add(((System.Data.SqlClient.SqlDataReader)dataSource).GetName(fieldIndex)); + } + } + } + else if (dataSource is System.Data.OleDb.OleDbCommand) + { + System.Data.OleDb.OleDbCommand command = (System.Data.OleDb.OleDbCommand)dataSource; + if (command.Connection != null) + { + command.Connection.Open(); + System.Data.OleDb.OleDbDataReader dataReader = command.ExecuteReader(); + if (dataReader.Read()) + { + for (int fieldIndex = 0; fieldIndex < dataReader.FieldCount; fieldIndex++) + { + if (!usedForYValue || dataReader.GetFieldType(fieldIndex) != typeof(string)) + { + names.Add(dataReader.GetName(fieldIndex)); + } + } + } + + dataReader.Close(); + command.Connection.Close(); + } + } + else if (dataSource is System.Data.SqlClient.SqlCommand) + { + System.Data.SqlClient.SqlCommand command = (System.Data.SqlClient.SqlCommand)dataSource; + if (command.Connection != null) + { + command.Connection.Open(); + System.Data.SqlClient.SqlDataReader dataReader = command.ExecuteReader(); + if (dataReader.Read()) + { + for (int fieldIndex = 0; fieldIndex < dataReader.FieldCount; fieldIndex++) + { + if (!usedForYValue || dataReader.GetFieldType(fieldIndex) != typeof(string)) + { + names.Add(dataReader.GetName(fieldIndex)); + } + } + } + + dataReader.Close(); + command.Connection.Close(); + } + } + + + // Check if DataTable was set + if (dataTable != null) + { + // Add table columns names + foreach (DataColumn column in dataTable.Columns) + { + if (!usedForYValue || column.DataType != typeof(string)) + { + names.Add(column.ColumnName); + } + } + } + + else if (names.Count == 0 && dataSource is ITypedList) + { + foreach (PropertyDescriptor pd in ((ITypedList)dataSource).GetItemProperties(null)) + { + if (!usedForYValue || pd.PropertyType != typeof(string)) + { + names.Add(pd.Name); + } + } + } + else if (names.Count == 0 && dataSource is IEnumerable) + { + // .Net 2.0 ObjectDataSource processing + IEnumerator e = ((IEnumerable)dataSource).GetEnumerator(); + e.Reset(); + e.MoveNext(); + foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(e.Current)) + { + if (!usedForYValue || pd.PropertyType != typeof(string)) + { + names.Add(pd.Name); + } + + } + } + + + + // Check if list still empty + if (names.Count == 0) + { + // Add first column or any data member name + names.Add("0"); + } + + } + + return names; + } + + /// + /// Data binds control to the data source + /// + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", + Justification="Too large of a code change to justify making this change")] + internal void DataBind() + { + // Set bound flag + this.boundToDataSource = true; + + object dataSource = this.DataSource; + if (dataSource != null) + { + + // Convert data adapters to command object + if (dataSource is System.Data.OleDb.OleDbDataAdapter) + { + dataSource = ((System.Data.OleDb.OleDbDataAdapter)dataSource).SelectCommand; + } + else if (dataSource is System.Data.SqlClient.SqlDataAdapter) + { + dataSource = ((System.Data.SqlClient.SqlDataAdapter)dataSource).SelectCommand; + } + + // Convert data source to recognizable source for the series + if (dataSource is DataSet && ((DataSet)dataSource).Tables.Count > 0) + { + dataSource = ((DataSet)dataSource).DefaultViewManager.CreateDataView(((DataSet)dataSource).Tables[0]); + + } + else if (dataSource is DataTable) + { + dataSource = new DataView((DataTable)dataSource); + } + else if (dataSource is System.Data.OleDb.OleDbCommand) + { + System.Data.OleDb.OleDbCommand command = (System.Data.OleDb.OleDbCommand)dataSource; + command.Connection.Open(); + System.Data.OleDb.OleDbDataReader dataReader = command.ExecuteReader(); + + this.DataBind(dataReader, null); + + dataReader.Close(); + command.Connection.Close(); + return; + } + else if (dataSource is System.Data.SqlClient.SqlCommand) + { + System.Data.SqlClient.SqlCommand command = (System.Data.SqlClient.SqlCommand)dataSource; + command.Connection.Open(); + System.Data.SqlClient.SqlDataReader dataReader = command.ExecuteReader(); + + this.DataBind(dataReader, null); + + dataReader.Close(); + command.Connection.Close(); + return; + } + else if (dataSource is IList) + { + dataSource = dataSource as IList; + } + else if (dataSource is IListSource ) + { + if (((IListSource)dataSource).ContainsListCollection && ((IListSource)dataSource).GetList().Count > 0) + { + dataSource = ((IListSource)dataSource).GetList()[0] as IEnumerable; + } + else + { + dataSource = ((IListSource)dataSource).GetList(); + } + } + else + { + dataSource = dataSource as IEnumerable; + } + + // Data bind + DataBind(dataSource as IEnumerable, null); + } + } + + /// + /// Data binds control to the data source + /// + /// Data source to bind to. + /// List of series to bind. + internal void DataBind(IEnumerable dataSource, ArrayList seriesList) + { + // Data bind series + if(dataSource != null && this.Common != null) + { + //************************************************************ + //** If list of series is not provided - bind all of them. + //************************************************************ + if(seriesList == null) + { + seriesList = new ArrayList(); + foreach(Series series in this.Common.Chart.Series) + { + // note: added for design time data binding + if (this.Common.Chart.IsDesignMode()) + { + if (series.YValueMembers.Length > 0) + { + seriesList.Add(series); + } + } + else + { + seriesList.Add(series); + } + } + } + + //************************************************************ + //** Clear all data points in data bound series + //************************************************************ + foreach(Series series in seriesList) + { + if(series.XValueMember.Length > 0 || series.YValueMembers.Length > 0) + { + series.Points.Clear(); + } + } + + //************************************************************ + //** Get and reset data enumerator. + //************************************************************ + IEnumerator enumerator = dataSource.GetEnumerator(); + if(enumerator.GetType() != typeof(System.Data.Common.DbEnumerator) ) + { + try + { + enumerator.Reset(); + } + // Some enumerators may not support Resetting + catch (InvalidOperationException) + { + } + catch (NotImplementedException) + { + } + catch (NotSupportedException) + { + } + } + + + //************************************************************ + //** Loop through the enumerator. + //************************************************************ + bool valueExsists = true; + bool autoDetectType = true; + do + { + // Move to the next item + valueExsists = enumerator.MoveNext(); + + // Loop through all series + foreach(Series series in seriesList) + { + if(series.XValueMember.Length > 0 || series.YValueMembers.Length > 0) + { + //************************************************************ + //** Check and convert fields names. + //************************************************************ + + // Convert comma separated field names string to array of names + string[] yFieldNames = null; + if(series.YValueMembers.Length > 0) + { + yFieldNames = series.YValueMembers.Replace(",,", "\n").Split(','); + for(int index = 0; index < yFieldNames.Length; index++) + { + yFieldNames[index] = yFieldNames[index].Replace("\n", ",").Trim(); + } + } + + // Double check that a string object is not provided for data binding + if(dataSource is string) + { + throw (new ArgumentException(SR.ExceptionDataBindYValuesToString, "dataSource")); + } + + // Check number of fields + if(yFieldNames == null || yFieldNames.GetLength(0) > series.YValuesPerPoint) + { + throw(new ArgumentOutOfRangeException("dataSource", SR.ExceptionDataPointYValuesCountMismatch(series.YValuesPerPoint.ToString(System.Globalization.CultureInfo.InvariantCulture) ) ) ); + } + + //************************************************************ + //** Create new data point. + //************************************************************ + if(valueExsists) + { + // Auto detect values type + if(autoDetectType) + { + autoDetectType = false; + + // Make sure Y field is not empty + string yField = yFieldNames[0]; + int fieldIndex = 1; + while(yField.Length == 0 && fieldIndex < yFieldNames.Length) + { + yField = yFieldNames[fieldIndex++]; + } + + DataPointCollection.AutoDetectValuesType(series, enumerator, series.XValueMember.Trim(), enumerator, yField); + } + + + // Create new point + DataPoint newDataPoint = new DataPoint(series); + bool emptyValues = false; + bool xValueIsNull = false; + + //************************************************************ + //** Get new point X and Y values. + //************************************************************ + object[] yValuesObj = new object[yFieldNames.Length]; + object xValueObj = null; + + // Set X to the value provided or use sequence numbers starting with 1 + if(series.XValueMember.Length > 0) + { + xValueObj = DataPointCollection.ConvertEnumerationItem(enumerator.Current, series.XValueMember.Trim()); + if(xValueObj is System.DBNull || xValueObj == null) + { + xValueIsNull = true; + emptyValues = true; + xValueObj = 0.0; + } + } + + if(yFieldNames.Length == 0) + { + yValuesObj[0] = DataPointCollection.ConvertEnumerationItem(enumerator.Current, null); + if(yValuesObj[0] is System.DBNull || yValuesObj[0] == null) + { + emptyValues = true; + yValuesObj[0] = 0.0; + } + } + else + { + for(int i = 0; i < yFieldNames.Length; i++) + { + if(yFieldNames[i].Length > 0) + { + yValuesObj[i] = DataPointCollection.ConvertEnumerationItem(enumerator.Current, yFieldNames[i]); + if(yValuesObj[i] is System.DBNull || yValuesObj[i] == null) + { + emptyValues = true; + yValuesObj[i] = 0.0; + } + } + else + { + yValuesObj[i] = (((Series)seriesList[0]).IsYValueDateTime()) ? DateTime.Now.Date.ToOADate() : 0.0; + } + } + } + + + // Add data point if X value is not Null + if(!xValueIsNull) + { + if(emptyValues) + { + if(xValueObj != null) + { + newDataPoint.SetValueXY(xValueObj, yValuesObj); + } + else + { + newDataPoint.SetValueXY(0, yValuesObj); + } + series.Points.DataPointInit(ref newDataPoint); + newDataPoint.IsEmpty = true; + series.Points.Add(newDataPoint); + } + else + { + if(xValueObj != null) + { + newDataPoint.SetValueXY(xValueObj, yValuesObj); + } + else + { + newDataPoint.SetValueXY(0, yValuesObj); + } + series.Points.DataPointInit(ref newDataPoint); + series.Points.Add(newDataPoint); + } + } + if (this.Common.Chart.IsDesignMode()) + { + series["TempDesignData"] = "true"; + } + } + } + } + + } while(valueExsists); + + } + } + + + /// + /// Aligns data points using their axis labels. + /// + /// Indicates if points should be sorted by axis labels. + /// Sorting pointSortOrder. + internal void AlignDataPointsByAxisLabel(bool sortAxisLabels, PointSortOrder sortingOrder) + { + // Find series which are attached to the same X axis in the same chart area + foreach(ChartArea chartArea in this.ChartAreas) + { + + // Check if chart area is visible + if(chartArea.Visible) + + { + // Create series list for primary and secondary X axis + ArrayList chartAreaSeriesPrimary = new ArrayList(); + ArrayList chartAreaSeriesSecondary = new ArrayList(); + foreach(Series series in this.Common.Chart.Series) + { + // Check if series belongs to the chart area + if (series.ChartArea == chartArea.Name) + { + if(series.XSubAxisName.Length == 0) + { + if(series.XAxisType == AxisType.Primary) + { + chartAreaSeriesPrimary.Add(series); + } + else + { + chartAreaSeriesSecondary.Add(series); + } + } + } + } + + // Align series + AlignDataPointsByAxisLabel(chartAreaSeriesPrimary, sortAxisLabels, sortingOrder); + AlignDataPointsByAxisLabel(chartAreaSeriesSecondary, sortAxisLabels, sortingOrder); + } + } + } + + /// + /// Aligns data points using their axis labels. + /// + /// List of series to align. + /// Indicates if points should be sorted by axis labels. + /// Sorting order. + internal void AlignDataPointsByAxisLabel( + ArrayList seriesList, + bool sortAxisLabels, + PointSortOrder sortingOrder) + { + // List is empty + if(seriesList.Count == 0) + { + return; + } + + // Collect information about all points in all series + bool indexedX = true; + bool uniqueAxisLabels = true; + ArrayList axisLabels = new ArrayList(); + foreach(Series series in seriesList) + { + ArrayList seriesAxisLabels = new ArrayList(); + foreach(DataPoint point in series.Points) + { + // Check if series has indexed X values + if(!series.IsXValueIndexed && point.XValue != 0.0) + { + indexedX = false; + break; + } + + // Add axis label to the list and make sure it's non-empty and unique + if(point.AxisLabel.Length == 0) + { + uniqueAxisLabels = false; + break; + } + else if(seriesAxisLabels.Contains(point.AxisLabel)) + { + uniqueAxisLabels = false; + break; + } + else if(!axisLabels.Contains(point.AxisLabel)) + { + axisLabels.Add(point.AxisLabel); + } + + seriesAxisLabels.Add(point.AxisLabel); + } + } + + // Sort axis labels + if(sortAxisLabels) + { + axisLabels.Sort(); + if(sortingOrder == PointSortOrder.Descending) + { + axisLabels.Reverse(); + } + } + + // All series must be indexed + if(!indexedX) + { + throw (new InvalidOperationException(SR.ExceptionChartDataPointsAlignmentFaild)); + } + + // AxisLabel can't be empty or duplicated + if(!uniqueAxisLabels) + { + throw (new InvalidOperationException(SR.ExceptionChartDataPointsAlignmentFaildAxisLabelsInvalid)); + } + + // Assign unique X values for data points in all series with same axis LabelStyle + if(indexedX && uniqueAxisLabels) + { + foreach(Series series in seriesList) + { + foreach(DataPoint point in series.Points) + { + point.XValue = axisLabels.IndexOf(point.AxisLabel) + 1; + } + + // Sort points by X value + series.Sort(PointSortOrder.Ascending, "X"); + } + + // Make sure ther are no missing points + foreach(Series series in seriesList) + { + series.IsXValueIndexed = true; + for(int index = 0; index < axisLabels.Count; index++) + { + if(index >= series.Points.Count || + series.Points[index].XValue != index + 1) + { + DataPoint newPoint = new DataPoint(series); + newPoint.AxisLabel = (string)axisLabels[index]; + newPoint.XValue = index + 1; + newPoint.YValues[0] = 0.0; + newPoint.IsEmpty = true; + series.Points.Insert(index, newPoint); + } + } + } + + } + + } + + /// + /// Data bind chart to the table. Series will be automatically added to the chart depending on + /// the number of unique values in the seriesGroupByField column of the data source. + /// Data source can be the Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow. + /// + /// Data source. + /// Name of the field used to group data into series. + /// Name of the field for X values. + /// Comma separated name(s) of the field(s) for Y value(s). + /// Other point properties binding rule in format: PointProperty=Field[{Format}] [,PointProperty=Field[{Format}]]. For example: "Tooltip=Price{C1},Url=WebSiteName". + /// Indicates that series should be sorted by group field. + /// Series sorting order by group field. + internal void DataBindCrossTab( + IEnumerable dataSource, + string seriesGroupByField, + string xField, + string yFields, + string otherFields, + bool sort, + PointSortOrder sortingOrder) + { + // Check arguments + if (dataSource == null) + throw (new ArgumentNullException("dataSource", SR.ExceptionDataPointInsertionNoDataSource)); + + if (dataSource is string) + throw (new ArgumentException(SR.ExceptionDataBindSeriesToString, "dataSource")); + + if (String.IsNullOrEmpty(yFields)) + throw (new ArgumentException(SR.ExceptionChartDataPointsInsertionFailedYValuesEmpty, "yFields")); + + if (String.IsNullOrEmpty(seriesGroupByField)) + throw (new ArgumentException(SR.ExceptionDataBindSeriesGroupByParameterIsEmpty, "seriesGroupByField")); + + + // List of series and group by field values + ArrayList seriesList = new ArrayList(); + ArrayList groupByValueList = new ArrayList(); + + // Convert comma separated Y values field names string to array of names + string[] yFieldNames = null; + if(yFields != null) + { + yFieldNames = yFields.Replace(",,", "\n").Split(','); + for(int index = 0; index < yFieldNames.Length; index++) + { + yFieldNames[index] = yFieldNames[index].Replace("\n", ","); + } + } + + // Convert other fields/properties names to two arrays of names + string[] otherAttributeNames = null; + string[] otherFieldNames = null; + string[] otherValueFormat = null; + DataPointCollection.ParsePointFieldsParameter( + otherFields, + ref otherAttributeNames, + ref otherFieldNames, + ref otherValueFormat); + + + // Get and reset enumerator + IEnumerator enumerator = DataPointCollection.GetDataSourceEnumerator(dataSource); + if(enumerator.GetType() != typeof(System.Data.Common.DbEnumerator)) + { + try + { + enumerator.Reset(); + } + // Some enumerators may not support Resetting + catch (NotSupportedException) + { + } + catch (NotImplementedException) + { + } + catch (InvalidOperationException) + { + } + + } + + // Add data points + bool valueExsist = true; + object[] yValuesObj = new object[yFieldNames.Length]; + object xValueObj = null; + bool autoDetectType = true; + + do + { + // Move to the next objects in the enumerations + if(valueExsist) + { + valueExsist = enumerator.MoveNext(); + } + + // Create and initialize data point + if(valueExsist) + { + // Get value of the group by field + object groupObj = DataPointCollection.ConvertEnumerationItem( + enumerator.Current, + seriesGroupByField); + + // Check series group by field and create new series if required + Series series = null; + int seriesIndex = groupByValueList.IndexOf(groupObj); + if(seriesIndex >= 0) + { + // Select existing series from the list + series = (Series)seriesList[seriesIndex]; + } + else + { + // Create new series + series = new Series(); + series.YValuesPerPoint = yFieldNames.GetLength(0); + + // If not the first series in the list copy some properties + if(seriesList.Count > 0) + { + series.XValueType = ((Series)seriesList[0]).XValueType; + series.autoXValueType = ((Series)seriesList[0]).autoXValueType; + series.YValueType = ((Series)seriesList[0]).YValueType; + series.autoYValueType = ((Series)seriesList[0]).autoYValueType; + } + + // Try to set series name based on grouping vlaue + string groupObjStr = groupObj as string; + if(groupObjStr != null) + { + series.Name = groupObjStr; + } + else + { + series.Name = seriesGroupByField + " - " + groupObj.ToString(); + } + + + // Add series and group value into the lists + groupByValueList.Add(groupObj); + seriesList.Add(series); + } + + + // Auto detect valu(s) type + if(autoDetectType) + { + autoDetectType = false; + DataPointCollection.AutoDetectValuesType(series, enumerator, xField, enumerator, yFieldNames[0]); + } + + // Create new data point + DataPoint newDataPoint = new DataPoint(series); + bool emptyValues = false; + + // Set X to the value provided + if(xField.Length > 0) + { + xValueObj = DataPointCollection.ConvertEnumerationItem(enumerator.Current, xField); + if( DataPointCollection.IsEmptyValue(xValueObj) ) + { + emptyValues = true; + xValueObj = 0.0; + } + } + + // Set Y values + if(yFieldNames.Length == 0) + { + yValuesObj[0] = DataPointCollection.ConvertEnumerationItem(enumerator.Current, null); + if( DataPointCollection.IsEmptyValue(yValuesObj[0]) ) + { + emptyValues = true; + yValuesObj[0] = 0.0; + } + } + else + { + for(int i = 0; i < yFieldNames.Length; i++) + { + yValuesObj[i] = DataPointCollection.ConvertEnumerationItem(enumerator.Current, yFieldNames[i]); + if( DataPointCollection.IsEmptyValue(yValuesObj[i] ) ) + { + emptyValues = true; + yValuesObj[i] = 0.0; + } + } + } + + // Set other values + if(otherAttributeNames != null && + otherAttributeNames.Length > 0) + { + for(int i = 0; i < otherFieldNames.Length; i++) + { + // Get object by field name + object obj = DataPointCollection.ConvertEnumerationItem(enumerator.Current, otherFieldNames[i]); + if( !DataPointCollection.IsEmptyValue( obj ) ) + { + newDataPoint.SetPointCustomProperty( + obj, + otherAttributeNames[i], + otherValueFormat[i]); + } + } + } + + // IsEmpty value was detected + if(emptyValues) + { + if(xValueObj != null) + { + newDataPoint.SetValueXY(xValueObj, yValuesObj); + } + else + { + newDataPoint.SetValueXY(0, yValuesObj); + } + DataPointCollection.DataPointInit(series, ref newDataPoint); + newDataPoint.IsEmpty = true; + series.Points.Add(newDataPoint); + } + else + { + if(xValueObj != null) + { + newDataPoint.SetValueXY(xValueObj, yValuesObj); + } + else + { + newDataPoint.SetValueXY(0, yValuesObj); + } + DataPointCollection.DataPointInit(series, ref newDataPoint); + series.Points.Add(newDataPoint); + } + } + + } while(valueExsist); + + // Sort series usig values of group by field + if(sort) + { + // Duplicate current list + ArrayList oldList = (ArrayList)groupByValueList.Clone(); + + // Sort list + groupByValueList.Sort(); + if(sortingOrder == PointSortOrder.Descending) + { + groupByValueList.Reverse(); + } + + // Change order of series in collection + ArrayList sortedSeriesList = new ArrayList(); + foreach(object obj in groupByValueList) + { + sortedSeriesList.Add(seriesList[oldList.IndexOf(obj)]); + } + seriesList = sortedSeriesList; + } + + // Add all series from the list into the series collection + foreach(Series series in seriesList) + { + this.Common.Chart.Series.Add(series); + } + } + + /// + /// Automatically creates and binds series to specified data table. + /// Each column of the table becomes a Y value in a separate series. + /// Series X value field may also be provided. + /// + /// Data source. + /// Name of the field for series X values. + internal void DataBindTable( + IEnumerable dataSource, + string xField) + { + // Check arguments + if (dataSource == null) + throw new ArgumentNullException("dataSource"); + + // Get list of member names from the data source + ArrayList dataSourceFields = GetDataSourceMemberNames(dataSource, true); + + // Remove X value field if it's there + if (xField != null && xField.Length > 0) + { + int index = -1; + for (int i = 0; i < dataSourceFields.Count; i++) + { + if ( String.Equals((string)dataSourceFields[i], xField, StringComparison.OrdinalIgnoreCase ) ) + { + index = i; + break; + } + } + if (index >= 0) + { + dataSourceFields.RemoveAt(index); + } + else + { + // Check if field name passed as index + bool parseSucceed = int.TryParse(xField, NumberStyles.Any, CultureInfo.InvariantCulture, out index); + if (parseSucceed && index >= 0 && index < dataSourceFields.Count) + { + dataSourceFields.RemoveAt(index); + } + } + } + + // Get number of series + int seriesNumber = dataSourceFields.Count; + if (seriesNumber > 0) + { + // Create as many series as fields in the data source + ArrayList seriesList = new ArrayList(); + int index = 0; + foreach (string fieldName in dataSourceFields) + { + Series series = new Series(fieldName); + + // Set binding properties + series.YValueMembers = fieldName; + series.XValueMember = xField; + + // Add to list + seriesList.Add(series); + ++index; + } + + + // Data bind series + this.DataBind(dataSource, seriesList); + + // Add all series from the list into the series collection + foreach (Series series in seriesList) + { + // Clear binding properties + series.YValueMembers = String.Empty; + series.XValueMember = String.Empty; + + // Add series into the list + this.Common.Chart.Series.Add(series); + } + } + } + + #endregion // Data Binding + + #endregion + + } + + /// + /// ChartPicture class represents chart content like legends, titles, + /// chart areas and series. It provides methods for positioning and + /// drawing all chart elements. + /// + internal class ChartPicture : ChartElement, IServiceProvider + { + #region Fields + + /// + /// Indicates that chart exceptions should be suppressed. + /// + private bool _suppressExceptions = false; + + // Chart Graphic object + internal ChartGraphics ChartGraph { get; set; } + + // Private data members, which store properties values + private GradientStyle _backGradientStyle = GradientStyle.None; + private Color _backSecondaryColor = Color.Empty; + private Color _backColor = Color.White; + private string _backImage = ""; + private ChartImageWrapMode _backImageWrapMode = ChartImageWrapMode.Tile; + private Color _backImageTransparentColor = Color.Empty; + private ChartImageAlignmentStyle _backImageAlign = ChartImageAlignmentStyle.TopLeft; + private Color _borderColor = Color.White; + private int _borderWidth = 1; + private ChartDashStyle _borderDashStyle = ChartDashStyle.NotSet; + private ChartHatchStyle _backHatchStyle = ChartHatchStyle.None; + private AntiAliasingStyles _antiAliasing = AntiAliasingStyles.All; + private TextAntiAliasingQuality _textAntiAliasingQuality = TextAntiAliasingQuality.High; + private bool _isSoftShadows = true; + private int _width = 300; + private int _height = 300; + private DataManipulator _dataManipulator = new DataManipulator(); + internal HotRegionsList hotRegionsList = null; + private BorderSkin _borderSkin = null; +#if !Microsoft_CONTROL + private bool _isMapEnabled = true; + private MapAreasCollection _mapAreas = null; +#endif + // Chart areas collection + private ChartAreaCollection _chartAreas = null; + + // Chart legend collection + private LegendCollection _legends = null; + + // Chart title collection + private TitleCollection _titles = null; + + // Chart annotation collection + private AnnotationCollection _annotations = null; + + // Annotation smart labels class + internal AnnotationSmartLabel annotationSmartLabel = new AnnotationSmartLabel(); + + // Chart picture events + internal event EventHandler BeforePaint; + internal event EventHandler AfterPaint; + + // Chart title position rectangle + private RectangleF _titlePosition = RectangleF.Empty; + + // Element spacing size + internal const float elementSpacing = 3F; + + // Maximum size of the font in percentage + internal const float maxTitleSize = 15F; + + // Printing indicator + internal bool isPrinting = false; + + // Indicates chart selection mode + internal bool isSelectionMode = false; + + private FontCache _fontCache = new FontCache(); + + // Position of the chart 3D border + private RectangleF _chartBorderPosition = RectangleF.Empty; + +#if Microsoft_CONTROL + + // Saving As Image indicator + internal bool isSavingAsImage = false; + + // Indicates that chart background is restored from the double buffer + // prior to drawing top level objects like annotations, cursors and selection. + internal bool backgroundRestored = false; + + // Buffered image of non-top level chart elements + internal Bitmap nonTopLevelChartBuffer = null; + +#endif // Microsoft_CONTROL + + #endregion + + #region Constructors + + /// + /// Constructor. + /// + /// Service container + public ChartPicture(IServiceContainer container) + { + if(container == null) + { + throw(new ArgumentNullException(SR.ExceptionInvalidServiceContainer)); + } + + // Create and set Common Elements + Common = new CommonElements(container); + ChartGraph= new ChartGraphics(Common); + hotRegionsList = new HotRegionsList(Common); + + // Create border properties class + _borderSkin = new BorderSkin(this); + + // Create a collection of chart areas + _chartAreas = new ChartAreaCollection(this); + + // Create a collection of legends + _legends = new LegendCollection(this); + + // Create a collection of titles + _titles = new TitleCollection(this); + + // Create a collection of annotations + _annotations = new AnnotationCollection(this); + + // Set Common elements for data manipulator + _dataManipulator.Common = Common; + +#if !Microsoft_CONTROL + // Create map areas collection + _mapAreas = new MapAreasCollection(); +#endif + } + + /// + /// Returns Chart service object + /// + /// Service AxisName + /// Chart picture + [EditorBrowsableAttribute(EditorBrowsableState.Never)] + object IServiceProvider.GetService(Type serviceType) + { + if(serviceType == typeof(ChartPicture)) + { + return this; + } + throw (new ArgumentException( SR.ExceptionChartPictureUnsupportedType( serviceType.ToString() ) ) ); + } + + #endregion + + #region Painting and selection methods + + /// + /// Performs empty painting. + /// + internal void PaintOffScreen() + { + // Check chart size + // NOTE: Fixes issue #4733 + if (this.Width <= 0 || this.Height <= 0) + { + return; + } + + // Set process Mode to hot regions + this.Common.HotRegionsList.ProcessChartMode |= ProcessMode.HotRegions; +#if Microsoft_CONTROL + this.Common.HotRegionsList.hitTestCalled = true; +#endif // Microsoft_CONTROL + + // Enable selection mode + this.isSelectionMode = true; + + // Hot Region list does not exist. Create the list. + //this.common.HotRegionsList.List = new ArrayList(); + this.Common.HotRegionsList.Clear(); + + // Create a new bitmap + Bitmap image = new Bitmap(Math.Max(1,Width), Math.Max(1,Height)); + + // Creates a new Graphics object from the + // specified Image object. + Graphics offScreen = Graphics.FromImage(image); + + // Connect Graphics object with Chart Graphics object + ChartGraph.Graphics = offScreen; + + // Remember the previous dirty flag +#if Microsoft_CONTROL + bool oldDirtyFlag = this.Common.Chart.dirtyFlag; +#endif //Microsoft_CONTROL + + + Paint(ChartGraph.Graphics, false); + + image.Dispose(); + + // Restore the previous dirty flag +#if Microsoft_CONTROL + this.Common.Chart.dirtyFlag = oldDirtyFlag; +#endif //Microsoft_CONTROL + + // Disable selection mode + this.isSelectionMode = false; + + // Set process Mode to hot regions + this.Common.HotRegionsList.ProcessChartMode |= ProcessMode.HotRegions; + + } + + /// + /// Gets text rendering quality. + /// + /// Text rendering quality. + internal TextRenderingHint GetTextRenderingHint() + { + TextRenderingHint result = TextRenderingHint.SingleBitPerPixelGridFit; + if( (this.AntiAliasing & AntiAliasingStyles.Text) == AntiAliasingStyles.Text ) + { + result = TextRenderingHint.ClearTypeGridFit; + if(this.TextAntiAliasingQuality == TextAntiAliasingQuality.Normal) + { + result = TextRenderingHint.AntiAlias; + } + else if(this.TextAntiAliasingQuality == TextAntiAliasingQuality.SystemDefault) + { + result = TextRenderingHint.SystemDefault; + } + } + else + { + result = TextRenderingHint.SingleBitPerPixelGridFit; + } + + return result; + } + + internal bool GetBorderSkinVisibility() + { + return _borderSkin.SkinStyle != BorderSkinStyle.None && this.Width > 20 && this.Height > 20; + } + + /// + /// This function paints a chart. + /// + /// The graph provides drawing object to the display device. A Graphics object is associated with a specific device context. + /// Indicates that only chart top level elements like cursors, selection or annotation objects must be redrawn. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "3#svg")] + internal void Paint( + Graphics graph, + bool paintTopLevelElementOnly ) + { + +#if Microsoft_CONTROL + + // Reset restored and saved backgound flags + this.backgroundRestored = false; + +#endif // Microsoft_CONTROL + + // Reset Annotation Smart Labels + this.annotationSmartLabel.Reset(); + + // Do not draw the control if size is less than 5 pixel + if (this.Width < 5 || this.Height < 5) + { + return; + } + +#if Microsoft_CONTROL + + bool resetHotRegionList = false; + + if( + this.Common.HotRegionsList.hitTestCalled + || IsToolTipsEnabled() + ) + { + Common.HotRegionsList.ProcessChartMode = ProcessMode.HotRegions | ProcessMode.Paint; + + this.Common.HotRegionsList.hitTestCalled = false; + + // Clear list of hot regions + if(paintTopLevelElementOnly) + { + // If repainting only top level elements (annotations) - + // clear top level objects hot regions only + for(int index = 0; index < this.Common.HotRegionsList.List.Count; index++) + { + HotRegion region = (HotRegion)this.Common.HotRegionsList.List[index]; + if(region.Type == ChartElementType.Annotation) + { + this.Common.HotRegionsList.List.RemoveAt(index); + --index; + } + } + } + else + { + // If repainting whole chart - clear all hot regions + resetHotRegionList = true; + } + } + else + { + Common.HotRegionsList.ProcessChartMode = ProcessMode.Paint; + + // If repainting whole chart - clear all hot regions + resetHotRegionList = true; + } + + // Reset hot region list + if(resetHotRegionList) + { + this.Common.HotRegionsList.Clear(); + } + +#else + if( this.IsMapEnabled ) + { + Common.HotRegionsList.ProcessChartMode |= ProcessMode.ImageMaps | ProcessMode.Paint; + + // Clear any existing non-custom image map areas + for(int index = 0; index < this.MapAreas.Count; index++) + { + MapArea mapArea = this.MapAreas[index]; + if(!mapArea.IsCustom) + { + this.MapAreas.RemoveAt(index); + --index; + } + } + } + + +#endif //#if Microsoft_CONTROL + + // Check if control was data bound + ChartImage chartImage = this as ChartImage; + if(chartImage != null && !chartImage.boundToDataSource) + { + if(this.Common != null && this.Common.Chart != null && !this.Common.Chart.IsDesignMode()) + { + this.Common.Chart.DataBind(); + } + } + + // Connect Graphics object with Chart Graphics object + ChartGraph.Graphics = graph; + + Common.graph = ChartGraph; + + // Set anti alias mode + ChartGraph.AntiAliasing = _antiAliasing; + ChartGraph.softShadows = _isSoftShadows; + ChartGraph.TextRenderingHint = GetTextRenderingHint(); + + try + { + // Check if only chart area cursors and annotations must be redrawn + if(!paintTopLevelElementOnly) + { + // Fire Before Paint event + OnBeforePaint(new ChartPaintEventArgs(this.Chart, this.ChartGraph, this.Common, new ElementPosition(0, 0, 100, 100))); + + // Flag indicates that resize method should be called + // after adjusting the intervals in 3D charts + bool resizeAfterIntervalAdjusting = false; + + // RecalculateAxesScale paint chart areas + foreach (ChartArea area in _chartAreas ) + { + + // Check if area is visible + if(area.Visible) + + { + area.Set3DAnglesAndReverseMode(); + area.SetTempValues(); + area.ReCalcInternal(); + + // Resize should be called the second time + if( area.Area3DStyle.Enable3D && !area.chartAreaIsCurcular) + { + resizeAfterIntervalAdjusting = true; + } + } + } + + // Call Customize event + this.Common.Chart.CallOnCustomize(); + + // Resize picture + Resize(ChartGraph, resizeAfterIntervalAdjusting); + + + // This code is introduce because labels has to + // be changed when scene is rotated. + bool intervalReCalculated = false; + foreach (ChartArea area in _chartAreas ) + { + if( area.Area3DStyle.Enable3D && + !area.chartAreaIsCurcular + + && area.Visible + + ) + + { + // Make correction for interval in 3D space + intervalReCalculated = true; + area.Estimate3DInterval( ChartGraph ); + area.ReCalcInternal(); + } + } + + // Resize chart areas after updating 3D interval + if(resizeAfterIntervalAdjusting) + { + // NOTE: Fixes issue #6808. + // In 3D chart area interval will be changed to compenstae for the axis rotation angle. + // This will cause all standard labels to be changed. We need to call the customize event + // the second time to give user a chance to modify those labels. + if (intervalReCalculated) + { + // Call Customize event + this.Common.Chart.CallOnCustomize(); + } + + // Resize chart elements + Resize(ChartGraph); + } + + + //*********************************************************************** + //** Draw chart 3D border + //*********************************************************************** + if (GetBorderSkinVisibility()) + { + // Fill rectangle with page color + ChartGraph.FillRectangleAbs( new RectangleF( 0, 0, Width-1 , Height-1 ), + _borderSkin.PageColor, + ChartHatchStyle.None, + "", + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + _borderSkin.PageColor, + 1, + ChartDashStyle.Solid, + PenAlignment.Inset ); + + // Draw 3D border + ChartGraph.Draw3DBorderAbs( + _borderSkin, + this._chartBorderPosition, + BackColor, + BackHatchStyle, + BackImage, + BackImageWrapMode, + BackImageTransparentColor, + BackImageAlignment, + BackGradientStyle, + BackSecondaryColor, + BorderColor, + BorderWidth, + BorderDashStyle); + } + + // Paint Background + else + { + ChartGraph.FillRectangleAbs( new RectangleF( 0, 0, Width-1 , Height-1 ), + BackColor, + BackHatchStyle, + BackImage, + BackImageWrapMode, + BackImageTransparentColor, + BackImageAlignment, + BackGradientStyle, + BackSecondaryColor, + BorderColor, + BorderWidth, + BorderDashStyle, + PenAlignment.Inset ); + } + + // Call BackPaint event + this.Chart.CallOnPrePaint(new ChartPaintEventArgs(this.Chart, this.ChartGraph, this.Common, new ElementPosition(0, 0, 100, 100))); + + // Call paint function for each chart area. + foreach (ChartArea area in _chartAreas ) + { + + // Check if area is visible + if(area.Visible) + + { + area.Paint(ChartGraph); + } + } + + // This code is introduced because of GetPointsInterval method, + // which is very time consuming. There is no reason to calculate + // interval after painting. + foreach (ChartArea area in _chartAreas ) + { + // Reset interval data + area.intervalData = double.NaN; + } + + // Draw Legends + foreach(Legend legendCurrent in this.Legends) + { + legendCurrent.Paint(ChartGraph); + } + + // Draw chart titles from the collection + foreach(Title titleCurrent in this.Titles) + { + titleCurrent.Paint(ChartGraph); + } + + // Call Paint event + this.Chart.CallOnPostPaint(new ChartPaintEventArgs(this.Chart, this.ChartGraph, this.Common, new ElementPosition(0, 0, 100, 100))); + } + + // Draw annotation objects + this.Annotations.Paint(ChartGraph, paintTopLevelElementOnly); + + // Draw chart areas cursors in all areas. + // Only if not in selection + if(!this.isSelectionMode) + { + foreach (ChartArea area in _chartAreas ) + { + + // Check if area is visible + if(area.Visible) + + { + area.PaintCursors(ChartGraph, paintTopLevelElementOnly); + } + } + } + + // Return default values + foreach (ChartArea area in _chartAreas ) + { + + // Check if area is visible + if(area.Visible) + + { + area.Restore3DAnglesAndReverseMode(); + area.GetTempValues(); + } + } + } + catch(System.Exception) + { + throw; + } + finally + { + // Fire After Paint event + OnAfterPaint(new ChartPaintEventArgs(this.Chart, this.ChartGraph, this.Common, new ElementPosition(0, 0, 100, 100))); + + // Restore temp values for each chart area + foreach (ChartArea area in _chartAreas ) + { + + // Check if area is visible + if(area.Visible) + + { + area.Restore3DAnglesAndReverseMode(); + area.GetTempValues(); + } + } + +#if !Microsoft_CONTROL + if (this.Chart.IsDesignMode()) + { + this.Chart.MapAreas.RemoveNonCustom(); + } +#endif //!Microsoft_CONTROL + } + } + + /// + /// Invoke before paint delegates. + /// + /// Event arguments. + protected virtual void OnBeforePaint(ChartPaintEventArgs e) + { + if (BeforePaint != null) + { + //Invokes the delegates. + BeforePaint(this, e); + } + } + + /// + /// Invoke after paint delegates. + /// + /// Event arguments. + protected virtual void OnAfterPaint(ChartPaintEventArgs e) + { + if (AfterPaint != null) + { + //Invokes the delegates. + AfterPaint(this, e); + } + } + + internal override void Invalidate() + { + base.Invalidate(); + +#if Microsoft_CONTROL + if (Chart!=null) + Chart.Invalidate(); +#endif + } + #endregion + + #region Resizing methods + + /// + /// Resize the chart picture. + /// + /// Chart graphics. + public void Resize(ChartGraphics chartGraph) + { + Resize(chartGraph, false); + } + + /// + /// Resize the chart picture. + /// + /// Chart graphics. + /// Indicates that only chart area position is calculated. + public void Resize(ChartGraphics chartGraph, bool calcAreaPositionOnly) + { + // Set the chart size for Common elements + Common.Width = _width; + Common.Height = _height; + + // Set the chart size for Chart graphics + chartGraph.SetPictureSize( _width, _height ); + + // Initialize chart area(s) rectangle + RectangleF chartAreasRectangle = new RectangleF(0, 0, _width - 1, _height - 1); + chartAreasRectangle = chartGraph.GetRelativeRectangle(chartAreasRectangle); + + //****************************************************** + //** Get the 3D border interface + //****************************************************** + _titlePosition = RectangleF.Empty; + IBorderType border3D = null; + bool titleInBorder = false; + + if(_borderSkin.SkinStyle != BorderSkinStyle.None) + { + // Set border size + this._chartBorderPosition = chartGraph.GetAbsoluteRectangle(chartAreasRectangle); + + // Get border interface + border3D = Common.BorderTypeRegistry.GetBorderType(_borderSkin.SkinStyle.ToString()); + if(border3D != null) + { + border3D.Resolution = chartGraph.Graphics.DpiX; + // Check if title should be displayed in the border + titleInBorder = border3D.GetTitlePositionInBorder() != RectangleF.Empty; + _titlePosition = chartGraph.GetRelativeRectangle(border3D.GetTitlePositionInBorder()); + _titlePosition.Width = chartAreasRectangle.Width - _titlePosition.Width; + + // Adjust are position to the border size + border3D.AdjustAreasPosition(chartGraph, ref chartAreasRectangle); + } + } + + //****************************************************** + //** Calculate position of all titles in the collection + //****************************************************** + RectangleF frameTitlePosition = RectangleF.Empty; + if(titleInBorder) + { + frameTitlePosition = new RectangleF(_titlePosition.Location, _titlePosition.Size); + } + foreach(Title title in this.Titles) + { + if (title.DockedToChartArea == Constants.NotSetValue && + title.Position.Auto && + title.Visible) + { + title.CalcTitlePosition(chartGraph, ref chartAreasRectangle, ref frameTitlePosition, elementSpacing); + } + } + + //****************************************************** + //** Calculate position of all legends in the collection + //****************************************************** + this.Legends.CalcLegendPosition(chartGraph, ref chartAreasRectangle, elementSpacing); + + //****************************************************** + //** Calculate position of the chart area(s) + //****************************************************** + chartAreasRectangle.Width -= elementSpacing; + chartAreasRectangle.Height -= elementSpacing; + RectangleF areaPosition = new RectangleF(); + + + // Get number of chart areas that requeres automatic positioning + int areaNumber = 0; + foreach (ChartArea area in _chartAreas ) + { + + // Check if area is visible + if(area.Visible) + + { + if(area.Position.Auto) + { + ++areaNumber; + } + } + } + + // Calculate how many columns & rows of areas we going to have + int areaColumns = (int)Math.Floor(Math.Sqrt(areaNumber)); + if(areaColumns < 1) + { + areaColumns = 1; + } + int areaRows = (int)Math.Ceiling(((float)areaNumber) / ((float)areaColumns)); + + // Set position for all areas + int column = 0; + int row = 0; + foreach (ChartArea area in _chartAreas ) + { + + // Check if area is visible + if(area.Visible) + + { + if(area.Position.Auto) + { + // Calculate area position + areaPosition.Width = chartAreasRectangle.Width / areaColumns - elementSpacing; + areaPosition.Height = chartAreasRectangle.Height / areaRows - elementSpacing; + areaPosition.X = chartAreasRectangle.X + column * (chartAreasRectangle.Width / areaColumns) + elementSpacing; + areaPosition.Y = chartAreasRectangle.Y + row * (chartAreasRectangle.Height / areaRows) + elementSpacing; + + // Calculate position of all titles in the collection docked outside of the chart area + TitleCollection.CalcOutsideTitlePosition(this, chartGraph, area, ref areaPosition, elementSpacing); + + // Calculate position of the legend if it's docked outside of the chart area + this.Legends.CalcOutsideLegendPosition(chartGraph, area, ref areaPosition, elementSpacing); + + // Set area position without changing the Auto flag + area.Position.SetPositionNoAuto(areaPosition.X, areaPosition.Y, areaPosition.Width, areaPosition.Height); + + // Go to next area + ++row; + if(row >= areaRows) + { + row = 0; + ++column; + } + } + else + { + RectangleF rect = area.Position.ToRectangleF(); + + // Calculate position of all titles in the collection docked outside of the chart area + TitleCollection.CalcOutsideTitlePosition(this, chartGraph, area, ref rect, elementSpacing); + + // Calculate position of the legend if it's docked outside of the chart area + this.Legends.CalcOutsideLegendPosition(chartGraph, area, ref rect, elementSpacing); + } + } + } + + //****************************************************** + //** Align chart areas Position if required + //****************************************************** + AlignChartAreasPosition(); + + //******************************************************** + //** Check if only chart area position must be calculated. + //******************************************************** + if(!calcAreaPositionOnly) + { + + //****************************************************** + //** Call Resize function for each chart area. + //****************************************************** + foreach (ChartArea area in _chartAreas ) + { + + // Check if area is visible + if(area.Visible) + + { + area.Resize(chartGraph); + } + } + + //****************************************************** + //** Align chart areas InnerPlotPosition if required + //****************************************************** + AlignChartAreas(AreaAlignmentStyles.PlotPosition); + + //****************************************************** + //** Calculate position of the legend if it's inside + //** chart plotting area + //****************************************************** + + // Calculate position of all titles in the collection docked outside of the chart area + TitleCollection.CalcInsideTitlePosition(this, chartGraph, elementSpacing); + + this.Legends.CalcInsideLegendPosition(chartGraph, elementSpacing); + } + } + + /// + /// Minimum and maximum do not have to be calculated + /// from data series every time. It is very time + /// consuming. Minimum and maximum are buffered + /// and only when this flags are set Minimum and + /// Maximum are refreshed from data. + /// + internal void ResetMinMaxFromData() + { + if (_chartAreas != null) + { + // Call ResetMinMaxFromData function for each chart area. + foreach (ChartArea area in _chartAreas) + { + + // Check if area is visible + if (area.Visible) + { + area.ResetMinMaxFromData(); + } + } + } + } + + /// + /// RecalculateAxesScale the chart picture. + /// + public void Recalculate() + { + // Call ReCalc function for each chart area. + foreach (ChartArea area in _chartAreas ) + { + + // Check if area is visible + if(area.Visible) + + { + area.ReCalcInternal(); + } + } + } + + #endregion + + #region Chart picture properties + + // VSTS 96787-Text Direction (RTL/LTR) +#if !Microsoft_CONTROL + private RightToLeft rightToLeft = RightToLeft.No; +#endif //!Microsoft_CONTROL + /// + /// Gets or sets the RightToLeft type. + /// + [ + DefaultValue(RightToLeft.No) + ] + public RightToLeft RightToLeft + { + get + { +#if Microsoft_CONTROL + return this.Common.Chart.RightToLeft; +#else // !WIN_CONTROL + return this.rightToLeft; +#endif // WIN_CONTROL + } + set + { +#if Microsoft_CONTROL + this.Common.Chart.RightToLeft = value; +#else // !Microsoft_CONTROL + this.rightToLeft = value; +#endif // Microsoft_CONTROL + } + } + + /// + /// Indicates that non-critical chart exceptions will be suppressed. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(false), + SRDescription("DescriptionAttributeSuppressExceptions"), + ] + internal bool SuppressExceptions + { + set + { + _suppressExceptions = value; + } + get + { + return _suppressExceptions; + } + } + + /// + /// Chart border skin style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(BorderSkinStyle.None), + SRDescription("DescriptionAttributeBorderSkin"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif + ] + public BorderSkin BorderSkin + { + get + { + return _borderSkin; + } + set + { + _borderSkin = value; + } + } + +#if ! Microsoft_CONTROL + + /// + /// Indicates that chart image map is enabled. + /// + [ + SRCategory("CategoryAttributeMap"), + Bindable(true), + SRDescription("DescriptionAttributeMapEnabled"), + PersistenceMode(PersistenceMode.InnerProperty), + DefaultValue(true) + ] + public bool IsMapEnabled + { + get + { + return _isMapEnabled; + } + set + { + _isMapEnabled = value; + } + } + + /// + /// Chart map areas collection. + /// + [ + SRCategory("CategoryAttributeMap"), + SRDescription("DescriptionAttributeMapAreas"), + PersistenceMode(PersistenceMode.InnerProperty), + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base) + ] + public MapAreasCollection MapAreas + { + get + { + return _mapAreas; + } + } +#endif + + /// + /// Reference to chart area collection + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeChartAreas"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base) + ] + public ChartAreaCollection ChartAreas + { + get + { + return _chartAreas; + } + } + + /// + /// Chart legend collection. + /// + [ + SRCategory("CategoryAttributeChart"), + SRDescription("DescriptionAttributeLegends"), + Editor(Editors.LegendCollectionEditor.Editor, Editors.LegendCollectionEditor.Base), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif + ] + public LegendCollection Legends + { + get + { + return _legends; + } + } + + /// + /// Chart title collection. + /// + [ + SRCategory("CategoryAttributeCharttitle"), + SRDescription("DescriptionAttributeTitles"), + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif + ] + public TitleCollection Titles + { + get + { + return _titles; + } + } + + + + /// + /// Chart annotation collection. + /// + [ + SRCategory("CategoryAttributeChart"), + SRDescription("DescriptionAttributeAnnotations3"), + Editor(Editors.AnnotationCollectionEditor.Editor, Editors.AnnotationCollectionEditor.Base), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif + ] + public AnnotationCollection Annotations + { + get + { + return _annotations; + } + } + + + + /// + /// Background color for the Chart + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "White"), + SRDescription("DescriptionAttributeBackColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackColor + { + get + { + return _backColor; + } + set + { +#if !Microsoft_CONTROL + if(value == Color.Empty || value.A != 255 || value == Color.Transparent) + { + // NOTE: Transparent colors are valid + } +#endif + _backColor = value; + } + } + + /// + /// Border color for the Chart + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "White"), + SRDescription("DescriptionAttributeBorderColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BorderColor + { + get + { + return _borderColor; + } + set + { + _borderColor = value; + } + } + + /// + /// Chart width + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(300), + SRDescription("DescriptionAttributeWidth"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int Width + { + get + { + return _width; + } + set + { + this.InspectChartDimensions(value, this.Height); + _width = value; + Common.Width = _width; + } + } + + /// + /// Series Data Manipulator + /// + [ + SRCategory("CategoryAttributeData"), + SRDescription("DescriptionAttributeDataManipulator"), + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public DataManipulator DataManipulator + { + get + { + return _dataManipulator; + } + } + + + + + /// + /// Chart height + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(300), + SRDescription("DescriptionAttributeHeight3"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int Height + { + get + { + return _height; + } + set + { + this.InspectChartDimensions(this.Width, value); + _height = value; + Common.Height = value; + } + } + + /// + /// Back Hatch style + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartHatchStyle.None), + SRDescription("DescriptionAttributeBackHatchStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + public ChartHatchStyle BackHatchStyle + { + get + { + return _backHatchStyle; + } + set + { + _backHatchStyle = value; + } + } + + /// + /// Chart area background image + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeBackImage"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + NotifyParentPropertyAttribute(true) + ] + public string BackImage + { + get + { + return _backImage; + } + set + { + _backImage = value; + } + } + + /// + /// Chart area background image drawing mode. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageWrapMode.Tile), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageWrapMode"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageWrapMode BackImageWrapMode + { + get + { + return _backImageWrapMode; + } + set + { + _backImageWrapMode = value; + } + } + + /// + /// Background image transparent color. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackImageTransparentColor + { + get + { + return _backImageTransparentColor; + } + set + { + _backImageTransparentColor = value; + } + } + + /// + /// Background image alignment used by ClampUnscale drawing mode. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageAlignmentStyle.TopLeft), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackImageAlign"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageAlignmentStyle BackImageAlignment + { + get + { + return _backImageAlign; + } + set + { + _backImageAlign = value; + } + } + + /// + /// Indicates that smoothing is applied while drawing shadows. + /// + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeSoftShadows3"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsSoftShadows + { + get + { + return _isSoftShadows; + } + set + { + _isSoftShadows = value; + } + } + + /// + /// Specifies whether smoothing (antialiasing) is applied while drawing chart. + /// + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(typeof(AntiAliasingStyles), "All"), + SRDescription("DescriptionAttributeAntiAlias"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public AntiAliasingStyles AntiAliasing + { + get + { + return _antiAliasing; + } + set + { + _antiAliasing = value; + } + } + + /// + /// Specifies the quality of text antialiasing. + /// + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(typeof(TextAntiAliasingQuality), "High"), + SRDescription("DescriptionAttributeTextAntiAliasingQuality"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif + ] + public TextAntiAliasingQuality TextAntiAliasingQuality + { + get + { + return _textAntiAliasingQuality; + } + set + { + _textAntiAliasingQuality = value; + } + } + + /// + /// A type for the background gradient + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(GradientStyle.None), + SRDescription("DescriptionAttributeBackGradientStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + public GradientStyle BackGradientStyle + { + get + { + return _backGradientStyle; + } + set + { + _backGradientStyle = value; + } + } + + /// + /// The second color which is used for a gradient + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackSecondaryColor + { + get + { + return _backSecondaryColor; + } + set + { +#if !Microsoft_CONTROL + if(value != Color.Empty && (value.A != 255 || value == Color.Transparent)) + { + throw (new ArgumentException( SR.ExceptionBackSecondaryColorIsTransparent)); + } +#endif + _backSecondaryColor = value; + } + } + + /// + /// The width of the border line + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeChart_BorderlineWidth"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int BorderWidth + { + get + { + return _borderWidth; + } + set + { + if(value < 0) + { + throw(new ArgumentOutOfRangeException("value", SR.ExceptionChartBorderIsNegative)); + } + _borderWidth = value; + } + } + + /// + /// The style of the border line + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartDashStyle.NotSet), + SRDescription("DescriptionAttributeBorderDashStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartDashStyle BorderDashStyle + { + get + { + return _borderDashStyle; + } + set + { + _borderDashStyle = value; + } + } + + /// + /// Gets the font cache. + /// + /// The font cache. + internal FontCache FontCache + { + get { return _fontCache; } + } + + #endregion + + #region Chart areas alignment methods + + /// + /// Checks if any of the chart areas are aligned. + /// Also checks if the chart ares name in AlignWithChartArea property is valid. + /// + /// True if at least one area requires alignment. + private bool IsAreasAlignmentRequired() + { + bool alignmentRequired = false; + + // Loop through all chart areas + foreach(ChartArea area in this.ChartAreas) + { + + // Check if chart area is visible + if(area.Visible) + + { + // Check if area is aligned + if (area.AlignWithChartArea != Constants.NotSetValue) + { + alignmentRequired = true; + + // Check the chart area used for alignment + if (this._chartAreas.IndexOf(area.AlignWithChartArea)<0) + { + throw (new InvalidOperationException(SR.ExceptionChartAreaNameReferenceInvalid(area.Name, area.AlignWithChartArea))); + } + } + } + } + + return alignmentRequired; + } + + /// + /// Creates a list of the aligned chart areas. + /// + /// Master chart area. + /// Alignment type. + /// Vertical or Horizontal orientation. + /// List of areas that area aligned to the master area. + private ArrayList GetAlignedAreasGroup(ChartArea masterArea, AreaAlignmentStyles type, AreaAlignmentOrientations orientation) + { + ArrayList areaList = new ArrayList(); + + // Loop throught the chart areas and get the ones aligned with specified master area + foreach(ChartArea area in this.ChartAreas) + { + + // Check if chart area is visible + if(area.Visible) + + { + if(area.Name != masterArea.Name && + area.AlignWithChartArea == masterArea.Name && + (area.AlignmentStyle & type) == type && + (area.AlignmentOrientation & orientation) == orientation ) + { + // Add "slave" area into the list + areaList.Add(area); + } + } + } + + // If list is not empty insert "master" area in the beginning + if(areaList.Count > 0) + { + areaList.Insert(0, masterArea); + } + + return areaList; + } + + /// + /// Performs specified type of alignment for the chart areas. + /// + /// Alignment type required. + internal void AlignChartAreas(AreaAlignmentStyles type) + { + // Check if alignment required + if(IsAreasAlignmentRequired()) + { + // Loop through all chart areas + foreach(ChartArea area in this.ChartAreas) + { + + // Check if chart area is visible + if(area.Visible) + + { + // Get vertical areas alignment group using current area as a master + ArrayList alignGroup = GetAlignedAreasGroup( + area, + type, + AreaAlignmentOrientations.Vertical); + + // Align each area in the group + if(alignGroup.Count > 0) + { + AlignChartAreasPlotPosition(alignGroup, AreaAlignmentOrientations.Vertical); + } + + // Get horizontal areas alignment group using current area as a master + alignGroup = GetAlignedAreasGroup( + area, + type, + AreaAlignmentOrientations.Horizontal); + + // Align each area in the group + if(alignGroup.Count > 0) + { + AlignChartAreasPlotPosition(alignGroup, AreaAlignmentOrientations.Horizontal); + } + } + } + } + } + + /// + /// Align inner plot position of the chart areas in the group. + /// + /// List of areas in the group. + /// Group orientation. + private void AlignChartAreasPlotPosition(ArrayList areasGroup, AreaAlignmentOrientations orientation) + { + //**************************************************************** + //** Find the smalles size of the inner plot + //**************************************************************** + RectangleF areaPlotPosition = ((ChartArea)areasGroup[0]).PlotAreaPosition.ToRectangleF(); + foreach(ChartArea area in areasGroup) + { + if(area.PlotAreaPosition.X > areaPlotPosition.X) + { + areaPlotPosition.X += area.PlotAreaPosition.X - areaPlotPosition.X; + areaPlotPosition.Width -= area.PlotAreaPosition.X - areaPlotPosition.X; + } + if(area.PlotAreaPosition.Y > areaPlotPosition.Y) + { + areaPlotPosition.Y += area.PlotAreaPosition.Y - areaPlotPosition.Y; + areaPlotPosition.Height -= area.PlotAreaPosition.Y - areaPlotPosition.Y; + } + if(area.PlotAreaPosition.Right < areaPlotPosition.Right) + { + areaPlotPosition.Width -= areaPlotPosition.Right - area.PlotAreaPosition.Right; + if(areaPlotPosition.Width < 5) + { + areaPlotPosition.Width = 5; + } + } + if(area.PlotAreaPosition.Bottom < areaPlotPosition.Bottom) + { + areaPlotPosition.Height -= areaPlotPosition.Bottom - area.PlotAreaPosition.Bottom; + if(areaPlotPosition.Height < 5) + { + areaPlotPosition.Height = 5; + } + } + } + + //**************************************************************** + //** Align inner plot position for all areas + //**************************************************************** + foreach(ChartArea area in areasGroup) + { + // Get curretn plot position of the area + RectangleF rect = area.PlotAreaPosition.ToRectangleF(); + + // Adjust area position + if( (orientation & AreaAlignmentOrientations.Vertical) == AreaAlignmentOrientations.Vertical) + { + rect.X = areaPlotPosition.X; + rect.Width = areaPlotPosition.Width; + } + if( (orientation & AreaAlignmentOrientations.Horizontal) == AreaAlignmentOrientations.Horizontal) + { + rect.Y = areaPlotPosition.Y; + rect.Height = areaPlotPosition.Height; + } + + // Set new plot position in coordinates relative to chart picture + area.PlotAreaPosition.SetPositionNoAuto(rect.X, rect.Y, rect.Width, rect.Height); + + // Set new plot position in coordinates relative to chart area position + rect.X = (rect.X - area.Position.X) / area.Position.Width * 100f; + rect.Y = (rect.Y - area.Position.Y) / area.Position.Height * 100f; + rect.Width = rect.Width / area.Position.Width * 100f; + rect.Height = rect.Height / area.Position.Height * 100f; + area.InnerPlotPosition.SetPositionNoAuto(rect.X, rect.Y, rect.Width, rect.Height); + + if( (orientation & AreaAlignmentOrientations.Vertical) == AreaAlignmentOrientations.Vertical) + { + area.AxisX2.AdjustLabelFontAtSecondPass(ChartGraph, area.InnerPlotPosition.Auto); + area.AxisX.AdjustLabelFontAtSecondPass(ChartGraph, area.InnerPlotPosition.Auto); + } + if( (orientation & AreaAlignmentOrientations.Horizontal) == AreaAlignmentOrientations.Horizontal) + { + area.AxisY2.AdjustLabelFontAtSecondPass(ChartGraph, area.InnerPlotPosition.Auto); + area.AxisY.AdjustLabelFontAtSecondPass(ChartGraph, area.InnerPlotPosition.Auto); + } + } + + } + + /// + /// Aligns positions of the chart areas. + /// + private void AlignChartAreasPosition() + { + // Check if alignment required + if(IsAreasAlignmentRequired()) + { + // Loop through all chart areas + foreach(ChartArea area in this.ChartAreas) + { + + // Check if chart area is visible + if(area.Visible) + + { + // Check if area is alignd by Position to any other area + if (area.AlignWithChartArea != Constants.NotSetValue && (area.AlignmentStyle & AreaAlignmentStyles.Position) == AreaAlignmentStyles.Position) + { + // Get current area position + RectangleF areaPosition = area.Position.ToRectangleF(); + + // Get master chart area + ChartArea masterArea = this.ChartAreas[area.AlignWithChartArea]; + + // Vertical alignment + if((area.AlignmentOrientation & AreaAlignmentOrientations.Vertical) == AreaAlignmentOrientations.Vertical) + { + // Align area position + areaPosition.X = masterArea.Position.X; + areaPosition.Width = masterArea.Position.Width; + } + + // Horizontal alignment + if((area.AlignmentOrientation & AreaAlignmentOrientations.Horizontal) == AreaAlignmentOrientations.Horizontal) + { + // Align area position + areaPosition.Y = masterArea.Position.Y; + areaPosition.Height = masterArea.Position.Height; + } + + // Set new position + area.Position.SetPositionNoAuto(areaPosition.X, areaPosition.Y, areaPosition.Width, areaPosition.Height); + } + } + } + } + } + +#if Microsoft_CONTROL + + /// + /// Align chart areas cursor. + /// + /// Changed chart area. + /// Orientation of the changed cursor. + /// AxisName of change cursor or selection. + internal void AlignChartAreasCursor(ChartArea changedArea, AreaAlignmentOrientations orientation, bool selectionChanged) + { + // Check if alignment required + if(IsAreasAlignmentRequired()) + { + // Loop through all chart areas + foreach(ChartArea area in this.ChartAreas) + { + + // Check if chart area is visible + if(area.Visible) + + { + // Get vertical areas alignment group using current area as a master + ArrayList alignGroup = GetAlignedAreasGroup( + area, + AreaAlignmentStyles.Cursor, + orientation); + + // Align each area in the group if it contains changed area + if(alignGroup.Contains(changedArea)) + { + // Set cursor position for all areas in the group + foreach(ChartArea groupArea in alignGroup) + { + groupArea.alignmentInProcess = true; + + if(orientation == AreaAlignmentOrientations.Vertical) + { + if(selectionChanged) + { + groupArea.CursorX.SelectionStart = changedArea.CursorX.SelectionStart; + groupArea.CursorX.SelectionEnd = changedArea.CursorX.SelectionEnd; + } + else + { + groupArea.CursorX.Position = changedArea.CursorX.Position; + } + } + if(orientation == AreaAlignmentOrientations.Horizontal) + { + if(selectionChanged) + { + groupArea.CursorY.SelectionStart = changedArea.CursorY.SelectionStart; + groupArea.CursorY.SelectionEnd = changedArea.CursorY.SelectionEnd; + } + else + { + groupArea.CursorY.Position = changedArea.CursorY.Position; + } + } + + groupArea.alignmentInProcess = false; + } + } + } + } + } + } + + /// + /// One of the chart areas was zoomed by the user. + /// + /// Changed chart area. + /// Orientation of the changed scaleView. + /// Area double fuffer image must be disposed. + internal void AlignChartAreasZoomed(ChartArea changedArea, AreaAlignmentOrientations orientation, bool disposeBufferBitmap) + { + // Check if alignment required + if(IsAreasAlignmentRequired()) + { + // Loop through all chart areas + foreach(ChartArea area in this.ChartAreas) + { + + // Check if chart area is visible + if(area.Visible) + + { + // Get vertical areas alignment group using current area as a master + ArrayList alignGroup = GetAlignedAreasGroup( + area, + AreaAlignmentStyles.AxesView, + orientation); + + // Align each area in the group if it contains changed area + if(alignGroup.Contains(changedArea)) + { + // Set cursor position for all areas in the group + foreach(ChartArea groupArea in alignGroup) + { + // Clear image buffer + if(groupArea.areaBufferBitmap != null && disposeBufferBitmap) + { + groupArea.areaBufferBitmap.Dispose(); + groupArea.areaBufferBitmap = null; + } + + if(orientation == AreaAlignmentOrientations.Vertical) + { + groupArea.CursorX.SelectionStart = double.NaN; + groupArea.CursorX.SelectionEnd = double.NaN; + } + if(orientation == AreaAlignmentOrientations.Horizontal) + { + groupArea.CursorY.SelectionStart = double.NaN; + groupArea.CursorY.SelectionEnd = double.NaN; + } + } + } + } + } + } + } + +#endif //Microsoft_CONTROL + + /// + /// Align chart areas axes views. + /// + /// Changed chart area. + /// Orientation of the changed scaleView. + internal void AlignChartAreasAxesView(ChartArea changedArea, AreaAlignmentOrientations orientation) + { + // Check if alignment required + if(IsAreasAlignmentRequired()) + { + // Loop through all chart areas + foreach(ChartArea area in this.ChartAreas) + { + + // Check if chart area is visible + if(area.Visible) + + { + // Get vertical areas alignment group using current area as a master + ArrayList alignGroup = GetAlignedAreasGroup( + area, + AreaAlignmentStyles.AxesView, + orientation); + + // Align each area in the group if it contains changed area + if(alignGroup.Contains(changedArea)) + { + // Set cursor position for all areas in the group + foreach(ChartArea groupArea in alignGroup) + { + groupArea.alignmentInProcess = true; + + if(orientation == AreaAlignmentOrientations.Vertical) + { + groupArea.AxisX.ScaleView.Position = changedArea.AxisX.ScaleView.Position; + groupArea.AxisX.ScaleView.Size = changedArea.AxisX.ScaleView.Size; + groupArea.AxisX.ScaleView.SizeType = changedArea.AxisX.ScaleView.SizeType; + + groupArea.AxisX2.ScaleView.Position = changedArea.AxisX2.ScaleView.Position; + groupArea.AxisX2.ScaleView.Size = changedArea.AxisX2.ScaleView.Size; + groupArea.AxisX2.ScaleView.SizeType = changedArea.AxisX2.ScaleView.SizeType; + } + if(orientation == AreaAlignmentOrientations.Horizontal) + { + groupArea.AxisY.ScaleView.Position = changedArea.AxisY.ScaleView.Position; + groupArea.AxisY.ScaleView.Size = changedArea.AxisY.ScaleView.Size; + groupArea.AxisY.ScaleView.SizeType = changedArea.AxisY.ScaleView.SizeType; + + groupArea.AxisY2.ScaleView.Position = changedArea.AxisY2.ScaleView.Position; + groupArea.AxisY2.ScaleView.Size = changedArea.AxisY2.ScaleView.Size; + groupArea.AxisY2.ScaleView.SizeType = changedArea.AxisY2.ScaleView.SizeType; + } + + groupArea.alignmentInProcess = false; + } + } + } + } + } + } + + #endregion + + #region Helper methods + + /// + /// Inspects the chart dimensions. + /// + /// The width. + /// The height. + internal void InspectChartDimensions(int width, int height) + { + if (this.Chart.IsDesignMode() && ((width * height) > (100 * 1024 *1024))) + { + throw new ArgumentException(SR.ExceptionChartOutOfLimits); + } + if (width < 0) + { + throw new ArgumentException(SR.ExceptionValueMustBeGreaterThan("Width", "0px")); + } + if (height < 0) + { + throw new ArgumentException(SR.ExceptionValueMustBeGreaterThan("Height", "0px")); + } + } + + /// + /// Loads chart appearance template from file. + /// + /// Template file name to load from. + public void LoadTemplate(string name) + { + // Check arguments + if (name == null) + throw new ArgumentNullException("name"); + + // Load template data into the stream +#if Microsoft_CONTROL + Stream stream = new FileStream(name, FileMode.Open, FileAccess.Read); +#else // Microsoft_CONTROL + Stream stream = LoadTemplateData(name); +#endif // Microsoft_CONTROL + + // Load template from stream + LoadTemplate(stream); + + // Close tempate stream + stream.Close(); + } + + /// + /// Loads chart appearance template from stream. + /// + /// Template stream to load from. + public void LoadTemplate(Stream stream) + { + // Check arguments + if (stream == null) + throw new ArgumentNullException("stream"); + + ChartSerializer serializer = (ChartSerializer)this.Common.container.GetService(typeof(ChartSerializer)); + if (serializer != null) + { + // Save previous serializer properties + string oldSerializableContent = serializer.SerializableContent; + string oldNonSerializableContent = serializer.NonSerializableContent; + SerializationFormat oldFormat = serializer.Format; + bool oldIgnoreUnknownXmlAttributes = serializer.IsUnknownAttributeIgnored; + bool oldTemplateMode = serializer.IsTemplateMode; + + // Set serializer properties + serializer.Content = SerializationContents.Appearance; + serializer.SerializableContent += ",Chart.Titles,Chart.Annotations," + + "Chart.Legends,Legend.CellColumns,Legend.CustomItems,LegendItem.Cells," + + "Chart.Series,Series.*Style," + + "Chart.ChartAreas,ChartArea.Axis*," + + "Axis.*Grid,Axis.*TickMark, Axis.*Style," + + "Axis.StripLines, Axis.CustomLabels"; + serializer.Format = SerializationFormat.Xml; + serializer.IsUnknownAttributeIgnored = true; + serializer.IsTemplateMode = true; + + try + { + // Load template + serializer.Load(stream); + } + catch (Exception ex) + { + throw (new InvalidOperationException(ex.Message)); + } + finally + { + // Restore previous serializer properties + serializer.SerializableContent = oldSerializableContent; + serializer.NonSerializableContent = oldNonSerializableContent; + serializer.Format = oldFormat; + serializer.IsUnknownAttributeIgnored = oldIgnoreUnknownXmlAttributes; + serializer.IsTemplateMode = oldTemplateMode; + } + } + } + +#if !Microsoft_CONTROL + + /// + /// Loads template data from the URL. + /// + /// Template URL. + /// Stream with template data or null if error. + private Stream LoadTemplateData(string url) + { + Debug.Assert(url != null, "LoadTemplateData: handed a null url string"); + + Stream dataStream = null; + + // Try to load as relative URL using the Control object + if(dataStream == null) + { + if (this.Common != null && + this.Common.Chart != null && + this.Common.Chart.Page != null) + { + try + { + dataStream = new FileStream( + this.Common.Chart.Page.MapPath(url), + FileMode.Open); + } + catch (NotSupportedException) + { + dataStream = null; + } + catch (SecurityException) + { + dataStream = null; + } + catch (FileNotFoundException) + { + dataStream = null; + } + catch (DirectoryNotFoundException) + { + dataStream = null; + } + catch (PathTooLongException) + { + dataStream = null; + } + } + } + + // Try to load image using the Web Request + if(dataStream == null) + { + Uri templateUri = null; + try + { + // Try to create URI directly from template URL (will work in case of absolute URL) + templateUri = new Uri(url); + } + catch (UriFormatException) + { + templateUri = null; + } + + // Make absolute URL using web form document URL + if(templateUri == null) + { + if (this.Common != null && this.Common.Chart != null) + { + string webFormUrl = this.Common.Chart.webFormDocumentURL; + int slashIndex = webFormUrl.LastIndexOf('/'); + if(slashIndex != -1) + { + webFormUrl = webFormUrl.Substring(0, slashIndex + 1); + } + + try + { + templateUri = new Uri(new Uri(webFormUrl), url); + } + catch (UriFormatException) + { + templateUri = null; + } + } + } + + // Load image from file or web resource + if(templateUri != null) + { + try + { + WebRequest request = WebRequest.Create(templateUri); + dataStream = request.GetResponse().GetResponseStream(); + } + catch (NotSupportedException) + { + dataStream = null; + } + catch (NotImplementedException) + { + dataStream = null; + } + catch (SecurityException) + { + dataStream = null; + } + } + } + + // Try to load as file + if(dataStream == null) + { + dataStream = new FileStream(url, FileMode.Open); + } + + return dataStream; + } + +#endif // Microsoft_CONTROL + + + +#if !Microsoft_CONTROL + + + /// + /// Writes chart map tag into the stream. + /// + /// Html writer to output the data to. + /// Chart map name. + internal void WriteChartMapTag(HtmlTextWriter output, string mapName) + { + output.WriteLine(); + output.AddAttribute(HtmlTextWriterAttribute.Name, mapName); + output.AddAttribute(HtmlTextWriterAttribute.Id, mapName); + output.RenderBeginTag(HtmlTextWriterTag.Map); + + //**************************************************** + //** Fire map areas customize event + //**************************************************** + + // Make sure only non-custom items are passed into the event handler + MapAreasCollection custCollection = new MapAreasCollection(); + + // Move all non-custom items + for (int index = 0; index < _mapAreas.Count; index++) + { + if (!_mapAreas[index].IsCustom) + { + custCollection.Add(_mapAreas[index]); + _mapAreas.RemoveAt(index); + --index; + } + } + + // Call a notification event, so that area items collection can be modified by user + Common.Chart.CallOnCustomizeMapAreas(custCollection); + + // Add customized items + foreach(MapArea area in custCollection) + { + area.IsCustom = false; + _mapAreas.Add(area); + } + + //**************************************************** + //** Add all map areas + //**************************************************** + foreach (MapArea area in _mapAreas) + { + area.RenderTag(output, this.Common.Chart); + } + // if this procedure is enforced to run the image maps have to have at least one map area. + if (_mapAreas.Count == 0) + { + output.Write("\"\""); + } + + //**************************************************** + //** End of the map + //**************************************************** + output.RenderEndTag(); + + return; + } + +#endif + + /// + /// Returns the default title from Titles collection. + /// + /// Create title if it doesn't exists. + /// Default title. + internal Title GetDefaultTitle(bool create) + { + // Check if default title exists + Title defaultTitle = null; + foreach(Title title in this.Titles) + { + if(title.Name == "Default Title") + { + defaultTitle = title; + } + } + + // Create new default title + if(defaultTitle == null && create) + { + defaultTitle = new Title(); + defaultTitle.Name = "Default Title"; + this.Titles.Insert(0, defaultTitle); + } + + return defaultTitle; + } + + /// + /// Checks if tooltips are enabled + /// + /// true if tooltips enabled + private bool IsToolTipsEnabled() + { + + // Data series loop + foreach( Series series in Common.DataManager.Series ) + { + // Check series tooltips + if( series.ToolTip.Length > 0) + { + // ToolTips enabled + return true; + } + + // Check series tooltips + if( series.LegendToolTip.Length > 0 || + series.LabelToolTip.Length > 0) + { + // ToolTips enabled + return true; + } + + // Check point tooltips only for "non-Fast" chart types + if( !series.IsFastChartType() ) + { + // Data point loop + foreach( DataPoint point in series.Points ) + { + // ToolTip empty + if( point.ToolTip.Length > 0) + { + // ToolTips enabled + return true; + } + // ToolTip empty + if( point.LegendToolTip.Length > 0 || + point.LabelToolTip.Length > 0) + { + // ToolTips enabled + return true; + } + } + } + } + + // Legend items loop + foreach( Legend legend in Legends ) + { + foreach( LegendItem legendItem in legend.CustomItems ) + { + // ToolTip empty + if( legendItem.ToolTip.Length > 0 ) + { + return true; + } + } + } + + // Title items loop + foreach( Title title in Titles ) + { + // ToolTip empty + if( title.ToolTip.Length > 0 ) + { + return true; + } + } + + return false; + } + + #endregion + + #region IDisposable Members + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Dispose managed resources + if (ChartGraph != null) + { + ChartGraph.Dispose(); + ChartGraph = null; + } + if (_legends != null) + { + _legends.Dispose(); + _legends = null; + } + if (_titles != null) + { + _titles.Dispose(); + _titles = null; + } + if (_chartAreas != null) + { + _chartAreas.Dispose(); + _chartAreas = null; + } + if (_annotations != null) + { + _annotations.Dispose(); + _annotations = null; + } + if (hotRegionsList != null) + { + hotRegionsList.Dispose(); + hotRegionsList = null; + } + if (_fontCache != null) + { + _fontCache.Dispose(); + _fontCache = null; + } + if (_borderSkin != null) + { + _borderSkin.Dispose(); + _borderSkin = null; + } +#if ! Microsoft_CONTROL + if (_mapAreas != null) + { + _mapAreas.Dispose(); + _mapAreas = null; + } +#endif + +#if Microsoft_CONTROL + if (nonTopLevelChartBuffer != null) + { + nonTopLevelChartBuffer.Dispose(); + nonTopLevelChartBuffer = null; + } +#endif + } + base.Dispose(disposing); + } + + #endregion + } + + /// + /// Event arguments of Chart paint event. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class ChartPaintEventArgs : EventArgs + { + #region Fields + + // Private fields + private object _chartElement = null; + private ChartGraphics _chartGraph = null; + private CommonElements _common = null; + private Chart _chart = null; + private ElementPosition _position = null; + + #endregion + + #region Properties + + + /// + /// Gets the chart element of the event. + /// + /// The chart element. + public object ChartElement + { + get + { + return _chartElement; + } + } + + + /// + /// Gets the ChartGraphics object of the event. + /// + public ChartGraphics ChartGraphics + { + get + { + return _chartGraph; + } + } + + /// + /// Chart Common elements. + /// + internal CommonElements CommonElements + { + get + { + return _common; + } + } + + /// + /// Chart element position in relative coordinates of the event. + /// + public ElementPosition Position + { + get + { + return _position; + } + } + + /// + /// Chart object of the event. + /// + public Chart Chart + { + get + { + if (_chart == null && _common != null) + { + _chart = _common.Chart; + } + + return _chart; + } + } + + #endregion + + #region Methods + + /// + /// Default constructor is not accessible + /// + private ChartPaintEventArgs() + { + } + + /// + /// Paint event arguments constructor. + /// + /// Chart element. + /// Chart graphics. + /// Common elements. + /// Position. + internal ChartPaintEventArgs(object chartElement, ChartGraphics chartGraph, CommonElements common, ElementPosition position) + { + this._chartElement = chartElement; + this._chartGraph = chartGraph; + this._common = common; + this._position = position; + } + + #endregion + } + + /// + /// Event arguments of localized numbers formatting event. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class FormatNumberEventArgs : EventArgs + { + #region Fields + + // Private fields + private double _value; + private string _format; + private string _localizedValue; + private ChartValueType _valueType = ChartValueType.Auto; + private object _senderTag; + private ChartElementType _elementType = ChartElementType.Nothing; + + #endregion + + #region Properties + + /// + /// Value to be formatted. + /// + public double Value + { + get { return this._value; } + } + + /// + /// Localized text. + /// + public string LocalizedValue + { + get { return _localizedValue; } + set { _localizedValue = value; } + } + + /// + /// Format string. + /// + public string Format + { + get { return _format; } + } + + /// + /// Value type. + /// + public ChartValueType ValueType + { + get { return _valueType; } + } + + /// + /// The sender object of the event. + /// + public object SenderTag + { + get { return _senderTag; } + } + + /// + /// Chart element type. + /// + public ChartElementType ElementType + { + get { return _elementType; } + } + + #endregion + + #region Methods + + /// + /// Default constructor is not accessible + /// + private FormatNumberEventArgs() + { + } + + /// + /// Object constructor. + /// + /// Value to be formatted. + /// Format string. + /// Value type.. + /// Localized value. + /// Chart element object tag. + /// Chart element type. + internal FormatNumberEventArgs(double value, string format, ChartValueType valueType, string localizedValue, object senderTag, ChartElementType elementType) + { + this._value = value; + this._format = format; + this._valueType = valueType; + this._localizedValue = localizedValue; + this._senderTag = senderTag; + this._elementType = elementType; + } + + #endregion + } + + #region FontCache + /// + /// Font cache class helps ChartElements to reuse the Font instances + /// + internal class FontCache : IDisposable + { + #region Static + + // Default font family name + private static string _defaultFamilyName; + + /// + /// Gets the default font family name. + /// + /// The default font family name. + public static string DefaultFamilyName + { + get + { + if (_defaultFamilyName == null) + { + // Find the "Microsoft Sans Serif" font + foreach (FontFamily fontFamily in FontFamily.Families) + { + if (fontFamily.Name == "Microsoft Sans Serif") + { + _defaultFamilyName = fontFamily.Name; + break; + } + } + // Not found - use the default Sans Serif font + if (_defaultFamilyName == null) + { + _defaultFamilyName = FontFamily.GenericSansSerif.Name; + } + } + return _defaultFamilyName; + } + } + #endregion + + #region Fields + + // Cached fonts dictionary + private Dictionary _fontCache = new Dictionary(new KeyInfo.EqualityComparer()); + + #endregion // Fields + + #region Properties + /// + /// Gets the default font. + /// + /// The default font. + public Font DefaultFont + { + get { return this.GetFont(DefaultFamilyName, 8); } + } + + /// + /// Gets the default font. + /// + /// The default font. + public Font DefaultBoldFont + { + get { return this.GetFont(DefaultFamilyName, 8, FontStyle.Bold); } + } + #endregion + + #region Methods + + /// + /// Gets the font. + /// + /// Name of the family. + /// The size. + /// Font instance + public Font GetFont(string familyName, int size) + { + KeyInfo key = new KeyInfo(familyName, size); + if (!this._fontCache.ContainsKey(key)) + { + this._fontCache.Add(key, new Font(familyName, size)); + } + return this._fontCache[key]; + } + + /// + /// Gets the font. + /// + /// Name of the family. + /// The size. + /// The style. + /// Font instance + public Font GetFont(string familyName, float size, FontStyle style) + { + KeyInfo key = new KeyInfo(familyName, size, style); + if (!this._fontCache.ContainsKey(key)) + { + this._fontCache.Add(key, new Font(familyName, size, style)); + } + return this._fontCache[key]; + } + + /// + /// Gets the font. + /// + /// The family. + /// The size. + /// The style. + /// Font instance + public Font GetFont(FontFamily family, float size, FontStyle style) + { + KeyInfo key = new KeyInfo(family, size, style); + if (!this._fontCache.ContainsKey(key)) + { + this._fontCache.Add(key, new Font(family, size, style)); + } + return this._fontCache[key]; + } + + /// + /// Gets the font. + /// + /// The family. + /// The size. + /// The style. + /// The unit. + /// Font instance + public Font GetFont(FontFamily family, float size, FontStyle style, GraphicsUnit unit) + { + KeyInfo key = new KeyInfo(family, size, style, unit); + if (!this._fontCache.ContainsKey(key)) + { + this._fontCache.Add(key, new Font(family, size, style, unit)); + } + return this._fontCache[key]; + } + + #endregion + + #region IDisposable Members + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + foreach (Font font in _fontCache.Values) + { + font.Dispose(); + } + _fontCache.Clear(); + GC.SuppressFinalize(this); + } + + #endregion + + #region FontKeyInfo struct + /// + /// Font key info + /// + private class KeyInfo + { + string _familyName; + float _size = 8; + GraphicsUnit _unit = GraphicsUnit.Point; + FontStyle _style = FontStyle.Regular; + int _gdiCharSet = 1; + + /// + /// Initializes a new instance of the class. + /// + /// Name of the family. + /// The size. + public KeyInfo(string familyName, float size) + { + this._familyName = familyName; + this._size = size; + } + /// + /// Initializes a new instance of the class. + /// + /// Name of the family. + /// The size. + /// The style. + public KeyInfo(string familyName, float size, FontStyle style) + { + this._familyName = familyName; + this._size = size; + this._style = style; + } + /// + /// Initializes a new instance of the class. + /// + /// The family. + /// The size. + /// The style. + public KeyInfo(FontFamily family, float size, FontStyle style) + { + this._familyName = family.ToString(); + this._size = size; + this._style = style; + } + /// + /// Initializes a new instance of the class. + /// + /// The family. + /// The size. + /// The style. + /// The unit. + public KeyInfo(FontFamily family, float size, FontStyle style, GraphicsUnit unit) + { + this._familyName = family.ToString(); + this._size = size; + this._style = style; + this._unit = unit; + } + + #region IEquatable Members + /// + /// KeyInfo equality comparer + /// + internal class EqualityComparer : IEqualityComparer + { + /// + /// Determines whether the specified objects are equal. + /// + /// The first object of type to compare. + /// The second object of type to compare. + /// + /// true if the specified objects are equal; otherwise, false. + /// + public bool Equals(KeyInfo x, KeyInfo y) + { + return + x._size == y._size && + x._familyName == y._familyName && + x._unit == y._unit && + x._style == y._style && + x._gdiCharSet == y._gdiCharSet; + } + + /// + /// Returns a hash code for the specified object. + /// + /// The for which a hash code is to be returned. + /// A hash code for the specified object. + /// The type of is a reference type and is null. + public int GetHashCode(KeyInfo obj) + { + return obj._familyName.GetHashCode() ^ obj._size.GetHashCode(); + } + } + #endregion + } + #endregion + } + #endregion + + +} diff --git a/System.Web.DataVisualization/Common/General/ChartArea.cs b/System.Web.DataVisualization/Common/General/ChartArea.cs new file mode 100644 index 000000000..86b909780 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ChartArea.cs @@ -0,0 +1,3157 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartArea.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ChartArea +// +// Purpose: The ChartArea class represents one chart area within +// a chart image, and is used to plot one or more chart +// series. The number of chart series that can be plotted +// in a chart area is unlimited. +// +// Reviewed: GS - August 6, 2002 +// AG - August 7, 2002 +// AG - Microsoft 16, 2007 +// +//=================================================================== + +#region Used namespaces +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL + + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; + using System.ComponentModel.Design.Serialization; + using System.Reflection; + using System.Windows.Forms.Design; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + #region Chart area aligment enumerations + + /// + /// An enumeration of the alignment orientations of a ChartArea + /// + [Flags] + public enum AreaAlignmentOrientations + { + /// + /// Chart areas are not automatically aligned. + /// + None = 0, + + /// + /// Chart areas are aligned vertically. + /// + Vertical = 1, + + /// + /// Chart areas are aligned horizontally. + /// + Horizontal = 2, + + /// + /// Chart areas are aligned using all values (horizontally and vertically). + /// + All = Vertical | Horizontal + } + + /// + /// An enumeration of the alignment styles of a ChartArea + /// + [Flags] + public enum AreaAlignmentStyles + { + /// + /// Chart areas are not automatically aligned. + /// + None = 0, + + /// + /// Chart areas are aligned by positions. + /// + Position = 1, + + /// + /// Chart areas are aligned by inner plot positions. + /// + PlotPosition = 2, + + /// + /// Chart areas are aligned by axes views. + /// + AxesView = 4, + +#if Microsoft_CONTROL + + /// + /// Cursor and Selection alignment. + /// + Cursor = 8, + + /// + /// Complete alignment. + /// + All = Position | PlotPosition | Cursor | AxesView +#else // Microsoft_CONTROL + + /// + /// Complete alignment. + /// + All = Position | PlotPosition | AxesView + +#endif // Microsoft_CONTROL + } + + #endregion + + /// + /// The ChartArea class is used to create and display a chart + /// area within a chart image. The chart area is a rectangular + /// area on a chart image. It has 4 axes, horizontal and vertical grids. + /// A chart area can contain more than one different chart type. + /// The number of chart series that can be plotted in a chart area + /// is unlimited. + /// + /// ChartArea class exposes all the properties and methods + /// of its base ChartArea3D class. + /// + [ + DefaultProperty("Axes"), + SRDescription("DescriptionAttributeChartArea_ChartArea"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public partial class ChartArea : ChartNamedElement + { + #region Chart Area Fields + + /// + /// Plot area position + /// + internal ElementPosition PlotAreaPosition; + + // Private data members, which store properties values + private Axis[] _axisArray = new Axis[4]; + private Color _backColor = Color.Empty; + private ChartHatchStyle _backHatchStyle = ChartHatchStyle.None; + private string _backImage = ""; + private ChartImageWrapMode _backImageWrapMode = ChartImageWrapMode.Tile; + private Color _backImageTransparentColor = Color.Empty; + private ChartImageAlignmentStyle _backImageAlignment = ChartImageAlignmentStyle.TopLeft; + private GradientStyle _backGradientStyle = GradientStyle.None; + private Color _backSecondaryColor = Color.Empty; + private Color _borderColor = Color.Black; + private int _borderWidth = 1; + private ChartDashStyle _borderDashStyle = ChartDashStyle.NotSet; + private int _shadowOffset = 0; + private Color _shadowColor = Color.FromArgb(128, 0, 0, 0); + private ElementPosition _areaPosition = null; + private ElementPosition _innerPlotPosition = null; + internal int IterationCounter = 0; + + private bool _isSameFontSizeForAllAxes = false; + internal float axesAutoFontSize = 8f; + + private string _alignWithChartArea = Constants.NotSetValue; + private AreaAlignmentOrientations _alignmentOrientation = AreaAlignmentOrientations.Vertical; + private AreaAlignmentStyles _alignmentStyle = AreaAlignmentStyles.All; + private int _circularSectorNumber = int.MinValue; + private int _circularUsePolygons = int.MinValue; + + // Flag indicates that chart area is acurrently aligned + internal bool alignmentInProcess = false; + + // Chart area position before adjustments + internal RectangleF originalAreaPosition = RectangleF.Empty; + + // Chart area inner plot position before adjustments + internal RectangleF originalInnerPlotPosition = RectangleF.Empty; + + // Chart area position before adjustments + internal RectangleF lastAreaPosition = RectangleF.Empty; + + + // Center of the circulat chart area + internal PointF circularCenter = PointF.Empty; + + private ArrayList _circularAxisList = null; + +#if Microsoft_CONTROL + // Buffered plotting area image + internal Bitmap areaBufferBitmap = null; + + private Cursor _cursorX = new Cursor(); + private Cursor _cursorY = new Cursor(); +#endif + + // Area SmartLabel class + internal SmartLabel smartLabels = new SmartLabel(); + + // Gets or sets a flag that specifies whether the chart area is visible. + private bool _visible = true; + + #endregion + + #region Chart Area Cursor properties + +#if Microsoft_CONTROL + + /// + /// Gets or sets a Cursor object that is used for cursors and selected ranges along the X-axis. + /// + [ + SRCategory("CategoryAttributeCursor"), + Bindable(true), + DefaultValue(null), + SRDescription("DescriptionAttributeChartArea_CursorX"), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), + TypeConverter(typeof(NoNameExpandableObjectConverter)), + ] + public Cursor CursorX + { + get + { + return _cursorX; + } + set + { + _cursorX = value; + + // Initialize chart object + _cursorX.Initialize(this, AxisName.X); + } + } + + /// + /// Gets or sets a Cursor object that is used for cursors and selected ranges along the Y-axis. + /// + [ + SRCategory("CategoryAttributeCursor"), + Bindable(true), + DefaultValue(null), + SRDescription("DescriptionAttributeChartArea_CursorY"), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), + TypeConverter(typeof(NoNameExpandableObjectConverter)), + ] + public Cursor CursorY + { + get + { + return _cursorY; + } + set + { + _cursorY = value; + + // Initialize chart object + _cursorY.Initialize(this, AxisName.Y); + } + } + +#endif // Microsoft_CONTROL + + #endregion + + #region Chart Area properties + + /// + /// Gets or sets a flag that specifies whether the chart area is visible. + /// + /// + /// When this flag is set to false, all series, legends, titles and annotation objects + /// associated with the chart area will also be hidden. + /// + /// + /// True if the chart area is visible; false otherwise. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(true), + SRDescription("DescriptionAttributeChartArea_Visible"), + ParenthesizePropertyNameAttribute(true), + ] + virtual public bool Visible + { + get + { + return _visible; + } + set + { + _visible = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the name of the ChartArea object to which this chart area should be aligned. + /// + [ + SRCategory("CategoryAttributeAlignment"), + Bindable(true), + DefaultValue(Constants.NotSetValue), + SRDescription("DescriptionAttributeChartArea_AlignWithChartArea"), + TypeConverter(typeof(LegendAreaNameConverter)), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public string AlignWithChartArea + { + get + { + return _alignWithChartArea; + } + set + { + if (value != _alignWithChartArea) + { + if (String.IsNullOrEmpty(value)) + { + _alignWithChartArea = Constants.NotSetValue; + } + else + { + if (Chart != null && Chart.ChartAreas != null) + { + Chart.ChartAreas.VerifyNameReference(value); + } + _alignWithChartArea = value; + } + Invalidate(); + } + } + } + + /// + /// Gets or sets the alignment orientation of a chart area. + /// + [ + SRCategory("CategoryAttributeAlignment"), + Bindable(true), + DefaultValue(AreaAlignmentOrientations.Vertical), + SRDescription("DescriptionAttributeChartArea_AlignOrientation"), + Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public AreaAlignmentOrientations AlignmentOrientation + { + get + { + return _alignmentOrientation; + } + set + { + _alignmentOrientation = value; + Invalidate(); + } + } + + + /// + /// Gets or sets the alignment style of the ChartArea. + /// + [ + SRCategory("CategoryAttributeAlignment"), + Bindable(true), + DefaultValue(AreaAlignmentStyles.All), + SRDescription("DescriptionAttributeChartArea_AlignType"), + Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public AreaAlignmentStyles AlignmentStyle + { + get + { + return _alignmentStyle; + } + set + { + _alignmentStyle = value; + Invalidate(); + } + } + + /// + /// Gets or sets an array that represents all axes for a chart area. + /// + [ + SRCategory("CategoryAttributeAxes"), + Bindable(true), + SRDescription("DescriptionAttributeChartArea_Axes"), + TypeConverter(typeof(AxesArrayConverter)), + Editor(Editors.AxesArrayEditor.Editor, Editors.AxesArrayEditor.Base), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public Axis[] Axes + { + get + { + return _axisArray; + } + set + { + AxisX = value[0]; + AxisY = value[1]; + AxisX2 = value[2]; + AxisY2 = value[3]; + Invalidate(); + } + } + + /// + /// Avoid serialization of the axes array + /// + [EditorBrowsableAttribute(EditorBrowsableState.Never)] + internal bool ShouldSerializeAxes() + { + return false; + } + + /// + /// Gets or sets an Axis object that represents the primary Y-axis. + /// + [ + SRCategory("CategoryAttributeAxis"), + Bindable(true), + Browsable(false), + SRDescription("DescriptionAttributeChartArea_AxisY"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] + public Axis AxisY + { + get + { + return axisY; + } + set + { + axisY = value; + axisY.Initialize(this, AxisName.Y); + _axisArray[1] = axisY; + Invalidate(); + } + } + + /// + /// Gets or sets an Axis object that represents the primary X-axis. + /// + [ + SRCategory("CategoryAttributeAxis"), + Bindable(true), + Browsable(false), + SRDescription("DescriptionAttributeChartArea_AxisX"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] + public Axis AxisX + { + get + { + return axisX; + } + set + { + axisX = value; + axisX.Initialize(this, AxisName.X); + _axisArray[0] = axisX; + Invalidate(); + } + } + + /// + /// Gets or sets an Axis object that represents the secondary X-axis. + /// + [ + SRCategory("CategoryAttributeAxis"), + Bindable(true), + Browsable(false), + SRDescription("DescriptionAttributeChartArea_AxisX2"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] + public Axis AxisX2 + { + get + { + return axisX2; + } + set + { + axisX2 = value; + axisX2.Initialize(this, AxisName.X2); + _axisArray[2] = axisX2; + Invalidate(); + } + } + + /// + /// Gets or sets an Axis object that represents the secondary Y-axis. + /// + [ + SRCategory("CategoryAttributeAxis"), + Bindable(true), + Browsable(false), + SRDescription("DescriptionAttributeChartArea_AxisY2"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] + public Axis AxisY2 + { + get + { + return axisY2; + } + set + { + axisY2 = value; + axisY2.Initialize(this, AxisName.Y2); + _axisArray[3] = axisY2; + Invalidate(); + } + } + + /// + /// Gets or sets an ElementPosition object, which defines the position of a chart area object within the chart image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeChartArea_Position"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ElementPositionConverter)), + SerializationVisibilityAttribute(SerializationVisibility.Element) + ] + public ElementPosition Position + { + get + { + // Serialize only position values if Auto set to false + if(this.Chart != null && this.Chart.serializationStatus == SerializationStatus.Saving ) + { + if(_areaPosition.Auto) + { + return new ElementPosition(); + } + else + { + ElementPosition newPosition = new ElementPosition(); +#if Microsoft_CONTROL + newPosition.Auto = false; +#else + newPosition.Auto = true; +#endif + newPosition.SetPositionNoAuto(_areaPosition.X, _areaPosition.Y, _areaPosition.Width, _areaPosition.Height); + return newPosition; + } + } + return _areaPosition; + } + set + { + _areaPosition = value; + _areaPosition.Parent = this; + _areaPosition.resetAreaAutoPosition = true; + Invalidate(); + } + } + + /// + /// Determoines if this position should be serialized. + /// + /// + internal bool ShouldSerializePosition() + { + return !this.Position.Auto; + } + + /// + /// Gets or sets an ElementPosition object, which defines the inner plot position of a chart area object. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeChartArea_InnerPlotPosition"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ElementPositionConverter)), + SerializationVisibilityAttribute(SerializationVisibility.Element) + ] + public ElementPosition InnerPlotPosition + { + get + { + // Serialize only position values if Auto set to false + if (this.Common != null && this.Common.Chart != null && this.Common.Chart.serializationStatus == SerializationStatus.Saving) + { + if(_innerPlotPosition.Auto) + { + return new ElementPosition(); + } + else + { + ElementPosition newPosition = new ElementPosition(); +#if Microsoft_CONTROL + newPosition.Auto = false; +#else + newPosition.Auto = true; +#endif + newPosition.SetPositionNoAuto(_innerPlotPosition.X, _innerPlotPosition.Y, _innerPlotPosition.Width, _innerPlotPosition.Height); + return newPosition; + } + } + return _innerPlotPosition; + } + set + { + _innerPlotPosition = value; + _innerPlotPosition.Parent = this; + Invalidate(); + } + } + + /// + /// Determoines if this position should be serialized. + /// + /// + internal bool ShouldSerializeInnerPlotPosition() + { + return !this.InnerPlotPosition.Auto; + } + + /// + /// Gets or sets the background color of a ChartArea object. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackColor + { + get + { + return _backColor; + } + set + { + _backColor = value; + Invalidate(); + } + } + + /// + /// Gets or sets the hatching style of a ChartArea object. + /// + [ + + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackHatchStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + + ] + public ChartHatchStyle BackHatchStyle + { + get + { + return _backHatchStyle; + } + set + { + _backHatchStyle = value; + Invalidate(); + } + } + + /// + /// Gets or sets the background image of a ChartArea object. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeBackImage"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + NotifyParentPropertyAttribute(true) + ] + public string BackImage + { + get + { + return _backImage; + } + set + { + _backImage = value; + Invalidate(); + } + } + + /// + /// Gets or sets the drawing mode of the background image of a ChartArea object. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageWrapMode.Tile), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageWrapMode"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageWrapMode BackImageWrapMode + { + get + { + return _backImageWrapMode; + } + set + { + _backImageWrapMode = value; + Invalidate(); + } + } + + /// + /// Gets or sets the color of a ChartArea object's background image that will be drawn as transparent. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackImageTransparentColor + { + get + { + return _backImageTransparentColor; + } + set + { + _backImageTransparentColor = value; + Invalidate(); + } + } + + /// + /// Gets or sets the alignment of a ChartArea object. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageAlignmentStyle.TopLeft), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackImageAlign"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageAlignmentStyle BackImageAlignment + { + get + { + return _backImageAlignment; + } + set + { + _backImageAlignment = value; + Invalidate(); + } + } + + /// + /// Gets or sets the orientation of a chart element's gradient, + /// and also determines whether or not a gradient is used. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackGradientStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + public GradientStyle BackGradientStyle + { + get + { + return _backGradientStyle; + } + set + { + _backGradientStyle = value; + Invalidate(); + } + } + + /// + /// Gets or sets the secondary color of a ChartArea object. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackSecondaryColor + { + get + { + return _backSecondaryColor; + } + set + { + _backSecondaryColor = value; + Invalidate(); + } + } + + /// + /// Gets or sets the shadow color of a ChartArea object. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "128,0,0,0"), + SRDescription("DescriptionAttributeShadowColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color ShadowColor + { + get + { + return _shadowColor; + } + set + { + _shadowColor = value; + Invalidate(); + } + } + + /// + /// Gets or sets the shadow offset (in pixels) of a ChartArea object. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributeShadowOffset"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int ShadowOffset + { + get + { + return _shadowOffset; + } + set + { + _shadowOffset = value; + Invalidate(); + } + } + + /// + /// Gets or sets the border color of a ChartArea object. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeBorderColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BorderColor + { + get + { + return _borderColor; + } + set + { + _borderColor = value; + Invalidate(); + } + } + + /// + /// Gets or sets the border width of a ChartArea object. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeBorderWidth"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int BorderWidth + { + get + { + return _borderWidth; + } + set + { + if(value < 0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionBorderWidthIsNegative)); + } + _borderWidth = value; + Invalidate(); + } + } + + /// + /// Gets or sets the style of the border line of a ChartArea object. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartDashStyle.NotSet), + SRDescription("DescriptionAttributeBorderDashStyle"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartDashStyle BorderDashStyle + { + get + { + return _borderDashStyle; + } + set + { + _borderDashStyle = value; + Invalidate(); + } + } + + /// + /// Gets or sets the unique name of a ChartArea object. + /// + [ + + SRCategory("CategoryAttributeMisc"), + Bindable(true), + SRDescription("DescriptionAttributeChartArea_Name"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public override string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + + /// + /// Gets or sets a Boolean that determines if the labels of the axes for all chart area + /// , which have LabelsAutoFit property set to true, are of equal size. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(false), + SRDescription("DescriptionAttributeChartArea_EquallySizedAxesFont"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsSameFontSizeForAllAxes + { + get + { + return _isSameFontSizeForAllAxes; + } + set + { + _isSameFontSizeForAllAxes = value; + Invalidate(); + } + } + + + #endregion + + #region Constructors + /// + /// ChartArea constructor. + /// + public ChartArea() + { + Initialize(); + } + + /// + /// ChartArea constructor. + /// + /// The name. + public ChartArea(string name) : base(name) + { + Initialize(); + } + #endregion + + #region Chart Area Methods + /// + /// Restores series order and X axis reversed mode for the 3D charts. + /// + internal void Restore3DAnglesAndReverseMode() + { + if(this.Area3DStyle.Enable3D && !this.chartAreaIsCurcular) + { + // Restore axis "IsReversed" property and old Y angle + this.AxisX.IsReversed = oldReverseX; + this.AxisX2.IsReversed = oldReverseX; + this.AxisY.IsReversed = oldReverseY; + this.AxisY2.IsReversed = oldReverseY; + this.Area3DStyle.Rotation = oldYAngle; + } + } + + /// + /// Sets series order and X axis reversed mode for the 3D charts. + /// + internal void Set3DAnglesAndReverseMode() + { + // Clear series reversed flag + _reverseSeriesOrder = false; + + // If 3D charting is enabled + if(this.Area3DStyle.Enable3D) + { + // Make sure primary & secondary axis has the same IsReversed settings + // This is a limitation for the 3D chart required for labels drawing. + this.AxisX2.IsReversed = this.AxisX.IsReversed; + this.AxisY2.IsReversed = this.AxisY.IsReversed; + + // Remember reversed order of X & Y axis and Angles + oldReverseX = this.AxisX.IsReversed; + oldReverseY = this.AxisY.IsReversed; + oldYAngle = this.Area3DStyle.Rotation; + + // Check if Y angle + if(this.Area3DStyle.Rotation > 90 || this.Area3DStyle.Rotation < -90) + { + // This method depends on the 'switchValueAxes' field which is calculated based on the chart types + // of the series associated with the chart area. We need to call SetData method to make sure this field + // is correctly initialized. Because we only need to collect information about the series, we pass 'false' + // as parameters to limit the amount of work this function does. + this.SetData(false, false); + + // Reversed series order + _reverseSeriesOrder = true; + + // Reversed primary and secondary X axis + if(!this.switchValueAxes) + { + this.AxisX.IsReversed = !this.AxisX.IsReversed; + this.AxisX2.IsReversed = !this.AxisX2.IsReversed; + } + + // Reversed primary and secondary Y axis for chart types like Bar + else + { + this.AxisY.IsReversed = !this.AxisY.IsReversed; + this.AxisY2.IsReversed = !this.AxisY2.IsReversed; + } + + // Adjust Y angle + if(this.Area3DStyle.Rotation > 90) + { + this.Area3DStyle.Rotation = (this.Area3DStyle.Rotation - 90) - 90; + } + else if(this.Area3DStyle.Rotation < -90) + { + this.Area3DStyle.Rotation = (this.Area3DStyle.Rotation + 90) + 90; + } + } + } + } + + /// + /// Save all automatic values like Minimum and Maximum. + /// + internal void SetTempValues() + { + // Save non automatic area position + if(!this.Position.Auto) + { + this.originalAreaPosition = this.Position.ToRectangleF(); + } + + // Save non automatic area inner plot position + if(!this.InnerPlotPosition.Auto) + { + this.originalInnerPlotPosition = this.InnerPlotPosition.ToRectangleF(); + } + + this._circularSectorNumber = int.MinValue; + this._circularUsePolygons = int.MinValue; + this._circularAxisList = null; + + // Save Minimum and maximum values for all axes + axisX.StoreAxisValues(); + axisX2.StoreAxisValues(); + axisY.StoreAxisValues(); + axisY2.StoreAxisValues(); + } + + /// + /// Load all automatic values like Minimum and Maximum with original values. + /// + internal void GetTempValues() + { + // Take Minimum and maximum values for all axes + axisX.ResetAxisValues(); + axisX2.ResetAxisValues(); + axisY.ResetAxisValues(); + axisY2.ResetAxisValues(); + + // Restore non automatic area position + if(!this.originalAreaPosition.IsEmpty) + { + this.lastAreaPosition = this.Position.ToRectangleF(); + this.Position.SetPositionNoAuto(this.originalAreaPosition.X, this.originalAreaPosition.Y, this.originalAreaPosition.Width, this.originalAreaPosition.Height); + this.originalAreaPosition = RectangleF.Empty; + } + + // Save non automatic area inner plot position + if(!this.originalInnerPlotPosition.IsEmpty) + { + this.InnerPlotPosition.SetPositionNoAuto(this.originalInnerPlotPosition.X, this.originalInnerPlotPosition.Y, this.originalInnerPlotPosition.Width, this.originalInnerPlotPosition.Height); + this.originalInnerPlotPosition = RectangleF.Empty; + } + } + + /// + /// Initialize Chart area and axes + /// + internal void Initialize() + { + // Initialize 3D style class + _area3DStyle = new ChartArea3DStyle(this); + + // Create axes for this chart area. + axisY = new Axis( ); + axisX = new Axis( ); + axisX2 = new Axis( ); + axisY2 = new Axis( ); + + // Initialize axes; + axisX.Initialize(this, AxisName.X); + axisY.Initialize(this, AxisName.Y); + axisX2.Initialize(this, AxisName.X2); + axisY2.Initialize(this, AxisName.Y2); + + // Initialize axes array + _axisArray[0] = axisX; + _axisArray[1] = axisY; + _axisArray[2] = axisX2; + _axisArray[3] = axisY2; + + // Set flag to reset auto values for all areas + _areaPosition = new ElementPosition(this); + _areaPosition.resetAreaAutoPosition = true; + + _innerPlotPosition = new ElementPosition(this); + + // Set the position of the new chart area + if( PlotAreaPosition == null ) + { + PlotAreaPosition = new ElementPosition(this); + } + +#if Microsoft_CONTROL + + // Initialize cursor class + this._cursorX.Initialize(this, AxisName.X); + this._cursorY.Initialize(this, AxisName.Y); + +#endif // Microsoft_CONTROL + } + + /// + /// Minimum and maximum do not have to be calculated + /// from data series every time. It is very time + /// consuming. Minimum and maximum are buffered + /// and only when this flags are set Minimum and + /// Maximum are refreshed from data. + /// + internal void ResetMinMaxFromData() + { + _axisArray[0].refreshMinMaxFromData = true; + _axisArray[1].refreshMinMaxFromData = true; + _axisArray[2].refreshMinMaxFromData = true; + _axisArray[3].refreshMinMaxFromData = true; + } + + /// + /// Recalculates the axes scale of a chart area. + /// + public void RecalculateAxesScale() + { + // Read axis Max/Min from data + ResetMinMaxFromData(); + +#if Microsoft_CONTROL + Set3DAnglesAndReverseMode(); + SetTempValues(); +#endif + + // Initialize area position + _axisArray[0].ReCalc( PlotAreaPosition ); + _axisArray[1].ReCalc( PlotAreaPosition ); + _axisArray[2].ReCalc( PlotAreaPosition ); + _axisArray[3].ReCalc( PlotAreaPosition ); + + // Find all Data and chart types which belong + // to this chart area an set default values + SetData(); + +#if Microsoft_CONTROL + Restore3DAnglesAndReverseMode(); + GetTempValues(); +#endif + } + + /// + /// RecalculateAxesScale the chart area + /// + internal void ReCalcInternal() + { + // Initialize area position + _axisArray[0].ReCalc( PlotAreaPosition ); + _axisArray[1].ReCalc( PlotAreaPosition ); + _axisArray[2].ReCalc( PlotAreaPosition ); + _axisArray[3].ReCalc( PlotAreaPosition ); + + // Find all Data and chart types which belong + // to this chart area an set default values + SetData(); + } + + + /// + /// Reset auto calculated chart area values. + /// + internal void ResetAutoValues() + { + _axisArray[0].ResetAutoValues(); + _axisArray[1].ResetAutoValues(); + _axisArray[2].ResetAutoValues(); + _axisArray[3].ResetAutoValues(); + } + + /// + /// Calculates Position for the background. + /// + /// Calculate with scroll bars + /// Background rectangle + internal RectangleF GetBackgroundPosition( bool withScrollBars ) + { + // For pie and doughnut, which do not have axes, the position + // for the background is Chart area position not plotting + // area position. + RectangleF backgroundPosition = PlotAreaPosition.ToRectangleF(); + if( !requireAxes ) + { + backgroundPosition = Position.ToRectangleF(); + } + + // Without scroll bars + if( !withScrollBars ) + { + return backgroundPosition; + } + + // Add scroll bar rectangles to the area background + RectangleF backgroundPositionWithScrollBars = new RectangleF(backgroundPosition.Location, backgroundPosition.Size); + +#if Microsoft_CONTROL + + if( requireAxes ) + { + // Loop through all axis + foreach(Axis axis in this.Axes) + { + // Find axis with visible scroll bars + if(axis.ScrollBar.IsVisible && axis.ScrollBar.IsPositionedInside) + { + // Change size of the background rectangle depending on the axis position + if(axis.AxisPosition == AxisPosition.Bottom) + { + backgroundPositionWithScrollBars.Height += (float)axis.ScrollBar.GetScrollBarRelativeSize(); + } + else if(axis.AxisPosition == AxisPosition.Top) + { + backgroundPositionWithScrollBars.Y -= (float)axis.ScrollBar.GetScrollBarRelativeSize(); + backgroundPositionWithScrollBars.Height += (float)axis.ScrollBar.GetScrollBarRelativeSize(); + } + else if(axis.AxisPosition == AxisPosition.Left) + { + backgroundPositionWithScrollBars.X -= (float)axis.ScrollBar.GetScrollBarRelativeSize(); + backgroundPositionWithScrollBars.Width += (float)axis.ScrollBar.GetScrollBarRelativeSize(); + } + else if(axis.AxisPosition == AxisPosition.Left) + { + backgroundPositionWithScrollBars.Width += (float)axis.ScrollBar.GetScrollBarRelativeSize(); + } + } + } + } + +#endif // Microsoft_CONTROL + return backgroundPositionWithScrollBars; + } + + /// + /// Call when the chart area is resized. + /// + /// Chart graphics object. + internal void Resize(ChartGraphics chartGraph) + { + // Initialize plotting area position + RectangleF plottingRect = Position.ToRectangleF(); + if(!InnerPlotPosition.Auto) + { + plottingRect.X += (Position.Width / 100F) * InnerPlotPosition.X; + plottingRect.Y += (Position.Height / 100F) * InnerPlotPosition.Y; + plottingRect.Width = (Position.Width / 100F) * InnerPlotPosition.Width; + plottingRect.Height = (Position.Height / 100F) * InnerPlotPosition.Height; + } + + //****************************************************** + //** Calculate number of vertical and horizontal axis + //****************************************************** + int verticalAxes = 0; + int horizontalAxes = 0; + foreach(Axis axis in this.Axes) + { + if(axis.enabled) + { + if(axis.AxisPosition == AxisPosition.Bottom) + { + ++horizontalAxes; + } + else if(axis.AxisPosition == AxisPosition.Top) + { + ++horizontalAxes; + } + else if(axis.AxisPosition == AxisPosition.Left) + { + ++verticalAxes; + } + else if(axis.AxisPosition == AxisPosition.Right) + { + ++verticalAxes; + } + } + } + if(horizontalAxes <= 0 ) + { + horizontalAxes = 1; + } + if(verticalAxes <= 0 ) + { + verticalAxes = 1; + } + + + //****************************************************** + //** Find same auto-fit font size + //****************************************************** + Axis[] axisArray = (this.switchValueAxes) ? + new Axis[] {this.AxisX, this.AxisX2, this.AxisY, this.AxisY2} : + new Axis[] {this.AxisY, this.AxisY2, this.AxisX, this.AxisX2}; + if(this.IsSameFontSizeForAllAxes) + { + axesAutoFontSize = 20; + foreach(Axis axis in axisArray) + { + // Process only enabled axis + if(axis.enabled) + { + // Resize axis + if(axis.AxisPosition == AxisPosition.Bottom || axis.AxisPosition == AxisPosition.Top) + { + axis.Resize(chartGraph, this.PlotAreaPosition, plottingRect, horizontalAxes, InnerPlotPosition.Auto); + } + else + { + axis.Resize(chartGraph, this.PlotAreaPosition, plottingRect, verticalAxes, InnerPlotPosition.Auto); + } + + // Calculate smallest font size + if(axis.IsLabelAutoFit && axis.autoLabelFont != null) + { + axesAutoFontSize = Math.Min(axesAutoFontSize, axis.autoLabelFont.Size); + } + } + } + } + + //****************************************************** + //** Adjust plotting area position according to the axes + //** elements (title, labels, tick marks) size. + //****************************************************** + RectangleF rectLabelSideSpacing = RectangleF.Empty; + foreach(Axis axis in axisArray) + { + // Process only enabled axis + if( ! axis.enabled ) + { + //****************************************************** + //** Adjust for the 3D Wall Width for disabled axis + //****************************************************** + if(InnerPlotPosition.Auto && this.Area3DStyle.Enable3D && !this.chartAreaIsCurcular) + { + SizeF areaWallSize = chartGraph.GetRelativeSize(new SizeF(this.Area3DStyle.WallWidth, this.Area3DStyle.WallWidth)); + if(axis.AxisPosition == AxisPosition.Bottom) + { + plottingRect.Height -= areaWallSize.Height; + } + else if(axis.AxisPosition == AxisPosition.Top) + { + plottingRect.Y += areaWallSize.Height; + plottingRect.Height -= areaWallSize.Height; + } + else if(axis.AxisPosition == AxisPosition.Right) + { + plottingRect.Width -= areaWallSize.Width; + } + else if(axis.AxisPosition == AxisPosition.Left) + { + plottingRect.X += areaWallSize.Width; + plottingRect.Width -= areaWallSize.Width; + } + } + + continue; + } + + //****************************************************** + //** Calculate axes elements position + //****************************************************** + if(axis.AxisPosition == AxisPosition.Bottom || axis.AxisPosition == AxisPosition.Top) + { + axis.Resize(chartGraph, this.PlotAreaPosition, plottingRect, horizontalAxes, InnerPlotPosition.Auto); + } + else + { + axis.Resize(chartGraph, this.PlotAreaPosition, plottingRect, verticalAxes, InnerPlotPosition.Auto); + } + + // Shift top/bottom labels so they will not overlap with left/right labels + PreventTopBottomAxesLabelsOverlapping(axis); + + //****************************************************** + //** Check axis position + //****************************************************** + float axisPosition = (float)axis.GetAxisPosition(); + if(axis.AxisPosition == AxisPosition.Bottom) + { + if(!axis.GetIsMarksNextToAxis()) + { + axisPosition = plottingRect.Bottom; + } + axisPosition = plottingRect.Bottom - axisPosition; + } + else if(axis.AxisPosition == AxisPosition.Top) + { + if(!axis.GetIsMarksNextToAxis()) + { + axisPosition = plottingRect.Y; + } + axisPosition = axisPosition - plottingRect.Top; + } + else if(axis.AxisPosition == AxisPosition.Right) + { + if(!axis.GetIsMarksNextToAxis()) + { + axisPosition = plottingRect.Right; + } + axisPosition = plottingRect.Right - axisPosition; + } + else if(axis.AxisPosition == AxisPosition.Left) + { + if(!axis.GetIsMarksNextToAxis()) + { + axisPosition = plottingRect.X; + } + axisPosition = axisPosition - plottingRect.Left; + } + + //****************************************************** + //** Adjust axis elements size with axis position + //****************************************************** + // Calculate total size of axis elements + float axisSize = axis.markSize + axis.labelSize; + +#if SUBAXES + // Add sub-axis size + if(!this.chartAreaIsCurcular && !this.Area3DStyle.Enable3D) + { + foreach(SubAxis subAxis in axis.SubAxes) + { + axisSize += subAxis.markSize + subAxis.labelSize + subAxis.titleSize; + } + } +#endif // SUBAXES + + // Adjust depending on the axis position + axisSize -= axisPosition; + if(axisSize < 0) + { + axisSize = 0; + } + + + // Add axis title and scroll bar size (always outside of plotting area) + axisSize += axis.titleSize + axis.scrollBarSize; + + + // Calculate horizontal axes size for circualar area + if(this.chartAreaIsCurcular && + (axis.AxisPosition == AxisPosition.Top || axis.AxisPosition == AxisPosition.Bottom) ) + { + axisSize = axis.titleSize + axis.markSize + axis.scrollBarSize; + } + + //****************************************************** + //** Adjust plotting area + //****************************************************** + if(InnerPlotPosition.Auto) + { + if(axis.AxisPosition == AxisPosition.Bottom) + { + plottingRect.Height -= axisSize; + } + else if(axis.AxisPosition == AxisPosition.Top) + { + plottingRect.Y += axisSize; + plottingRect.Height -= axisSize; + } + else if(axis.AxisPosition == AxisPosition.Left) + { + plottingRect.X += axisSize; + plottingRect.Width -= axisSize; + } + else if(axis.AxisPosition == AxisPosition.Right) + { + plottingRect.Width -= axisSize; + } + + // Check if labels side offset should be processed + bool addLabelsSideOffsets = true; + + // Update the plotting area depending on the size required for labels on the sides + if (addLabelsSideOffsets) + { + if (axis.AxisPosition == AxisPosition.Bottom || axis.AxisPosition == AxisPosition.Top) + { + if (axis.labelNearOffset != 0 && axis.labelNearOffset < Position.X) + { + float offset = Position.X - axis.labelNearOffset; + if (Math.Abs(offset) > plottingRect.Width * 0.3f) + { + offset = plottingRect.Width * 0.3f; + } + + // NOTE: Code was removed to solve an issue with extra space when labels angle = 45 + //rectLabelSideSpacing.Width = (float)Math.Max(offset, rectLabelSideSpacing.Width); + rectLabelSideSpacing.X = (float)Math.Max(offset, rectLabelSideSpacing.X); + } + + if (axis.labelFarOffset > Position.Right) + { + if ((axis.labelFarOffset - Position.Right) < plottingRect.Width * 0.3f) + { + rectLabelSideSpacing.Width = (float)Math.Max(axis.labelFarOffset - Position.Right, rectLabelSideSpacing.Width); + } + else + { + rectLabelSideSpacing.Width = (float)Math.Max(plottingRect.Width * 0.3f, rectLabelSideSpacing.Width); + } + } + } + + else + { + if (axis.labelNearOffset != 0 && axis.labelNearOffset < Position.Y) + { + float offset = Position.Y - axis.labelNearOffset; + if (Math.Abs(offset) > plottingRect.Height * 0.3f) + { + offset = plottingRect.Height * 0.3f; + } + + // NOTE: Code was removed to solve an issue with extra space when labels angle = 45 + //rectLabelSideSpacing.Height = (float)Math.Max(offset, rectLabelSideSpacing.Height); + rectLabelSideSpacing.Y = (float)Math.Max(offset, rectLabelSideSpacing.Y); + } + + if (axis.labelFarOffset > Position.Bottom) + { + if ((axis.labelFarOffset - Position.Bottom) < plottingRect.Height * 0.3f) + { + rectLabelSideSpacing.Height = (float)Math.Max(axis.labelFarOffset - Position.Bottom, rectLabelSideSpacing.Height); + } + else + { + rectLabelSideSpacing.Height = (float)Math.Max(plottingRect.Height * 0.3f, rectLabelSideSpacing.Height); + } + } + } + } + } + } + + //****************************************************** + //** Make sure there is enough space + //** for labels on the chart sides + //****************************************************** + if (!this.chartAreaIsCurcular) + { + if (rectLabelSideSpacing.Y > 0 && rectLabelSideSpacing.Y > plottingRect.Y - Position.Y) + { + float delta = (plottingRect.Y - Position.Y) - rectLabelSideSpacing.Y; + plottingRect.Y -= delta; + plottingRect.Height += delta; + } + if (rectLabelSideSpacing.X > 0 && rectLabelSideSpacing.X > plottingRect.X - Position.X) + { + float delta = (plottingRect.X - Position.X) - rectLabelSideSpacing.X; + plottingRect.X -= delta; + plottingRect.Width += delta; + } + if (rectLabelSideSpacing.Height > 0 && rectLabelSideSpacing.Height > Position.Bottom - plottingRect.Bottom) + { + plottingRect.Height += (Position.Bottom - plottingRect.Bottom) - rectLabelSideSpacing.Height; + } + if (rectLabelSideSpacing.Width > 0 && rectLabelSideSpacing.Width > Position.Right - plottingRect.Right) + { + plottingRect.Width += (Position.Right - plottingRect.Right) - rectLabelSideSpacing.Width; + } + } + + //****************************************************** + //** Plotting area must be square for the circular + //** chart area (in pixels). + //****************************************************** + if(this.chartAreaIsCurcular) + { + // Adjust area to fit the axis title + float xTitleSize = (float)Math.Max(this.AxisY.titleSize, this.AxisY2.titleSize); + if(xTitleSize > 0) + { + plottingRect.X += xTitleSize; + plottingRect.Width -= 2f * xTitleSize; + } + float yTitleSize = (float)Math.Max(this.AxisX.titleSize, this.AxisX2.titleSize); + if(yTitleSize > 0) + { + plottingRect.Y += yTitleSize; + plottingRect.Height -= 2f * yTitleSize; + } + + // Make a square plotting rect + RectangleF rect = chartGraph.GetAbsoluteRectangle( plottingRect ); + if(rect.Width > rect.Height) + { + rect.X += (rect.Width - rect.Height) / 2f; + rect.Width = rect.Height; + } + else + { + rect.Y += (rect.Height - rect.Width) / 2f; + rect.Height = rect.Width; + } + plottingRect = chartGraph.GetRelativeRectangle( rect ); + + // Remember circular chart area center + this.circularCenter = new PointF(plottingRect.X + plottingRect.Width/2f, plottingRect.Y + plottingRect.Height/2f); + + // Calculate auto-fit font of the circular axis labels and update area position + FitCircularLabels(chartGraph, this.PlotAreaPosition, ref plottingRect, xTitleSize, yTitleSize); + } + + //****************************************************** + //** Set plotting area position + //****************************************************** + if(plottingRect.Width < 0f) + { + plottingRect.Width = 0f; + } + if(plottingRect.Height < 0f) + { + plottingRect.Height = 0f; + } + PlotAreaPosition.FromRectangleF(plottingRect); + InnerPlotPosition.SetPositionNoAuto( + (float)Math.Round((plottingRect.X - Position.X) / (Position.Width / 100F), 5), + (float)Math.Round((plottingRect.Y - Position.Y) / (Position.Height / 100F), 5), + (float)Math.Round(plottingRect.Width / (Position.Width / 100F), 5), + (float)Math.Round(plottingRect.Height / (Position.Height / 100F), 5)); + + + //****************************************************** + //** Adjust label font size for axis, which were + //** automatically calculated after the opposite axis + //** change the size of plotting area. + //****************************************************** + this.AxisY2.AdjustLabelFontAtSecondPass(chartGraph, InnerPlotPosition.Auto); + this.AxisY.AdjustLabelFontAtSecondPass(chartGraph, InnerPlotPosition.Auto); + if(InnerPlotPosition.Auto) + { + this.AxisX2.AdjustLabelFontAtSecondPass(chartGraph, InnerPlotPosition.Auto); + this.AxisX.AdjustLabelFontAtSecondPass(chartGraph, InnerPlotPosition.Auto); + } + + } + + /// + /// Finds axis by it's position. Can be Null. + /// + /// Axis position to find + /// Found axis. + private Axis FindAxis(AxisPosition axisPosition) + { + foreach(Axis axis in this.Axes) + { + if(axis.AxisPosition == axisPosition) + { + return axis; + } + } + return null; + } + + /// + /// Shift top/bottom labels so they will not overlap with left/right labels. + /// + /// Axis to shift up/down. + private void PreventTopBottomAxesLabelsOverlapping(Axis axis) + { + // If axis is not on the edge of the chart area do not + // try to adjust it's position when axis labels overlap + // labels of the oppositie axis. + if( !axis.IsAxisOnAreaEdge ) + { + return; + } + + // Shift bottom axis labels down + if(axis.AxisPosition == AxisPosition.Bottom) + { + // Get labels position + float labelsPosition = (float)axis.GetAxisPosition(); + if( !axis.GetIsMarksNextToAxis() ) + { + labelsPosition = axis.PlotAreaPosition.Bottom; + } + + // Only adjust labels outside plotting area + if(Math.Round(labelsPosition, 2) < Math.Round(axis.PlotAreaPosition.Bottom, 2)) + { + return; + } + + // Check if labels may overlap with Left axis + Axis leftAxis = FindAxis(AxisPosition.Left); + if(leftAxis != null && + leftAxis.enabled && + leftAxis.labelFarOffset != 0 && + leftAxis.labelFarOffset > labelsPosition && + axis.labelNearOffset != 0 && + axis.labelNearOffset < PlotAreaPosition.X) + { + float overlap = (float)(leftAxis.labelFarOffset - labelsPosition) * 0.75f; + if(overlap > axis.markSize) + { + axis.markSize += overlap - axis.markSize; + } + } + + // Check if labels may overlap with Right axis + Axis rightAxis = FindAxis(AxisPosition.Right); + if(rightAxis != null && + rightAxis.enabled && + rightAxis.labelFarOffset != 0 && + rightAxis.labelFarOffset > labelsPosition && + axis.labelFarOffset != 0 && + axis.labelFarOffset > PlotAreaPosition.Right) + { + float overlap = (float)(rightAxis.labelFarOffset - labelsPosition) * 0.75f; + if(overlap > axis.markSize) + { + axis.markSize += overlap - axis.markSize; + } + } + } + + // Shift top axis labels up + else if(axis.AxisPosition == AxisPosition.Top) + { + // Get labels position + float labelsPosition = (float)axis.GetAxisPosition(); + if( !axis.GetIsMarksNextToAxis() ) + { + labelsPosition = axis.PlotAreaPosition.Y; + } + + // Only adjust labels outside plotting area + if(Math.Round(labelsPosition, 2) < Math.Round(axis.PlotAreaPosition.Y, 2)) + { + return; + } + + // Check if labels may overlap with Left axis + Axis leftAxis = FindAxis(AxisPosition.Left); + if(leftAxis != null && + leftAxis.enabled && + leftAxis.labelNearOffset != 0 && + leftAxis.labelNearOffset < labelsPosition && + axis.labelNearOffset != 0 && + axis.labelNearOffset < PlotAreaPosition.X) + { + float overlap = (float)(labelsPosition - leftAxis.labelNearOffset) * 0.75f; + if(overlap > axis.markSize) + { + axis.markSize += overlap - axis.markSize; + } + } + + // Check if labels may overlap with Right axis + Axis rightAxis = FindAxis(AxisPosition.Right); + if(rightAxis != null && + rightAxis.enabled && + rightAxis.labelNearOffset != 0 && + rightAxis.labelNearOffset < labelsPosition && + axis.labelFarOffset != 0 && + axis.labelFarOffset > PlotAreaPosition.Right) + { + float overlap = (float)(labelsPosition - rightAxis.labelNearOffset) * 0.75f; + if(overlap > axis.markSize) + { + axis.markSize += overlap - axis.markSize; + } + } + } + + } + + #endregion + + #region Painting and Selection Methods + + /// + /// Draws chart area background and/or border. + /// + /// Chart graphics. + /// Background position. + /// Draws chart area border only. + private void PaintAreaBack(ChartGraphics graph, RectangleF position, bool borderOnly) + { + if(!borderOnly) + { + // Draw background + if(!this.Area3DStyle.Enable3D || !requireAxes || chartAreaIsCurcular) + { + // 3D Pie Chart doesn't need scene + // Draw 2D background + graph.FillRectangleRel( + position, + BackColor, + BackHatchStyle, + BackImage, + BackImageWrapMode, + BackImageTransparentColor, + BackImageAlignment, + BackGradientStyle, + BackSecondaryColor, + (requireAxes) ? Color.Empty : BorderColor, + (requireAxes) ? 0 : BorderWidth, + BorderDashStyle, + ShadowColor, + ShadowOffset, + PenAlignment.Outset, + chartAreaIsCurcular, + (chartAreaIsCurcular && this.CircularUsePolygons) ? this.CircularSectorsNumber : 0, + this.Area3DStyle.Enable3D); + } + else + { + // Draw chart area 3D scene + this.DrawArea3DScene(graph, position); + } + } + else + { + if(!this.Area3DStyle.Enable3D || !requireAxes || chartAreaIsCurcular) + { + // Draw chart area border + if(BorderColor != Color.Empty && BorderWidth > 0) + { + graph.FillRectangleRel( position, + Color.Transparent, + ChartHatchStyle.None, + "", + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + BorderColor, + BorderWidth, + BorderDashStyle, + Color.Empty, + 0, + PenAlignment.Outset, + chartAreaIsCurcular, + (chartAreaIsCurcular && this.CircularUsePolygons) ? this.CircularSectorsNumber : 0, + this.Area3DStyle.Enable3D); + } + } + + } + } + + /// + /// Paint the chart area. + /// + /// Chart graphics. + internal void Paint( ChartGraphics graph ) + { + // Check if plot area position was recalculated. + // If not and non-auto InnerPlotPosition & Position were + // specified - do all needed calculations + if (PlotAreaPosition.Width == 0 && + PlotAreaPosition.Height == 0 && + !InnerPlotPosition.Auto + && !Position.Auto) + { + // Initialize plotting area position + RectangleF plottingRect = Position.ToRectangleF(); + if (!InnerPlotPosition.Auto) + { + plottingRect.X += (Position.Width / 100F) * InnerPlotPosition.X; + plottingRect.Y += (Position.Height / 100F) * InnerPlotPosition.Y; + plottingRect.Width = (Position.Width / 100F) * InnerPlotPosition.Width; + plottingRect.Height = (Position.Height / 100F) * InnerPlotPosition.Height; + } + + PlotAreaPosition.FromRectangleF(plottingRect); + } + + // Get background position rectangle. + RectangleF backgroundPositionWithScrollBars = GetBackgroundPosition(true); + RectangleF backgroundPosition = GetBackgroundPosition(false); + + // Add hot region for plotting area. + if (Common.ProcessModeRegions) + { + Common.HotRegionsList.AddHotRegion(backgroundPosition, this, ChartElementType.PlottingArea, true); + } + // Draw background + PaintAreaBack(graph, backgroundPositionWithScrollBars, false); + + // Call BackPaint event + Common.Chart.CallOnPrePaint(new ChartPaintEventArgs(this, graph, Common, PlotAreaPosition)); + + // Draw chart types without axes - Pie. + if (!requireAxes && ChartTypes.Count != 0) + { + // Find first chart type that do not require axis (like Pie) and draw it. + // Chart types that do not require axes (circular charts) cannot be combined with + // any other chart types. + // NOTE: Fixes issues #4672 and #4692 + for (int chartTypeIndex = 0; chartTypeIndex < ChartTypes.Count; chartTypeIndex++) + { + IChartType chartType = Common.ChartTypeRegistry.GetChartType((string)ChartTypes[chartTypeIndex]); + if (!chartType.RequireAxes) + { + chartType.Paint(graph, Common, this, null); + break; + } + } + + // Call Paint event + Common.Chart.CallOnPostPaint(new ChartPaintEventArgs(this, graph, Common, PlotAreaPosition)); + return; + } + + + + // Reset Smart Labels + this.smartLabels.Reset(); + + + + // Set values for optimized drawing + foreach (Axis currentAxis in this._axisArray) + { + currentAxis.optimizedGetPosition = true; + currentAxis.paintViewMax = currentAxis.ViewMaximum; + currentAxis.paintViewMin = currentAxis.ViewMinimum; + currentAxis.paintRange = currentAxis.paintViewMax - currentAxis.paintViewMin; + currentAxis.paintAreaPosition = PlotAreaPosition.ToRectangleF(); + if (currentAxis.ChartArea != null && currentAxis.ChartArea.chartAreaIsCurcular) + { + // Update position for circular chart area + currentAxis.paintAreaPosition.Width /= 2.0f; + currentAxis.paintAreaPosition.Height /= 2.0f; + } + currentAxis.paintAreaPositionBottom = currentAxis.paintAreaPosition.Y + currentAxis.paintAreaPosition.Height; + currentAxis.paintAreaPositionRight = currentAxis.paintAreaPosition.X + currentAxis.paintAreaPosition.Width; + if (currentAxis.AxisPosition == AxisPosition.Top || currentAxis.AxisPosition == AxisPosition.Bottom) + currentAxis.paintChartAreaSize = currentAxis.paintAreaPosition.Width; + else + currentAxis.paintChartAreaSize = currentAxis.paintAreaPosition.Height; + + currentAxis.valueMultiplier = 0.0; + if (currentAxis.paintRange != 0) + { + currentAxis.valueMultiplier = currentAxis.paintChartAreaSize / currentAxis.paintRange; + } + } + + // Draw Axis Striplines (only when StripWidth > 0) + bool useScaleSegments = false; + Axis[] axesArray = new Axis[] { axisY, axisY2, axisX, axisX2 }; + foreach (Axis currentAxis in axesArray) + { + + useScaleSegments = (currentAxis.ScaleSegments.Count > 0); + + if (!useScaleSegments) + { + currentAxis.PaintStrips(graph, false); + } + + else + { + foreach (AxisScaleSegment scaleSegment in currentAxis.ScaleSegments) + { + scaleSegment.SetTempAxisScaleAndInterval(); + + currentAxis.PaintStrips(graph, false); + + scaleSegment.RestoreAxisScaleAndInterval(); + } + } + } + + // Draw Axis Grids + axesArray = new Axis[] { axisY, axisX2, axisY2, axisX }; + foreach (Axis currentAxis in axesArray) + { + + useScaleSegments = (currentAxis.ScaleSegments.Count > 0); + + if (!useScaleSegments) + { + currentAxis.PaintGrids(graph); + } + + else + { + foreach (AxisScaleSegment scaleSegment in currentAxis.ScaleSegments) + { + scaleSegment.SetTempAxisScaleAndInterval(); + + currentAxis.PaintGrids(graph); + + scaleSegment.RestoreAxisScaleAndInterval(); + } + } + + } + + // Draw Axis Striplines (only when StripWidth == 0) + foreach (Axis currentAxis in axesArray) + { + + useScaleSegments = (currentAxis.ScaleSegments.Count > 0); + + if (!useScaleSegments) + { + currentAxis.PaintStrips(graph, true); + } + + else + { + foreach (AxisScaleSegment scaleSegment in currentAxis.ScaleSegments) + { + scaleSegment.SetTempAxisScaleAndInterval(); + + currentAxis.PaintStrips(graph, true); + + scaleSegment.RestoreAxisScaleAndInterval(); + } + } + + } + + // Draw Axis elements on the back of the 3D scene + if (this.Area3DStyle.Enable3D && !this.chartAreaIsCurcular) + { + foreach (Axis currentAxis in axesArray) + { + + useScaleSegments = (currentAxis.ScaleSegments.Count > 0); + + if (!useScaleSegments) + { + currentAxis.PrePaint(graph); + } + + else + { + foreach (AxisScaleSegment scaleSegment in currentAxis.ScaleSegments) + { + scaleSegment.SetTempAxisScaleAndInterval(); + + currentAxis.PrePaint(graph); + + scaleSegment.RestoreAxisScaleAndInterval(); + } + + } + + } + } + + // Draws chart area border + bool borderDrawn = false; + if (this.Area3DStyle.Enable3D || !IsBorderOnTopSeries()) + { + borderDrawn = true; + PaintAreaBack(graph, backgroundPosition, true); + } + + // Draw chart types + if (!this.Area3DStyle.Enable3D || this.chartAreaIsCurcular) + { + // Drawing in 2D space + + // NOTE: Fixes issue #6443 and #5385 + // If two chart series of the same type (for example Line) are separated + // by other series (for example Area) the order is not correct. + // Old implementation draws ALL series that belongs to the chart type. + ArrayList typeAndSeries = this.GetChartTypesAndSeriesToDraw(); + + // Draw series by chart type or by series + foreach (ChartTypeAndSeriesInfo chartTypeInfo in typeAndSeries) + { + this.IterationCounter = 0; + IChartType type = Common.ChartTypeRegistry.GetChartType(chartTypeInfo.ChartType); + + // If 'chartTypeInfo.Series' set to NULL all series of that chart type are drawn at once + type.Paint(graph, Common, this, chartTypeInfo.Series); + } + } + else + { + // Drawing in 3D space + PaintChartSeries3D(graph); + } + + // Draw area border if it wasn't drawn prior to the series + if (!borderDrawn) + { + PaintAreaBack(graph, backgroundPosition, true); + } + + // Draw Axis + foreach (Axis currentAxis in axesArray) + { + + useScaleSegments = (currentAxis.ScaleSegments.Count > 0); + + if (!useScaleSegments) + { + // Paint axis and Reset temp axis offset for side-by-side charts like column + currentAxis.Paint(graph); + } + + else + { + // Some of the axis elements like grid lines and tickmarks + // are drawn for each segment + foreach (AxisScaleSegment scaleSegment in currentAxis.ScaleSegments) + { + scaleSegment.SetTempAxisScaleAndInterval(); + + currentAxis.PaintOnSegmentedScalePassOne(graph); + + scaleSegment.RestoreAxisScaleAndInterval(); + } + + // Other elements like labels, title, axis line are drawn once + currentAxis.PaintOnSegmentedScalePassTwo(graph); + } + + } + + // Call Paint event + Common.Chart.CallOnPostPaint(new ChartPaintEventArgs(this, graph, Common, PlotAreaPosition)); + + // Draw axis scale break lines + axesArray = new Axis[] { axisY, axisY2 }; + foreach (Axis currentAxis in axesArray) + { + for (int segmentIndex = 0; segmentIndex < (currentAxis.ScaleSegments.Count - 1); segmentIndex++) + { + currentAxis.ScaleSegments[segmentIndex].PaintBreakLine(graph, currentAxis.ScaleSegments[segmentIndex + 1]); + + } + } + + // Reset values for optimized drawing + foreach (Axis curentAxis in this._axisArray) + { + curentAxis.optimizedGetPosition = false; + + + // Reset preffered number of intervals on the axis + curentAxis.prefferedNumberofIntervals = 5; + + // Reset flag that scale segments are used + curentAxis.scaleSegmentsUsed = false; + + + } + } + + /// + /// Checks if chart area border should be drawn on top of series. + /// + /// True if border should be darwn on top. + private bool IsBorderOnTopSeries() + { + // For most of the chart types chart area border is drawn on top. + bool result = true; + foreach( Series series in this.Common.Chart.Series ) + { + if(series.ChartArea == this.Name) + { + // It is common for the Bubble and Point chart types to draw markers + // partially outside of the chart area. By drawing the border before + // series we avoiding the possibility of drawing the border line on + // top of the marker. + if(series.ChartType == SeriesChartType.Bubble || + series.ChartType == SeriesChartType.Point) + { + return false; + } + } + } + return result; + } + + /// + /// Paint the chart area cursors. + /// + /// Chart graphics. + /// Indicates that only cursors are redrawn. + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "These parameters are used when compiling for the Microsoft version of Chart")] + internal void PaintCursors( ChartGraphics graph, bool cursorOnly ) + { + // Cursors and selection are supoorted only in 2D charts + if(this.Area3DStyle.Enable3D == true) + { + return; + } + + // Do not draw cursor/selection for chart types that do not require axis (like Pie) + if(!this.requireAxes) + { + return; + } + + // Cursors and selection are not supoorted in circular areas + if(this.chartAreaIsCurcular) + { + return; + } + + // Do not draw cursor/selection while printing + if(this.Common != null && + this.Common.ChartPicture != null && + this.Common.ChartPicture.isPrinting) + { + return; + } + + // Do not draw cursor/selection when chart area is not visible + // because either width or height is set to zero + if(this.Position.Width == 0f || + this.Position.Height == 0f) + { + return; + } + +#if Microsoft_CONTROL + + Chart chart = this.Common.Chart; + ChartPicture chartPicture = Common.ChartPicture; + + // Check if cursor should be drawn + if(!double.IsNaN(_cursorX.SelectionStart) || + !double.IsNaN(_cursorX.SelectionEnd) || + !double.IsNaN(_cursorX.Position) || + !double.IsNaN(_cursorY.SelectionStart) || + !double.IsNaN(_cursorY.SelectionEnd) || + !double.IsNaN(_cursorY.Position)) + { + + if(!chartPicture.backgroundRestored && + !chartPicture.isSelectionMode ) + { + chartPicture.backgroundRestored = true; + + Rectangle chartPosition = new Rectangle(0, 0, chartPicture.Width, chartPicture.Height); + + // Get chart area position + Rectangle absAreaPlotPosition = Rectangle.Round(graph.GetAbsoluteRectangle(PlotAreaPosition.ToRectangleF())); + int maxCursorWidth = (CursorY.LineWidth > CursorX.LineWidth) ? CursorY.LineWidth + 1 : CursorX.LineWidth + 1; + absAreaPlotPosition.Inflate(maxCursorWidth, maxCursorWidth); + absAreaPlotPosition.Intersect(new Rectangle(0, 0, chart.Width, chart.Height)); + + // Create area buffer bitmap + if(areaBufferBitmap == null || + chartPicture.nonTopLevelChartBuffer == null || + !cursorOnly) + { + // Dispose previous bitmap + if(areaBufferBitmap != null) + { + areaBufferBitmap.Dispose(); + areaBufferBitmap = null; + } + if(chartPicture.nonTopLevelChartBuffer != null) + { + chartPicture.nonTopLevelChartBuffer.Dispose(); + chartPicture.nonTopLevelChartBuffer = null; + } + + + // Copy chart area plotting rectangle from the chart's dubble buffer image into area dubble buffer image + if(chart.paintBufferBitmap != null) + { + areaBufferBitmap = chart.paintBufferBitmap.Clone(absAreaPlotPosition, chart.paintBufferBitmap.PixelFormat); + } + + // Copy whole chart from the chart's dubble buffer image into area dubble buffer image + if(chart.paintBufferBitmap != null && + chart.paintBufferBitmap.Size.Width >= chartPosition.Size.Width && + chart.paintBufferBitmap.Size.Height >= chartPosition.Size.Height) + { + chartPicture.nonTopLevelChartBuffer = chart.paintBufferBitmap.Clone( + chartPosition, chart.paintBufferBitmap.PixelFormat); + } + + } + else if(cursorOnly && chartPicture.nonTopLevelChartBuffer != null) + { + // Restore previous background + chart.paintBufferBitmapGraphics.DrawImageUnscaled( + chartPicture.nonTopLevelChartBuffer, + chartPosition); + } + } + + // Draw chart area cursors and range selection + + _cursorY.Paint(graph); + _cursorX.Paint(graph); + + } +#endif // Microsoft_CONTROL + + } + + #endregion + + #region Circular chart area methods + + /// + /// Gets a circular chart type interface that belongs to this chart area. + /// + /// ICircularChartType interface or null. + internal ICircularChartType GetCircularChartType() + { + // Get number of sectors in circular chart area + foreach(Series series in this.Common.DataManager.Series) + { + if(series.IsVisible() && series.ChartArea == this.Name) + { + ICircularChartType type = Common.ChartTypeRegistry.GetChartType(series.ChartTypeName) as ICircularChartType;; + if(type != null) + { + return type; + } + } + } + return null; + } + + /// + /// Calculate size of the circular axis labels and sets auto-fit font. + /// + /// Chart graphics object. + /// The Chart area position. + /// Plotting area size. + /// Size of title on the axis. + /// Size of title on the axis. + internal void FitCircularLabels( + ChartGraphics chartGraph, + ElementPosition chartAreaPosition, + ref RectangleF plotArea, + float xTitleSize, + float yTitleSize) + { + // Check if axis labels are enabled + if(!this.AxisX.LabelStyle.Enabled) + { + return; + } + + // Get absolute titles size + SizeF titleSize = chartGraph.GetAbsoluteSize(new SizeF(xTitleSize, yTitleSize)); + + // Get absolute position of area + RectangleF plotAreaRectAbs = chartGraph.GetAbsoluteRectangle( plotArea ); + RectangleF areaRectAbs = chartGraph.GetAbsoluteRectangle( chartAreaPosition.ToRectangleF()); + + // Get absolute markers size and spacing + float spacing = chartGraph.GetAbsolutePoint(new PointF(0, this.AxisX.markSize + Axis.elementSpacing)).Y; + + // Get circular axis list + ArrayList axisList = GetCircularAxisList(); + + // Get circular axis labels style + CircularAxisLabelsStyle labelsStyle = GetCircularAxisLabelsStyle(); + + //***************************************************************** + //** Calculate the auto-fit font if required + //***************************************************************** + if(this.AxisX.LabelStyle.Enabled && this.AxisX.IsLabelAutoFit) + { + // Set max auto fit font + this.AxisX.autoLabelFont = Common.ChartPicture.FontCache.GetFont( + this.AxisX.LabelStyle.Font.FontFamily, + 14, + this.AxisX.LabelStyle.Font.Style, + GraphicsUnit.Point); + + // Get estimated labels size + float labelsSizeEstimate = GetCircularLabelsSize(chartGraph, areaRectAbs, plotAreaRectAbs, titleSize); + labelsSizeEstimate = (float)Math.Min(labelsSizeEstimate * 1.1f, plotAreaRectAbs.Width / 5f); + labelsSizeEstimate += spacing; + + // Calculate auto-fit font + this.AxisX.GetCircularAxisLabelsAutoFitFont(chartGraph, axisList, labelsStyle, plotAreaRectAbs, areaRectAbs, labelsSizeEstimate); + } + + //***************************************************************** + //** Shrink plot area size proportionally + //***************************************************************** + + // Get labels size + float labelsSize = GetCircularLabelsSize(chartGraph, areaRectAbs, plotAreaRectAbs, titleSize); + + // Check if change size is smaller than radius + labelsSize = (float)Math.Min(labelsSize, plotAreaRectAbs.Width / 2.5f); + labelsSize += spacing; + + plotAreaRectAbs.X += labelsSize; + plotAreaRectAbs.Width -= 2f * labelsSize; + plotAreaRectAbs.Y += labelsSize; + plotAreaRectAbs.Height -= 2f * labelsSize; + + // Restrict minimum plot area size + if(plotAreaRectAbs.Width < 1.0f) + { + plotAreaRectAbs.Width = 1.0f; + } + if(plotAreaRectAbs.Height < 1.0f) + { + plotAreaRectAbs.Height = 1.0f; + } + + plotArea = chartGraph.GetRelativeRectangle( plotAreaRectAbs ); + + + //***************************************************************** + //** Set axes labels size + //***************************************************************** + SizeF relativeLabelSize = chartGraph.GetRelativeSize(new SizeF(labelsSize, labelsSize)); + this.AxisX.labelSize = relativeLabelSize.Height; + this.AxisX2.labelSize = relativeLabelSize.Height; + this.AxisY.labelSize = relativeLabelSize.Width; + this.AxisY2.labelSize = relativeLabelSize.Width; + + } + + /// + /// Calculate size of the circular axis labels. + /// + /// Chart graphics object. + /// The Chart area position. + /// Plotting area size. + /// Size of title on the axes. + /// Circulat labels style. + internal float GetCircularLabelsSize( + ChartGraphics chartGraph, + RectangleF areaRectAbs, + RectangleF plotAreaRectAbs, + SizeF titleSize) + { + // Find current horiz. and vert. spacing between plotting and chart areas + SizeF areaDiff = new SizeF(plotAreaRectAbs.X - areaRectAbs.X, plotAreaRectAbs.Y - areaRectAbs.Y); + areaDiff.Width -= titleSize.Width; + areaDiff.Height -= titleSize.Height; + + // Get absolute center of the area + PointF areaCenterAbs = chartGraph.GetAbsolutePoint(this.circularCenter); + + // Get circular axis list + ArrayList axisList = GetCircularAxisList(); + + // Get circular axis labels style + CircularAxisLabelsStyle labelsStyle = GetCircularAxisLabelsStyle(); + + // Defines on how much (pixels) the circular chart area radius should be reduced + float labelsSize = 0f; + + //***************************************************************** + //** Loop through all axis labels + //***************************************************************** + foreach(CircularChartAreaAxis axis in axisList) + { + //***************************************************************** + //** Measure label text + //***************************************************************** + SizeF textSize = chartGraph.MeasureString( + axis.Title.Replace("\\n", "\n"), + (this.AxisX.autoLabelFont == null) ? this.AxisX.LabelStyle.Font : this.AxisX.autoLabelFont); + textSize.Width = (float)Math.Ceiling(textSize.Width * 1.1f); + textSize.Height = (float)Math.Ceiling(textSize.Height * 1.1f); + + + //***************************************************************** + //** Calculate area size change depending on labels style + //***************************************************************** + if(labelsStyle == CircularAxisLabelsStyle.Circular) + { + labelsSize = (float)Math.Max( + labelsSize, + textSize.Height); + } + else if(labelsStyle == CircularAxisLabelsStyle.Radial) + { + float textAngle = axis.AxisPosition + 90; + + // For angled text find it's X and Y components + float width = (float)Math.Cos(textAngle/180F*Math.PI) * textSize.Width; + float height = (float)Math.Sin(textAngle/180F*Math.PI) * textSize.Width; + width = (float)Math.Abs(Math.Ceiling(width)); + height = (float)Math.Abs(Math.Ceiling(height)); + + // Reduce text size by current spacing between plotting area and chart area + width -= areaDiff.Width; + height -= areaDiff.Height; + if(width < 0) + width = 0; + if(height < 0) + height = 0; + + + labelsSize = (float)Math.Max( + labelsSize, + Math.Max(width, height)); + } + else if(labelsStyle == CircularAxisLabelsStyle.Horizontal) + { + // Get text angle + float textAngle = axis.AxisPosition; + if(textAngle > 180f) + { + textAngle -= 180f; + } + + // Get label rotated position + PointF[] labelPosition = new PointF[] { new PointF(areaCenterAbs.X, plotAreaRectAbs.Y) }; + Matrix newMatrix = new Matrix(); + newMatrix.RotateAt(textAngle, areaCenterAbs); + newMatrix.TransformPoints(labelPosition); + + // Calculate width + float width = textSize.Width; + width -= areaRectAbs.Right - labelPosition[0].X; + if(width < 0f) + { + width = 0f; + } + + labelsSize = (float)Math.Max( + labelsSize, + Math.Max(width, textSize.Height)); + } + } + + return labelsSize; + } + + /// + /// True if polygons should be used instead of the circles for the chart area. + /// + internal bool CircularUsePolygons + { + get + { + // Check if value was precalculated + if(this._circularUsePolygons == int.MinValue) + { + _circularUsePolygons = 0; + + // Look for custom properties in series + foreach(Series series in this.Common.DataManager.Series) + { + if(series.ChartArea == this.Name && series.IsVisible()) + { + // Get custom attribute + if (series.IsCustomPropertySet(CustomPropertyName.AreaDrawingStyle)) + { + if(String.Compare(series[CustomPropertyName.AreaDrawingStyle], "Polygon", StringComparison.OrdinalIgnoreCase) == 0) + { + _circularUsePolygons = 1; + } + else if (String.Compare(series[CustomPropertyName.AreaDrawingStyle], "Circle", StringComparison.OrdinalIgnoreCase) == 0) + { + _circularUsePolygons = 0; + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid( series[CustomPropertyName.AreaDrawingStyle], "AreaDrawingStyle"))); + } + break; + } + } + } + } + + return (this._circularUsePolygons == 1); + } + } + + /// + /// Gets circular area axis labels style. + /// + /// Axis labels style. + internal CircularAxisLabelsStyle GetCircularAxisLabelsStyle() + { + CircularAxisLabelsStyle style = CircularAxisLabelsStyle.Auto; + + // Get maximum number of points in all series + foreach(Series series in this.Common.DataManager.Series) + { + if(series.IsVisible() && series.ChartArea == this.Name && series.IsCustomPropertySet(CustomPropertyName.CircularLabelsStyle)) + { + string styleName = series[CustomPropertyName.CircularLabelsStyle]; + if(String.Compare( styleName, "Auto", StringComparison.OrdinalIgnoreCase) == 0 ) + { + style = CircularAxisLabelsStyle.Auto; + } + else if(String.Compare( styleName,"Circular", StringComparison.OrdinalIgnoreCase) == 0) + { + style = CircularAxisLabelsStyle.Circular; + } + else if(String.Compare( styleName,"Radial", StringComparison.OrdinalIgnoreCase) == 0) + { + style = CircularAxisLabelsStyle.Radial; + } + else if (String.Compare(styleName, "Horizontal", StringComparison.OrdinalIgnoreCase) == 0) + { + style = CircularAxisLabelsStyle.Horizontal; + } + else + { + throw(new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid( styleName, "CircularLabelsStyle"))); + } + + } + } + + // Get auto style + if(style == CircularAxisLabelsStyle.Auto) + { + int sectorNumber = CircularSectorsNumber; + style = CircularAxisLabelsStyle.Horizontal; + if(sectorNumber > 30) + { + style = CircularAxisLabelsStyle.Radial; + } + } + + return style; + } + + /// + /// Number of sectors in the circular area. + /// + internal int CircularSectorsNumber + { + get + { + // Check if value was precalculated + if(this._circularSectorNumber == int.MinValue) + { + this._circularSectorNumber = GetCircularSectorNumber(); + } + + return this._circularSectorNumber; + } + } + + /// + /// Gets number of sectors in the circular chart area. + /// + /// Number of sectors. + private int GetCircularSectorNumber() + { + ICircularChartType type = this.GetCircularChartType(); + if(type != null) + { + return type.GetNumerOfSectors(this, this.Common.DataManager.Series); + } + return 0; + } + + /// + /// Fills a list of circular axis. + /// + /// Axes list. + internal ArrayList GetCircularAxisList() + { + // Check if list was already created + if(_circularAxisList == null) + { + _circularAxisList = new ArrayList(); + + // Loop through all sectors + int sectorNumber = GetCircularSectorNumber(); + for(int sectorIndex = 0; sectorIndex < sectorNumber; sectorIndex++) + { + // Create new axis object + CircularChartAreaAxis axis = new CircularChartAreaAxis(sectorIndex * 360f/sectorNumber); + + // Check if custom X axis labels will be used + if(this.AxisX.CustomLabels.Count > 0) + { + if(sectorIndex < this.AxisX.CustomLabels.Count) + { + axis.Title = this.AxisX.CustomLabels[sectorIndex].Text; + axis.TitleForeColor = this.AxisX.CustomLabels[sectorIndex].ForeColor; + } + } + else + { + // Get axis title from all series + foreach(Series series in this.Common.DataManager.Series) + { + if(series.IsVisible() && series.ChartArea == this.Name && sectorIndex < series.Points.Count) + { + if(series.Points[sectorIndex].AxisLabel.Length > 0) + { + axis.Title = series.Points[sectorIndex].AxisLabel; + break; + } + } + } + } + + // Add axis into the list + _circularAxisList.Add(axis); + } + + } + return _circularAxisList; + } + + /// + /// Converts circular position of the X axis to angle in degrees. + /// + /// X axis position. + /// Angle in degrees. + internal float CircularPositionToAngle(double position) + { + // Get X axis scale size + double scaleRatio = 360.0 / Math.Abs(this.AxisX.Maximum - this.AxisX.Minimum); + + return (float)(position * scaleRatio + this.AxisX.Crossing); + } + + #endregion + + #region 2D Series drawing order methods + + /// + /// Helper method that returns a list of 'ChartTypeAndSeriesInfo' objects. + /// This list is used for chart area series drawing in 2D mode. Each + /// object may represent an individual series or all series that belong + /// to one chart type. + /// + /// This method is intended to fix issues #6443 and #5385 when area chart + /// type incorrectly overlaps point or line chart type. + /// + /// List of 'ChartTypeAndSeriesInfo' objects. + private ArrayList GetChartTypesAndSeriesToDraw() + { + ArrayList resultList = new ArrayList(); + + // Build chart type or series position based lists + if (this.ChartTypes.Count > 1 && + (this.ChartTypes.Contains(ChartTypeNames.Area) + || this.ChartTypes.Contains(ChartTypeNames.SplineArea) + ) + ) + { + // Array of chart type names that do not require furher processing + ArrayList processedChartType = new ArrayList(); + ArrayList splitChartType = new ArrayList(); + + // Draw using the exact order in the series collection + int seriesIndex = 0; + foreach (Series series in this.Common.DataManager.Series) + { + // Check if series is visible and belongs to the chart area + if (series.ChartArea==this.Name && series.IsVisible() && series.Points.Count > 0) + { + // Check if this chart type was already processed + if (!processedChartType.Contains(series.ChartTypeName)) + { + // Check if curent chart type can be individually processed + bool canBeIndividuallyProcessed = false; + if (series.ChartType == SeriesChartType.Point || + series.ChartType == SeriesChartType.Line || + series.ChartType == SeriesChartType.Spline || + series.ChartType == SeriesChartType.StepLine) + { + canBeIndividuallyProcessed = true; + } + + if (!canBeIndividuallyProcessed) + { + // Add a record to process all series of that chart type at once + resultList.Add(new ChartTypeAndSeriesInfo(series.ChartTypeName)); + processedChartType.Add(series.ChartTypeName); + } + else + { + // Check if curent chart type has more that 1 series and they are split + // by other series + bool chartTypeIsSplit = false; + + if (splitChartType.Contains(series.ChartTypeName)) + { + chartTypeIsSplit = true; + } + else + { + bool otherChartTypeFound = false; + for (int curentSeriesIndex = seriesIndex + 1; curentSeriesIndex < this.Common.DataManager.Series.Count; curentSeriesIndex++) + { + if (series.ChartTypeName == this.Common.DataManager.Series[curentSeriesIndex].ChartTypeName) + { + if (otherChartTypeFound) + { + chartTypeIsSplit = true; + splitChartType.Add(series.ChartTypeName); + } + } + else + { + if (this.Common.DataManager.Series[curentSeriesIndex].ChartType == SeriesChartType.Area || + this.Common.DataManager.Series[curentSeriesIndex].ChartType == SeriesChartType.SplineArea) + { + otherChartTypeFound = true; + } + } + } + } + + if (chartTypeIsSplit) + { + // Add a record to process this series individually + resultList.Add(new ChartTypeAndSeriesInfo(series)); + } + else + { + // Add a record to process all series of that chart type at once + resultList.Add(new ChartTypeAndSeriesInfo(series.ChartTypeName)); + processedChartType.Add(series.ChartTypeName); + } + } + } + } + + ++seriesIndex; + } + } + else + { + foreach (string chartType in this.ChartTypes) + { + resultList.Add(new ChartTypeAndSeriesInfo(chartType)); + } + } + + return resultList; + } + + /// + /// Internal data structure that stores chart type name and optionally series object. + /// + internal class ChartTypeAndSeriesInfo + { + /// + /// Object constructor. + /// + public ChartTypeAndSeriesInfo() + { + } + + /// + /// Object constructor. + /// + /// Chart type name to initialize with. + public ChartTypeAndSeriesInfo(string chartType) + { + this.ChartType = chartType; + } + + /// + /// Object constructor. + /// + /// Series to initialize with. + public ChartTypeAndSeriesInfo(Series series) + { + this.ChartType = series.ChartTypeName; + this.Series = series; + } + + // Chart type name + internal string ChartType = string.Empty; + + // Series object. Can be set to NULL! + internal Series Series = null; + + } + + #endregion // 2D Series drawing order methods + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", MessageId = "axisX")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", MessageId = "axisX2")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", MessageId = "axisY")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", MessageId = "axisY2")] + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Dispose managed resources + if (this._axisArray != null) + { + foreach (Axis axis in this._axisArray) + { + axis.Dispose(); + } + this._axisArray = null; + } + if ( this._areaPosition != null) + { + this._areaPosition.Dispose(); + this._areaPosition = null; + } + if (this._innerPlotPosition != null) + { + this._innerPlotPosition.Dispose(); + this._innerPlotPosition = null; + } + if (this.PlotAreaPosition != null) + { + this.PlotAreaPosition.Dispose(); + this.PlotAreaPosition = null; + } +#if Microsoft_CONTROL + if (this.areaBufferBitmap != null) + { + this.areaBufferBitmap.Dispose(); + this.areaBufferBitmap = null; + } + if (this._cursorX != null) + { + this._cursorX.Dispose(); + this._cursorX = null; + } + if (this._cursorY != null) + { + this._cursorY.Dispose(); + this._cursorY = null; + } +#endif + } + base.Dispose(disposing); + } + + + #endregion + + } +} diff --git a/System.Web.DataVisualization/Common/General/ChartArea3D.cs b/System.Web.DataVisualization/Common/General/ChartArea3D.cs new file mode 100644 index 000000000..f05891df6 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ChartArea3D.cs @@ -0,0 +1,2239 @@ +//------------------------------------------------------------- +// +// Copyright � Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartArea3D.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ChartArea3DStyle, ChartArea3D +// +// Purpose: ChartArea3D class represents 3D chart area. It contains +// methods for coordinates transformation, drawing the 3D +// scene and many 3D related helper methods. +// +// Reviewed: AG - Microsoft 16, 2007 +// +//=================================================================== + +#region Used namespaces +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Collections; +using System.Globalization; +using System.Collections.Generic; + +#if WINFORMS_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI; +#endif + + +#endregion + +#if WINFORMS_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region 3D lightStyle style enumerations + + /// + /// A lighting style for a 3D chart area. + /// + public enum LightStyle + { + /// + /// No lighting. + /// + None, + /// + /// Simplistic lighting. + /// + Simplistic, + /// + /// Realistic lighting. + /// + Realistic + } + + #endregion + + #region 3D Center of Projetion coordinates enumeration + + /// + /// Coordinates of the Center Of Projection + /// + [Flags] + internal enum COPCoordinates + { + /// + /// Check X coordinate. + /// + X = 1, + /// + /// Check Y coordinate. + /// + Y = 2, + /// + /// Check Z coordinate. + /// + Z = 4 + } + + #endregion + + /// + /// The ChartArea3DStyleClass class provides the functionality for 3D attributes of chart areas, + /// such as rotation angles and perspective. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class ChartArea3DStyle + { + #region Constructor and Initialization + + /// + /// ChartArea3DStyle constructor. + /// + public ChartArea3DStyle() + { + } + + /// + /// ChartArea3DStyle constructor. + /// + public ChartArea3DStyle(ChartArea chartArea) + { + this._chartArea = chartArea; + } + + /// + /// Initialize Chart area and axes + /// + /// Chart area object. + internal void Initialize(ChartArea chartArea) + { + this._chartArea = chartArea; + } + + #endregion + + #region Fields + + // Reference to the chart area object + private ChartArea _chartArea = null; + + // Enables/disables 3D chart types in the area. + private bool _enable3D = false; + + // Indicates that axes are set at the right angle independent of the rotation. + private bool _isRightAngleAxes = true; + + // Indicates that series should be drawn as isClustered. + private bool _isClustered = false; + + // 3D area lightStyle style. + private LightStyle _lightStyle = LightStyle.Simplistic; + + // 3D area perspective which controls the scaleView of the chart depth. + private int _perspective = 0; + + // Chart area rotation angle around the X axis. + private int _inclination = 30; + + // Chart area rotation angle around the Y axis. + private int _rotation = 30; + + // Chart area walls width. + private int _wallWidth = 7; + + // Series points depth in percentages + private int _pointDepth = 100; + + // Series points gap depth in percentages + private int _pointGapDepth = 100; + + #endregion + + #region Properties + + /// + /// Gets or sets a Boolean value that toggles 3D for a chart area on and off. + /// + [ + SRCategory("CategoryAttribute3D"), + Bindable(true), + DefaultValue(false), + SRDescription("DescriptionAttributeChartArea3DStyle_Enable3D"), + ParenthesizePropertyNameAttribute(true) + ] + public bool Enable3D + { + get + { + return this._enable3D; + } + set + { + if (this._enable3D != value) + { + this._enable3D = value; + + if (this._chartArea != null) + { +#if SUBAXES + // If one of the axes has sub axis the scales has to be recalculated + foreach(Axis axis in this._chartArea.Axes) + { + if(axis.SubAxes.Count > 0) + { + this._chartArea.ResetAutoValues(); + break; + } + } +#endif // SUBAXES + + this._chartArea.Invalidate(); + } + } + } + } + + + /// + /// Gets or sets a Boolean that determines if a chart area is displayed using an isometric projection. + /// + [ + SRCategory("CategoryAttribute3D"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeChartArea3DStyle_RightAngleAxes"), + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public bool IsRightAngleAxes + { + get + { + return _isRightAngleAxes; + } + set + { + _isRightAngleAxes = value; + + // Adjust 3D properties values + if (_isRightAngleAxes) + { + // Disable perspective if right angle axis are used + this._perspective = 0; + } + + if (this._chartArea != null) + { + this._chartArea.Invalidate(); + } + } + } + + + /// + /// Gets or sets a Boolean value that determines if bar chart or column + /// chart data series are clustered (displayed along distinct rows). + /// + [ + SRCategory("CategoryAttribute3D"), + Bindable(true), + DefaultValue(false), + SRDescription("DescriptionAttributeChartArea3DStyle_Clustered"), + ] + public bool IsClustered + { + get + { + return _isClustered; + } + set + { + _isClustered = value; + if (this._chartArea != null) + { + this._chartArea.Invalidate(); + } + } + } + + /// + /// Gets or sets the style of lighting for a 3D chart area. + /// + [ + SRCategory("CategoryAttribute3D"), + Bindable(true), + DefaultValue(typeof(LightStyle), "Simplistic"), + SRDescription("DescriptionAttributeChartArea3DStyle_Light"), + ] + public LightStyle LightStyle + { + get + { + return _lightStyle; + } + set + { + _lightStyle = value; + if (this._chartArea != null) + { + this._chartArea.Invalidate(); + } + } + } + + /// + /// Gets or sets the percent of perspective for a 3D chart area. + /// + [ + SRCategory("CategoryAttribute3D"), + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributeChartArea3DStyle_Perspective"), + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public int Perspective + { + get + { + return _perspective; + } + set + { + if(value < 0 || value > 100) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionChartArea3DPerspectiveInvalid)); + } + + _perspective = value; + + // Adjust 3D properties values + if (_perspective != 0) + { + // Disable right angle axes + this._isRightAngleAxes = false; + } + + if (this._chartArea != null) + { + this._chartArea.Invalidate(); + } + } + } + + /// + /// Gets or sets the inclination for a 3D chart area. + /// + [ + SRCategory("CategoryAttribute3D"), + Bindable(true), + DefaultValue(30), + SRDescription("DescriptionAttributeChartArea3DStyle_Inclination"), + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public int Inclination + { + get + { + return _inclination; + } + set + { + if(value < -90 || value > 90) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionChartArea3DInclinationInvalid)); + } + _inclination = value; + + if (this._chartArea != null) + { + this._chartArea.Invalidate(); + } + } + } + + /// + /// Gets or sets the rotation angle for a 3D chart area. + /// + [ + SRCategory("CategoryAttribute3D"), + Bindable(true), + DefaultValue(30), + SRDescription("DescriptionAttributeChartArea3DStyle_Rotation"), + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public int Rotation + { + get + { + return _rotation; + } + set + { + if(value < -180 || value > 180) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionChartArea3DRotationInvalid)); + } + _rotation = value; + + if (this._chartArea != null) + { + this._chartArea.Invalidate(); + } + } + } + + /// + /// Gets or sets the width of the walls displayed in 3D chart areas. + /// + [ + SRCategory("CategoryAttribute3D"), + Bindable(true), + DefaultValue(7), + SRDescription("DescriptionAttributeChartArea3DStyle_WallWidth"), + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public int WallWidth + { + get + { + return _wallWidth; + } + set + { + if(value < 0 || value > 30) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionChartArea3DWallWidthInvalid)); + } + + _wallWidth = value; + if (this._chartArea != null) + { + this._chartArea.Invalidate(); + } + } + } + + /// + /// Gets or sets the depth of data points displayed in 3D chart areas (0-1000%). + /// + [ + SRCategory("CategoryAttribute3D"), + Bindable(true), + DefaultValue(100), + SRDescription("DescriptionAttributeChartArea3DStyle_PointDepth"), + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public int PointDepth + { + get + { + return _pointDepth; + } + set + { + if(value < 0 || value > 1000) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionChartArea3DPointsDepthInvalid)); + } + + _pointDepth = value; + if (this._chartArea != null) + { + this._chartArea.Invalidate(); + } + } + } + + /// + /// Gets or sets the distance between series rows in 3D chart areas (0-1000%). + /// + [ + SRCategory("CategoryAttribute3D"), + Bindable(true), + DefaultValue(100), + SRDescription("DescriptionAttributeChartArea3DStyle_PointGapDepth"), + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public int PointGapDepth + { + get + { + return _pointGapDepth; + } + set + { + if(value < 0 || value > 1000) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionChartArea3DPointsGapInvalid)); + } + + _pointGapDepth = value; + if (this._chartArea != null) + { + this._chartArea.Invalidate(); + } + } + } + + #endregion + } + + /// + /// ChartArea3D class represents 3D chart area. It contains all the 3D + /// scene settings and methods for drawing the 3D plotting area, and calculating + /// the depth of chart elements. + /// + public partial class ChartArea + { + #region Fields + + // Chart area 3D style attribuytes + private ChartArea3DStyle _area3DStyle = new ChartArea3DStyle(); + + // Coordinate convertion matrix + internal Matrix3D matrix3D = new Matrix3D(); + + // Chart area scene wall width in relative coordinates + internal SizeF areaSceneWallWidth = SizeF.Empty; + + // Chart area scene depth + internal float areaSceneDepth = 0; + + // Visible surfaces in plotting area + private SurfaceNames _visibleSurfaces; + + // Z axis depth of series points + private double _pointsDepth = 0; + + // Z axis depth of the gap between isClustered series + private double _pointsGapDepth = 0; + + /// + /// Indicates that series order should be reversed to simulate Y axis rotation. + /// + private bool _reverseSeriesOrder = false; + + /// + /// Old X axis reversed flag + /// + internal bool oldReverseX = false; + + /// + /// Old Y axis reversed flag + /// + internal bool oldReverseY = false; + + /// + /// Old Y axis rotation angle + /// + internal int oldYAngle = 30; + + /// + /// List of all stack group names + /// + private ArrayList _stackGroupNames = null; + + /// + /// This list contains an array of series names for each 3D cluster + /// + internal List> seriesClusters = null; + + #endregion + + #region 3D Style properties + + /// + /// Gets or sets a ChartArea3DStyle object, used to draw all series in a chart area in 3D. + /// + [ + SRCategory("CategoryAttribute3D"), + Bindable(true), + DefaultValue(null), + SRDescription("DescriptionAttributeArea3DStyle"), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), + TypeConverter(typeof(NoNameExpandableObjectConverter)), +#if !WINFORMS_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif + ] + public ChartArea3DStyle Area3DStyle + { + get + { + return _area3DStyle; + } + set + { + _area3DStyle = value; + + // Initialize style object + _area3DStyle.Initialize((ChartArea)this); + } + } + + /// + /// Indicates that series order should be reversed to simulate Y axis rotation. + /// + internal bool ReverseSeriesOrder + { + get { return _reverseSeriesOrder; } + } + + /// + /// Gets the list of all stack group names + /// + internal ArrayList StackGroupNames + { + get { return _stackGroupNames; } + } + + #endregion + + #region 3D Coordinates transfotmation methods + + /// + /// Call this method to apply 3D transformations on an array of 3D points (must be done before calling GDI+ drawing methods). + /// + /// 3D Points array. + public void TransformPoints( Point3D[] points ) + { + // Convert Z coordinates from 0-100% to axis values + foreach(Point3D pt in points) + { + pt.Z = (pt.Z / 100f) * this.areaSceneDepth; + } + + // Transform points + this.matrix3D.TransformPoints( points ); + } + + #endregion + + #region 3D Scene drawing methods + + /// + /// Draws chart area 3D scene, which consists of 3 or 2 walls. + /// + /// Chart graphics object. + /// Chart area 2D position. + internal void DrawArea3DScene(ChartGraphics graph, RectangleF position) + { + // Reference to the chart area class + ChartArea chartArea = (ChartArea)this; + + // Calculate relative size of the wall + areaSceneWallWidth = graph.GetRelativeSize( new SizeF(this.Area3DStyle.WallWidth, this.Area3DStyle.WallWidth)); + + //*********************************************************** + //** Calculate the depth of the chart area scene + //*********************************************************** + areaSceneDepth = GetArea3DSceneDepth(); + + //*********************************************************** + //** Initialize coordinate transformation matrix + //*********************************************************** + this.matrix3D.Initialize( + position, + areaSceneDepth, + this.Area3DStyle.Inclination, + this.Area3DStyle.Rotation, + this.Area3DStyle.Perspective, + this.Area3DStyle.IsRightAngleAxes); + + //*********************************************************** + //** Initialize Lighting + //*********************************************************** + this.matrix3D.InitLight( + this.Area3DStyle.LightStyle + ); + + //*********************************************************** + //** Find chart area visible surfaces + //*********************************************************** + _visibleSurfaces = graph.GetVisibleSurfaces( + position, + 0, + areaSceneDepth, + this.matrix3D); + + //*********************************************************** + //** Chech if area scene should be drawn + //*********************************************************** + Color sceneBackColor = chartArea.BackColor; + + // Do not draw the transparent walls + if(sceneBackColor == Color.Transparent) + { + // Area wall is not visible + areaSceneWallWidth = SizeF.Empty; + return; + } + + // If color is not set (default) - use LightGray + if(sceneBackColor == Color.Empty) + { + sceneBackColor = Color.LightGray; + } + + //*********************************************************** + //** Adjust scene 2D rectangle so that wall are drawn + //** outside plotting area. + //*********************************************************** + // If bottom wall is visible + if(IsBottomSceneWallVisible()) + { + position.Height += areaSceneWallWidth.Height; + } + + // Adjust for the left/right wall + position.Width += areaSceneWallWidth.Width; + if(this.Area3DStyle.Rotation > 0) + { + position.X -= areaSceneWallWidth.Width; + } + + //*********************************************************** + //** Draw scene walls + //*********************************************************** + + // Draw back wall + RectangleF wallRect2D = new RectangleF(position.Location, position.Size); + float wallDepth = areaSceneWallWidth.Width; + float wallZPosition = -wallDepth; + + // For isometric projection Front wall should be visible sometimes + if( IsMainSceneWallOnFront()) + { + wallZPosition = areaSceneDepth; + } + + graph.Fill3DRectangle( + wallRect2D, + wallZPosition, + wallDepth, + this.matrix3D, + chartArea.Area3DStyle.LightStyle, + sceneBackColor, + chartArea.BorderColor, + chartArea.BorderWidth, + chartArea.BorderDashStyle, + DrawingOperationTypes.DrawElement ); + + // Draw side wall on the left or right side + wallRect2D = new RectangleF(position.Location, position.Size); + wallRect2D.Width = areaSceneWallWidth.Width; + if(!IsSideSceneWallOnLeft()) + { + // Wall is on the right side + wallRect2D.X = position.Right - areaSceneWallWidth.Width; + } + graph.Fill3DRectangle( + wallRect2D, + 0f, + areaSceneDepth, + this.matrix3D, + chartArea.Area3DStyle.LightStyle, + sceneBackColor, + chartArea.BorderColor, + chartArea.BorderWidth, + chartArea.BorderDashStyle, + DrawingOperationTypes.DrawElement); + + // Draw bottom wall + if(IsBottomSceneWallVisible()) + { + wallRect2D = new RectangleF(position.Location, position.Size); + wallRect2D.Height = areaSceneWallWidth.Height; + wallRect2D.Y = position.Bottom - areaSceneWallWidth.Height; + wallRect2D.Width -= areaSceneWallWidth.Width; + if(IsSideSceneWallOnLeft()) + { + wallRect2D.X += areaSceneWallWidth.Width; + } + + wallZPosition = 0; + graph.Fill3DRectangle( + wallRect2D, + 0f, + areaSceneDepth, + this.matrix3D, + chartArea.Area3DStyle.LightStyle, + sceneBackColor, + chartArea.BorderColor, + chartArea.BorderWidth, + chartArea.BorderDashStyle, + DrawingOperationTypes.DrawElement ); + } + + } + + /// + /// Helper method which return True if bottom wall of the + /// chart area scene is visible. + /// + /// True if bottom wall is visible. + internal bool IsBottomSceneWallVisible() + { + return (this.Area3DStyle.Inclination >= 0); + } + + /// + /// Helper method which return True if main wall of the + /// chart area scene is displayed on the front side. + /// + /// True if front wall is visible. + internal bool IsMainSceneWallOnFront() + { + // Note: Not used in this version! + return false; + } + + /// + /// Helper method which return True if side wall of the + /// chart area scene is displayed on the left side. + /// + /// True if bottom wall is visible. + internal bool IsSideSceneWallOnLeft() + { + return (this.Area3DStyle.Rotation > 0); + } + + #endregion + + #region 3D Scene depth claculation methods + + /// + /// Call this method to get the Z position of a series (useful for custom drawing). + /// + /// The series to retrieve the Z position for. + /// The Z position of the specified series. Measured as a percentage of the chart area's depth. + public float GetSeriesZPosition(Series series) + { + float positionZ, depth; + GetSeriesZPositionAndDepth(series, out depth, out positionZ); + return ((positionZ + depth/2f) / this.areaSceneDepth) * 100f; + } + + /// + /// Call this method to get the depth of a series in a chart area. + /// + /// The series to retrieve the depth for. + /// The depth of the specified series. Measured as a percentage of the chart area's depth. + public float GetSeriesDepth(Series series) + { + float positionZ, depth; + GetSeriesZPositionAndDepth(series, out depth, out positionZ); + return (depth / this.areaSceneDepth) * 100f; + } + + /// + /// Calculates area 3D scene depth depending on the number of isClustered + /// series and interval between points. + /// + /// Returns the depth of the chart area scene. + private float GetArea3DSceneDepth() + { + //*********************************************************** + //** Calculate the smallest interval between points + //*********************************************************** + + // Check if any series attached to the area is indexed + bool indexedSeries = ChartHelper.IndexedSeries(this.Common, this._series.ToArray()); + + // Smallest interval series + Series smallestIntervalSeries = null; + if(this._series.Count > 0) + { + smallestIntervalSeries = this.Common.DataManager.Series[(string)this._series[0]]; + } + + // Get X axis + Axis xAxis = ((ChartArea)this).AxisX; + if(this._series.Count > 0) + { + Series firstSeries = this.Common.DataManager.Series[this._series[0]]; + if(firstSeries != null && firstSeries.XAxisType == AxisType.Secondary) + { + xAxis = ((ChartArea)this).AxisX2; + } + } + + // Get smallest interval between points (use interval 1 for indexed series) + double clusteredInterval = 1; + if(!indexedSeries) + { + bool sameInterval; + clusteredInterval = this.GetPointsInterval(this._series, xAxis.IsLogarithmic, xAxis.logarithmBase, false, out sameInterval, out smallestIntervalSeries); + } + + //*********************************************************** + //** Check if "DrawSideBySide" attribute is set. + //*********************************************************** + bool drawSideBySide = false; + if(smallestIntervalSeries != null) + { + drawSideBySide = Common.ChartTypeRegistry.GetChartType(smallestIntervalSeries.ChartTypeName).SideBySideSeries; + foreach(string seriesName in this._series) + { + if(this.Common.DataManager.Series[seriesName].IsCustomPropertySet(CustomPropertyName.DrawSideBySide)) + { + string attribValue = this.Common.DataManager.Series[seriesName][CustomPropertyName.DrawSideBySide]; + if(String.Compare(attribValue, "False", StringComparison.OrdinalIgnoreCase) == 0) + { + drawSideBySide = false; + } + else if(String.Compare(attribValue, "True", StringComparison.OrdinalIgnoreCase) == 0) + { + drawSideBySide = true; + } + else if (String.Compare(attribValue, "Auto", StringComparison.OrdinalIgnoreCase) == 0) + { + // Do nothing + } + else + { + throw (new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid)); + } + } + } + } + + // Get smallest interval cate----cal axis + Axis categoricalAxis = ((ChartArea)this).AxisX; + if(smallestIntervalSeries != null && smallestIntervalSeries.XAxisType == AxisType.Secondary) + { + categoricalAxis = ((ChartArea)this).AxisX2; + } + + //*********************************************************** + //** If series with the smallest interval is displayed + //** side-by-side - devide the interval by number of series + //** of the same chart type. + //*********************************************************** + double pointWidthSize = 0.8; + int seriesNumber = 1; + if(smallestIntervalSeries != null) + { + // Check if series is side-by-side + if(this.Area3DStyle.IsClustered && drawSideBySide) + { + // Count number of side-by-side series + seriesNumber = 0; + foreach(string seriesName in this._series) + { + // Get series object from name + Series curSeries = this.Common.DataManager.Series[seriesName]; + if(String.Compare(curSeries.ChartTypeName, smallestIntervalSeries.ChartTypeName, StringComparison.OrdinalIgnoreCase) == 0 ) + { + ++seriesNumber; + } + } + } + } + + + + //*********************************************************** + //** Stacked column and bar charts can be drawn side-by-side + //** using the StackGroupName custom properties. The code + //** checks if multiple groups are used how many of these + //** groups exsist. + //** + //** If isClustered mode enabled each stack group is drawn + //** using it's own cluster. + //*********************************************************** + if(smallestIntervalSeries != null && this.Area3DStyle.IsClustered) + { + // Check series support stack groups + if(Common.ChartTypeRegistry.GetChartType(smallestIntervalSeries.ChartTypeName).SupportStackedGroups) + { + // Calculate how many stack groups exsist + seriesNumber = 0; + ArrayList stackGroupNames = new ArrayList(); + foreach(string seriesName in this._series) + { + // Get series object from name + Series curSeries = this.Common.DataManager.Series[seriesName]; + if(String.Compare(curSeries.ChartTypeName, smallestIntervalSeries.ChartTypeName, StringComparison.OrdinalIgnoreCase) == 0 ) + { + string seriesStackGroupName = string.Empty; + if(curSeries.IsCustomPropertySet(CustomPropertyName.StackedGroupName)) + { + seriesStackGroupName = curSeries[CustomPropertyName.StackedGroupName]; + } + + // Add group name if it do not already exsist + if(!stackGroupNames.Contains(seriesStackGroupName)) + { + stackGroupNames.Add(seriesStackGroupName); + } + } + } + seriesNumber = stackGroupNames.Count; + } + } + + + + //*********************************************************** + //** Check if series provide custom value for point\gap depth + //*********************************************************** + _pointsDepth = clusteredInterval * pointWidthSize * this.Area3DStyle.PointDepth / 100.0; + _pointsDepth = categoricalAxis.GetPixelInterval(_pointsDepth); + if(smallestIntervalSeries != null) + { + _pointsDepth = smallestIntervalSeries.GetPointWidth( + this.Common.graph, + categoricalAxis, + clusteredInterval, + 0.8) / seriesNumber; + _pointsDepth *= this.Area3DStyle.PointDepth / 100.0; + } + _pointsGapDepth = (_pointsDepth * 0.8) * this.Area3DStyle.PointGapDepth / 100.0; + + // Get point depth and gap from series + if(smallestIntervalSeries != null) + { + smallestIntervalSeries.GetPointDepthAndGap( + this.Common.graph, + categoricalAxis, + ref _pointsDepth, + ref _pointsGapDepth); + } + + + //*********************************************************** + //** Calculate scene depth + //*********************************************************** + return (float)((_pointsGapDepth + _pointsDepth) * GetNumberOfClusters()); + } + + /// + /// Calculates the depth and Z position for specified series. + /// + /// Series object. + /// Returns series depth. + /// Returns series Z position. + internal void GetSeriesZPositionAndDepth(Series series, out float depth, out float positionZ) + { + // Check arguments + if (series == null) + throw new ArgumentNullException("series"); + + // Get series cluster index + int seriesIndex = GetSeriesClusterIndex(series); + + // Initialize the output parameters + depth = (float)_pointsDepth; + positionZ = (float)(_pointsGapDepth / 2.0 + (_pointsDepth + _pointsGapDepth) * seriesIndex); + } + + + + /// + /// Returns number of clusters on the Z axis. + /// + /// Number of clusters on the Z axis. + internal int GetNumberOfClusters() + { + if(this.seriesClusters == null) + { + // Lists that hold processed chart types and stacked groups + ArrayList processedChartTypes = new ArrayList(); + ArrayList processedStackedGroups = new ArrayList(); + + // Reset series cluster list + this.seriesClusters = new List>(); + + // Iterate through all series that belong to this chart area + int clusterIndex = -1; + foreach(string seriesName in this._series) + { + // Get series object by name + Series curSeries = this.Common.DataManager.Series[seriesName]; + + // Check if stacked chart type is using multiple groups that + // can be displayed in individual clusters + if(!this.Area3DStyle.IsClustered && + Common.ChartTypeRegistry.GetChartType(curSeries.ChartTypeName).SupportStackedGroups) + { + // Get group name + string stackGroupName = StackedColumnChart.GetSeriesStackGroupName(curSeries); + + // Check if group was already counted + if(processedStackedGroups.Contains(stackGroupName)) + { + // Find in which cluster this stacked group is located + bool found = false; + for(int index = 0; !found && index < this.seriesClusters.Count; index++) + { + foreach(string name in this.seriesClusters[index]) + { + // Get series object by name + Series ser = this.Common.DataManager.Series[name]; + if(stackGroupName == StackedColumnChart.GetSeriesStackGroupName(ser)) + { + clusterIndex = index; + found = true; + } + } + } + } + else + { + // Increase cluster index + clusterIndex = this.seriesClusters.Count; + + // Add processed group name + processedStackedGroups.Add(stackGroupName); + } + } + + + // Chech if series is displayed in the same cluster than other series + else if( Common.ChartTypeRegistry.GetChartType(curSeries.ChartTypeName).Stacked || + (this.Area3DStyle.IsClustered && Common.ChartTypeRegistry.GetChartType(curSeries.ChartTypeName).SideBySideSeries) ) + { + // Check if this chart type is already in the list + if(processedChartTypes.Contains(curSeries.ChartTypeName.ToUpper(System.Globalization.CultureInfo.InvariantCulture))) + { + // Find in which cluster this chart type is located + bool found = false; + for(int index = 0; !found && index < this.seriesClusters.Count; index++) + { + foreach(string name in this.seriesClusters[index]) + { + // Get series object by name + Series ser = this.Common.DataManager.Series[name]; + if(ser.ChartTypeName.ToUpper(System.Globalization.CultureInfo.InvariantCulture) == + curSeries.ChartTypeName.ToUpper(System.Globalization.CultureInfo.InvariantCulture)) + { + clusterIndex = index; + found = true; + } + } + } + } + else + { + // Increase cluster index + clusterIndex = this.seriesClusters.Count; + + // Add new chart type into the collection + processedChartTypes.Add(curSeries.ChartTypeName.ToUpper(System.Globalization.CultureInfo.InvariantCulture)); + } + } + else + { + // Create New cluster + clusterIndex = this.seriesClusters.Count; + } + + // Create an item in the cluster list that will hold all series names + if(this.seriesClusters.Count <= clusterIndex) + { + this.seriesClusters.Add(new List()); + } + + // Add series name into the current cluster + this.seriesClusters[clusterIndex].Add(seriesName); + } + } + + return this.seriesClusters.Count; + } + + /// + /// Get series cluster index. + /// + /// Series object. + /// Series cluster index. + internal int GetSeriesClusterIndex(Series series) + { + // Fill list of clusters + if(this.seriesClusters == null) + { + this.GetNumberOfClusters(); + } + + // Iterate through all clusters + for(int clusterIndex = 0; clusterIndex < this.seriesClusters.Count; clusterIndex++) + { + List seriesNames = this.seriesClusters[clusterIndex]; + + // Iterate through all series names + foreach(string seriesName in seriesNames) + { + if(seriesName == series.Name) + { + // Check if series are drawn in reversed order + if(this._reverseSeriesOrder) + { + clusterIndex = (this.seriesClusters.Count - 1) - clusterIndex; + } + return clusterIndex; + } + } + } + return 0; + } + + + + #endregion + + #region 3D Scene helper methods + + /// + /// This method is used to calculate estimated scene + /// depth. Regular scene depth method can not be used + /// because Plot area position is zero. Instead, Chart + /// area position is used to find depth of the scene. + /// Algorithm which draws axis labels will decide what + /// should be size and position of plotting area. + /// + /// Returns estimated scene depth + private float GetEstimatedSceneDepth() + { + float sceneDepth; + + ChartArea area = (ChartArea) this; + + + // Reset current list of clusters + this.seriesClusters = null; + + + ElementPosition plottingAreaRect = area.InnerPlotPosition; + + area.AxisX.PlotAreaPosition = area.Position; + area.AxisY.PlotAreaPosition = area.Position; + area.AxisX2.PlotAreaPosition = area.Position; + area.AxisY2.PlotAreaPosition = area.Position; + + sceneDepth = GetArea3DSceneDepth(); + + area.AxisX.PlotAreaPosition = plottingAreaRect; + area.AxisY.PlotAreaPosition = plottingAreaRect; + area.AxisX2.PlotAreaPosition = plottingAreaRect; + area.AxisY2.PlotAreaPosition = plottingAreaRect; + + return sceneDepth; + } + + /// + /// Estimate Interval for 3D Charts. When scene is rotated the + /// number of labels should be changed. + /// + /// Chart graphics object. + internal void Estimate3DInterval(ChartGraphics graph ) + { + // Reference to the chart area class + ChartArea area = (ChartArea)this; + + // Calculate relative size of the wall + areaSceneWallWidth = graph.GetRelativeSize( new SizeF(this.Area3DStyle.WallWidth, this.Area3DStyle.WallWidth)); + + //*********************************************************** + //** Calculate the depth of the chart area scene + //*********************************************************** + areaSceneDepth = GetEstimatedSceneDepth(); + + RectangleF plottingRect = area.Position.ToRectangleF(); + + // Check if plot area position was recalculated. + // If not and non-auto InnerPlotPosition & Position were + // specified - do all needed calculations + if(PlotAreaPosition.Width == 0 && + PlotAreaPosition.Height == 0 && + !area.InnerPlotPosition.Auto + && !area.Position.Auto) + { + // Initialize plotting area position + + if(!area.InnerPlotPosition.Auto) + { + plottingRect.X += (area.Position.Width / 100F) * area.InnerPlotPosition.X; + plottingRect.Y += (area.Position.Height / 100F) * area.InnerPlotPosition.Y; + plottingRect.Width = (area.Position.Width / 100F) * area.InnerPlotPosition.Width; + plottingRect.Height = (area.Position.Height / 100F) * area.InnerPlotPosition.Height; + } + + } + + int yAngle = GetRealYAngle( ); + + //*********************************************************** + //** Initialize coordinate transformation matrix + //*********************************************************** + Matrix3D intervalMatrix3D = new Matrix3D(); + intervalMatrix3D.Initialize( + plottingRect, + areaSceneDepth, + this.Area3DStyle.Inclination, + yAngle, + this.Area3DStyle.Perspective, + this.Area3DStyle.IsRightAngleAxes); + bool notUsed; + float zPosition; + double size; + + Point3D [] points = new Point3D[8]; + + if( area.switchValueAxes ) + { + + // X Axis + zPosition = axisX.GetMarksZPosition( out notUsed ); + + points[0] = new Point3D( plottingRect.X, plottingRect.Y, zPosition ); + points[1] = new Point3D( plottingRect.X, plottingRect.Bottom, zPosition ); + + // Y Axis + zPosition = axisY.GetMarksZPosition( out notUsed ); + + points[2] = new Point3D( plottingRect.X, plottingRect.Bottom, zPosition ); + points[3] = new Point3D( plottingRect.Right, plottingRect.Bottom, zPosition ); + + // X2 Axis + zPosition = axisX2.GetMarksZPosition( out notUsed ); + + points[4] = new Point3D( plottingRect.X, plottingRect.Y, zPosition ); + points[5] = new Point3D( plottingRect.X, plottingRect.Bottom, zPosition ); + + // Y2 Axis + zPosition = axisY2.GetMarksZPosition( out notUsed ); + + points[6] = new Point3D( plottingRect.X, plottingRect.Y, zPosition ); + points[7] = new Point3D( plottingRect.Right, plottingRect.Y, zPosition ); + } + else + { + // X Axis + zPosition = axisX.GetMarksZPosition( out notUsed ); + + points[0] = new Point3D( plottingRect.X, plottingRect.Bottom, zPosition ); + points[1] = new Point3D( plottingRect.Right, plottingRect.Bottom, zPosition ); + + // Y Axis + zPosition = axisY.GetMarksZPosition( out notUsed ); + + points[2] = new Point3D( plottingRect.X, plottingRect.Y, zPosition ); + points[3] = new Point3D( plottingRect.X, plottingRect.Bottom, zPosition ); + + // X2 Axis + zPosition = axisX2.GetMarksZPosition( out notUsed ); + + points[4] = new Point3D( plottingRect.X, plottingRect.Y, zPosition ); + points[5] = new Point3D( plottingRect.Right, plottingRect.Y, zPosition ); + + // Y2 Axis + zPosition = axisY2.GetMarksZPosition( out notUsed ); + + points[6] = new Point3D( plottingRect.X, plottingRect.Y, zPosition ); + points[7] = new Point3D( plottingRect.X, plottingRect.Bottom, zPosition ); + } + + // Crossing has to be reset because interval and + // sometimes minimum and maximum are changed. + foreach( Axis axis in area.Axes ) + { + axis.crossing = axis.tempCrossing; + } + + // Transform all points + intervalMatrix3D.TransformPoints( points ); + + int axisIndx = 0; + foreach( Axis axis in area.Axes ) + { + // Find size of projected axis + size = Math.Sqrt( + ( points[axisIndx].X - points[axisIndx+1].X ) * ( points[axisIndx].X - points[axisIndx+1].X ) + + ( points[axisIndx].Y - points[axisIndx+1].Y ) * ( points[axisIndx].Y - points[axisIndx+1].Y ) ); + + // At the beginning plotting area chart is not calculated because + // algorithm for labels calculates plotting area position. To + // calculate labels position we need interval and interval + // need this correction. Because of that Chart area is used + // instead of plotting area position. If secondary label is + // enabled error for using chart area position instead of + // plotting area position is much bigger. This value + // corrects this error. + float plottingChartAreaCorrection = 1; + if( !area.switchValueAxes ) + { + plottingChartAreaCorrection = 0.5F; + } + + // Set correction for axis size + if( axis.AxisName == AxisName.X || axis.AxisName == AxisName.X2 ) + { + if( area.switchValueAxes ) + axis.interval3DCorrection = size / plottingRect.Height; + else + axis.interval3DCorrection = size / plottingRect.Width; + } + else + { + if( area.switchValueAxes ) + axis.interval3DCorrection = size / plottingRect.Width; + else + axis.interval3DCorrection = size / plottingRect.Height * plottingChartAreaCorrection; + } + + // There is a limit for correction + if( axis.interval3DCorrection < 0.15 ) + axis.interval3DCorrection = 0.15; + + // There is a limit for correction + if( axis.interval3DCorrection > 0.8 ) + axis.interval3DCorrection = 1.0; + + axisIndx += 2; + + } + } + + + /// + /// Calculates real Y angle from Y angle and reverseSeriesOrder field + /// + /// Real Y angle + internal int GetRealYAngle( ) + { + int yAngle; + + // Case from -90 to 90 + yAngle = this.Area3DStyle.Rotation; + + // Case from 90 to 180 + if( this._reverseSeriesOrder && this.Area3DStyle.Rotation >= 0 ) + yAngle = this.Area3DStyle.Rotation - 180; + + // Case from -90 to -180 + if( this._reverseSeriesOrder && this.Area3DStyle.Rotation <= 0 ) + yAngle = this.Area3DStyle.Rotation + 180; + + return yAngle; + } + + /// + /// Check if surface element should be drawn on the Back or Front layer. + /// + /// Surface name. + /// Back/front layer. + /// Indicates that element is on the edge (drawn on the back layer). + /// True if element should be drawn. + internal bool ShouldDrawOnSurface(SurfaceNames surfaceName, bool backLayer, bool onEdge) + { + // Check if surface element should be drawn on the Back or Front layer. + bool isVisible = ((this._visibleSurfaces & surfaceName) == surfaceName); + + // Elements on the edge are drawn on the back layer + if(onEdge) + { + return backLayer; + } + + return (backLayer == (!isVisible) ); + } + + /// + /// Indicates that data points in all series of this + /// chart area should be drawn in reversed order. + /// + /// True if series points should be drawn in reversed order. + internal bool DrawPointsInReverseOrder() + { + return (this.Area3DStyle.Rotation <= 0); + } + + /// + /// Checks if points should be drawn from sides to center. + /// + /// Which coordinate of COP (X, Y or Z) to test for surface overlapping + /// True if points should be drawn from sides to center. + internal bool DrawPointsToCenter(ref COPCoordinates coord) + { + bool result = false; + COPCoordinates resultCoordinates = 0; + + // Check only if perspective is set + if(this.Area3DStyle.Perspective != 0) + { + if( (coord & COPCoordinates.X) == COPCoordinates.X ) + { + // Only when Left & Right sides of plotting area are invisible + if ((this._visibleSurfaces & SurfaceNames.Left) == 0 && + (this._visibleSurfaces & SurfaceNames.Right) == 0) + { + result = true; + } + resultCoordinates = resultCoordinates | COPCoordinates.X; + } + if( (coord & COPCoordinates.Y) == COPCoordinates.Y ) + { + // Only when Top & Bottom sides of plotting area are invisible + if ((this._visibleSurfaces & SurfaceNames.Top) == 0 && + (this._visibleSurfaces & SurfaceNames.Bottom) == 0) + { + result = true; + } + resultCoordinates = resultCoordinates | COPCoordinates.Y; + } + if( (coord & COPCoordinates.Z) == COPCoordinates.Z ) + { + // Only when Front & Back sides of plotting area are invisible + if ((this._visibleSurfaces & SurfaceNames.Front) == 0 && + (this._visibleSurfaces & SurfaceNames.Back) == 0) + { + result = true; + } + resultCoordinates = resultCoordinates | COPCoordinates.Z; + } + } + + return result; + } + + /// + /// Checks if series should be drawn from sides to center. + /// + /// True if series should be drawn from sides to center. + internal bool DrawSeriesToCenter() + { + // Check only if perspective is set + if(this.Area3DStyle.Perspective != 0) + { + // Only when Left & Right sides of plotting area are invisible + if ((this._visibleSurfaces & SurfaceNames.Front) == 0 && + (this._visibleSurfaces & SurfaceNames.Back) == 0) + { + return true; + } + } + + return false; + } + + #endregion + + #region 3D Series drawing and selection methods + + /// + /// Draws 3D series in the chart area. + /// + /// Chart graphics object. + internal void PaintChartSeries3D( ChartGraphics graph ) + { + // Reference to the chart area object + ChartArea area = (ChartArea)this; + + // Get order of series drawing + List seriesDrawingOrder = GetSeriesDrawingOrder(_reverseSeriesOrder); + + // Loop through all series in the order of drawing + IChartType type; + foreach( object seriesObj in seriesDrawingOrder) + { + Series series = (Series)seriesObj; + type = Common.ChartTypeRegistry.GetChartType(series.ChartTypeName); + type.Paint( graph, Common, area, series ); + } + } + + #endregion + + #region 3D Series & Points drawing order methods + + /// + /// Gets a list of series names that belong to the same 3D cluster. + /// + /// One of the series names that belongs to the cluster. + /// List of all series names that belong to the same cluster as specified series. + internal List GetClusterSeriesNames(string seriesName) + { + // Iterate through all clusters + foreach(List seriesNames in this.seriesClusters) + { + if(seriesNames.Contains(seriesName)) + { + return seriesNames; + } + } + return new List(); + } + + /// + /// Gets the series list in drawing order. + /// + /// Series order should be reversed because of the Y axis angle. + /// Gets the series list in drawing order. + private List GetSeriesDrawingOrder(bool reverseSeriesOrder) + { + // Create list of series + List seriesList = new List(); + + // Iterate through all clusters + foreach(List seriesNames in this.seriesClusters) + { + // Make sure there is at least one series + if(seriesNames.Count > 0) + { + // Get first series object in the current cluster + Series series = Common.DataManager.Series[seriesNames[0]]; + + // Add series into the drawing list + seriesList.Add(series); + } + } + + // Reversed series list + if(reverseSeriesOrder) + { + seriesList.Reverse(); + } + + // Check if series should be drawn from sides into the center + if(DrawSeriesToCenter() && + this.matrix3D.IsInitialized()) + { + // Get Z coordinate of Center Of Projection + Point3D areaProjectionCenter = new Point3D(float.NaN, float.NaN, float.NaN); + areaProjectionCenter = this.GetCenterOfProjection(COPCoordinates.Z); + if(!float.IsNaN(areaProjectionCenter.Z)) + { + // Loop through all series + for(int seriesIndex = 0; seriesIndex < seriesList.Count; seriesIndex++) + { + // Check if series is not empty + if(((Series)seriesList[seriesIndex]).Points.Count == 0) + { + continue; + } + + // Get series Z position + float seriesDepth, seriesZPosition; + this.GetSeriesZPositionAndDepth((Series)seriesList[seriesIndex], out seriesDepth, out seriesZPosition); + + // Check if series passes the Z coordinate of Center of Projection + if(seriesZPosition >= areaProjectionCenter.Z) + { + // Reversed all series order staring from previous series + --seriesIndex; + if(seriesIndex < 0) + seriesIndex = 0; + seriesList.Reverse(seriesIndex, seriesList.Count - seriesIndex); + break; + } + } + } + } + + return seriesList; + } + + + /// + /// Gets number of stack groups in specified array of series names. + /// + /// Array of series names. + /// Number of stack groups. One by default. + private int GetNumberOfStackGroups(IList seriesNamesList) + { + this._stackGroupNames = new ArrayList(); + foreach( object seriesName in seriesNamesList ) + { + // Get series object + Series ser = this.Common.DataManager.Series[(string)seriesName]; + + // Get stack group name from the series + string stackGroupName = string.Empty; + if(ser.IsCustomPropertySet(CustomPropertyName.StackedGroupName)) + { + stackGroupName = ser[CustomPropertyName.StackedGroupName]; + } + + // Add group name if it do not already exsist + if(!this._stackGroupNames.Contains(stackGroupName)) + { + this._stackGroupNames.Add(stackGroupName); + } + } + + return this._stackGroupNames.Count; + } + + /// + /// Gets index of the series stack group. + /// + /// Series to get the index for. + /// Group name this series belongs to. + /// Index of series stack group. + internal int GetSeriesStackGroupIndex(Series series, ref string stackGroupName) + { + stackGroupName = string.Empty; + if(this._stackGroupNames != null) + { + // Get stack group name from the series + if(series.IsCustomPropertySet(CustomPropertyName.StackedGroupName)) + { + stackGroupName = series[CustomPropertyName.StackedGroupName]; + } + return this._stackGroupNames.IndexOf(stackGroupName); + } + return 0; + } + + + + /// + /// Determine the order of points drawing from one or several series of the same type. + /// + /// List of series names. + /// Chart type. + /// If True selection mode is active (points order should be reversed). + /// Which coordinate of COP (X, Y or Z) to test for surface overlapping + /// Points comparer class. Can be Null. + /// Index of the main Y value. + /// Series should be drawn side by side. + /// Array list of points in drawing order. + internal ArrayList GetDataPointDrawingOrder( + List seriesNamesList, + IChartType chartType, + bool selection, + COPCoordinates coord, + IComparer comparer, + int mainYValueIndex, + bool sideBySide) + { + ChartArea area = (ChartArea)this; + + // Array of points in all series + ArrayList pointsList = new ArrayList(); + + //************************************************************ + //** Analyse input series + //************************************************************ + + // Find the number of data series for side-by-side drawing + double numOfSeries = 1; + if(area.Area3DStyle.IsClustered && !chartType.Stacked && sideBySide) + { + numOfSeries = seriesNamesList.Count; + } + + + // Check stacked series group names + if(chartType.SupportStackedGroups) + { + // Fill the list of group names and get the number of unique groups + int numberOfGroups = this.GetNumberOfStackGroups(seriesNamesList); + + // If series are not isClustered set series number to the stacked group number + if(this.Area3DStyle.IsClustered && + seriesNamesList.Count > 0) + { + numOfSeries = numberOfGroups; + } + } + + + // Check if chart series are indexed + bool indexedSeries = ChartHelper.IndexedSeries(this.Common, seriesNamesList.ToArray()); + + //************************************************************ + //** Loop through all series and fill array of points + //************************************************************ + int seriesIndx = 0; + foreach( object seriesName in seriesNamesList ) + { + // Get series object + Series ser = this.Common.DataManager.Series[(string)seriesName]; + + + // Check if stacked groups present + if(chartType.SupportStackedGroups && + this._stackGroupNames != null) + { + // Get index of the series using stacked group + string groupName = string.Empty; + seriesIndx = this.GetSeriesStackGroupIndex(ser, ref groupName); + + // Set current group name + StackedColumnChart stackedColumnChart = chartType as StackedColumnChart; + if (stackedColumnChart != null) + { + stackedColumnChart.currentStackGroup = groupName; + } + else + { + StackedBarChart stackedBarChart = chartType as StackedBarChart; + if (stackedBarChart != null) + { + stackedBarChart.currentStackGroup = groupName; + } + } + } + + + // Set active vertical/horizontal axis and their max/min values + Axis vAxis = (ser.YAxisType == AxisType.Primary) ? area.AxisY : area.AxisY2; + Axis hAxis = (ser.XAxisType == AxisType.Primary) ? area.AxisX : area.AxisX2; + + // Get points interval: + // - set interval to 1 for indexed series + // - if points are not equaly spaced, the minimum interval between points is selected. + // - if points have same interval bars do not overlap each other. + bool sameInterval = true; + double interval = 1; + if(!indexedSeries) + { + interval = area.GetPointsInterval( seriesNamesList, hAxis.IsLogarithmic, hAxis.logarithmBase, true, out sameInterval ); + } + + // Get column width + double width = ser.GetPointWidth(area.Common.graph, hAxis, interval, 0.8) / numOfSeries; + + // Get series depth and Z position + float seriesDepth, seriesZPosition; + this.GetSeriesZPositionAndDepth(ser, out seriesDepth, out seriesZPosition); + + //************************************************************ + //** Loop through all points in series + //************************************************************ + int index = 0; + foreach( DataPoint point in ser.Points ) + { + // Increase point index + index++; + + // Set x position + double xCenterVal; + double xPosition; + if( indexedSeries ) + { + // The formula for position is based on a distance + //from the grid line or nPoints position. + xPosition = hAxis.GetPosition( (double)index ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width; + xCenterVal = hAxis.GetPosition( (double)index ); + + } + else if( sameInterval ) + { + xPosition = hAxis.GetPosition( point.XValue ) - width * ((double) numOfSeries) / 2.0 + width/2 + seriesIndx * width; + xCenterVal = hAxis.GetPosition( point.XValue ); + } + else + { + xPosition = hAxis.GetPosition( point.XValue ); + xCenterVal = hAxis.GetPosition( point.XValue ); + } + + + //************************************************************ + //** Create and add new DataPoint3D object + //************************************************************ + DataPoint3D pointEx = new DataPoint3D(); + pointEx.indexedSeries = indexedSeries; + pointEx.dataPoint = point; + pointEx.index = index; + pointEx.xPosition = xPosition; + pointEx.xCenterVal = xCenterVal; + pointEx.width = ser.GetPointWidth(area.Common.graph, hAxis, interval, 0.8) / numOfSeries; + pointEx.depth = seriesDepth; + pointEx.zPosition = seriesZPosition; + + // Set Y value and height + double yValue = chartType.GetYValue(Common, area, ser, point, index - 1, mainYValueIndex); + if (point.IsEmpty && Double.IsNaN(yValue)) + { + yValue = 0.0; + } + pointEx.yPosition = vAxis.GetPosition(yValue); + pointEx.height = vAxis.GetPosition(yValue - chartType.GetYValue(Common, area, ser, point, index - 1, -1)); + + + pointsList.Add(pointEx); + } + + // Data series index + if(numOfSeries > 1 && sideBySide) + { + seriesIndx++; + } + } + + //************************************************************ + //** Sort points in drawing order + //************************************************************ + if(comparer == null) + { + comparer = new PointsDrawingOrderComparer((ChartArea)this, selection, coord); + } + pointsList.Sort(comparer); + + return pointsList; + } + + #endregion + + #region Points drawing order comparer class + + /// + /// Used to compare points in array and sort them by drawing order. + /// + internal class PointsDrawingOrderComparer : IComparer + { + /// + /// Chart area object reference. + /// + private ChartArea _area = null; + + /// + /// Area X position where visible sides are switched. + /// + private Point3D _areaProjectionCenter = new Point3D(float.NaN, float.NaN, float.NaN); + + /// + /// Selection mode. Points order should be reversed. + /// + private bool _selection = false; + + /// + /// Public constructor. + /// + /// Chart area. + /// Selection indicator. + /// Which coordinate of COP (X, Y or Z) to test for surface overlapping + public PointsDrawingOrderComparer(ChartArea area, bool selection, COPCoordinates coord) + { + this._area = area; + this._selection = selection; + + // Get center of projection + if(area.DrawPointsToCenter(ref coord)) + { + _areaProjectionCenter = area.GetCenterOfProjection(coord); + } + } + + /// + /// Comparer method. + /// + /// First object. + /// Second object. + /// Comparison result. + public int Compare(object o1, object o2) + { + DataPoint3D point1 = (DataPoint3D) o1; + DataPoint3D point2 = (DataPoint3D) o2; + + int result = 0; + if(point1.xPosition < point2.xPosition) + { + result = -1; + } + else if(point1.xPosition > point2.xPosition) + { + result = 1; + } + else + { + + // If X coordinate is the same - filter by Y coordinate + if(point1.yPosition < point2.yPosition) + { + result = 1; + } + else if(point1.yPosition > point2.yPosition) + { + result = -1; + } + + // Order points from sides to center + if(!float.IsNaN(_areaProjectionCenter.Y)) + { + double yMin1 = Math.Min(point1.yPosition, point1.height); + double yMax1 = Math.Max(point1.yPosition, point1.height); + double yMin2 = Math.Min(point2.yPosition, point2.height); + double yMax2 = Math.Max(point2.yPosition, point2.height); + + if(_area.IsBottomSceneWallVisible()) + { + if( yMin1 <= _areaProjectionCenter.Y && yMin2 <= _areaProjectionCenter.Y ) + { + result *= -1; + } + else if( yMin1 <= _areaProjectionCenter.Y) + { + result = 1; + } + + } + else + { + + if( yMax1 >= _areaProjectionCenter.Y && yMax2 >= _areaProjectionCenter.Y ) + { + result *= 1; + } + else if( yMax1 >= _areaProjectionCenter.Y) + { + result = 1; + } + else + { + result *= -1; + } + } + } + + // Reversed order if looking from the bottom + else if(!_area.IsBottomSceneWallVisible()) + { + result *= -1; + } + + } + + if(point1.xPosition != point2.xPosition) + { + // Order points from sides to center + if (!float.IsNaN(_areaProjectionCenter.X)) + { + if ((point1.xPosition + point1.width / 2f) >= _areaProjectionCenter.X && + (point2.xPosition + point2.width / 2f) >= _areaProjectionCenter.X) + { + result *= -1; + } + } + + // Reversed order of points by X value + else if (_area.DrawPointsInReverseOrder()) + { + result *= -1; + } + } + + return (_selection) ? -result : result; + } + } + +#endregion + + #region Center of Projection calculation methods + + /// + /// Returns one or many (X, Y, Z) coordinates of the center of projection. + /// + /// Defines coordinates to return. + /// Center of projection. Value can be set to float.NaN if not defined or outside plotting area. + internal Point3D GetCenterOfProjection(COPCoordinates coord) + { + // Define 2 points in the opposite corners of the plotting area + Point3D[] points = new Point3D[2]; + points[0] = new Point3D(this.PlotAreaPosition.X, this.PlotAreaPosition.Bottom, 0f); + points[1] = new Point3D(this.PlotAreaPosition.Right, this.PlotAreaPosition.Y, this.areaSceneDepth); + + // Check if surfaces (points 1 & 2) has same orientation + bool xSameOrientation, ySameOrientation, zSameOrientation; + CheckSurfaceOrientation( + coord, + points[0], + points[1], + out xSameOrientation, + out ySameOrientation, + out zSameOrientation); + + // If orientation of all surfaces is the same - no futher processing is required (COP is outside of plotting area) + Point3D resultPoint = new Point3D( + (xSameOrientation) ? float.NaN : 0f, + (ySameOrientation) ? float.NaN : 0f, + (zSameOrientation) ? float.NaN : 0f); + if( ( ((coord & COPCoordinates.X) != COPCoordinates.X) || xSameOrientation ) && + ( ((coord & COPCoordinates.Y) != COPCoordinates.Y) || ySameOrientation ) && + ( ((coord & COPCoordinates.Z) != COPCoordinates.Z) || zSameOrientation ) ) + { + return resultPoint; + } + + // Calculate the smallest interval (0.5 pixels) in relative coordinates + SizeF interval = new SizeF(0.5f, 0.5f); +#if WINFORMS_CONTROL + interval.Width = interval.Width * 100F / ((float)(this.Common.Chart.Width - 1)); + interval.Height = interval.Height * 100F / ((float)(this.Common.Chart.Height - 1)); +#else + interval.Width = interval.Width * 100F / ((float)(this.Common.Chart.Width.Value - 1)); + interval.Height = interval.Height * 100F / ((float)(this.Common.Chart.Height.Value - 1)); +#endif //#if WINFORMS_CONTROL + + // Find middle point and check it's surface orientation + bool doneFlag = false; + while(!doneFlag) + { + // Find middle point + Point3D middlePoint = new Point3D( + (points[0].X + points[1].X) / 2f, + (points[0].Y + points[1].Y) / 2f, + (points[0].Z + points[1].Z) / 2f); + + // Check if surfaces (points 1 & middle) has same orientation + CheckSurfaceOrientation( + coord, + points[0], + middlePoint, + out xSameOrientation, + out ySameOrientation, + out zSameOrientation); + + // Calculate points 1 & 2 depending on surface orientation of the middle point + points[(xSameOrientation) ? 0 : 1].X = middlePoint.X; + points[(ySameOrientation) ? 0 : 1].Y = middlePoint.Y; + points[(zSameOrientation) ? 0 : 1].Z = middlePoint.Z; + + // Check if no more calculations required + doneFlag = true; + if( (coord & COPCoordinates.X) == COPCoordinates.X && + Math.Abs(points[1].X - points[0].X) >= interval.Width) + { + doneFlag = false; + } + if( (coord & COPCoordinates.Y) == COPCoordinates.Y && + Math.Abs(points[1].Y - points[0].Y) >= interval.Height) + { + doneFlag = false; + } + if( (coord & COPCoordinates.Z) == COPCoordinates.Z && + Math.Abs(points[1].Z - points[0].Z) >= interval.Width) + { + doneFlag = false; + } + } + + // Calculate result point + if(!float.IsNaN(resultPoint.X)) + resultPoint.X = (points[0].X + points[1].X) / 2f; + if(!float.IsNaN(resultPoint.Y)) + resultPoint.Y = (points[0].Y + points[1].Y) / 2f; + if(!float.IsNaN(resultPoint.Z)) + resultPoint.Z = (points[0].Z + points[1].Z) / 2f; + return resultPoint; + } + + /// + /// Checks orientations of two normal surfaces for each coordinate X, Y and Z. + /// + /// Defines coordinates to return. + /// First point. + /// Second point. + /// X surfaces orientation is the same. + /// Y surfaces orientation is the same. + /// Z surfaces orientation is the same. + private void CheckSurfaceOrientation( + COPCoordinates coord, + Point3D point1, + Point3D point2, + out bool xSameOrientation, + out bool ySameOrientation, + out bool zSameOrientation) + { + Point3D[] pointsSurface = new Point3D[3]; + bool surf1, surf2; + + // Initialize returned values + xSameOrientation = true; + ySameOrientation = true; + zSameOrientation = true; + + // Check X axis coordinates (ledt & right surfaces) + if( (coord & COPCoordinates.X) == COPCoordinates.X ) + { + // Define Left surface coordinates, transform them and check visibility + pointsSurface[0] = new Point3D(point1.X, this.PlotAreaPosition.Y, 0f); + pointsSurface[1] = new Point3D(point1.X, this.PlotAreaPosition.Bottom, 0f); + pointsSurface[2] = new Point3D(point1.X, this.PlotAreaPosition.Bottom, this.areaSceneDepth); + this.matrix3D.TransformPoints( pointsSurface ); + surf1 = ChartGraphics.IsSurfaceVisible(pointsSurface[0], pointsSurface[1], pointsSurface[2]); + + // Define Right surface coordinates, transform them and check visibility + pointsSurface[0] = new Point3D(point2.X, this.PlotAreaPosition.Y, 0f); + pointsSurface[1] = new Point3D(point2.X, this.PlotAreaPosition.Bottom, 0f); + pointsSurface[2] = new Point3D(point2.X, this.PlotAreaPosition.Bottom, this.areaSceneDepth); + this.matrix3D.TransformPoints( pointsSurface ); + surf2 = ChartGraphics.IsSurfaceVisible(pointsSurface[0], pointsSurface[1], pointsSurface[2]); + + // Check if surfaces have same visibility + xSameOrientation = (surf1 == surf2); + } + + // Check Y axis coordinates (top & bottom surfaces) + if( (coord & COPCoordinates.Y) == COPCoordinates.Y ) + { + // Define Bottom surface coordinates, transform them and check visibility + pointsSurface[0] = new Point3D(this.PlotAreaPosition.X, point1.Y, this.areaSceneDepth); + pointsSurface[1] = new Point3D(this.PlotAreaPosition.X, point1.Y, 0f); + pointsSurface[2] = new Point3D(this.PlotAreaPosition.Right, point1.Y, 0f); + this.matrix3D.TransformPoints( pointsSurface ); + surf1 = ChartGraphics.IsSurfaceVisible(pointsSurface[0], pointsSurface[1], pointsSurface[2]); + + // Define Top surface coordinates, transform them and check visibility + pointsSurface[0] = new Point3D(this.PlotAreaPosition.X, point2.Y, this.areaSceneDepth); + pointsSurface[1] = new Point3D(this.PlotAreaPosition.X, point2.Y, 0f); + pointsSurface[2] = new Point3D(this.PlotAreaPosition.Right, point2.Y, 0f); + this.matrix3D.TransformPoints( pointsSurface ); + surf2 = ChartGraphics.IsSurfaceVisible(pointsSurface[0], pointsSurface[1], pointsSurface[2]); + + // Check if surfaces have same visibility + ySameOrientation = (surf1 == surf2); + } + + // Check Y axis coordinates (front & back surfaces) + if( (coord & COPCoordinates.Z) == COPCoordinates.Z ) + { + // Define Front surface coordinates, transform them and check visibility + pointsSurface[0] = new Point3D(this.PlotAreaPosition.X, this.PlotAreaPosition.Y, point1.Z); + pointsSurface[1] = new Point3D(this.PlotAreaPosition.X, this.PlotAreaPosition.Bottom, point1.Z); + pointsSurface[2] = new Point3D(this.PlotAreaPosition.Right, this.PlotAreaPosition.Bottom, point1.Z); + this.matrix3D.TransformPoints( pointsSurface ); + surf1 = ChartGraphics.IsSurfaceVisible(pointsSurface[0], pointsSurface[1], pointsSurface[2]); + + // Define Back surface coordinates, transform them and check visibility + pointsSurface[0] = new Point3D(this.PlotAreaPosition.X, this.PlotAreaPosition.Y, point2.Z); + pointsSurface[1] = new Point3D(this.PlotAreaPosition.X, this.PlotAreaPosition.Bottom, point2.Z); + pointsSurface[2] = new Point3D(this.PlotAreaPosition.Right, this.PlotAreaPosition.Bottom, point2.Z); + this.matrix3D.TransformPoints( pointsSurface ); + surf2 = ChartGraphics.IsSurfaceVisible(pointsSurface[0], pointsSurface[1], pointsSurface[2]); + + // Check if surfaces have same visibility + zSameOrientation = (surf1 == surf2); + } + } +#endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/ChartAreaAxes.cs b/System.Web.DataVisualization/Common/General/ChartAreaAxes.cs new file mode 100644 index 000000000..66f15e50c --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ChartAreaAxes.cs @@ -0,0 +1,1986 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartAreaAxes.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ChartAreaAxes +// +// Purpose: ChartAreaAxes is base class of Chart Area class. +// This class searches for all series, which belongs +// to this chart area and sets axes minimum and +// maximum values using data. This class also checks +// for chart types, which belong to this chart area +// and prepare axis scale according to them (Stacked +// chart types have different max and min values). +// This class recognizes indexed values and prepares +// axes for them. +// +// Reviewed: GS - Jul 31, 2002 +// AG - August 7, 2002 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Generic; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + /// + /// ChartAreaAxes class represents axes (X, Y, X2 and Y2) in the chart area. + /// It contains methods that collect statistical information on the series data and + /// other axes related methods. + /// + public partial class ChartArea + { + #region Fields + + // Axes which belong to this Chart Area + internal Axis axisY = null; + internal Axis axisX = null; + internal Axis axisX2 = null; + internal Axis axisY2 = null; + + // Array of series which belong to this chart area + private List _series = new List(); + + // Array of chart types which belong to this chart area + internal ArrayList chartTypes = new ArrayList(); + + /// + /// List of series names that last interval numbers where cashed for + /// + private string _intervalSeriesList = ""; + + // Minimum interval between two data points for all + // series which belong to this chart area. + internal double intervalData = double.NaN; + + // Minimum interval between two data points for all + // series which belong to this chart area. + // IsLogarithmic version of the interval. + internal double intervalLogData = double.NaN; + + // Series with minimum interval between two data points for all + // series which belong to this chart area. + private Series _intervalSeries = null; + + // Indicates that points are located through equal X intervals + internal bool intervalSameSize = false; + + // Indicates that points alignment checked + internal bool diffIntervalAlignmentChecked = false; + + // Chart Area contains stacked chart types + internal bool stacked = false; + + // Chart type with two y values used for scale ( bubble chart type ) + internal bool secondYScale = false; + + // The X and Y axes are switched + internal bool switchValueAxes = false; + + // True for all chart types, which have axes. False for doughnut and pie chart. + internal bool requireAxes = true; + + // Indicates that chart area has circular shape (like in radar or polar chart) + internal bool chartAreaIsCurcular = false; + + // Chart Area contains 100 % stacked chart types + internal bool hundredPercent = false; + + // Chart Area contains 100 % stacked chart types + internal bool hundredPercentNegative = false; + + #endregion + + #region Internal properties + + /// + /// True if sub axis supported on this chart area + /// + internal bool IsSubAxesSupported + { + get + { + if(((ChartArea)this).Area3DStyle.Enable3D || + ((ChartArea)this).chartAreaIsCurcular) + { + return false; + } + return true; + } + } + + /// + /// Data series which belongs to this chart area. + /// + internal List Series + { + get + { + return _series; + } + } + + /// + /// Chart types which belongs to this chart area. + /// + internal ArrayList ChartTypes + { + get + { + return chartTypes; + } + } + + #endregion + + #region Methods + + /// + /// Gets main or sub axis from the chart area. + /// + /// Axis name. NOTE: This parameter only defines X or Y axis. + /// Second axisType parameter is used to select primary or secondary axis. + /// Axis type. + /// Sub-axis name or empty string. + /// Main or sub axis of the chart area. + internal Axis GetAxis(AxisName axisName, AxisType axisType, string subAxisName) + { + // Ignore sub axis in 3D + if( ((ChartArea)this).Area3DStyle.Enable3D) + { + subAxisName = string.Empty; + } + + if(axisName == AxisName.X || axisName == AxisName.X2) + { + if(axisType == AxisType.Primary) + { + return ((ChartArea)this).AxisX.GetSubAxis(subAxisName); + } + return ((ChartArea)this).AxisX2.GetSubAxis(subAxisName); + } + else + { + if(axisType == AxisType.Primary) + { + return ((ChartArea)this).AxisY.GetSubAxis(subAxisName); + } + return ((ChartArea)this).AxisY2.GetSubAxis(subAxisName); + } + } + + /// + /// Sets default axis values for all different chart type + /// groups. Chart type groups are sets of chart types. + /// + internal void SetDefaultAxesValues( ) + { + // The X and Y axes are switched ( Bar chart, stacked bar ... ) + if( switchValueAxes ) + { + // Set axis positions + axisY.AxisPosition = AxisPosition.Bottom; + axisX.AxisPosition = AxisPosition.Left; + axisX2.AxisPosition = AxisPosition.Right; + axisY2.AxisPosition = AxisPosition.Top; + } + else + { + // Set axis positions + axisY.AxisPosition = AxisPosition.Left; + axisX.AxisPosition = AxisPosition.Bottom; + axisX2.AxisPosition = AxisPosition.Top; + axisY2.AxisPosition = AxisPosition.Right; + } + + // Reset opposite Axes field. This cashing + // value is used for optimization. + foreach( Axis axisItem in ((ChartArea)this).Axes ) + { + axisItem.oppositeAxis = null; +#if SUBAXES + foreach( SubAxis subAxisItem in axisItem.SubAxes ) + { + subAxisItem.m_oppositeAxis = null; + } +#endif // SUBAXES + } + + // *********************** + // Primary X Axes + // *********************** + // Find the number of series which belong to this axis + if (this.chartAreaIsCurcular) + { + // Set axis Maximum/Minimum and Interval for circular chart + axisX.SetAutoMaximum(360.0); + axisX.SetAutoMinimum(0.0); + axisX.SetInterval = Math.Abs(axisX.maximum - axisX.minimum) / 12.0; + } + else + { + SetDefaultFromIndexesOrData(axisX, AxisType.Primary); + } + +#if SUBAXES + // *********************** + // Primary X Sub-Axes + // *********************** + foreach(SubAxis subAxis in axisX.SubAxes) + { + SetDefaultFromIndexesOrData(subAxis, AxisType.Primary); + } +#endif // SUBAXES + + // *********************** + // Secondary X Axes + // *********************** + SetDefaultFromIndexesOrData(axisX2, AxisType.Secondary); + +#if SUBAXES + // *********************** + // Secondary X Sub-Axes + // *********************** + foreach(SubAxis subAxis in axisX2.SubAxes) + { + SetDefaultFromIndexesOrData(subAxis, AxisType.Secondary); + } +#endif // SUBAXES + + // *********************** + // Primary Y axis + // *********************** + if( GetYAxesSeries( AxisType.Primary, string.Empty ).Count != 0 ) + { + // Find minimum and maximum from Y values. + SetDefaultFromData( axisY ); + axisY.EstimateAxis(); + } + +#if SUBAXES + // *********************** + // Primary Y Sub-Axes + // *********************** + foreach(SubAxis subAxis in axisY.SubAxes) + { + // Find the number of series which belong to this axis + if( GetYAxesSeries( AxisType.Primary, subAxis.SubAxisName ).Count != 0 ) + { + // Find minimum and maximum from Y values. + SetDefaultFromData( subAxis ); + subAxis.EstimateAxis(); + } + } +#endif // SUBAXES + + // *********************** + // Secondary Y axis + // *********************** + if( GetYAxesSeries( AxisType.Secondary, string.Empty ).Count != 0 ) + { + // Find minimum and maximum from Y values. + SetDefaultFromData( axisY2 ); + axisY2.EstimateAxis(); + } + +#if SUBAXES + // *********************** + // Secondary Y Sub-Axes + // *********************** + foreach(SubAxis subAxis in axisY2.SubAxes) + { + // Find the number of series which belong to this axis + if( GetYAxesSeries( AxisType.Secondary, subAxis.SubAxisName ).Count != 0 ) + { + // Find minimum and maximum from Y values. + SetDefaultFromData( subAxis ); + subAxis.EstimateAxis(); + } + } +#endif // SUBAXES + + // Sets axis position. Axis position depends + // on crossing and reversed value. + axisX.SetAxisPosition(); + axisX2.SetAxisPosition(); + axisY.SetAxisPosition(); + axisY2.SetAxisPosition(); + + // Enable axes, which are + // used in data series. + this.EnableAxes(); + + + + + // Get scale break segments + Axis[] axesYArray = new Axis[] { axisY, axisY2 }; + foreach(Axis currentAxis in axesYArray) + { + // Get automatic scale break segments + currentAxis.ScaleBreakStyle.GetAxisSegmentForScaleBreaks(currentAxis.ScaleSegments); + + // Make sure axis scale do not exceed segments scale + if(currentAxis.ScaleSegments.Count > 0) + { + // Save flag that scale segments are used + currentAxis.scaleSegmentsUsed = true; + + if(currentAxis.minimum < currentAxis.ScaleSegments[0].ScaleMinimum) + { + currentAxis.minimum = currentAxis.ScaleSegments[0].ScaleMinimum; + } + if(currentAxis.minimum > currentAxis.ScaleSegments[currentAxis.ScaleSegments.Count - 1].ScaleMaximum) + { + currentAxis.minimum = currentAxis.ScaleSegments[currentAxis.ScaleSegments.Count - 1].ScaleMaximum; + } + } + } + + + + bool useScaleSegments = false; + + // Fill Labels + Axis[] axesArray = new Axis[] { axisX, axisX2, axisY, axisY2 }; + foreach(Axis currentAxis in axesArray) + { + + useScaleSegments = (currentAxis.ScaleSegments.Count > 0); + + if(!useScaleSegments) + { + currentAxis.FillLabels(true); + } + + else + { + bool removeLabels = true; + int segmentIndex = 0; + foreach(AxisScaleSegment scaleSegment in currentAxis.ScaleSegments) + { + scaleSegment.SetTempAxisScaleAndInterval(); + + currentAxis.FillLabels(removeLabels); + removeLabels = false; + + scaleSegment.RestoreAxisScaleAndInterval(); + + // Remove last label for all segments except of the last + if(segmentIndex < (currentAxis.ScaleSegments.Count - 1) && + currentAxis.CustomLabels.Count > 0) + { + currentAxis.CustomLabels.RemoveAt(currentAxis.CustomLabels.Count - 1); + } + + ++segmentIndex; + } + } + + } + foreach (Axis currentAxis in axesArray) + { + currentAxis.PostFillLabels(); + } + } + + /// + /// Sets the axis defaults. + /// If the at least one of the series bound to this axis is Indexed then the defaults are set using the SetDefaultsFromIndexes(). + /// Otherwise the SetDefaultFromData() is used. + /// + /// Axis to process + /// Axis type + private void SetDefaultFromIndexesOrData(Axis axis, AxisType axisType) + { + //Get array of the series that are linked to this axis + List axisSeriesNames = GetXAxesSeries(axisType, axis.SubAxisName); + // VSTS: 196381 + // before this change: If we find one indexed series we will treat all series as indexed. + // after this change : We will assume that all series are indexed. + // If we find one non indexed series we will treat all series as non indexed. + bool indexedSeries = true; + // DT comments 1: + // If we have mix of indexed with non-indexed series + // enforce all indexed series as non-indexed; + // The result of mixed type of series will be more natural + // and easy to detect the problem - all datapoints of indexed + // series will be displayed on zero position. + //===================================== + // bool nonIndexedSeries = false; + //======================================= + //Loop through the series looking for a indexed one + foreach(string seriesName in axisSeriesNames) + { + // Get series + Series series = Common.DataManager.Series[seriesName]; + // Check if series is indexed + if (!ChartHelper.IndexedSeries(series)) + { + // found one nonindexed series - we will treat all series as non indexed. + indexedSeries = false; + break; + } + // DT comments 2 + //else + //{ + // nonIndexedSeries = true; + //} + } + + //DT comments 3 + //if (!indexedSeries && nonIndexedSeries) + //{ + // foreach (string seriesName in axisSeriesNames) + // { + // // Get series + // Series series = Common.DataManager.Series[seriesName]; + // series.xValuesZeros = false; + // } + //} + + if (indexedSeries) + { + if (axis.IsLogarithmic) + { + throw (new InvalidOperationException(SR.ExceptionChartAreaAxisScaleLogarithmicUnsuitable)); + } + //Set axis defaults from the indexed series + SetDefaultFromIndexes(axis); + //We are done... + return; + } + + // If haven't found any indexed series -> Set axis defaults from the series data + SetDefaultFromData(axis); + axis.EstimateAxis(); + } + + /// + /// Enable axes, which are + /// used in chart area data series. + /// + private void EnableAxes() + { + if( _series == null ) + { + return; + } + + bool activeX = false; + bool activeY = false; + bool activeX2 = false; + bool activeY2 = false; + + // Data series from this chart area + foreach( string ser in _series ) + { + Series dataSeries = Common.DataManager.Series[ ser ]; + + // X axes + if( dataSeries.XAxisType == AxisType.Primary ) + { + activeX = true; +#if SUBAXES + this.Activate( axisX, true, dataSeries.XSubAxisName ); +#else + this.Activate( axisX, true ); +#endif // SUBAXES + + } + else + { + activeX2 = true; +#if SUBAXES + this.Activate( axisX2, true, dataSeries.XSubAxisName ); +#else + this.Activate( axisX2, true ); +#endif // SUBAXES + } + // Y axes + if( dataSeries.YAxisType == AxisType.Primary ) + { + activeY = true; +#if SUBAXES + this.Activate( axisY, true, dataSeries.YSubAxisName ); +#else + this.Activate( axisY, true ); +#endif // SUBAXES + } + else + { + activeY2 = true; +#if SUBAXES + this.Activate( axisY2, true, dataSeries.YSubAxisName ); +#else + this.Activate( axisY2, true ); +#endif // SUBAXES + } + } + +#if SUBAXES + // Enable Axes + if(!activeX) + this.Activate( axisX, false, string.Empty ); + if(!activeY) + this.Activate( axisY, false, string.Empty ); + if(!activeX2) + this.Activate( axisX2, false, string.Empty ); + if(!activeY2) + this.Activate( axisY2, false, string.Empty ); +#else // SUBAXES + // Enable Axes + if(!activeX) + this.Activate( axisX, false); + if(!activeY) + this.Activate( axisY, false); + if(!activeX2) + this.Activate( axisX2, false); + if(!activeY2) + this.Activate( axisY2, false); +#endif // SUBAXES + } + +#if SUBAXES + + /// + /// Enable axis. + /// + /// Axis. + /// True if axis is active. + /// Sub axis name to activate. + private void Activate( Axis axis, bool active, string subAxisName ) + { + // Auto-Enable axis + if( axis.autoEnabled == true ) + { + axis.enabled = active; + } + + // Auto-Enable sub axes + if(subAxisName.Length > 0) + { + SubAxis subAxis = axis.SubAxes.FindByName(subAxisName); + if(subAxis != null) + { + if( subAxis.autoEnabled == true ) + { + subAxis.enabled = active; + } + } + } + } +#else + /// + /// Enable axis. + /// + /// Axis. + /// True if axis is active. + private void Activate( Axis axis, bool active ) + { + if( axis.autoEnabled == true ) + { + axis.enabled = active; + } + } +#endif // SUBAXES + + /// + /// Check if all data points from series in + /// this chart area are empty. + /// + /// True if all points are empty + bool AllEmptyPoints() + { + // Data series from this chart area + foreach( string seriesName in this._series ) + { + Series dataSeries = Common.DataManager.Series[ seriesName ]; + + // Data point loop + foreach( DataPoint point in dataSeries.Points ) + { + if( !point.IsEmpty ) + { + return false; + } + } + } + return true; + } + + /// + /// This method sets default minimum and maximum + /// values from values in the data manager. This + /// case is used if X values are not equal to 0 or IsXValueIndexed flag is set. + /// + /// Axis + private void SetDefaultFromData( Axis axis ) + { +#if SUBAXES + // Process all sub-axes + if(!axis.IsSubAxis) + { + foreach(SubAxis subAxis in axis.SubAxes) + { + this.SetDefaultFromData( subAxis ); + } + } +#endif // SUBAXES + + + // Used for scrolling with logarithmic axes. + if( !Double.IsNaN(axis.ScaleView.Position) && + !Double.IsNaN(axis.ScaleView.Size) && + !axis.refreshMinMaxFromData && + axis.IsLogarithmic ) + { + return; + } + + // Get minimum and maximum from data source + double autoMaximum; + double autoMinimum; + this.GetValuesFromData( axis, out autoMinimum, out autoMaximum ); + + // *************************************************** + // This part of code is used to add a margin to the + // axis and to set minimum value to zero if + // IsStartedFromZero property is used. There is special + // code for logarithmic scale, which will set minimum + // to one instead of zero. + // *************************************************** + // The minimum and maximum values from data manager don’t exist. + + if( axis.enabled && + ( (axis.AutoMaximum || double.IsNaN( axis.Maximum )) && (autoMaximum == Double.MaxValue || autoMaximum == Double.MinValue)) || + ( (axis.AutoMinimum || double.IsNaN( axis.Minimum )) && (autoMinimum == Double.MaxValue || autoMinimum == Double.MinValue )) ) + { + if( this.AllEmptyPoints() ) + { + // Supress exception and use predefined min & max + autoMaximum = 8.0; + autoMinimum = 1.0; + } + else + { + if(!this.Common.ChartPicture.SuppressExceptions) + { + throw (new InvalidOperationException(SR.ExceptionAxisMinimumMaximumInvalid)); + } + } + } + + // Axis margin used for zooming + axis.marginView = 0.0; + if( axis.margin == 100 && (axis.axisType == AxisName.X || axis.axisType == AxisName.X2) ) + { + axis.marginView = this.GetPointsInterval( false, 10 ); + } + + // If minimum and maximum are same margin always exist. + if( autoMaximum == autoMinimum && + axis.Maximum == axis.Minimum ) + { + axis.marginView = 1; + } + + // Do not make axis margine for logarithmic axes + if( axis.IsLogarithmic ) + { + axis.marginView = 0.0; + } + + // Adjust Maximum - Add a gap + if( axis.AutoMaximum ) + { + // Add a Gap for X axis + if( !axis.roundedXValues && ( axis.axisType == AxisName.X || axis.axisType == AxisName.X2 ) ) + { + axis.SetAutoMaximum( autoMaximum + axis.marginView ); + } + else + { + if( axis.isStartedFromZero && autoMaximum < 0 ) + { + axis.SetAutoMaximum( 0.0 ); + } + else + { + axis.SetAutoMaximum( autoMaximum ); + } + } + } + + // Adjust Minimum - make rounded values and add a gap + if( axis.AutoMinimum ) + { + // IsLogarithmic axis + if( axis.IsLogarithmic ) + { + if( autoMinimum < 1.0 ) + { + axis.SetAutoMinimum( autoMinimum ); + } + else if( axis.isStartedFromZero ) + { + axis.SetAutoMinimum( 1.0 ); + } + else + { + axis.SetAutoMinimum( autoMinimum ); + } + } + else + { + if( autoMinimum > 0.0 ) // If Auto calculated Minimum value is positive + { + // Adjust Minimum + if( !axis.roundedXValues && ( axis.axisType == AxisName.X || axis.axisType == AxisName.X2 ) ) + { + axis.SetAutoMinimum( autoMinimum - axis.marginView ); + } + // If start From Zero property is true 0 is always on the axis. + // NOTE: Not applicable if date-time values are drawn. Fixes issue #5644 + else if( axis.isStartedFromZero && + !this.SeriesDateTimeType( axis.axisType, axis.SubAxisName ) ) + { + axis.SetAutoMinimum( 0.0 ); + } + else + { + axis.SetAutoMinimum( autoMinimum ); + } + } + else // If Auto calculated Minimum value is non positive + { + if( axis.axisType == AxisName.X || axis.axisType == AxisName.X2 ) + { + axis.SetAutoMinimum( autoMinimum - axis.marginView ); + } + else + { + // If start From Zero property is true 0 is always on the axis. + axis.SetAutoMinimum( autoMinimum ); + } + } + } + } + + // If maximum or minimum are not auto set value to non logarithmic + if( axis.IsLogarithmic && axis.logarithmicConvertedToLinear ) + { + if( !axis.AutoMinimum ) + { + axis.minimum = axis.logarithmicMinimum; + } + + if( !axis.AutoMaximum ) + { + axis.maximum = axis.logarithmicMaximum; + } + // Min and max will take real values again if scale is logarithmic. + axis.logarithmicConvertedToLinear = false; + } + + // Check if Minimum == Maximum + if(this.Common.ChartPicture.SuppressExceptions && + axis.maximum == axis.minimum) + { + axis.minimum = axis.maximum; + axis.maximum = axis.minimum + 1.0; + } + } + + /// + /// This method checks if all series in the chart area have “integer type” + /// for specified axes, which means int, uint, long and ulong. + /// + /// Name of the axis + /// Sub axis name. + /// True if all series are integer + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "subAxisName")] + internal bool SeriesIntegerType( AxisName axisName, string subAxisName ) + { + // Series which belong to this chart area + foreach( string seriesName in this._series ) + { + Series ser = Common.DataManager.Series[ seriesName ]; + // X axes type + if( axisName == AxisName.X ) + { +#if SUBAXES + if( ser.XAxisType == AxisType.Primary && ser.XSubAxisName == subAxisName) +#else //SUBAXES + if ( ser.XAxisType == AxisType.Primary) +#endif //SUBAXES + { + if(ser.XValueType != ChartValueType.Int32 && + ser.XValueType != ChartValueType.UInt32 && + ser.XValueType != ChartValueType.UInt64 && + ser.XValueType != ChartValueType.Int64 ) + { + return false; + } + else + { + return true; + } + } + } + // X axes type + else if( axisName == AxisName.X2 ) + { +#if SUBAXES + if( ser.XAxisType == AxisType.Secondary && ser.XSubAxisName == subAxisName) +#else //SUBAXES + if ( ser.XAxisType == AxisType.Secondary) +#endif //SUBAXES + + { + if(ser.XValueType != ChartValueType.Int32 && + ser.XValueType != ChartValueType.UInt32 && + ser.XValueType != ChartValueType.UInt64 && + ser.XValueType != ChartValueType.Int64 ) + { + return false; + } + else + { + return true; + } + } + } + // Y axes type + else if( axisName == AxisName.Y ) + { +#if SUBAXES + if( ser.YAxisType == AxisType.Primary && ser.YSubAxisName == subAxisName) +#else //SUBAXES + if ( ser.YAxisType == AxisType.Primary) +#endif //SUBAXES + + { + if(ser.YValueType != ChartValueType.Int32 && + ser.YValueType != ChartValueType.UInt32 && + ser.YValueType != ChartValueType.UInt64 && + ser.YValueType != ChartValueType.Int64 ) + { + return false; + } + else + { + return true; + } + } + } + else if( axisName == AxisName.Y2 ) + { +#if SUBAXES + if( ser.YAxisType == AxisType.Secondary && ser.YSubAxisName == subAxisName) +#else //SUBAXES + if ( ser.YAxisType == AxisType.Secondary) +#endif //SUBAXES + + { + if(ser.YValueType != ChartValueType.Int32 && + ser.YValueType != ChartValueType.UInt32 && + ser.YValueType != ChartValueType.UInt64 && + ser.YValueType != ChartValueType.Int64 ) + { + return false; + } + else + { + return true; + } + } + } + } + return false; + } + + /// + /// This method checks if all series in the chart area have “date-time type” + /// for specified axes. + /// + /// Name of the axis + /// Sub axis name. + /// True if all series are date-time. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "subAxisName")] + internal bool SeriesDateTimeType( AxisName axisName, string subAxisName ) + { + // Series which belong to this chart area + foreach( string seriesName in this._series ) + { + Series ser = Common.DataManager.Series[ seriesName ]; + // X axes type + if( axisName == AxisName.X ) + { +#if SUBAXES + if( ser.XAxisType == AxisType.Primary && ser.XSubAxisName == subAxisName) +#else //SUBAXES + if ( ser.XAxisType == AxisType.Primary) +#endif //SUBAXES + { + if(ser.XValueType != ChartValueType.Date && + ser.XValueType != ChartValueType.DateTime && + ser.XValueType != ChartValueType.Time && + ser.XValueType != ChartValueType.DateTimeOffset) + { + return false; + } + else + { + return true; + } + } + } + // X axes type + else if( axisName == AxisName.X2 ) + { +#if SUBAXES + if( ser.XAxisType == AxisType.Secondary && ser.XSubAxisName == subAxisName) +#else //SUBAXES + if ( ser.XAxisType == AxisType.Secondary) +#endif //SUBAXES + { + if(ser.XValueType != ChartValueType.Date && + ser.XValueType != ChartValueType.DateTime && + ser.XValueType != ChartValueType.Time && + ser.XValueType != ChartValueType.DateTimeOffset) + { + return false; + } + else + { + return true; + } + } + } + // Y axes type + else if( axisName == AxisName.Y ) + { +#if SUBAXES + if( ser.YAxisType == AxisType.Primary && ser.YSubAxisName == subAxisName) +#else //SUBAXES + if ( ser.YAxisType == AxisType.Primary) +#endif //SUBAXES + { + if(ser.YValueType != ChartValueType.Date && + ser.YValueType != ChartValueType.DateTime && + ser.YValueType != ChartValueType.Time && + ser.YValueType != ChartValueType.DateTimeOffset) + { + return false; + } + else + { + return true; + } + } + } + else if( axisName == AxisName.Y2 ) + { +#if SUBAXES + if( ser.YAxisType == AxisType.Secondary && ser.YSubAxisName == subAxisName) +#else //SUBAXES + if ( ser.YAxisType == AxisType.Secondary) +#endif //SUBAXES + { + if(ser.YValueType != ChartValueType.Date && + ser.YValueType != ChartValueType.DateTime && + ser.YValueType != ChartValueType.Time && + ser.YValueType != ChartValueType.DateTimeOffset) + { + return false; + } + else + { + return true; + } + } + } + } + return false; + } + + /// + /// This method calculates minimum and maximum from data series. + /// + /// Axis which is used to find minimum and maximum + /// Minimum value from data. + /// Maximum value from data. + private void GetValuesFromData( Axis axis, out double autoMinimum, out double autoMaximum ) + { + // Get number of points in series + int currentPointsNumber = this.GetNumberOfAllPoints(); + + if( !axis.refreshMinMaxFromData && + !double.IsNaN(axis.minimumFromData) && + !double.IsNaN(axis.maximumFromData) && + axis.numberOfPointsInAllSeries == currentPointsNumber ) + { + autoMinimum = axis.minimumFromData; + autoMaximum = axis.maximumFromData; + return; + } + + // Set Axis type + AxisType type = AxisType.Primary; + if( axis.axisType == AxisName.X2 || axis.axisType == AxisName.Y2 ) + { + type = AxisType.Secondary; + } + + // Creates a list of series, which have same X axis type. + string [] xAxesSeries = GetXAxesSeries(type, axis.SubAxisName).ToArray(); + + // Creates a list of series, which have same Y axis type. + string [] yAxesSeries = GetYAxesSeries( type, axis.SubAxisName ).ToArray(); + + // Get auto maximum and auto minimum value + if( axis.axisType == AxisName.X2 || axis.axisType == AxisName.X ) // X axis type is used (X or X2) + { + if( stacked ) // Chart area has a stacked chart types + { + try + { + Common.DataManager.GetMinMaxXValue(out autoMinimum, out autoMaximum, xAxesSeries ); + } + catch(System.Exception) + { + throw (new InvalidOperationException(SR.ExceptionAxisStackedChartsDataPointsNumberMismatch)); + } + } + + // Chart type with two y values used for scale ( bubble chart type ) + else if( secondYScale ) + { + autoMaximum = Common.DataManager.GetMaxXWithRadiusValue( (ChartArea)this, xAxesSeries ); + autoMinimum = Common.DataManager.GetMinXWithRadiusValue( (ChartArea)this, xAxesSeries ); + ChartValueType valueTypes = Common.DataManager.Series[xAxesSeries[0]].XValueType; + if( valueTypes != ChartValueType.Date && + valueTypes != ChartValueType.DateTime && + valueTypes != ChartValueType.Time && + valueTypes != ChartValueType.DateTimeOffset ) + { + axis.roundedXValues = true; + } + } + else + { + Common.DataManager.GetMinMaxXValue(out autoMinimum, out autoMaximum, xAxesSeries ); + } + } + else // Y axis type is used (Y or Y2) + { + + // ***************************** + // Stacked Chart AxisName + // ***************************** + if( stacked ) // Chart area has a stacked chart types + { + try + { + if(hundredPercent) // It's a hundred percent stacked chart + { + autoMaximum = Common.DataManager.GetMaxHundredPercentStackedYValue(hundredPercentNegative, yAxesSeries ); + autoMinimum = Common.DataManager.GetMinHundredPercentStackedYValue(hundredPercentNegative, yAxesSeries ); + } + else + { + // If stacked groupes are used Min/Max range must calculated + // for each group seperatly. + double stackMaxBarColumn = double.MinValue; + double stackMinBarColumn = double.MaxValue; + double stackMaxArea = double.MinValue; + double stackMinArea = double.MaxValue; + + // Split series by group names + ArrayList stackedGroups = this.SplitSeriesInStackedGroups(yAxesSeries); + foreach(string[] groupSeriesNames in stackedGroups) + { + // For stacked bar and column + double stackMaxBarColumnForGroup = Common.DataManager.GetMaxStackedYValue(0, groupSeriesNames ); + double stackMinBarColumnForGroup = Common.DataManager.GetMinStackedYValue(0, groupSeriesNames ); + + // For stacked area + double stackMaxAreaForGroup = Common.DataManager.GetMaxUnsignedStackedYValue(0, groupSeriesNames ); + double stackMinAreaForGroup = Common.DataManager.GetMinUnsignedStackedYValue(0, groupSeriesNames ); + + // Select minimum/maximum + stackMaxBarColumn = Math.Max(stackMaxBarColumn, stackMaxBarColumnForGroup); + stackMinBarColumn = Math.Min(stackMinBarColumn, stackMinBarColumnForGroup); + stackMaxArea = Math.Max(stackMaxArea, stackMaxAreaForGroup); + stackMinArea = Math.Min(stackMinArea, stackMinAreaForGroup); + } + + + autoMaximum = Math.Max(stackMaxBarColumn,stackMaxArea); + autoMinimum = Math.Min(stackMinBarColumn,stackMinArea); + } + // IsLogarithmic axis + if( axis.IsLogarithmic && autoMinimum < 1.0 ) + autoMinimum = 1.0; + } + catch(System.Exception) + { + throw (new InvalidOperationException(SR.ExceptionAxisStackedChartsDataPointsNumberMismatch)); + } + } + // Chart type with two y values used for scale ( bubble chart type ) + else if( secondYScale ) + { + autoMaximum = Common.DataManager.GetMaxYWithRadiusValue( (ChartArea)this, yAxesSeries ); + autoMinimum = Common.DataManager.GetMinYWithRadiusValue( (ChartArea)this, yAxesSeries ); + } + + // ***************************** + // Non Stacked Chart Types + // ***************************** + else + { + // Check if any series in the area has ExtraYValuesConnectedToYAxis flag set + bool extraYValuesConnectedToYAxis = false; + if(this.Common != null && this.Common.Chart != null) + { + foreach(Series series in this.Common.Chart.Series) + { + if(series.ChartArea == ((ChartArea)this).Name) + { + IChartType charType = Common.ChartTypeRegistry.GetChartType( series.ChartTypeName ); + if(charType != null && charType.ExtraYValuesConnectedToYAxis) + { + extraYValuesConnectedToYAxis = true; + break; + } + } + } + } + + // The first Chart type can have many Y values (Stock Chart, Range Chart) + if( extraYValuesConnectedToYAxis ) + { + Common.DataManager.GetMinMaxYValue(out autoMinimum, out autoMaximum, yAxesSeries ); + } + else + { // The first Chart type can have only one Y value + Common.DataManager.GetMinMaxYValue(0, out autoMinimum, out autoMaximum, yAxesSeries ); + } + } + } + + // Store Minimum and maximum from data. There is no + // reason to calculate this values every time. + axis.maximumFromData = autoMaximum; + axis.minimumFromData = autoMinimum; + axis.refreshMinMaxFromData = false; + + // Make extra test for stored minimum and maximum values + // from data. If Number of points is different then data + // source is changed. That means that we should read + // data again. + axis.numberOfPointsInAllSeries = currentPointsNumber; + } + + + /// + /// Splits a single array of series names into multiple arrays + /// based on the stacked group name. + /// + /// Array of series name to split. + /// An array list that contains sub-arrays of series names split by group name. + private ArrayList SplitSeriesInStackedGroups(string[] seriesNames) + { + Hashtable groupsHashTable = new Hashtable(); + foreach(string seriesName in seriesNames) + { + // Get series object + Series series = this.Common.Chart.Series[seriesName]; + + // NOTE: Fix for issue #6716 + // Double check that series supports stacked group feature + string groupName = string.Empty; + if(StackedColumnChart.IsSeriesStackGroupNameSupported(series)) + { + // Get stacked group name (empty string by default) + groupName = StackedColumnChart.GetSeriesStackGroupName(series); + } + + // Check if this group was alreday added in to the hashtable + if (groupsHashTable.ContainsKey(groupName)) + { + ArrayList list = (ArrayList)groupsHashTable[groupName]; + list.Add(seriesName); + } + else + { + ArrayList list = new ArrayList(); + list.Add(seriesName); + groupsHashTable.Add(groupName, list); + } + } + + // Convert results to a list that contains array of strings + ArrayList result = new ArrayList(); + foreach(DictionaryEntry entry in groupsHashTable) + { + ArrayList list = (ArrayList)entry.Value; + if(list.Count > 0) + { + int index = 0; + string[] stringArray = new String[list.Count]; + foreach(string str in list) + { + stringArray[index++] = str; + } + result.Add(stringArray); + } + } + + return result; + } + + + + /// + /// Find number of points for all series + /// + /// Number of points + private int GetNumberOfAllPoints() + { + int numOfPoints = 0; + foreach( Series series in Common.DataManager.Series ) + { + numOfPoints += series.Points.Count; + } + + return numOfPoints; + } + + /// + /// This method sets default minimum and maximum values from + /// indexes. This case is used if all X values in a series + /// have 0 value or IsXValueIndexed flag is set. + /// + /// Axis + private void SetDefaultFromIndexes( Axis axis ) + { + // Adjust margin for side-by-side charts like column + axis.SetTempAxisOffset( ); + + // Set Axis type + AxisType type = AxisType.Primary; + if( axis.axisType == AxisName.X2 || axis.axisType == AxisName.Y2 ) + { + type = AxisType.Secondary; + } + + // The maximum is equal to the number of data points. + double autoMaximum = Common.DataManager.GetNumberOfPoints( GetXAxesSeries( type, axis.SubAxisName ).ToArray() ); + double autoMinimum = 0.0; + + // Axis margin used only for zooming + axis.marginView = 0.0; + if( axis.margin == 100 ) + axis.marginView = 1.0; + + // If minimum and maximum are same margin always exist. + if( autoMaximum + axis.margin/100 == autoMinimum - axis.margin/100 + 1 ) + { + // Set Maximum Number. + axis.SetAutoMaximum( autoMaximum + 1 ); + axis.SetAutoMinimum( autoMinimum ); + } + else // Nomal case + { + // Set Maximum Number. + axis.SetAutoMaximum( autoMaximum + axis.margin/100 ); + axis.SetAutoMinimum( autoMinimum - axis.margin/100 + 1 ); + } + + // Find the interval. If the nuber of points + // is less then 10 interval is 1. + double axisInterval; + + if( axis.ViewMaximum - axis.ViewMinimum <= 10 ) + { + axisInterval = 1.0; + } + else + { + axisInterval = axis.CalcInterval( ( axis.ViewMaximum - axis.ViewMinimum ) / 5 ); + } + + ChartArea area = (ChartArea)this; + if( area.Area3DStyle.Enable3D && !double.IsNaN(axis.interval3DCorrection) ) + { + axisInterval = Math.Ceiling( axisInterval / axis.interval3DCorrection ); + + axis.interval3DCorrection = double.NaN; + + // Use interval + if( axisInterval > 1.0 && + axisInterval < 4.0 && + axis.ViewMaximum - axis.ViewMinimum <= 4 ) + { + axisInterval = 1.0; + } + + } + + axis.SetInterval = axisInterval; + + // If temporary offsets were defined for the margin, + // adjust offset for minor ticks and grids. + if(axis.offsetTempSet) + { + axis.minorGrid.intervalOffset -= axis.MajorGrid.GetInterval(); + axis.minorTickMark.intervalOffset -= axis.MajorTickMark.GetInterval(); + } + } + + /// + /// Sets the names of all data series which belong to + /// this chart area to collection and sets a list of all + /// different chart types. + /// + internal void SetData() + { + this.SetData(true, true); + } + + /// + /// Sets the names of all data series which belong to + /// this chart area to collection and sets a list of all + /// different chart types. + /// + /// If set to true the method will initialize axes default values. + /// If set to true the method will check that all primary X axis series are aligned if use the IsXValueIndexed flag. + internal void SetData( bool initializeAxes, bool checkIndexedAligned) + { + // Initialize chart type properties + stacked = false; + switchValueAxes = false; + requireAxes = true; + hundredPercent = false; + hundredPercentNegative = false; + chartAreaIsCurcular = false; + secondYScale = false; + + // AxisName of the chart area already set. + bool typeSet = false; + + // Remove all elements from the collection + this._series.Clear(); + + // Add series to the collection + foreach( Series series in Common.DataManager.Series ) + { + if (series.ChartArea == this.Name && series.IsVisible() && series.Points.Count > 0) + { + this._series.Add(series.Name); + } + } + + // Remove all elements from the collection + this.chartTypes.Clear(); + + // Add series to the collection + foreach( Series series in Common.DataManager.Series ) + { + // A item already exist. + bool foundItem = false; + if (series.IsVisible() && series.ChartArea==this.Name) + { + foreach( string type in chartTypes ) + { + // AxisName already exist in the chart area + if( type == series.ChartTypeName ) + { + foundItem = true; + } + } + // Add chart type to the collection of + // Chart area's chart types + if( !foundItem ) + { + // Set stacked type + if( Common.ChartTypeRegistry.GetChartType(series.ChartTypeName).Stacked ) + { + stacked = true; + } + + if( !typeSet ) + { + if( Common.ChartTypeRegistry.GetChartType(series.ChartTypeName).SwitchValueAxes ) + switchValueAxes = true; + if( !Common.ChartTypeRegistry.GetChartType(series.ChartTypeName).RequireAxes ) + requireAxes = false; + if( Common.ChartTypeRegistry.GetChartType(series.ChartTypeName).CircularChartArea ) + chartAreaIsCurcular = true; + if( Common.ChartTypeRegistry.GetChartType(series.ChartTypeName).HundredPercent ) + hundredPercent = true; + if( Common.ChartTypeRegistry.GetChartType(series.ChartTypeName).HundredPercentSupportNegative ) + hundredPercentNegative = true; + if( Common.ChartTypeRegistry.GetChartType(series.ChartTypeName).SecondYScale ) + secondYScale = true; + + typeSet = true; + } + else + { + if( Common.ChartTypeRegistry.GetChartType(series.ChartTypeName).SwitchValueAxes != switchValueAxes ) + { + throw (new InvalidOperationException(SR.ExceptionChartAreaChartTypesCanNotCombine)); + } + } + + // Series is not empty + if( Common.DataManager.GetNumberOfPoints( series.Name ) != 0 ) + { + this.chartTypes.Add( series.ChartTypeName ); + } + } + } + } + + // Check that all primary X axis series are aligned if use the IsXValueIndexed flag + if (checkIndexedAligned) + { + for (int axisIndex = 0; axisIndex <= 1; axisIndex++) + { + List seriesArray = this.GetXAxesSeries((axisIndex == 0) ? AxisType.Primary : AxisType.Secondary, string.Empty); + if (seriesArray.Count > 0) + { + bool indexed = false; + string seriesNamesStr = ""; + foreach (string seriesName in seriesArray) + { + seriesNamesStr = seriesNamesStr + seriesName.Replace(",", "\\,") + ","; + if (Common.DataManager.Series[seriesName].IsXValueIndexed) + { + indexed = true; + } + } + + if (indexed) + { + try + { + Common.DataManipulator.CheckXValuesAlignment( + Common.DataManipulator.ConvertToSeriesArray(seriesNamesStr.TrimEnd(','), false)); + } + catch (Exception e) + { + throw (new ArgumentException(SR.ExceptionAxisSeriesNotAligned + e.Message)); + } + } + } + } + } + if (initializeAxes) + { + // Set default min, max etc. + SetDefaultAxesValues(); + } + } + + /// + /// Returns names of all series, which belong to this chart area + /// and have same chart type. + /// + /// Chart type + /// Collection with series names + internal List GetSeriesFromChartType( string chartType ) + { + // New collection + List list = new List(); + + foreach( string seriesName in _series ) + { + if( String.Compare( chartType, Common.DataManager.Series[seriesName].ChartTypeName, StringComparison.OrdinalIgnoreCase ) == 0 ) + { + // Add a series name to the collection + list.Add( seriesName ); + } + } + + return list; + } + + /// + /// Returns all series which belong to this chart area. + /// + /// Collection with series + internal List GetSeries( ) + { + // New collection + List list = new List(); + + foreach( string seriesName in _series ) + { + list.Add(Common.DataManager.Series[seriesName]); + } + + return list; + } + + /// + /// Creates a list of series, which have same X axis type. + /// + /// Axis type + /// Sub Axis name + /// A list of series + internal List GetXAxesSeries( AxisType type, string subAxisName ) + { + // Create a new collection of series + List list = new List(); + if (_series.Count == 0) + { + return list; + } + // Ignore sub axis in 3D + if( !this.IsSubAxesSupported ) + { + if(subAxisName.Length > 0) + { + return list; + } + } + + // Find series which have same axis type + foreach( string ser in _series ) + { +#if SUBAXES + if( Common.DataManager.Series[ser].XAxisType == type && + (Common.DataManager.Series[ser].XSubAxisName == subAxisName || !this.IsSubAxesSupported) ) +#else // SUBAXES + if ( Common.DataManager.Series[ser].XAxisType == type) +#endif // SUBAXES + { + // Add a series to the collection + list.Add( ser ); + } + } + +#if SUBAXES + // If series list is empty for the sub-axis then + // try using the main axis. + if ( list.Count == 0 && subAxisName.Length > 0 ) + { + return GetXAxesSeries( type, string.Empty ); + } +#endif // SUBAXES + + // If primary series do not exist return secondary series + // Axis should always be connected with any series. + if ( list.Count == 0 ) + { + if (type == AxisType.Secondary) + { + return GetXAxesSeries(AxisType.Primary, string.Empty); + } + return GetXAxesSeries(AxisType.Secondary, string.Empty); + } + + return list; + } + + /// + /// Creates a list of series, which have same Y axis type. + /// + /// Axis type + /// Sub Axis name + /// A list of series + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "subAxisName")] + internal List GetYAxesSeries( AxisType type, string subAxisName ) + { + // Create a new collection of series + List list = new List(); + + // Find series which have same axis type + foreach( string ser in _series ) + { + // Get series Y axis type + AxisType seriesYAxisType = Common.DataManager.Series[ser].YAxisType; +#if SUBAXES + string seriesYSubAxisName = subAxisName; +#endif // SUBAXES + + // NOTE: Fixes issue #6969 + // Ignore series settings if only Primary Y axis supported by the chart type + if (Common.DataManager.Series[ser].ChartType == SeriesChartType.Radar || + Common.DataManager.Series[ser].ChartType == SeriesChartType.Polar) + { + seriesYAxisType = AxisType.Primary; +#if SUBAXES + seriesYSubAxisName = string.Empty; +#endif // SUBAXES + } + + +#if SUBAXES + if( seriesYAxisType == type && + (Common.DataManager.Series[ser].YSubAxisName == seriesYSubAxisName || !this.IsSubAxesSupported) ) +#else // SUBAXES + if (seriesYAxisType == type) +#endif // SUBAXES + { + // Add a series to the collection + list.Add( ser ); + } + } + +#if SUBAXES + // If series list is empty for the sub-axis then + // try using the main axis. + if ( list.Count == 0 && subAxisName.Length > 0 ) + { + return GetYAxesSeries( type, string.Empty ); + } +#endif // SUBAXES + + // If primary series do not exist return secondary series + // Axis should always be connected with any series. + if ( list.Count == 0 && type == AxisType.Secondary ) + { + return GetYAxesSeries( AxisType.Primary, string.Empty ); + } + + return list; + } + + /// + /// Get first series from the chart area + /// + /// Data series + internal Series GetFirstSeries() + { + if( _series.Count == 0 ) + { + throw (new InvalidOperationException(SR.ExceptionChartAreaSeriesNotFound)); + } + + return Common.DataManager.Series[_series[0]]; + } + + /// + /// This method returns minimum interval between + /// any two data points from series which belong + /// to this chart area. + /// + /// Indicates logarithmic scale. + /// Logarithm Base + /// Minimum Interval + internal double GetPointsInterval(bool isLogarithmic, double logarithmBase) + { + bool sameInterval; + return GetPointsInterval( _series, isLogarithmic, logarithmBase, false, out sameInterval ); + } + + /// + /// This method returns minimum interval between + /// any two data points from specified series. + /// + /// List of series. + /// Indicates logarithmic scale. + /// Base for logarithmic base + /// True if check for the same interval should be performed. + /// Return true if interval is the same. + /// Minimum Interval + internal double GetPointsInterval( List seriesList, bool isLogarithmic, double logarithmBase, bool checkSameInterval, out bool sameInterval ) + { + Series nullSeries = null; + return GetPointsInterval(seriesList, isLogarithmic, logarithmBase, checkSameInterval, out sameInterval, out nullSeries); + } + + /// + /// This method returns minimum interval between + /// any two data points from specified series. + /// + /// List of series. + /// Indicates logarithmic scale. + /// Logarithm Base + /// True if check for the same interval should be performed. + /// Return true if interval is the same. + /// Series with the smallest interval between points. + /// Minimum Interval + internal double GetPointsInterval( List seriesList, bool isLogarithmic, double logarithmicBase, bool checkSameInterval, out bool sameInterval, out Series series ) + { + long ticksInterval = long.MaxValue; + int monthsInteval = 0; + double previousInterval = double.MinValue; + double oldInterval = Double.MaxValue; + + // Initialize return value + sameInterval = true; + series = null; + + // Create comma separate string of series names + string seriesNames = ""; + if(seriesList != null) + { + foreach( string serName in seriesList ) + { + seriesNames += serName + ","; + } + } + + // Do not calculate interval every time; + if( checkSameInterval == false || diffIntervalAlignmentChecked == true) + { + if (!isLogarithmic) + { + if( !double.IsNaN(intervalData) && _intervalSeriesList == seriesNames) + { + sameInterval = intervalSameSize; + series = _intervalSeries; + return intervalData; + } + } + else + { + if( !double.IsNaN(intervalLogData) && _intervalSeriesList == seriesNames) + { + sameInterval = intervalSameSize; + series = _intervalSeries; + return intervalLogData; + } + } + } + + // Data series loop + int seriesIndex = 0; + Series currentSmallestSeries = null; + ArrayList[] seriesXValues = new ArrayList[seriesList.Count]; + foreach( string ser in seriesList ) + { + Series dataSeries = Common.DataManager.Series[ ser ]; + bool isXValueDateTime = dataSeries.IsXValueDateTime(); + + // Copy X values to array and prepare for sorting Sort X values. + seriesXValues[seriesIndex] = new ArrayList(); + bool sortPoints = false; + double prevXValue = double.MinValue; + double curentXValue = 0.0; + if(dataSeries.Points.Count > 0) + { + if (isLogarithmic) + { + prevXValue = Math.Log(dataSeries.Points[0].XValue, logarithmicBase); + } + else + { + prevXValue = dataSeries.Points[0].XValue; + } + } + foreach( DataPoint point in dataSeries.Points ) + { + if (isLogarithmic) + { + curentXValue = Math.Log(point.XValue, logarithmicBase); + } + else + { + curentXValue = point.XValue; + } + + if(prevXValue > curentXValue) + { + sortPoints = true; + } + + seriesXValues[seriesIndex].Add(curentXValue); + prevXValue = curentXValue; + } + + // Sort X values + if(sortPoints) + { + seriesXValues[seriesIndex].Sort(); + } + + // Data point loop + for( int point = 1; point < seriesXValues[seriesIndex].Count; point++ ) + { + // Interval between two sorted data points. + double interval = Math.Abs( (double)seriesXValues[seriesIndex][ point - 1 ] - (double)seriesXValues[seriesIndex][ point ] ); + + // Check if all intervals are same + if(sameInterval) + { + if(isXValueDateTime) + { + if(ticksInterval == long.MaxValue) + { + // Calculate first interval + GetDateInterval( + (double)seriesXValues[seriesIndex][ point - 1 ], + (double)seriesXValues[seriesIndex][ point ], + out monthsInteval, + out ticksInterval); + } + else + { + // Calculate current interval + long curentTicksInterval = long.MaxValue; + int curentMonthsInteval = 0; + GetDateInterval( + (double)seriesXValues[seriesIndex][ point - 1 ], + (double)seriesXValues[seriesIndex][ point ], + out curentMonthsInteval, + out curentTicksInterval); + + // Compare current interval with previous + if(curentMonthsInteval != monthsInteval || curentTicksInterval != ticksInterval) + { + sameInterval = false; + } + + } + } + else + { + if( previousInterval != interval && previousInterval != double.MinValue ) + { + sameInterval = false; + } + } + } + + previousInterval = interval; + + // If not minimum interval keep the old one + if( oldInterval > interval && interval != 0) + { + oldInterval = interval; + currentSmallestSeries = dataSeries; + } + } + + ++seriesIndex; + } + + // If interval is not the same check if points from all series are aligned + this.diffIntervalAlignmentChecked = false; + if( checkSameInterval && !sameInterval && seriesXValues.Length > 1) + { + bool sameXValue = false; + this.diffIntervalAlignmentChecked = true; + + // All X values must be same + int listIndex = 0; + foreach(ArrayList xList in seriesXValues) + { + for(int pointIndex = 0; pointIndex < xList.Count && !sameXValue; pointIndex++) + { + double xValue = (double)xList[pointIndex]; + + // Loop through all other lists and see if point is there + for(int index = listIndex + 1; index < seriesXValues.Length && !sameXValue; index++) + { + if( (pointIndex < seriesXValues[index].Count && (double)seriesXValues[index][pointIndex] == xValue) || + seriesXValues[index].Contains(xValue)) + { + sameXValue = true; + break; + } + } + } + + ++listIndex; + } + + + // Use side-by-side if at least one xommon X value between eries found + if(sameXValue) + { + sameInterval = true; + } + } + + + // Interval not found. Interval is 1. + if( oldInterval == Double.MaxValue) + { + oldInterval = 1; + } + + intervalSameSize = sameInterval; + if (!isLogarithmic) + { + intervalData = oldInterval; + _intervalSeries = currentSmallestSeries; + series = _intervalSeries; + _intervalSeriesList = seriesNames; + return intervalData; + } + else + { + intervalLogData = oldInterval; + _intervalSeries = currentSmallestSeries; + series = _intervalSeries; + _intervalSeriesList = seriesNames; + return intervalLogData; + } + } + + /// + /// Calculates the difference between two values in years, months, days, ... + /// + /// First value. + /// Second value. + /// Interval in months. + /// Interval in ticks. + private void GetDateInterval(double value1, double value2, out int monthsInteval, out long ticksInterval) + { + // Convert values to dates + DateTime date1 = DateTime.FromOADate(value1); + DateTime date2 = DateTime.FromOADate(value2); + + // Calculate months difference + monthsInteval = date2.Month - date1.Month; + monthsInteval += (date2.Year - date1.Year) * 12; + + // Calculate interval in ticks for days, hours, ... + ticksInterval = 0; + ticksInterval += (date2.Day - date1.Day) * TimeSpan.TicksPerDay; + ticksInterval += (date2.Hour - date1.Hour) * TimeSpan.TicksPerHour; + ticksInterval += (date2.Minute - date1.Minute) * TimeSpan.TicksPerMinute; + ticksInterval += (date2.Second - date1.Second) * TimeSpan.TicksPerSecond; + ticksInterval += (date2.Millisecond - date1.Millisecond) * TimeSpan.TicksPerMillisecond; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/ChartAreaCircular.cs b/System.Web.DataVisualization/Common/General/ChartAreaCircular.cs new file mode 100644 index 000000000..a8df57ebb --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ChartAreaCircular.cs @@ -0,0 +1,109 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartAreaCircular.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: CircularChartAreaAxis +// +// Purpose: CircularChartAreaAxis is a helper class which is used +// in circular chart areas for charts like Polar and +// Radar. +// +// Reviewed: AG - Microsoft 16, 2007 +// +//=================================================================== + + +#region Used namespaces +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +#if Microsoft_CONTROL + +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; +using System.Windows.Forms.DataVisualization.Charting; + +using System.Globalization; +using System.ComponentModel.Design.Serialization; +using System.Reflection; +using System.Windows.Forms.Design; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// CircularChartAreaAxis class represents a single axis in the circular + /// chart area chart like radar or polar. It contains axis angular + /// position, size and title properties. + /// + internal class CircularChartAreaAxis + { + #region Fields + + /// + /// Angle where axis is located. + /// + internal float AxisPosition = 0f; + + /// + /// Axis title. + /// + internal string Title = string.Empty; + + /// + /// Axis title color. + /// + internal Color TitleForeColor = Color.Empty; + + #endregion + + #region Constructors + + /// + /// Constructor. + /// + public CircularChartAreaAxis() + { + } + + /// + /// Constructor. + /// + internal CircularChartAreaAxis(float axisPosition) + { + this.AxisPosition = axisPosition; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/ChartAreaCollection.cs b/System.Web.DataVisualization/Common/General/ChartAreaCollection.cs new file mode 100644 index 000000000..c9620a2f0 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ChartAreaCollection.cs @@ -0,0 +1,107 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartAreaCollection.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ChartAreaCollection +// +// Purpose: ChartAreaCollection class represents a strongly +// typed collection of ChartArea objects. +// +// Reviewed: GS - Aug 8, 2002 +// AG - Aug 8, 2002 +// AG - Microsoft 16, 2007 +// +//=================================================================== + + +#region Used namespaces + +using System; +using System.Collections; +using System.Drawing; +using System.ComponentModel; + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// The ChartAreaCollection class represents a strongly typed collection of + /// ChartArea objects. Each chart area has a unique name in the collection + /// and can be retrieved by name or by index. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class ChartAreaCollection : ChartNamedElementCollection + { + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// Parent chart picture. + internal ChartAreaCollection(ChartPicture chartPicture) : base(chartPicture) + { + } + + #endregion + + #region Properties + /// + /// Gets the default chart area name. + /// + internal string DefaultNameReference + { + get { return this.Count > 0 ? this[0].Name : String.Empty; } + } + #endregion + + #region Methods + + /// + /// Creates a new ChartArea with the specified name and adds it to the collection. + /// + /// The new chart area name. + /// + public ChartArea Add(string name) + { + ChartArea area = new ChartArea(name); + this.Add(area); + return area; + } + + #endregion + + #region Event handlers + /// + /// Updates the ChartArea alignment references to another chart areas. + /// + /// The sender. + /// The instance containing the event data. + internal void ChartAreaNameReferenceChanged(object sender, NameReferenceChangedEventArgs e) + { + foreach (ChartArea chartArea in this) + if (chartArea.AlignWithChartArea == e.OldName) + chartArea.AlignWithChartArea = e.NewName; + } + + #endregion + + } +} diff --git a/System.Web.DataVisualization/Common/General/ChartAreaCursor.cs b/System.Web.DataVisualization/Common/General/ChartAreaCursor.cs new file mode 100644 index 000000000..72c06e7ba --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ChartAreaCursor.cs @@ -0,0 +1,1682 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartAreaCursor.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: Cursor, CursorEventArgs +// +// Purpose: A cursor is a horizontal or vertical line that +// defines a position along an axis. A range selection +// is a range along an axis that is defined by a beginning +// and end position, and is displayed using a semi-transparent +// color. +// +// Both cursors and range selections are implemented by the +// Cursor class, which is exposed as the CursorX and CursorY +// properties of the ChartArea object. The CursorX object is +// for the X axis of a chart area, and the CursorY object is +// for the Y axis. The AxisType property of these objects +// determines if the associated axis is primary or secondary. +// +// Cursors and range selections can be set via end-user +// interaction and programmatically. +// +// NOTE: ASP.NET version of the chart uses this class only +// for appearance and position properties. Drawing of the +// selection and cursor is implemented through client side +// java script. +// +// Reviewed: AG - August 8, 2002 +// AG - March 16, 2007 +// +//=================================================================== + +#if WINFORMS_CONTROL + +#region Used Namespaces + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.ComponentModel; +using System.Collections; +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; +using System.Drawing.Design; +using System.Collections.Generic; + +#endregion + +namespace System.Windows.Forms.DataVisualization.Charting +{ + /// + /// The Cursor class is responsible for chart axes cursor and selection + /// functionality. It contains properties which define visual appearance, + /// position and behavior settings. It also contains methods for + /// drawing cursor and selection in the plotting area. + /// + [ + DefaultProperty("Enabled"), + SRDescription("DescriptionAttributeCursor_Cursor"), + ] + public class Cursor : IDisposable + { + #region Cursor constructors and initialization + + /// + /// Public constructor + /// + public Cursor() + { + } + + /// + /// Initialize cursor class. + /// + /// Chart area the cursor belongs to. + /// Indicates which axes should be used X or Y. + internal void Initialize(ChartArea chartArea, AxisName attachedToXAxis) + { + // Set chart are reference + this._chartArea = chartArea; + + // Attach cursor to specified axis + this._attachedToXAxis = attachedToXAxis; + } + + #endregion + + #region Cursor fields + + // Reference to the chart area object the cursor belongs to + private ChartArea _chartArea = null; + + // Defines which axis the cursor attached to X or Y + private AxisName _attachedToXAxis = AxisName.X; + + // Enables/Disables chart area cursor. + private bool _isUserEnabled = false; + + // Enables/Disables chart area selection. + private bool _isUserSelectionEnabled = false; + + // Indicates that cursor will automatically scroll the area scaleView if necessary. + private bool _autoScroll = true; + + // Cursor line color + private Color _lineColor = Color.Red; + + // Cursor line width + private int _lineWidth = 1; + + // Cursor line style + private ChartDashStyle _lineDashStyle = ChartDashStyle.Solid; + + // Chart area selection color + private Color _selectionColor = Color.LightGray; + + // AxisName of the axes (primary/secondary) the cursor is attached to + private AxisType _axisType = AxisType.Primary; + + // Cursor position + private double _position = Double.NaN; + + // Range selection start position. + private double _selectionStart = Double.NaN; + + // Range selection end position. + private double _selectionEnd = Double.NaN; + + // Cursor movement interval current & original values + private double _interval = 1; + + // Cursor movement interval type + private DateTimeIntervalType _intervalType = DateTimeIntervalType.Auto; + + // Cursor movement interval offset current & original values + private double _intervalOffset = 0; + + // Cursor movement interval offset type + private DateTimeIntervalType _intervalOffsetType = DateTimeIntervalType.Auto; + + // Reference to the axis obhect + private Axis _axis = null; + + // User selection start point + private PointF _userSelectionStart = PointF.Empty; + + // Indicates that selection must be drawn + private bool _drawSelection = true; + + // Indicates that events must be fired when position/selection is changed + private bool _fireUserChangingEvent = false; + + // Indicates that XXXChanged events must be fired when position/selection is changed + private bool _fireUserChangedEvent = false; + + // Scroll size and direction when AutoScroll is set + private MouseEventArgs _mouseMoveArguments = null; + + // Timer used to scroll the data while selecting + private System.Windows.Forms.Timer _scrollTimer = new System.Windows.Forms.Timer(); + + // Indicates that axis data scaleView was scrolled as a result of the mouse move event + private bool _viewScrolledOnMouseMove = false; + + #endregion + + #region Cursor "Behavior" public properties. + + /// + /// Gets or sets the position of a cursor. + /// + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + DefaultValue(Double.NaN), + SRDescription("DescriptionAttributeCursor_Position"), + ParenthesizePropertyNameAttribute(true), + TypeConverter(typeof(DoubleDateNanValueConverter)), + ] + public double Position + { + get + { + return _position; + } + set + { + if(_position != value) + { + _position = value; + + // Align cursor in connected areas + if(this._chartArea != null && this._chartArea.Common != null && this._chartArea.Common.ChartPicture != null) + { + if(!this._chartArea.alignmentInProcess) + { + AreaAlignmentOrientations orientation = (this._attachedToXAxis == AxisName.X || this._attachedToXAxis == AxisName.X2) ? + AreaAlignmentOrientations.Vertical : AreaAlignmentOrientations.Horizontal; + this._chartArea.Common.ChartPicture.AlignChartAreasCursor(this._chartArea, orientation, false); + } + } + + if(this._chartArea != null && !this._chartArea.alignmentInProcess) + { + this.Invalidate(false); + } + + } + } + } + + /// + /// Gets or sets the starting position of a cursor's selected range. + /// + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + DefaultValue(Double.NaN), + SRDescription("DescriptionAttributeCursor_SelectionStart"), + TypeConverter(typeof(DoubleDateNanValueConverter)), + ] + public double SelectionStart + { + get + { + return _selectionStart; + } + set + { + if(_selectionStart != value) + { + _selectionStart = value; + + // Align cursor in connected areas + if(this._chartArea != null && this._chartArea.Common != null && this._chartArea.Common.ChartPicture != null) + { + if(!this._chartArea.alignmentInProcess) + { + AreaAlignmentOrientations orientation = (this._attachedToXAxis == AxisName.X || this._attachedToXAxis == AxisName.X2) ? + AreaAlignmentOrientations.Vertical : AreaAlignmentOrientations.Horizontal; + this._chartArea.Common.ChartPicture.AlignChartAreasCursor(this._chartArea, orientation, false); + } + } + + if(this._chartArea != null && !this._chartArea.alignmentInProcess) + { + this.Invalidate(false); + } + + } + } + } + + /// + /// Gets or sets the ending position of a range selection. + /// + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + DefaultValue(Double.NaN), + SRDescription("DescriptionAttributeCursor_SelectionEnd"), + TypeConverter(typeof(DoubleDateNanValueConverter)), + ] + public double SelectionEnd + { + get + { + return _selectionEnd; + } + set + { + if(_selectionEnd != value) + { + _selectionEnd = value; + + // Align cursor in connected areas + if(this._chartArea != null && this._chartArea.Common != null && this._chartArea.Common.ChartPicture != null) + { + if(!this._chartArea.alignmentInProcess) + { + AreaAlignmentOrientations orientation = (this._attachedToXAxis == AxisName.X || this._attachedToXAxis == AxisName.X2) ? + AreaAlignmentOrientations.Vertical : AreaAlignmentOrientations.Horizontal; + this._chartArea.Common.ChartPicture.AlignChartAreasCursor(this._chartArea, orientation, false); + } + } + + if(this._chartArea != null && !this._chartArea.alignmentInProcess) + { + this.Invalidate(false); + } + } + } + } + + /// + /// Gets or sets a property that enables or disables the cursor interface. + /// + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + DefaultValue(false), + SRDescription("DescriptionAttributeCursor_UserEnabled"), + ] + public bool IsUserEnabled + { + get + { + return _isUserEnabled; + } + set + { + _isUserEnabled = value; + } + } + + /// + /// Gets or sets a property that enables or disables the range selection interface. + /// + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + DefaultValue(false), + SRDescription("DescriptionAttributeCursor_UserSelection"), + ] + public bool IsUserSelectionEnabled + { + get + { + return _isUserSelectionEnabled; + } + set + { + _isUserSelectionEnabled = value; + } + } + + /// + /// Determines if scrolling will occur if a range selection operation + /// extends beyond a boundary of the chart area. + /// + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeCursor_AutoScroll"), + ] + public bool AutoScroll + { + get + { + return _autoScroll; + } + set + { + _autoScroll = value; + } + } + + /// + /// Gets or sets the type of axis that the cursor is attached to. + /// + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + SRDescription("DescriptionAttributeCursor_AxisType"), + DefaultValue(AxisType.Primary) + ] + public AxisType AxisType + { + get + { + return _axisType; + } + set + { + _axisType = value; + + // Reset reference to the axis object + _axis = null; + + this.Invalidate(true); + } + } + + /// + /// Gets or sets the cursor movement interval. + /// + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + DefaultValue(1.0), + SRDescription("DescriptionAttributeCursor_Interval"), + ] + public double Interval + { + get + { + return _interval; + } + set + { + _interval = value; + } + } + + /// + /// Gets or sets the unit of measurement of the Interval property. + /// + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeCursor_IntervalType") + ] + public DateTimeIntervalType IntervalType + { + get + { + return _intervalType; + } + set + { + _intervalType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto; + } + } + + + /// + /// Gets or sets the interval offset, which determines + /// where to draw the cursor and range selection. + /// + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + DefaultValue(0.0), + SRDescription("DescriptionAttributeCursor_IntervalOffset"), + ] + public double IntervalOffset + { + get + { + return _intervalOffset; + } + set + { + // Validation + if( value < 0.0 ) + { + throw (new ArgumentException(SR.ExceptionCursorIntervalOffsetIsNegative, "value")); + } + + _intervalOffset = value; + } + } + + /// + /// Gets or sets the unit of measurement of the IntervalOffset property. + /// + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeCursor_IntervalOffsetType"), + ] + public DateTimeIntervalType IntervalOffsetType + { + get + { + return _intervalOffsetType; + } + set + { + _intervalOffsetType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto; + } + } + #endregion + + #region Cursor "Appearance" public properties + + /// + /// Gets or sets the color the cursor line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "Red"), + SRDescription("DescriptionAttributeLineColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color LineColor + { + get + { + return _lineColor; + } + set + { + _lineColor = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the style of the cursor line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeLineDashStyle"), + ] + public ChartDashStyle LineDashStyle + { + get + { + return _lineDashStyle; + } + set + { + _lineDashStyle = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the width of the cursor line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeLineWidth"), + ] + public int LineWidth + { + get + { + return _lineWidth; + } + set + { + if(value < 0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionCursorLineWidthIsNegative)); + } + _lineWidth = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets a semi-transparent color that highlights a range of data. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "LightGray"), + SRDescription("DescriptionAttributeCursor_SelectionColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color SelectionColor + { + get + { + return _selectionColor; + } + set + { + _selectionColor = value; + this.Invalidate(false); + } + } + + #endregion + + #region Cursor painting methods + + /// + /// Draws chart area cursor and selection. + /// + /// Reference to the ChartGraphics object. + internal void Paint( ChartGraphics graph ) + { + //*************************************************** + //** Prepare for drawing + //*************************************************** + + // Do not proceed with painting if cursor is not attached to the axis + if(this.GetAxis() == null || + this._chartArea == null || + this._chartArea.Common == null || + this._chartArea.Common.ChartPicture == null || + this._chartArea.Common.ChartPicture.isPrinting) + { + return; + } + + // Get plot area position + RectangleF plotAreaPosition = this._chartArea.PlotAreaPosition.ToRectangleF(); + + // Detect if cursor is horizontal or vertical + bool horizontal = true; + if(this.GetAxis().AxisPosition == AxisPosition.Bottom || this.GetAxis().AxisPosition == AxisPosition.Top) + { + horizontal = false; + } + + //*************************************************** + //** Draw selection + //*************************************************** + + // Check if selection need to be drawn + if(this._drawSelection && + !double.IsNaN(this.SelectionStart) && + !double.IsNaN(this.SelectionEnd) && + this.SelectionColor != Color.Empty) + { + // Calculate selection rectangle + RectangleF rectSelection = GetSelectionRect(plotAreaPosition); + rectSelection.Intersect(plotAreaPosition); + + // Get opposite axis selection rectangle + RectangleF rectOppositeSelection = GetOppositeSelectionRect(plotAreaPosition); + + // Draw selection if rectangle is not empty + if(!rectSelection.IsEmpty && rectSelection.Width > 0 && rectSelection.Height > 0) + { + // Limit selection rectangle to the area of the opposite selection + if(!rectOppositeSelection.IsEmpty && rectOppositeSelection.Width > 0 && rectOppositeSelection.Height > 0) + { + rectSelection.Intersect(rectOppositeSelection); + + // We do not need to draw selection in the opposite axis + Cursor oppositeCursor = + (_attachedToXAxis == AxisName.X || _attachedToXAxis == AxisName.X2) ? + _chartArea.CursorY : _chartArea.CursorX; + oppositeCursor._drawSelection = false; + } + + // Make sure selection is inside plotting area + rectSelection.Intersect(plotAreaPosition); + + // If selection rectangle is not empty + if(rectSelection.Width > 0 && rectSelection.Height > 0) + { + // Add transparency to solid colors + Color rangeSelectionColor = this.SelectionColor; + if(rangeSelectionColor.A == 255) + { + rangeSelectionColor = Color.FromArgb(120, rangeSelectionColor); + } + + // Draw selection + graph.FillRectangleRel( rectSelection, + rangeSelectionColor, + ChartHatchStyle.None, + "", + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + Color.Empty, + 0, + ChartDashStyle.NotSet, + Color.Empty, + 0, + PenAlignment.Inset ); + } + } + } + + //*************************************************** + //** Draw cursor + //*************************************************** + + // Check if cursor need to be drawn + if(!double.IsNaN(this.Position) && + this.LineColor != Color.Empty && + this.LineWidth > 0 && + this.LineDashStyle != ChartDashStyle.NotSet) + { + // Calculate line position + bool insideArea = false; + PointF point1 = PointF.Empty; + PointF point2 = PointF.Empty; + if(horizontal) + { + // Set cursor coordinates + point1.X = plotAreaPosition.X; + point1.Y = (float)this.GetAxis().GetLinearPosition(this.Position); + point2.X = plotAreaPosition.Right; + point2.Y = point1.Y; + + // Check if cursor is inside plotting rect + if(point1.Y >= plotAreaPosition.Y && point1.Y <= plotAreaPosition.Bottom) + { + insideArea = true; + } + } + else + { + // Set cursor coordinates + point1.X = (float)this.GetAxis().GetLinearPosition(this.Position); + point1.Y = plotAreaPosition.Y; + point2.X = point1.X; + point2.Y = plotAreaPosition.Bottom; + + // Check if cursor is inside plotting rect + if(point1.X >= plotAreaPosition.X && point1.X <= plotAreaPosition.Right) + { + insideArea = true; + } + } + + // Draw cursor if it's inside the chart area plotting rectangle + if(insideArea) + { + graph.DrawLineRel(this.LineColor, this.LineWidth, this.LineDashStyle, point1, point2); + } + } + // Reset draw selection flag + this._drawSelection = true; + } + + #endregion + + #region Cursor position setting methods + + /// + /// This method sets the position of a cursor within a chart area at a given axis value. + /// + /// The new position of the cursor. Measured as a value along the relevant axis. + public void SetCursorPosition(double newPosition) + { + // Check if we are setting different value + if(this.Position != newPosition) + { + double newRoundedPosition = RoundPosition(newPosition); + // Send PositionChanging event + if(_fireUserChangingEvent && GetChartObject() != null) + { + CursorEventArgs arguments = new CursorEventArgs(this._chartArea, this.GetAxis(), newRoundedPosition); + GetChartObject().OnCursorPositionChanging(arguments); + + // Check if position values were changed in the event + newRoundedPosition = arguments.NewPosition; + } + + // Change position + this.Position = newRoundedPosition; + + // Send PositionChanged event + if(_fireUserChangedEvent && GetChartObject() != null) + { + CursorEventArgs arguments = new CursorEventArgs(this._chartArea, this.GetAxis(), this.Position); + GetChartObject().OnCursorPositionChanged(arguments); + } + } + } + + + /// + /// This method displays a cursor at the specified position. Measured in pixels. + /// + /// A PointF structure that specifies where the cursor will be drawn. + /// If true, the cursor will be drawn along the nearest chart area boundary + /// when the specified position does not fall within a ChartArea object. + public void SetCursorPixelPosition(PointF point, bool roundToBoundary) + { + if(this._chartArea != null && this._chartArea.Common != null && this.GetAxis() != null) + { + PointF relativeCoord = GetPositionInPlotArea(point, roundToBoundary); + if(!relativeCoord.IsEmpty) + { + // Get new cursor position + double newCursorPosition = PositionToCursorPosition(relativeCoord); + + // Set new cursor & selection position + this.SetCursorPosition(newCursorPosition); + } + } + } + + /// + /// This method sets the position of a selected range within a chart area at given axis values. + /// + /// The new starting position of the range selection. Measured as a value along the relevant axis.. + /// The new ending position of the range selection. Measured as a value along the relevant axis. + public void SetSelectionPosition(double newStart, double newEnd) + { + // Check if we are setting different value + if(this.SelectionStart != newStart || this.SelectionEnd != newEnd) + { + // Send PositionChanging event + double newRoundedSelectionStart = RoundPosition(newStart); + double newRoundedSelectionEnd = RoundPosition(newEnd); + + // Send SelectionRangeChanging event + if(_fireUserChangingEvent && GetChartObject() != null) + { + CursorEventArgs arguments = new CursorEventArgs(this._chartArea, this.GetAxis(), newRoundedSelectionStart, newRoundedSelectionEnd); + GetChartObject().OnSelectionRangeChanging(arguments); + + // Check if position values were changed in the event + newRoundedSelectionStart = arguments.NewSelectionStart; + newRoundedSelectionEnd = arguments.NewSelectionEnd; + } + + // Change selection position + this._selectionStart = newRoundedSelectionStart; + this._selectionEnd = newRoundedSelectionEnd; + + // Align cursor in connected areas + if(this._chartArea != null && this._chartArea.Common != null && this._chartArea.Common.ChartPicture != null) + { + if(!this._chartArea.alignmentInProcess) + { + AreaAlignmentOrientations orientation = (this._attachedToXAxis == AxisName.X || this._attachedToXAxis == AxisName.X2) ? + AreaAlignmentOrientations.Vertical : AreaAlignmentOrientations.Horizontal; + this._chartArea.Common.ChartPicture.AlignChartAreasCursor(this._chartArea, orientation, true); + } + } + + if(this._chartArea != null && !this._chartArea.alignmentInProcess) + { + this.Invalidate(false); + } + + // Send SelectionRangeChanged event + if(_fireUserChangedEvent && GetChartObject() != null) + { + CursorEventArgs arguments = new CursorEventArgs(this._chartArea, this.GetAxis(), this.SelectionStart, this.SelectionEnd); + GetChartObject().OnSelectionRangeChanged(arguments); + } + } + } + + + /// + /// This method sets the starting and ending positions of a range selection. + /// + /// A PointF structure that specifies where the range selection begins. + /// A PointF structure that specifies where the range selection ends + /// If true, the starting and ending points will be rounded to the nearest chart area boundary + /// when the specified positions do not fall within a ChartArea object. + public void SetSelectionPixelPosition(PointF startPoint, PointF endPoint, bool roundToBoundary) + { + if(this._chartArea != null && this._chartArea.Common != null && this.GetAxis() != null) + { + // Calculating the start position + double newStart = this.SelectionStart; + if(!startPoint.IsEmpty) + { + PointF relativeCoord = GetPositionInPlotArea(startPoint, roundToBoundary); + if(!relativeCoord.IsEmpty) + { + // Get new selection start position + newStart = PositionToCursorPosition(relativeCoord); + } + } + + // Setting the end position + double newEnd = newStart; + if(!endPoint.IsEmpty) + { + PointF relativeCoord = GetPositionInPlotArea(endPoint, roundToBoundary); + if(!relativeCoord.IsEmpty) + { + // Get new selection position + newEnd = PositionToCursorPosition(relativeCoord); + } + } + + // Set new selection start & end position + this.SetSelectionPosition(newStart, newEnd); + } + } + + #endregion + + #region Position rounding methods + + /// + /// Rounds new position of the cursor or range selection + /// + /// + /// + internal double RoundPosition(double cursorPosition) + { + double roundedPosition = cursorPosition; + + if(!double.IsNaN(roundedPosition)) + { + // Check if position rounding is required + if(this.GetAxis() != null && + this.Interval != 0 && + !double.IsNaN(this.Interval)) + { + // Get first series attached to this axis + Series axisSeries = null; + if(_axis.axisType == AxisName.X || _axis.axisType == AxisName.X2) + { + List seriesArray = _axis.ChartArea.GetXAxesSeries((_axis.axisType == AxisName.X) ? AxisType.Primary : AxisType.Secondary, _axis.SubAxisName); + if(seriesArray.Count > 0) + { + string seriesName = seriesArray[0] as string; + axisSeries = _axis.Common.DataManager.Series[seriesName]; + if(axisSeries != null && !axisSeries.IsXValueIndexed) + { + axisSeries = null; + } + } + } + + // If interval type is not set - use number + DateTimeIntervalType intervalType = + (this.IntervalType == DateTimeIntervalType.Auto) ? + DateTimeIntervalType.Number : this.IntervalType; + + // If interval offset type is not set - use interval type + DateTimeIntervalType offsetType = + (this.IntervalOffsetType == DateTimeIntervalType.Auto) ? + intervalType : this.IntervalOffsetType; + + // Round numbers + if(intervalType == DateTimeIntervalType.Number) + { + double newRoundedPosition = Math.Round(roundedPosition / this.Interval) * this.Interval; + + // Add offset number + if(this.IntervalOffset != 0 && + !double.IsNaN(IntervalOffset) && + offsetType != DateTimeIntervalType.Auto) + { + if(this.IntervalOffset > 0) + { + newRoundedPosition += ChartHelper.GetIntervalSize(newRoundedPosition, this.IntervalOffset, offsetType); + } + else + { + newRoundedPosition -= ChartHelper.GetIntervalSize(newRoundedPosition, this.IntervalOffset, offsetType); + } + } + + // Find rounded position after/before the current + double nextPosition = newRoundedPosition; + if(newRoundedPosition <= cursorPosition) + { + nextPosition += ChartHelper.GetIntervalSize(newRoundedPosition, this.Interval, intervalType, axisSeries, 0, DateTimeIntervalType.Number, true); + } + else + { + nextPosition -= ChartHelper.GetIntervalSize(newRoundedPosition, this.Interval, intervalType, axisSeries, 0, DateTimeIntervalType.Number, true); + } + + // Choose closest rounded position + if(Math.Abs(nextPosition - cursorPosition) > Math.Abs(cursorPosition - newRoundedPosition)) + { + roundedPosition = newRoundedPosition; + } + else + { + roundedPosition = nextPosition; + } + + } + + // Round date/time + else + { + // Find one rounded position prior and one after current position + // Adjust start position depending on the interval and type + double prevPosition = ChartHelper.AlignIntervalStart(cursorPosition, this.Interval, intervalType, axisSeries); + + // Adjust start position depending on the interval offset and offset type + if( IntervalOffset != 0 && axisSeries == null) + { + if(this.IntervalOffset > 0) + { + prevPosition += ChartHelper.GetIntervalSize( + prevPosition, + this.IntervalOffset, + offsetType, + axisSeries, + 0, + DateTimeIntervalType.Number, + true); + } + else + { + prevPosition += ChartHelper.GetIntervalSize( + prevPosition, + -this.IntervalOffset, + offsetType, + axisSeries, + 0, + DateTimeIntervalType.Number, + true); + } + } + + // Find rounded position after/before the current + double nextPosition = prevPosition; + if(prevPosition <= cursorPosition) + { + nextPosition += ChartHelper.GetIntervalSize(prevPosition, this.Interval, intervalType, axisSeries, 0, DateTimeIntervalType.Number, true); + } + else + { + nextPosition -= ChartHelper.GetIntervalSize(prevPosition, this.Interval, intervalType, axisSeries, 0, DateTimeIntervalType.Number, true); + } + + // Choose closest rounded position + if(Math.Abs(nextPosition - cursorPosition) > Math.Abs(cursorPosition - prevPosition)) + { + roundedPosition = prevPosition; + } + else + { + roundedPosition = nextPosition; + } + } + } + } + + return roundedPosition; + } + #endregion + + #region Mouse events handling for the Cursor + + /// + /// Mouse down event handler. + /// + internal void Cursor_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) + { + // Set flag to fire position changing events + _fireUserChangingEvent = true; + _fireUserChangedEvent = false; + + // Check if left mouse button was clicked in chart area + if(e.Button == MouseButtons.Left && !GetPositionInPlotArea(new PointF(e.X, e.Y), false).IsEmpty) + { + // Change cursor position and selection start position when mouse down + if(this.IsUserEnabled) + { + SetCursorPixelPosition(new PointF(e.X, e.Y), false); + } + if(this.IsUserSelectionEnabled) + { + this._userSelectionStart = new PointF(e.X, e.Y); + SetSelectionPixelPosition(this._userSelectionStart, PointF.Empty, false); + } + } + + // Clear flag to fire position changing events + _fireUserChangingEvent = false; + _fireUserChangedEvent = false; + } + + /// + /// Mouse up event handler. + /// + internal void Cursor_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) + { + // If in range selection mode + if(!this._userSelectionStart.IsEmpty) + { + // Stop timer + _scrollTimer.Stop(); + _mouseMoveArguments = null; + + // Check if axis data scaleView zooming UI is enabled + if(this._axis != null && + this._axis.ScaleView.Zoomable && + !double.IsNaN(this.SelectionStart) && + !double.IsNaN(this.SelectionEnd) && + this.SelectionStart != this.SelectionEnd) + { + // Zoom data scaleView + double start = Math.Min(this.SelectionStart, this.SelectionEnd); + double size = (double)Math.Max(this.SelectionStart, this.SelectionEnd) - start; + bool zoomed = this._axis.ScaleView.Zoom(start, size, DateTimeIntervalType.Number, true, true); + + // Clear image buffer + if(this._chartArea.areaBufferBitmap != null && zoomed) + { + this._chartArea.areaBufferBitmap.Dispose(); + this._chartArea.areaBufferBitmap = null; + } + + // Clear range selection + this.SelectionStart = double.NaN; + this.SelectionEnd = double.NaN; + + // NOTE: Fixes issue #6823 + // Clear cursor position after the zoom in operation + this.Position = double.NaN; + + // Align cursor in connected areas + if(this._chartArea != null && this._chartArea.Common != null && this._chartArea.Common.ChartPicture != null) + { + if(!this._chartArea.alignmentInProcess) + { + AreaAlignmentOrientations orientation = (this._attachedToXAxis == AxisName.X || this._attachedToXAxis == AxisName.X2) ? + AreaAlignmentOrientations.Vertical : AreaAlignmentOrientations.Horizontal; + this._chartArea.Common.ChartPicture.AlignChartAreasZoomed(this._chartArea, orientation, zoomed); + } + } + } + + // Fire XXXChanged events + if(GetChartObject() != null) + { + CursorEventArgs arguments = new CursorEventArgs(this._chartArea, this.GetAxis(), this.SelectionStart, this.SelectionEnd); + GetChartObject().OnSelectionRangeChanged(arguments); + + arguments = new CursorEventArgs(this._chartArea, this.GetAxis(), this.Position); + GetChartObject().OnCursorPositionChanged(arguments); + } + + // Stop range selection mode + this._userSelectionStart = PointF.Empty; + } + } + + /// + /// Mouse move event handler. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Justification = "The timer is used for simulating scrolling behavior")] + internal void Cursor_MouseMove(System.Windows.Forms.MouseEventArgs e, ref bool handled) + { + // Process range selection + if(this._userSelectionStart != PointF.Empty) + { + // Mouse move event should not be handled by any other chart elements + handled = true; + + // Set flag to fire position changing events + _fireUserChangingEvent = true; + _fireUserChangedEvent = false; + + // Check if mouse position is outside of the chart area and if not - try scrolling + if(this.AutoScroll) + { + if(this._chartArea != null && this._chartArea.Common != null && this.GetAxis()!= null) + { + // Check if axis data scaleView is enabled + if(!double.IsNaN(this._axis.ScaleView.Position) && !double.IsNaN(this._axis.ScaleView.Size)) + { + ScrollType scrollType = ScrollType.SmallIncrement; + bool insideChartArea = true; + double offsetFromBoundary = 0.0; + + // Translate mouse pixel coordinates into the relative chart area coordinates + float mouseX = e.X * 100F / ((float)(this._chartArea.Common.Width - 1)); + float mouseY = e.Y * 100F / ((float)(this._chartArea.Common.Height - 1)); + + // Check if coordinate is inside chart plotting area + if(this._axis.AxisPosition == AxisPosition.Bottom || this._axis.AxisPosition == AxisPosition.Top) + { + if(mouseX < this._chartArea.PlotAreaPosition.X) + { + scrollType = ScrollType.SmallDecrement; + insideChartArea = false; + offsetFromBoundary = this._chartArea.PlotAreaPosition.X - mouseX; + } + else if(mouseX > this._chartArea.PlotAreaPosition.Right) + { + scrollType = ScrollType.SmallIncrement; + insideChartArea = false; + offsetFromBoundary = mouseX - this._chartArea.PlotAreaPosition.Right; + } + } + else + { + if(mouseY < this._chartArea.PlotAreaPosition.Y) + { + scrollType = ScrollType.SmallIncrement; + insideChartArea = false; + offsetFromBoundary = this._chartArea.PlotAreaPosition.Y - mouseY; + } + else if(mouseY > this._chartArea.PlotAreaPosition.Bottom) + { + scrollType = ScrollType.SmallDecrement; + insideChartArea = false; + offsetFromBoundary = mouseY - this._chartArea.PlotAreaPosition.Bottom; + } + } + + // Try scrolling scaleView position + if(!insideChartArea) + { + // Set flag that data scaleView was scrolled + _viewScrolledOnMouseMove = true; + + // Get minimum scroll interval + double scrollInterval = ChartHelper.GetIntervalSize( + this._axis.ScaleView.Position, + this._axis.ScaleView.GetScrollingLineSize(), + this._axis.ScaleView.GetScrollingLineSizeType()); + offsetFromBoundary *= 2; + if(offsetFromBoundary > scrollInterval) + { + scrollInterval = ((int)(offsetFromBoundary / scrollInterval)) * scrollInterval; + } + + // Scroll axis data scaleView + double newDataViewPosition = this._axis.ScaleView.Position; + if(scrollType == ScrollType.SmallIncrement) + { + newDataViewPosition += scrollInterval; + } + else + { + newDataViewPosition -= scrollInterval; + } + + // Scroll axis data scaleView + this._axis.ScaleView.Scroll(newDataViewPosition); + + // Save last mouse move arguments + _mouseMoveArguments = new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta); + + // Start selection scrolling timer + if(!_scrollTimer.Enabled) + { + // Start timer + _scrollTimer.Tick += new EventHandler(SelectionScrollingTimerEventProcessor); + _scrollTimer.Interval = 200; + _scrollTimer.Start(); + } + } + else + { + // Stop timer + _scrollTimer.Stop(); + _mouseMoveArguments = null; + } + } + } + } + + // Change cursor position and selection end position when mouse moving + if(this.IsUserEnabled) + { + SetCursorPixelPosition(new PointF(e.X, e.Y), true); + } + if(this.IsUserSelectionEnabled) + { + // Set selection + SetSelectionPixelPosition(PointF.Empty, new PointF(e.X, e.Y), true); + } + + // Clear flag to fire position changing events + _fireUserChangingEvent = false; + _fireUserChangedEvent = false; + + // Clear flag that data scaleView was scrolled + _viewScrolledOnMouseMove = false; + + } + } + + /// + /// This is the method to run when the timer is raised. + /// Used to scroll axis data scaleView while mouse is outside of the chart area. + /// + /// + /// + private void SelectionScrollingTimerEventProcessor(Object myObject, EventArgs myEventArgs) + { + // Simulate mouse move events + if(_mouseMoveArguments != null) + { + bool handled = false; + this.Cursor_MouseMove(_mouseMoveArguments, ref handled); + } + } + + #endregion + +#region Cursor helper methods + + /// + /// Helper function which returns a reference to the chart object + /// + /// Chart object reference. + private Chart GetChartObject() + { + if(this._chartArea != null ) + { + return this._chartArea.Chart; + } + + return null; + } + + /// + /// Get rectangle of the axis range selection. + /// + /// Selection rectangle. + /// Plot area rectangle. + /// + private RectangleF GetSelectionRect(RectangleF plotAreaPosition) + { + RectangleF rect = RectangleF.Empty; + + if(this._axis != null && + this.SelectionStart != this.SelectionEnd) + { + double start = (float)this._axis.GetLinearPosition(this.SelectionStart); + double end = (float)this._axis.GetLinearPosition(this.SelectionEnd); + + // Detect if cursor is horizontal or vertical + bool horizontal = true; + if(this.GetAxis().AxisPosition == AxisPosition.Bottom || this.GetAxis().AxisPosition == AxisPosition.Top) + { + horizontal = false; + } + + if(horizontal) + { + rect.X = plotAreaPosition.X; + rect.Width = plotAreaPosition.Width; + rect.Y = (float)Math.Min(start, end); + rect.Height = (float)Math.Max(start, end) - rect.Y; + } + else + { + rect.Y = plotAreaPosition.Y; + rect.Height = plotAreaPosition.Height; + rect.X = (float)Math.Min(start, end); + rect.Width = (float)Math.Max(start, end) - rect.X; + } + } + + return rect; + } + + /// + /// Get rectangle of the opposite axis selection + /// + /// Plot area rectangle. + /// Opposite selection rectangle. + private RectangleF GetOppositeSelectionRect(RectangleF plotAreaPosition) + { + if(_chartArea != null) + { + // Get opposite cursor + Cursor oppositeCursor = + (_attachedToXAxis == AxisName.X || _attachedToXAxis == AxisName.X2) ? + _chartArea.CursorY : _chartArea.CursorX; + return oppositeCursor.GetSelectionRect(plotAreaPosition); + } + + return RectangleF.Empty; + } + + /// + /// Converts X or Y position value to the cursor axis value + /// + /// Position in relative coordinates. + /// Cursor position as axis value. + private double PositionToCursorPosition(PointF position) + { + // Detect if cursor is horizontal or vertical + bool horizontal = true; + if(this.GetAxis().AxisPosition == AxisPosition.Bottom || this.GetAxis().AxisPosition == AxisPosition.Top) + { + horizontal = false; + } + + // Convert relative coordinates into axis values + double newCursorPosition = double.NaN; + if(horizontal) + { + newCursorPosition = this.GetAxis().PositionToValue(position.Y); + } + else + { + newCursorPosition = this.GetAxis().PositionToValue(position.X); + } + + // Round new position using Step & StepType properties + newCursorPosition = RoundPosition(newCursorPosition); + + return newCursorPosition; + } + + + /// + /// Checks if specified point is located inside the plotting area. + /// Converts pixel coordinates to relative. + /// + /// Point coordinates to test. + /// Indicates that coordinates must be rounded to area boundary. + /// PointF.IsEmpty or relative coordinates in plotting area. + private PointF GetPositionInPlotArea(PointF point, bool roundToBoundary) + { + PointF result = PointF.Empty; + + if(this._chartArea != null && this._chartArea.Common != null && this.GetAxis()!= null) + { + // Translate mouse pixel coordinates into the relative chart area coordinates + result.X = point.X * 100F / ((float)(this._chartArea.Common.Width - 1)); + result.Y = point.Y * 100F / ((float)(this._chartArea.Common.Height - 1)); + + // Round coordinate if it' outside chart plotting area + RectangleF plotAreaPosition = this._chartArea.PlotAreaPosition.ToRectangleF(); + if(roundToBoundary) + { + if(result.X < plotAreaPosition.X) + { + result.X = plotAreaPosition.X; + } + if(result.X > plotAreaPosition.Right) + { + result.X = plotAreaPosition.Right; + } + if(result.Y < plotAreaPosition.Y) + { + result.Y = plotAreaPosition.Y; + } + if(result.Y > plotAreaPosition.Bottom) + { + result.Y = plotAreaPosition.Bottom; + } + } + else + { + // Check if coordinate is inside chart plotting area + if(result.X < plotAreaPosition.X || + result.X > plotAreaPosition.Right || + result.Y < plotAreaPosition.Y || + result.Y > plotAreaPosition.Bottom) + { + result = PointF.Empty; + } + } + } + + return result; + } + + /// + /// Invalidate chart are with the cursor. + /// + /// Chart area must be invalidated. + private void Invalidate(bool invalidateArea) + { + if(this.GetChartObject() != null && this._chartArea != null && !this.GetChartObject().disableInvalidates) + { + // If data scaleView was scrolled - just invalidate the chart area + if(_viewScrolledOnMouseMove || invalidateArea || this.GetChartObject().dirtyFlag) + { + this._chartArea.Invalidate(); + } + + // If only cursor/selection position was changed - use optimized drawing algorithm + else + { + // Set flag to redraw cursor/selection only + this.GetChartObject().paintTopLevelElementOnly = true; + + // Invalidate and update the chart + this._chartArea.Invalidate(); + this.GetChartObject().Update(); + + // Clear flag to redraw cursor/selection only + this.GetChartObject().paintTopLevelElementOnly = false; + } + } + } + + /// + /// Gets axis objects the cursor is attached to. + /// + /// Axis object. + internal Axis GetAxis() + { + if(_axis == null && _chartArea != null) + { + if(_attachedToXAxis == AxisName.X) + { + _axis = (_axisType == AxisType.Primary) ? _chartArea.AxisX : _chartArea.AxisX2; + } + else + { + _axis = (_axisType == AxisType.Primary) ? _chartArea.AxisY : _chartArea.AxisY2; + } + } + + return _axis; + } + + #endregion + +#region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + // Dispose managed resources + if (this._scrollTimer != null) + { + this._scrollTimer.Dispose(); + this._scrollTimer = null; + } + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + } + + /// + /// The CursorEventArgs class stores the event arguments for cursor and selection events. + /// + public class CursorEventArgs : EventArgs + { +#region Private fields + + // Private fields for properties values storage + private ChartArea _chartArea = null; + private Axis _axis = null; + private double _newPosition = double.NaN; + private double _newSelectionStart = double.NaN; + private double _newSelectionEnd = double.NaN; + + #endregion + +#region Constructors + + /// + /// CursorEventArgs constructor. + /// + /// ChartArea of the cursor. + /// Axis of the cursor. + /// New cursor position. + public CursorEventArgs(ChartArea chartArea, Axis axis, double newPosition) + { + this._chartArea = chartArea; + this._axis = axis; + this._newPosition = newPosition; + this._newSelectionStart = double.NaN; + this._newSelectionEnd = double.NaN; + } + + /// + /// CursorEventArgs constructor. + /// + /// ChartArea of the cursor. + /// Axis of the cursor. + /// New range selection starting position. + /// New range selection ending position. + public CursorEventArgs(ChartArea chartArea, Axis axis, double newSelectionStart, double newSelectionEnd) + { + this._chartArea = chartArea; + this._axis = axis; + this._newPosition = double.NaN; + this._newSelectionStart = newSelectionStart; + this._newSelectionEnd = newSelectionEnd; + } + + #endregion + +#region Properties + + /// + /// ChartArea of the event. + /// + [ + SRDescription("DescriptionAttributeChartArea"), + ] + public ChartArea ChartArea + { + get + { + return _chartArea; + } + } + + /// + /// Axis of the event. + /// + [ + SRDescription("DescriptionAttributeAxis"), + ] + public Axis Axis + { + get + { + return _axis; + } + } + + /// + /// New cursor position. + /// + [ + SRDescription("DescriptionAttributeCursorEventArgs_NewPosition"), + ] + public double NewPosition + { + get + { + return _newPosition; + } + set + { + _newPosition = value; + } + } + + /// + /// New range selection starting position. + /// + [ + SRDescription("DescriptionAttributeCursorEventArgs_NewSelectionStart"), + ] + public double NewSelectionStart + { + get + { + return _newSelectionStart; + } + set + { + _newSelectionStart = value; + } + } + + /// + /// New range selection ending position. + /// + [ + SRDescription("DescriptionAttributeCursorEventArgs_NewSelectionEnd"), + ] + public double NewSelectionEnd + { + get + { + return _newSelectionEnd; + } + set + { + _newSelectionEnd = value; + } + } + + #endregion + } +} + +#endif // #if WINFORMS_CONTROL \ No newline at end of file diff --git a/System.Web.DataVisualization/Common/General/ChartElement.cs b/System.Web.DataVisualization/Common/General/ChartElement.cs new file mode 100644 index 000000000..7e36ac624 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ChartElement.cs @@ -0,0 +1,1458 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartElement.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ChartHelper +// +// Purpose: The chart element is base class for the big number +// of classes. It stores common methods and data. +// +// Reviewed: GS - August 2, 2002 +// AG - August 8, 2002 +// AG - Microsoft 16, 2007 +// +//=================================================================== + + +#region Used namespaces + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Collections; +using System.Diagnostics.CodeAnalysis; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Enumerations + + /// + /// An enumeration that specifies a label alignment. + /// + [ + Flags + ] + public enum LabelAlignmentStyles + { + /// + /// Label is aligned to the top of the data point. + /// + Top = 1, + /// + /// Label is aligned to the bottom of the data point. + /// + Bottom = 2, + /// + /// Label is aligned to the right of the data point. + /// + Right = 4, + /// + /// Label is aligned to the left of the data point. + /// + Left = 8, + /// + /// Label is aligned to the top-left corner of the data point. + /// + TopLeft = 16, + /// + /// Label is aligned to the top-right corner of the data point. + /// + TopRight = 32, + /// + /// Label is aligned to the bottom-left of the data point. + /// + BottomLeft = 64, + /// + /// Label is aligned to the bottom-right of the data point. + /// + BottomRight = 128, + /// + /// Label is aligned to the center of the data point. + /// + Center = 256, + } + + /// + /// An enumeration of chart types. + /// + public enum SeriesChartType + { + /// + /// Point chart type. + /// + Point, + + /// + /// FastPoint chart type. + /// + FastPoint, + + /// + /// Bubble chart type. + /// + Bubble, + /// + /// Line chart type. + /// + Line, + /// + /// Spline chart type. + /// + Spline, + /// + /// StepLine chart type. + /// + StepLine, + + /// + /// FastLine chart type. + /// + FastLine, + + /// + /// Bar chart type. + /// + Bar, + /// + /// Stacked bar chart type. + /// + StackedBar, + /// + /// Hundred percent stacked bar chart type. + /// + StackedBar100, + /// + /// Column chart type. + /// + Column, + /// + /// Stacked column chart type. + /// + StackedColumn, + /// + /// Hundred percent stacked column chart type. + /// + StackedColumn100, + /// + /// Area chart type. + /// + Area, + /// + /// Spline area chart type. + /// + SplineArea, + /// + /// Stacked area chart type. + /// + StackedArea, + /// + /// Hundred percent stacked area chart type. + /// + StackedArea100, + /// + /// Pie chart type. + /// + Pie, + /// + /// Doughnut chart type. + /// + Doughnut, + /// + /// Stock chart type. + /// + Stock, + /// + /// CandleStick chart type. + /// + Candlestick, + /// + /// Range chart type. + /// + Range, + /// + /// Spline range chart type. + /// + SplineRange, + /// + /// RangeBar chart type. + /// + RangeBar, + /// + /// Range column chart type. + /// + RangeColumn, + /// + /// Radar chart type. + /// + Radar, + /// + /// Polar chart type. + /// + Polar, + /// + /// Error bar chart type. + /// + ErrorBar, + /// + /// Box plot chart type. + /// + BoxPlot, + /// + /// Renko chart type. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Renko")] + Renko, + /// + /// ThreeLineBreak chart type. + /// + ThreeLineBreak, + /// + /// Kagi chart type. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Kagi")] + Kagi, + /// + /// PointAndFigure chart type. + /// + PointAndFigure, + /// + /// Funnel chart type. + /// + Funnel, + /// + /// Pyramid chart type. + /// + Pyramid, + } + + /// + /// Axis Arrow orientation + /// + internal enum ArrowOrientation + { + /// + /// Arrow direction is Right - Left + /// + Left, + /// + /// Arrow direction is Left - Right + /// + Right, + /// + /// Arrow direction is Bottom - Top + /// + Top, + /// + /// Arrow direction is Top - Bottom + /// + Bottom + } + + /// + /// An enumeration of image alignment. + /// + public enum ChartImageAlignmentStyle + { + /// + /// The mage is aligned to the top left corner of the chart element. + /// + TopLeft, + /// + /// The image is aligned to the top boundary of the chart element. + /// + Top, + /// + /// The image is aligned to the top right corner of the chart element. + /// + TopRight, + /// + /// The image is aligned to the right boundary of the chart element. + /// + Right, + /// + /// The image is aligned to the bottom right corner of the chart element. + /// + BottomRight, + /// + /// The image is aligned to the bottom boundary of the chart element. + /// + Bottom, + /// + /// The image is aligned to the bottom left corner of the chart element. + /// + BottomLeft, + /// + /// The image is aligned to the left boundary of the chart element. + /// + Left, + /// + /// The image is aligned in the center of the chart element. + /// + Center + }; + + /// + /// An enumeration that specifies a background image drawing mode. + /// + public enum ChartImageWrapMode + { + /// + /// Background image is scaled to fit the entire chart element. + /// + Scaled = WrapMode.Clamp, + + /// + /// Background image is tiled to fit the entire chart element. + /// + Tile = WrapMode.Tile, + + /// + /// Every other tiled image is reversed around the X-axis. + /// + TileFlipX = WrapMode.TileFlipX, + + /// + /// Every other tiled image is reversed around the X-axis and Y-axis. + /// + TileFlipXY = WrapMode.TileFlipXY, + + /// + /// Every other tiled image is reversed around the Y-axis. + /// + TileFlipY = WrapMode.TileFlipY, + + /// + /// Background image is not scaled. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Unscaled")] + Unscaled = 100 + }; + + /// + /// An enumeration that specifies the state of an axis. + /// + public enum AxisEnabled + { + /// + /// The axis is only enabled if it used to plot a Series. + /// + Auto, + + /// + /// The axis is always enabled. + /// + True, + + /// + /// The axis is never enabled. + /// + False + + }; + + /// + /// An enumeration of units of measurement of an interval. + /// + public enum DateTimeIntervalType + { + /// + /// Automatically determined by the Chart control. + /// + Auto, + + /// + /// The interval is numerical. + /// + Number, + + /// + /// The interval is years. + /// + Years, + + /// + /// The interval is months. + /// + Months, + + /// + /// The interval is weeks. + /// + Weeks, + + /// + /// The interval is days. + /// + Days, + + /// + /// The interval is hours. + /// + Hours, + + /// + /// The interval is minutes. + /// + Minutes, + + /// + /// The interval is seconds. + /// + Seconds, + + /// + /// The interval is milliseconds. + /// + Milliseconds, + + /// + /// The interval type is not defined. + /// + NotSet, + } + + /// + /// An enumeration that specifies value types for various chart properties + /// + public enum ChartValueType + { + /// + /// Property type is set automatically by the Chart control. + /// + Auto, + + /// + /// Double value. + /// + Double, + + /// + /// Single value. + /// + Single, + + /// + /// Int32 value. + /// + Int32, + + /// + /// Int64 value. + /// + Int64, + + /// + /// UInt32 value. + /// + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", + Justification = "These names are patterned after the standard CLR types for consistency")] + UInt32, + + /// + /// UInt64 value. + /// + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", + Justification = "These names are patterned after the standard CLR types for consistency")] + UInt64, + + /// + /// String value. + /// + String, + + /// + /// DateTime value. + /// + DateTime, + + /// + /// Date portion of the DateTime value. + /// + Date, + + /// + /// Time portion of the DateTime value. + /// + Time, + + /// + /// DateTime with offset + /// + DateTimeOffset + }; + + /// + /// An enumeration that specifies a hatching style. + /// + public enum ChartHatchStyle + { + /// + /// No hatching style. + /// + None, + /// + /// Backward diagonal style. + /// + BackwardDiagonal, + /// + /// Cross style. + /// + Cross, + /// + /// Dark downward diagonal style. + /// + DarkDownwardDiagonal, + /// + /// Dark horizontal style. + /// + DarkHorizontal, + /// + /// Dark upward diagonal style. + /// + DarkUpwardDiagonal, + /// + /// Dark vertical style. + /// + DarkVertical, + /// + /// Dashed downward diagonal style. + /// + DashedDownwardDiagonal, + /// + /// Dashed horizontal style. + /// + DashedHorizontal, + /// + /// Dashed upward diagonal style. + /// + DashedUpwardDiagonal, + /// + /// Dashed vertical style. + /// + DashedVertical, + /// + /// Diagonal brick style. + /// + DiagonalBrick, + /// + /// Diagonal cross style. + /// + DiagonalCross, + /// + /// Divot style. + /// + Divot, + /// + /// Dotted diamond style. + /// + DottedDiamond, + /// + /// Dotted grid style. + /// + DottedGrid, + /// + /// Forward diagonal style. + /// + ForwardDiagonal, + /// + /// Horizontal style. + /// + Horizontal, + /// + /// Horizontal brick style. + /// + HorizontalBrick, + /// + /// Large checker board style. + /// + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "CheckerBoard")] + LargeCheckerBoard, + /// + /// Large confetti style. + /// + LargeConfetti, + /// + /// Large grid style. + /// + LargeGrid, + /// + /// Light downward diagonal style. + /// + LightDownwardDiagonal, + /// + /// Light horizontal style. + /// + LightHorizontal, + /// + /// Light upward diagonal style. + /// + LightUpwardDiagonal, + /// + /// Light vertical style. + /// + LightVertical, + /// + /// Narrow horizontal style. + /// + NarrowHorizontal, + /// + /// Narrow vertical style. + /// + NarrowVertical, + /// + /// Outlined diamond style. + /// + OutlinedDiamond, + /// + /// Percent05 style. + /// + Percent05, + /// + /// Percent10 style. + /// + Percent10, + /// + /// Percent20 style. + /// + Percent20, + /// + /// Percent25 style. + /// + Percent25, + /// + /// Percent30 style. + /// + Percent30, + /// + /// Percent40 style. + /// + Percent40, + /// + /// Percent50 style. + /// + Percent50, + /// + /// Percent60 style. + /// + Percent60, + /// + /// Percent70 style. + /// + Percent70, + /// + /// Percent75 style. + /// + Percent75, + /// + /// Percent80 style. + /// + Percent80, + /// + /// Percent90 style. + /// + Percent90, + /// + /// Plaid style. + /// + Plaid, + /// + /// Shingle style. + /// + Shingle, + /// + /// Small checker board style. + /// + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "CheckerBoard")] + SmallCheckerBoard, + /// + /// Small confetti style. + /// + SmallConfetti, + /// + /// Small grid style. + /// + SmallGrid, + /// + /// Solid diamond style. + /// + SolidDiamond, + /// + /// Sphere style. + /// + Sphere, + /// + /// Trellis style. + /// + Trellis, + /// + /// Vertical style. + /// + Vertical, + /// + /// Wave style. + /// + Wave, + /// + /// Weave style. + /// + Weave, + /// + /// Wide downward diagonal style. + /// + WideDownwardDiagonal, + /// + /// Wide upward diagonal style. + /// + WideUpwardDiagonal, + /// + /// ZigZag style. + /// + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "ZigZag")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Zig")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Zag")] + ZigZag + }; + + /// + /// An enumeration that specifies the level of anti-aliasing quality. + /// + public enum TextAntiAliasingQuality + { + /// + /// Normal anti-aliasing quality. + /// + Normal, + /// + /// High anti-aliasing quality. + /// + High, + /// + /// System default anti-aliasing quality. + /// + SystemDefault + } + + /// + /// An enumeration of anti-aliasing flags. + /// + [Flags] + public enum AntiAliasingStyles + { + /// + /// No anti-aliasing. + /// + None = 0, + + /// + /// Use anti-aliasing when drawing text. + /// + Text = 1, + + /// + /// Use anti-aliasing when drawing grahics primitives (e.g. lines, rectangle) + /// + Graphics = 2, + + /// + /// Use anti-alias for everything. + /// + All = Text | Graphics + + }; + + /// + /// An enumeration of marker styles. + /// + public enum MarkerStyle + { + /// + /// No marker is displayed for the series/data point. + /// + None = 0, + + /// + /// A square marker is displayed. + /// + Square = 1, + + /// + /// A circle marker is displayed. + /// + Circle = 2, + + /// + /// A diamond-shaped marker is displayed. + /// + Diamond = 3, + + /// + /// A triangular marker is displayed. + /// + Triangle = 4, + + /// + /// A cross-shaped marker is displayed. + /// + Cross = 5, + + /// + /// A 4-point star-shaped marker is displayed. + /// + Star4 = 6, + + /// + /// A 5-point star-shaped marker is displayed. + /// + Star5 = 7, + + /// + /// A 6-point star-shaped marker is displayed. + /// + Star6 = 8, + + /// + /// A 10-point star-shaped marker is displayed. + /// + Star10 = 9 + + }; + + /// + /// An enumeration of gradient styles. + /// + public enum GradientStyle + { + /// + /// No gradient is used. + /// + None, + + /// + /// Gradient is applied from left to right. + /// + LeftRight, + + /// + /// Gradient is applied from top to bottom. + /// + TopBottom, + + /// + /// Gradient is applied from the center outwards. + /// + Center, + + /// + /// Gradient is applied diagonally from left to right. + /// + DiagonalLeft, + + /// + /// Gradient is applied diagonally from right to left. + /// + DiagonalRight, + + /// + /// Gradient is applied horizontally from the center outwards. + /// + HorizontalCenter, + + /// + /// Gradient is applied vertically from the center outwards. + /// + VerticalCenter + }; + + #endregion + + #region ChartElement + + /// + /// Common chart helper methods used across different chart elements. + /// + internal class ChartHelper + { + #region Fields + + /// + /// Maximum number of grid lines per Axis + /// + internal const int MaxNumOfGridlines = 10000; + + #endregion // Fields + + #region Constructor + + /// + /// Private constructor to avoid instantiating the class + /// + private ChartHelper() { } + + #endregion // Constructor + + #region Methods + + /// + /// Adjust the beginnin of the first interval depending on the type and size. + /// + /// Original start point. + /// Interval size. + /// AxisName of the interval (Month, Year, ...). + /// Adjusted interval start position as double. + internal static double AlignIntervalStart(double start, double intervalSize, DateTimeIntervalType type) + { + return AlignIntervalStart(start, intervalSize, type, null); + } + + /// + /// Adjust the beginnin of the first interval depending on the type and size. + /// + /// Original start point. + /// Interval size. + /// AxisName of the interval (Month, Year, ...). + /// First series connected to the axis. + /// Adjusted interval start position as double. + internal static double AlignIntervalStart(double start, double intervalSize, DateTimeIntervalType type, Series series) + { + return AlignIntervalStart( start, intervalSize, type, series, true ); + } + + /// + /// Adjust the beginnin of the first interval depending on the type and size. + /// + /// Original start point. + /// Interval size. + /// AxisName of the interval (Month, Year, ...). + /// First series connected to the axis. + /// Interval is used for major gridlines or tickmarks. + /// Adjusted interval start position as double. + internal static double AlignIntervalStart(double start, double intervalSize, DateTimeIntervalType type, Series series, bool majorInterval) + { + // Special case for indexed series + if(series != null && series.IsXValueIndexed) + { + if(type == DateTimeIntervalType.Auto || + type == DateTimeIntervalType.Number) + { + if( majorInterval ) + { + return 1; + } + else + { + return 0; + } + } + + return -(series.Points.Count + 1); + } + + // Non indexed series + else + { + // Do not adjust start position for these interval type + if(type == DateTimeIntervalType.Auto || + type == DateTimeIntervalType.Number) + { + return start; + } + + // Get the beginning of the interval depending on type + DateTime newStartDate = DateTime.FromOADate(start); + + // Adjust the months interval depending on size + if(intervalSize > 0.0 && intervalSize != 1.0) + { + if(type == DateTimeIntervalType.Months && intervalSize <= 12.0 && intervalSize > 1) + { + // Make sure that the beginning is aligned correctly for cases + // like quarters and half years + DateTime resultDate = newStartDate; + DateTime sizeAdjustedDate = new DateTime(newStartDate.Year, 1, 1, 0, 0, 0); + while(sizeAdjustedDate < newStartDate) + { + resultDate = sizeAdjustedDate; + sizeAdjustedDate = sizeAdjustedDate.AddMonths((int)intervalSize); + } + + newStartDate = resultDate; + return newStartDate.ToOADate(); + } + } + + // Check interval type + switch(type) + { + case(DateTimeIntervalType.Years): + int year = (int)((int)(newStartDate.Year / intervalSize) * intervalSize); + if(year <= 0) + { + year = 1; + } + newStartDate = new DateTime(year, + 1, 1, 0, 0, 0); + break; + + case(DateTimeIntervalType.Months): + int month = (int)((int)(newStartDate.Month / intervalSize) * intervalSize); + if(month <= 0) + { + month = 1; + } + newStartDate = new DateTime(newStartDate.Year, + month, 1, 0, 0, 0); + break; + + case(DateTimeIntervalType.Days): + int day = (int)((int)(newStartDate.Day / intervalSize) * intervalSize); + if(day <= 0) + { + day = 1; + } + newStartDate = new DateTime(newStartDate.Year, + newStartDate.Month, day, 0, 0, 0); + break; + + case(DateTimeIntervalType.Hours): + int hour = (int)((int)(newStartDate.Hour / intervalSize) * intervalSize); + newStartDate = new DateTime(newStartDate.Year, + newStartDate.Month, newStartDate.Day, hour, 0, 0); + break; + + case(DateTimeIntervalType.Minutes): + int minute = (int)((int)(newStartDate.Minute / intervalSize) * intervalSize); + newStartDate = new DateTime(newStartDate.Year, + newStartDate.Month, + newStartDate.Day, + newStartDate.Hour, + minute, + 0); + break; + + case(DateTimeIntervalType.Seconds): + int second = (int)((int)(newStartDate.Second / intervalSize) * intervalSize); + newStartDate = new DateTime(newStartDate.Year, + newStartDate.Month, + newStartDate.Day, + newStartDate.Hour, + newStartDate.Minute, + second, + 0); + break; + + case(DateTimeIntervalType.Milliseconds): + int milliseconds = (int)((int)(newStartDate.Millisecond / intervalSize) * intervalSize); + newStartDate = new DateTime(newStartDate.Year, + newStartDate.Month, + newStartDate.Day, + newStartDate.Hour, + newStartDate.Minute, + newStartDate.Second, + milliseconds); + break; + + case(DateTimeIntervalType.Weeks): + + // NOTE: Code below was changed to fix issue #5962 + // Elements that have interval set to weeks should be aligned to the + // nearest Monday no matter how many weeks is the interval. + //newStartDate = newStartDate.AddDays(-((int)newStartDate.DayOfWeek * intervalSize)); + newStartDate = newStartDate.AddDays(-((int)newStartDate.DayOfWeek)); + newStartDate = new DateTime(newStartDate.Year, + newStartDate.Month, newStartDate.Day, 0, 0, 0); + break; + } + + return newStartDate.ToOADate(); + } + } + + + /// + /// Gets interval size as double number. + /// + /// Current value. + /// Interval size. + /// AxisName of the interval (Month, Year, ...). + /// Interval size as double. + internal static double GetIntervalSize(double current, double interval, DateTimeIntervalType type) + { + return GetIntervalSize( + current, + interval, + type, + null, + 0, + DateTimeIntervalType.Number, + true, + true); + } + + /// + /// Gets interval size as double number. + /// + /// Current value. + /// Interval size. + /// AxisName of the interval (Month, Year, ...). + /// First series connected to the axis. + /// Offset size. + /// Offset type(Month, Year, ...). + /// Force Integer indexed + /// Interval size as double. + internal static double GetIntervalSize( + double current, + double interval, + DateTimeIntervalType type, + Series series, + double intervalOffset, + DateTimeIntervalType intervalOffsetType, + bool forceIntIndex) + { + return GetIntervalSize( + current, + interval, + type, + series, + intervalOffset, + intervalOffsetType, + forceIntIndex, + true); + } + + /// + /// Gets interval size as double number. + /// + /// Current value. + /// Interval size. + /// AxisName of the interval (Month, Year, ...). + /// First series connected to the axis. + /// Offset size. + /// Offset type(Month, Year, ...). + /// Force Integer indexed + /// Force Integer indexed + /// Interval size as double. + internal static double GetIntervalSize( + double current, + double interval, + DateTimeIntervalType type, + Series series, + double intervalOffset, + DateTimeIntervalType intervalOffsetType, + bool forceIntIndex, + bool forceAbsInterval) + { + // AxisName is not date. + if( type == DateTimeIntervalType.Number || type == DateTimeIntervalType.Auto ) + { + return interval; + } + + // Special case for indexed series + if(series != null && series.IsXValueIndexed) + { + // Check point index + int pointIndex = (int)Math.Ceiling(current - 1); + if(pointIndex < 0) + { + pointIndex = 0; + } + if(pointIndex >= series.Points.Count || series.Points.Count <= 1) + { + return interval; + } + + // Get starting and ending values of the closest interval + double adjuster = 0; + double xValue = series.Points[pointIndex].XValue; + xValue = AlignIntervalStart(xValue, 1, type, null); + double xEndValue = xValue + GetIntervalSize(xValue, interval, type); + xEndValue += GetIntervalSize(xEndValue, intervalOffset, intervalOffsetType); + xValue += GetIntervalSize(xValue, intervalOffset, intervalOffsetType); + if(intervalOffset < 0) + { + xValue = xValue + GetIntervalSize(xValue, interval, type); + xEndValue = xEndValue + GetIntervalSize(xEndValue, interval, type); + } + + // The first point in the series + if(pointIndex == 0 && current < 0) + { + // Round the first point value depending on the interval type + DateTime dateValue = DateTime.FromOADate(series.Points[pointIndex].XValue); + DateTime roundedDateValue = dateValue; + switch(type) + { + case(DateTimeIntervalType.Years): // Ignore hours,... + roundedDateValue = new DateTime(dateValue.Year, + dateValue.Month, dateValue.Day, 0, 0, 0); + break; + + case(DateTimeIntervalType.Months): // Ignore hours,... + roundedDateValue = new DateTime(dateValue.Year, + dateValue.Month, dateValue.Day, 0, 0, 0); + break; + + case(DateTimeIntervalType.Days): // Ignore hours,... + roundedDateValue = new DateTime(dateValue.Year, + dateValue.Month, dateValue.Day, 0, 0, 0); + break; + + case(DateTimeIntervalType.Hours): // + roundedDateValue = new DateTime(dateValue.Year, + dateValue.Month, dateValue.Day, dateValue.Hour, + dateValue.Minute, 0); + break; + + case(DateTimeIntervalType.Minutes): + roundedDateValue = new DateTime(dateValue.Year, + dateValue.Month, + dateValue.Day, + dateValue.Hour, + dateValue.Minute, + dateValue.Second); + break; + + case(DateTimeIntervalType.Seconds): + roundedDateValue = new DateTime(dateValue.Year, + dateValue.Month, + dateValue.Day, + dateValue.Hour, + dateValue.Minute, + dateValue.Second, + 0); + break; + + case(DateTimeIntervalType.Weeks): + roundedDateValue = new DateTime(dateValue.Year, + dateValue.Month, dateValue.Day, 0, 0, 0); + break; + } + + // The first point value is exactly on the interval boundaries + if(roundedDateValue.ToOADate() == xValue || roundedDateValue.ToOADate() == xEndValue) + { + return - current + 1; + } + } + + // Adjuster of 0.5 means that position should be between points + ++pointIndex; + while(pointIndex < series.Points.Count) + { + if(series.Points[pointIndex].XValue >= xEndValue) + { + if(series.Points[pointIndex].XValue > xEndValue && !forceIntIndex) + { + adjuster = -0.5; + } + break; + } + + ++pointIndex; + } + + // If last point outside of the max series index + if(pointIndex == series.Points.Count) + { + pointIndex += series.Points.Count/5 + 1; + } + + double size = (pointIndex + 1) - current + adjuster; + + return (size != 0) ? size : interval; + } + + // Non indexed series + else + { + DateTime date = DateTime.FromOADate(current); + TimeSpan span = new TimeSpan(0); + + if(type == DateTimeIntervalType.Days) + { + span = TimeSpan.FromDays(interval); + } + else if(type == DateTimeIntervalType.Hours) + { + span = TimeSpan.FromHours(interval); + } + else if(type == DateTimeIntervalType.Milliseconds) + { + span = TimeSpan.FromMilliseconds(interval); + } + else if(type == DateTimeIntervalType.Seconds) + { + span = TimeSpan.FromSeconds(interval); + } + else if(type == DateTimeIntervalType.Minutes) + { + span = TimeSpan.FromMinutes(interval); + } + else if(type == DateTimeIntervalType.Weeks) + { + span = TimeSpan.FromDays(7.0 * interval); + } + else if(type == DateTimeIntervalType.Months) + { + // Special case handling when current date points + // to the last day of the month + bool lastMonthDay = false; + if(date.Day == DateTime.DaysInMonth(date.Year, date.Month)) + { + lastMonthDay = true; + } + + // Add specified amount of months + date = date.AddMonths((int)Math.Floor(interval)); + span = TimeSpan.FromDays(30.0 * ( interval - Math.Floor(interval) )); + + // Check if last month of the day was used + if(lastMonthDay && span.Ticks == 0) + { + // Make sure the last day of the month is selected + int daysInMobth = DateTime.DaysInMonth(date.Year, date.Month); + date = date.AddDays(daysInMobth - date.Day); + } + } + else if(type == DateTimeIntervalType.Years) + { + date = date.AddYears((int)Math.Floor(interval)); + span = TimeSpan.FromDays(365.0 * ( interval - Math.Floor(interval) )); + } + + // Check if an absolute interval size must be returned + double result = date.Add(span).ToOADate() - current; + if(forceAbsInterval) + { + result = Math.Abs(result); + } + return result; + } + } + + /// + /// Check if series is indexed. IsXValueIndexed flag is set or all X values are zeros. + /// + /// Data series to test. + /// True if series is indexed. + static internal bool IndexedSeries( Series series) + { + // X value indexed flag set + if (series.IsXValueIndexed) + { + return true; + } + + if (Utilities.CustomPropertyRegistry.IsXAxisQuantitativeChartTypes.Contains(series.ChartType) && + series.IsCustomPropertySet(Utilities.CustomPropertyName.IsXAxisQuantitative)) + { + string attribValue = series[Utilities.CustomPropertyName.IsXAxisQuantitative]; + if (String.Compare(attribValue, "True", StringComparison.OrdinalIgnoreCase) == 0) + { + return false; + } + } + + // Check if series has all X values set to zero + return SeriesXValuesZeros(series); + } + + /// + /// Check if all data points in the series have X value set to 0. + /// + /// Data series to check. + static private bool SeriesXValuesZeros( Series series ) + { + // Check if X value zeros check was already done + if(series.xValuesZerosChecked) + { + return series.xValuesZeros; + } + + // Data point loop + series.xValuesZerosChecked = true; + series.xValuesZeros = true; + foreach( DataPoint point in series.Points ) + { + if( point.XValue != 0.0 ) + { + // If any data point has value different than 0 return false + series.xValuesZeros = false; + break; + } + } + return series.xValuesZeros; + } + + /// + /// Check if any series is indexed. IsXValueIndexed flag is set or all X values are zeros. + /// + /// Reference to common chart classes. + /// Data series names. + /// True if any series is indexed. + static internal bool IndexedSeries(CommonElements common, params string[] series) + { + // Data series loop + bool zeroXValues = true; + foreach (string ser in series) + { + Series localSeries = common.DataManager.Series[ser]; + + // Check series indexed flag + if (localSeries.IsXValueIndexed) + { + // If flag set in at least one series - all series are indexed + return true; + } + + // Check if series has all X values set to zero + if (zeroXValues && !IndexedSeries(localSeries)) + { + zeroXValues = false; + } + } + + return zeroXValues; + } + + /// + /// Check if all data points in many series have X value set to 0. + /// + /// Reference to common chart classes. + /// Data series. + /// True if all data points have value 0. + static internal bool SeriesXValuesZeros(CommonElements common, params string[] series) + { + // Data series loop + foreach( string ser in series ) + { + // Check one series X values + if(!SeriesXValuesZeros(common.DataManager.Series[ ser ])) + { + return false; + } + } + return true; + } + + #endregion + } + + #endregion //ChartElement +} diff --git a/System.Web.DataVisualization/Common/General/ChartGraphics.cs b/System.Web.DataVisualization/Common/General/ChartGraphics.cs new file mode 100644 index 000000000..ac6545a25 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ChartGraphics.cs @@ -0,0 +1,5779 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartGraphics.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ChartGraphics +// +// Purpose: Chart graphic class is used for drawing Chart +// elements as Rectangles, Pie slices, lines, areas +// etc. This class is used in all classes where +// drawing is necessary. The GDI+ graphic class is +// used throw this class. Encapsulates a GDI+ chart +// drawing functionality +// +// Reviewed: GS - Jul 31, 2002 +// AG - August 7, 2002 +// AG - Microsoft 16, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Drawing.Imaging; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Enumerations + + /// + /// Defines the style how the bars/columns are drawn. + /// + internal enum BarDrawingStyle + { + /// + /// Default bar/column style. + /// + Default, + + /// + /// Cylinder bar/column style. + /// + Cylinder, + + /// + /// Emboss bar/column style. + /// + Emboss, + + /// + /// LightToDark bar/column style. + /// + LightToDark, + + /// + /// Wedge bar/column style. + /// + Wedge, + } + + /// + /// Defines the style how the pie and doughnut charts are drawn. + /// + internal enum PieDrawingStyle + { + /// + /// Default pie/doughnut drawing style. + /// + Default, + + /// + /// Soft edge shadow is drawn on the edges of the pie/doughnut slices. + /// + SoftEdge, + + /// + /// A shadow is drawn from the top to the bottom of the pie/doughnut chart. + /// + Concave, + } + + /// + /// An enumeration of line styles. + /// + public enum ChartDashStyle + { + /// + /// Line style not set + /// + NotSet, + /// + /// Specifies a line consisting of dashes. + /// + Dash, + /// + /// Specifies a line consisting of a repeating pattern of dash-dot. + /// + DashDot, + /// + /// Specifies a line consisting of a repeating pattern of dash-dot-dot. + /// + DashDotDot, + /// + /// Specifies a line consisting of dots. + /// + Dot, + /// + /// Specifies a solid line. + /// + Solid, + } + + #endregion + + /// + /// The ChartGraphics class provides all chart drawing capabilities. + /// It contains methods for drawing 2D primitives and also exposes + /// all ChartGraphics3D class methods for 3D shapes. Only this + /// class should be used for any drawing in the chart. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public partial class ChartGraphics : ChartElement + { + #region Fields + + // Common Elements + private CommonElements _common; + + // Reusable objects + private Pen _pen; + private SolidBrush _solidBrush; + private Matrix _myMatrix; + + // Private fields which represents picture size + private int _width; + private int _height; + + // Indicates that smoothing is applied while drawing shadows + internal bool softShadows = true; + + // Anti aliasing flags + private AntiAliasingStyles _antiAliasing = AntiAliasingStyles.All; + + // True if rendering into the metafile + internal bool IsMetafile = false; + + #endregion + + #region Lines Methods + + /// + /// Draws a line connecting the two specified points. + /// + /// Line color. + /// Line width. + /// Line style. + /// A Point that represents the first point to connect. + /// A Point that represents the second point to connect. + internal void DrawLineRel( + Color color, + int width, + ChartDashStyle style, + PointF firstPointF, + PointF secondPointF + ) + { + DrawLineAbs( + color, + width, + style, + GetAbsolutePoint(firstPointF), + GetAbsolutePoint(secondPointF) ); + } + + /// + /// Draws a line connecting the two specified points using absolute coordinates. + /// + /// Line color. + /// Line width. + /// Line style. + /// A Point that represents the first point to connect. + /// A Point that represents the second point to connect. + internal void DrawLineAbs( + Color color, + int width, + ChartDashStyle style, + PointF firstPoint, + PointF secondPoint + ) + { + // Do not draw line if width is 0 or style not set + if( width == 0 || style == ChartDashStyle.NotSet ) + { + return; + } + + // Set a line color + if(_pen.Color != color) + { + _pen.Color = color; + } + + // Set a line width + if(_pen.Width != width) + { + _pen.Width = width; + } + + // Set a line style + if(_pen.DashStyle != GetPenStyle( style )) + { + _pen.DashStyle = GetPenStyle( style ); + } + + // Remember SmoothingMode and turn off anti aliasing for + // vertical or horizontal lines usinig 1 pixel dashed pen. + // This prevents anialiasing from completly smoothing the + // dashed line. + SmoothingMode oldSmoothingMode = this.SmoothingMode; + if(width <= 1 && style != ChartDashStyle.Solid) + { + if(firstPoint.X == secondPoint.X || + firstPoint.Y == secondPoint.Y) + { + this.SmoothingMode = SmoothingMode.Default; + } + } + + // Draw a line + this.DrawLine(_pen, + (float)Math.Round(firstPoint.X), + (float)Math.Round(firstPoint.Y), + (float)Math.Round(secondPoint.X), + (float)Math.Round(secondPoint.Y) ); + + // Return old smoothing mode + this.SmoothingMode = oldSmoothingMode; + } + + /// + /// Draws a line with shadow connecting the two specified points. + /// + /// Line color. + /// Line width. + /// Line style. + /// A Point that represents the first point to connect. + /// A Point that represents the second point to connect. + /// Shadow Color. + /// Shadow Offset. + internal void DrawLineRel( + Color color, + int width, + ChartDashStyle style, + PointF firstPoint, + PointF secondPoint, + Color shadowColor, + int shadowOffset + ) + { + DrawLineAbs( + color, + width, + style, + GetAbsolutePoint(firstPoint), + GetAbsolutePoint(secondPoint), + shadowColor, + shadowOffset ); + } + + /// + /// Draws a line with shadow connecting the two specified points. + /// + /// Line color. + /// Line width. + /// Line style. + /// A Point that represents the first point to connect. + /// A Point that represents the second point to connect. + /// Shadow Color. + /// Shadow Offset. + internal void DrawLineAbs( + Color color, + int width, + ChartDashStyle style, + PointF firstPoint, + PointF secondPoint, + Color shadowColor, + int shadowOffset + ) + { + if(shadowOffset != 0) + { + // Shadow color + Color shColor; + + // Make shadow semi transparent + // if alpha value not used + if( shadowColor.A != 255 ) + shColor = shadowColor; + else + shColor = Color.FromArgb(color.A/2, shadowColor); + + // Set shadow line position + PointF firstShadow = new PointF( firstPoint.X + shadowOffset, firstPoint.Y + shadowOffset); + PointF secondShadow = new PointF( secondPoint.X + shadowOffset, secondPoint.Y + shadowOffset ); + + // Draw Shadow of Line + DrawLineAbs( shColor, width, style, firstShadow, secondShadow ); + } + + // Draw Line + DrawLineAbs( color, width, style, firstPoint, secondPoint ); + } + + #endregion + + #region Pen and Brush Methods + + /// + /// Creates a Hatch Brush. + /// + /// Chart Hatch style. + /// Back Color. + /// Fore Color. + /// Brush + internal Brush GetHatchBrush( + ChartHatchStyle hatchStyle, + Color backColor, + Color foreColor + ) + { + // Convert Chart Hatch Style enum + // to Hatch Style enum. + HatchStyle hatch; + hatch = (HatchStyle)Enum.Parse(typeof(HatchStyle),hatchStyle.ToString()); + + // Create Hatch Brush + return new HatchBrush( hatch, foreColor, backColor ); + } + + /// + /// Creates a textured brush. + /// + /// Image file name or URL. + /// Image transparent color. + /// Wrap mode. + /// Image background color. + /// Textured brush. + internal Brush GetTextureBrush( + string name, + Color backImageTransparentColor, + ChartImageWrapMode mode, + Color backColor + ) + { + // Load a image + System.Drawing.Image image = _common.ImageLoader.LoadImage( name ); + + // Create a brush + ImageAttributes attrib = new ImageAttributes(); + attrib.SetWrapMode((mode == ChartImageWrapMode.Unscaled) ? WrapMode.Clamp : ((WrapMode)mode)); + if(backImageTransparentColor != Color.Empty) + { + attrib.SetColorKey(backImageTransparentColor, backImageTransparentColor, ColorAdjustType.Default); + } + + // If image is a metafile background must be filled first + // Solves issue that background is not cleared correctly + if(backImageTransparentColor == Color.Empty && + image is Metafile && + backColor != Color.Transparent) + { + TextureBrush backFilledBrush = null; + Bitmap bitmap = new Bitmap(image.Width, image.Height); + using(Graphics graphics = Graphics.FromImage(bitmap)) + { + using(SolidBrush backBrush = new SolidBrush(backColor)) + { + graphics.FillRectangle(backBrush, 0, 0, image.Width, image.Height); + graphics.DrawImageUnscaled(image, 0, 0); + backFilledBrush= new TextureBrush( bitmap, new RectangleF(0,0,image.Width,image.Height), attrib); + } + } + + return backFilledBrush; + } + + + TextureBrush textureBrush; + + if (ImageLoader.DoDpisMatch(image, this.Graphics)) + textureBrush = new TextureBrush(image, new RectangleF(0, 0, image.Width, image.Height), attrib); + else // if the image dpi does not match the graphics dpi we have to scale the image + { + Image scaledImage = ImageLoader.GetScaledImage(image, this.Graphics); + textureBrush = new TextureBrush(scaledImage, new RectangleF(0, 0, scaledImage.Width, scaledImage.Height), attrib); + scaledImage.Dispose(); + } + + return textureBrush; + + } + + /// + /// This method creates a gradient brush. + /// + /// A rectangle which has to be filled with a gradient color. + /// First color. + /// Second color. + /// Gradient type . + /// Gradient Brush + internal Brush GetGradientBrush( + RectangleF rectangle, + Color firstColor, + Color secondColor, + GradientStyle type + ) + { + // Increse the brush rectangle by 1 pixel to ensure the fit + rectangle.Inflate(1f, 1f); + + Brush gradientBrush = null; + float angle = 0; + + // Function which create gradient brush fires exception if + // rectangle size is zero. + if( rectangle.Height == 0 || rectangle.Width == 0 ) + { + gradientBrush = new SolidBrush( Color.Black ); + return gradientBrush; + } + + // ******************************************* + // Linear Gradient + // ******************************************* + // Check linear type . + if( type == GradientStyle.LeftRight || type == GradientStyle.VerticalCenter ) + { + angle = 0; + } + else if( type == GradientStyle.TopBottom || type == GradientStyle.HorizontalCenter ) + { + angle = 90; + } + else if( type == GradientStyle.DiagonalLeft ) + { + angle = (float)(Math.Atan(rectangle.Width / rectangle.Height)* 180 / Math.PI); + } + else if( type == GradientStyle.DiagonalRight ) + { + angle = (float)(180 - Math.Atan(rectangle.Width / rectangle.Height)* 180 / Math.PI); + } + + // Create a linear gradient brush + if( type == GradientStyle.TopBottom || type == GradientStyle.LeftRight + || type == GradientStyle.DiagonalLeft || type == GradientStyle.DiagonalRight + || type == GradientStyle.HorizontalCenter || type == GradientStyle.VerticalCenter ) + { + RectangleF tempRect = new RectangleF(rectangle.X,rectangle.Y,rectangle.Width,rectangle.Height); + // For Horizontal and vertical center gradient types + if( type == GradientStyle.HorizontalCenter ) + { + // Resize and wrap gradient + tempRect.Height = tempRect.Height / 2F; + LinearGradientBrush linearGradientBrush = new LinearGradientBrush(tempRect, firstColor, secondColor, angle); + gradientBrush = linearGradientBrush; + linearGradientBrush.WrapMode = WrapMode.TileFlipX; + } + else if( type == GradientStyle.VerticalCenter ) + { + // Resize and wrap gradient + tempRect.Width = tempRect.Width / 2F; + LinearGradientBrush linearGradientBrush = new LinearGradientBrush(tempRect, firstColor, secondColor, angle); + gradientBrush = linearGradientBrush; + linearGradientBrush.WrapMode = WrapMode.TileFlipX; + } + else + { + gradientBrush = new LinearGradientBrush( rectangle, firstColor, secondColor, angle ); + } + return gradientBrush; + } + + // ******************************************* + // Gradient is not linear : From Center. + // ******************************************* + + // Create a path + GraphicsPath path = new GraphicsPath(); + + // Add a rectangle to the path + path.AddRectangle( rectangle ); + + // Create a gradient brush + PathGradientBrush pathGradientBrush = new PathGradientBrush(path); + gradientBrush = pathGradientBrush; + + // Set the center color + pathGradientBrush.CenterColor = firstColor; + + // Set the Surround color + Color[] colors = {secondColor}; + pathGradientBrush.SurroundColors = colors; + + if( path != null ) + { + path.Dispose(); + } + + return gradientBrush; + } + + /// + /// This method creates a gradient brush for pie. This gradient is one + /// of the types used only with pie and doughnut. + /// + /// A rectangle which has to be filled with a gradient color + /// First color + /// Second color + /// Gradient Brush + internal Brush GetPieGradientBrush( + RectangleF rectangle, + Color firstColor, + Color secondColor + ) + { + // Create a path that consists of a single ellipse. + GraphicsPath path = new GraphicsPath(); + path.AddEllipse( rectangle ); + + // Use the path to construct a brush. + PathGradientBrush gradientBrush = new PathGradientBrush(path); + + // Set the color at the center of the path. + gradientBrush.CenterColor = firstColor; + + // Set the color along the entire boundary + // of the path to aqua. + Color[] colors = {secondColor}; + + gradientBrush.SurroundColors = colors; + + if( path != null ) + { + path.Dispose(); + } + + return gradientBrush; + + } + + /// + /// Converts GDI+ line style to Chart Graph line style. + /// + /// Chart Line style. + /// GDI+ line style. + internal DashStyle GetPenStyle( ChartDashStyle style ) + { + // Convert to chart line styles. The custom style doesn’t exist. + switch( style ) + { + case ChartDashStyle.Dash: + return DashStyle.Dash; + case ChartDashStyle.DashDot: + return DashStyle.DashDot; + case ChartDashStyle.DashDotDot: + return DashStyle.DashDotDot; + case ChartDashStyle.Dot: + return DashStyle.Dot; + } + + return DashStyle.Solid; + } + + #endregion + + #region Markers + + /// + /// Creates polygon for multi-corner star marker. + /// + /// Marker rectangle. + /// Number of corners (4 and up). + /// Array of points. + internal PointF[] CreateStarPolygon(RectangleF rect, int numberOfCorners) + { + int numberOfCornersX2; + checked + { + numberOfCornersX2 = numberOfCorners * 2; + } + + bool outside = true; + PointF[] points = new PointF[numberOfCornersX2]; + PointF[] tempPoints = new PointF[1]; + // overflow check + for (int pointIndex = 0; pointIndex < numberOfCornersX2; pointIndex++) + { + tempPoints[0] = new PointF(rect.X + rect.Width/2f, (outside == true) ? rect.Y : rect.Y + rect.Height/4f); + Matrix matrix = new Matrix(); + matrix.RotateAt(pointIndex*(360f/(numberOfCorners*2f)), new PointF(rect.X + rect.Width/2f, rect.Y + rect.Height/2f)); + matrix.TransformPoints(tempPoints); + points[pointIndex] = tempPoints[0]; + outside = !outside; + } + + return points; + } + + /// + /// Draw marker using relative coordinates of the center. + /// + /// Coordinates of the center. + /// Marker style. + /// Marker size. + /// Marker color. + /// Marker border color. + /// Marker border size. + /// Marker image name. + /// Marker image transparent color. + /// Marker shadow size. + /// Marker shadow color. + /// Rectangle to which marker image should be scaled. + internal void DrawMarkerRel( + PointF point, + MarkerStyle markerStyle, + int markerSize, + Color markerColor, + Color markerBorderColor, + int markerBorderSize, + string markerImage, + Color markerImageTransparentColor, + int shadowSize, + Color shadowColor, + RectangleF imageScaleRect + ) + { + DrawMarkerAbs(this.GetAbsolutePoint(point), markerStyle, markerSize, markerColor, markerBorderColor, markerBorderSize, markerImage, markerImageTransparentColor, shadowSize, shadowColor, imageScaleRect, false); + } + + /// + /// Draw marker using absolute coordinates of the center. + /// + /// Coordinates of the center. + /// Marker style. + /// Marker size. + /// Marker color. + /// Marker border color. + /// Marker border size. + /// Marker image name. + /// Marker image transparent color. + /// Marker shadow size. + /// Marker shadow color. + /// Rectangle to which marker image should be scaled. + /// Always use anti aliasing when drawing the marker. + internal void DrawMarkerAbs( + PointF point, + MarkerStyle markerStyle, + int markerSize, + Color markerColor, + Color markerBorderColor, + int markerBorderSize, + string markerImage, + Color markerImageTransparentColor, + int shadowSize, + Color shadowColor, + RectangleF imageScaleRect, + bool forceAntiAlias + ) + { + // Hide border when zero width specified + if(markerBorderSize <= 0) + { + markerBorderColor = Color.Transparent; + } + + // Draw image instead of standart markers + if(markerImage.Length > 0) + { + // Get image + System.Drawing.Image image = _common.ImageLoader.LoadImage( markerImage ); + + if (image != null) + { + // Calculate image rectangle + RectangleF rect = RectangleF.Empty; + if (imageScaleRect == RectangleF.Empty) + { + SizeF size = new SizeF(); + ImageLoader.GetAdjustedImageSize(image, this.Graphics, ref size); + imageScaleRect.Width = size.Width; + imageScaleRect.Height = size.Height; + } + + rect.X = point.X - imageScaleRect.Width / 2F; + rect.Y = point.Y - imageScaleRect.Height / 2F; + rect.Width = imageScaleRect.Width; + rect.Height = imageScaleRect.Height; + + // Prepare image properties (transparent color) + ImageAttributes attrib = new ImageAttributes(); + if (markerImageTransparentColor != Color.Empty) + { + attrib.SetColorKey(markerImageTransparentColor, markerImageTransparentColor, ColorAdjustType.Default); + } + + // Draw image shadow + if (shadowSize != 0 && shadowColor != Color.Empty) + { + ImageAttributes attribShadow = new ImageAttributes(); + attribShadow.SetColorKey(markerImageTransparentColor, markerImageTransparentColor, ColorAdjustType.Default); + ColorMatrix colorMatrix = new ColorMatrix(); + colorMatrix.Matrix00 = 0.25f; // Red + colorMatrix.Matrix11 = 0.25f; // Green + colorMatrix.Matrix22 = 0.25f; // Blue + colorMatrix.Matrix33 = 0.5f; // alpha + colorMatrix.Matrix44 = 1.0f; // w + attribShadow.SetColorMatrix(colorMatrix); + + this.DrawImage(image, + new Rectangle((int)rect.X + shadowSize, (int)rect.Y + shadowSize, (int)rect.Width, (int)rect.Height), + 0, 0, image.Width, image.Height, + GraphicsUnit.Pixel, + attribShadow); + } + + // Draw image + this.DrawImage(image, + new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height), + 0, 0, image.Width, image.Height, + GraphicsUnit.Pixel, + attrib); + } + } + + // Draw standart marker using style, size and color + else if(markerStyle != MarkerStyle.None && markerSize > 0 && markerColor != Color.Empty) + { + // Enable antialising + SmoothingMode oldSmoothingMode = this.SmoothingMode; + if(forceAntiAlias) + { + this.SmoothingMode = SmoothingMode.AntiAlias; + } + + // Create solid color brush + using (SolidBrush brush = new SolidBrush(markerColor)) + { + // Calculate marker rectangle + RectangleF rect = RectangleF.Empty; + rect.X = point.X - ((float)markerSize) / 2F; + rect.Y = point.Y - ((float)markerSize) / 2F; + rect.Width = markerSize; + rect.Height = markerSize; + + // Draw marker depending on style + switch (markerStyle) + { + case (MarkerStyle.Star4): + case (MarkerStyle.Star5): + case (MarkerStyle.Star6): + case (MarkerStyle.Star10): + { + // Set number of corners + int cornerNumber = 4; + if (markerStyle == MarkerStyle.Star5) + { + cornerNumber = 5; + } + else if (markerStyle == MarkerStyle.Star6) + { + cornerNumber = 6; + } + else if (markerStyle == MarkerStyle.Star10) + { + cornerNumber = 10; + } + + // Get star polygon + PointF[] points = CreateStarPolygon(rect, cornerNumber); + + // Draw shadow + if (shadowSize != 0 && shadowColor != Color.Empty) + { + Matrix translateMatrix = this.Transform.Clone(); + translateMatrix.Translate(shadowSize, shadowSize); + Matrix oldMatrix = this.Transform; + this.Transform = translateMatrix; + + this.FillPolygon(new SolidBrush((shadowColor.A != 255) ? shadowColor : Color.FromArgb(markerColor.A / 2, shadowColor)), points); + + this.Transform = oldMatrix; + } + + // Draw star + this.FillPolygon(brush, points); + this.DrawPolygon(new Pen(markerBorderColor, markerBorderSize), points); + break; + } + case (MarkerStyle.Circle): + { + // Draw marker shadow + if (shadowSize != 0 && shadowColor != Color.Empty) + { + if (!softShadows) + { + using (SolidBrush shadowBrush = new SolidBrush((shadowColor.A != 255) ? shadowColor : Color.FromArgb(markerColor.A / 2, shadowColor))) + { + RectangleF shadowRect = rect; + shadowRect.X += shadowSize; + shadowRect.Y += shadowSize; + this.FillEllipse(shadowBrush, shadowRect); + } + } + else + { + // Add circle to the graphics path + using (GraphicsPath path = new GraphicsPath()) + { + path.AddEllipse(rect.X + shadowSize - 1, rect.Y + shadowSize - 1, rect.Width + 2, rect.Height + 2); + + // Create path brush + using (PathGradientBrush shadowBrush = new PathGradientBrush(path)) + { + shadowBrush.CenterColor = shadowColor; + + // Set the color along the entire boundary of the path + Color[] colors = { Color.Transparent }; + shadowBrush.SurroundColors = colors; + shadowBrush.CenterPoint = new PointF(point.X, point.Y); + + // Define brush focus scale + PointF focusScale = new PointF(1 - 2f * shadowSize / rect.Width, 1 - 2f * shadowSize / rect.Height); + if (focusScale.X < 0) + { + focusScale.X = 0; + } + if (focusScale.Y < 0) + { + focusScale.Y = 0; + } + shadowBrush.FocusScales = focusScale; + + // Draw shadow + this.FillPath(shadowBrush, path); + } + } + } + } + + this.FillEllipse(brush, rect); + this.DrawEllipse(new Pen(markerBorderColor, markerBorderSize), rect); + break; + } + case (MarkerStyle.Square): + { + // Draw marker shadow + if (shadowSize != 0 && shadowColor != Color.Empty) + { + FillRectangleShadowAbs(rect, shadowColor, shadowSize, shadowColor); + } + + this.FillRectangle(brush, rect); + this.DrawRectangle(new Pen(markerBorderColor, markerBorderSize), (int)Math.Round(rect.X, 0), (int)Math.Round(rect.Y, 0), (int)Math.Round(rect.Width, 0), (int)Math.Round(rect.Height, 0)); + break; + } + case (MarkerStyle.Cross): + { + // Calculate cross line width and size + float crossLineWidth = (float)Math.Ceiling(markerSize / 4F); + float crossSize = markerSize;// * (float)Math.Sin(45f/180f*Math.PI); + + // Calculate cross coordinates + PointF[] points = new PointF[12]; + points[0].X = point.X - crossSize / 2F; + points[0].Y = point.Y + crossLineWidth / 2F; + points[1].X = point.X - crossSize / 2F; + points[1].Y = point.Y - crossLineWidth / 2F; + + points[2].X = point.X - crossLineWidth / 2F; + points[2].Y = point.Y - crossLineWidth / 2F; + points[3].X = point.X - crossLineWidth / 2F; + points[3].Y = point.Y - crossSize / 2F; + points[4].X = point.X + crossLineWidth / 2F; + points[4].Y = point.Y - crossSize / 2F; + + points[5].X = point.X + crossLineWidth / 2F; + points[5].Y = point.Y - crossLineWidth / 2F; + points[6].X = point.X + crossSize / 2F; + points[6].Y = point.Y - crossLineWidth / 2F; + points[7].X = point.X + crossSize / 2F; + points[7].Y = point.Y + crossLineWidth / 2F; + + points[8].X = point.X + crossLineWidth / 2F; + points[8].Y = point.Y + crossLineWidth / 2F; + points[9].X = point.X + crossLineWidth / 2F; + points[9].Y = point.Y + crossSize / 2F; + points[10].X = point.X - crossLineWidth / 2F; + points[10].Y = point.Y + crossSize / 2F; + points[11].X = point.X - crossLineWidth / 2F; + points[11].Y = point.Y + crossLineWidth / 2F; + + // Rotate cross coordinates 45 degrees + Matrix rotationMatrix = new Matrix(); + rotationMatrix.RotateAt(45, point); + rotationMatrix.TransformPoints(points); + + // Draw shadow + if (shadowSize != 0 && shadowColor != Color.Empty) + { + // Create translation matrix + Matrix translateMatrix = this.Transform.Clone(); + translateMatrix.Translate( + (softShadows) ? shadowSize + 1 : shadowSize, + (softShadows) ? shadowSize + 1 : shadowSize); + Matrix oldMatrix = this.Transform; + this.Transform = translateMatrix; + + if (!softShadows) + { + using (Brush softShadowBrush = new SolidBrush((shadowColor.A != 255) ? shadowColor : Color.FromArgb(markerColor.A / 2, shadowColor))) + { + this.FillPolygon(softShadowBrush, points); + } + } + else + { + // Add polygon to the graphics path + using (GraphicsPath path = new GraphicsPath()) + { + path.AddPolygon(points); + + // Create path brush + using (PathGradientBrush shadowBrush = new PathGradientBrush(path)) + { + shadowBrush.CenterColor = shadowColor; + + // Set the color along the entire boundary of the path + Color[] colors = { Color.Transparent }; + shadowBrush.SurroundColors = colors; + shadowBrush.CenterPoint = new PointF(point.X, point.Y); + + // Define brush focus scale + PointF focusScale = new PointF(1 - 2f * shadowSize / rect.Width, 1 - 2f * shadowSize / rect.Height); + if (focusScale.X < 0) + { + focusScale.X = 0; + } + if (focusScale.Y < 0) + { + focusScale.Y = 0; + } + shadowBrush.FocusScales = focusScale; + + // Draw shadow + this.FillPath(shadowBrush, path); + } + } + } + + this.Transform = oldMatrix; + } + + // Create translation matrix + Matrix translateMatrixShape = this.Transform.Clone(); + Matrix oldMatrixShape = this.Transform; + this.Transform = translateMatrixShape; + + this.FillPolygon(brush, points); + this.DrawPolygon(new Pen(markerBorderColor, markerBorderSize), points); + + this.Transform = oldMatrixShape; + + break; + } + case (MarkerStyle.Diamond): + { + PointF[] points = new PointF[4]; + points[0].X = rect.X; + points[0].Y = rect.Y + rect.Height / 2F; + points[1].X = rect.X + rect.Width / 2F; + points[1].Y = rect.Top; + points[2].X = rect.Right; + points[2].Y = rect.Y + rect.Height / 2F; + points[3].X = rect.X + rect.Width / 2F; + points[3].Y = rect.Bottom; + + // Draw shadow + if (shadowSize != 0 && shadowColor != Color.Empty) + { + Matrix translateMatrix = this.Transform.Clone(); + translateMatrix.Translate((softShadows) ? 0 : shadowSize, + (softShadows) ? 0 : shadowSize); + Matrix oldMatrix = this.Transform; + this.Transform = translateMatrix; + + if (!softShadows) + { + using (Brush softShadowBrush = new SolidBrush((shadowColor.A != 255) ? shadowColor : Color.FromArgb(markerColor.A / 2, shadowColor))) + { + this.FillPolygon(softShadowBrush, points); + } + } + else + { + // Calculate diamond size + float diamondSize = markerSize * (float)Math.Sin(45f / 180f * Math.PI); + + // Calculate diamond rectangle position + RectangleF diamondRect = RectangleF.Empty; + diamondRect.X = point.X - ((float)diamondSize) / 2F; + diamondRect.Y = point.Y - ((float)diamondSize) / 2F - shadowSize; + diamondRect.Width = diamondSize; + diamondRect.Height = diamondSize; + + // Set rotation matrix to 45 + translateMatrix.RotateAt(45, point); + this.Transform = translateMatrix; + + FillRectangleShadowAbs(diamondRect, shadowColor, shadowSize, shadowColor); + } + + + this.Transform = oldMatrix; + } + + this.FillPolygon(brush, points); + this.DrawPolygon(new Pen(markerBorderColor, markerBorderSize), points); + break; + } + case (MarkerStyle.Triangle): + { + PointF[] points = new PointF[3]; + points[0].X = rect.X; + points[0].Y = rect.Bottom; + points[1].X = rect.X + rect.Width / 2F; + points[1].Y = rect.Top; + points[2].X = rect.Right; + points[2].Y = rect.Bottom; + + // Draw image shadow + if (shadowSize != 0 && shadowColor != Color.Empty) + { + Matrix translateMatrix = this.Transform.Clone(); + translateMatrix.Translate((softShadows) ? shadowSize - 1 : shadowSize, + (softShadows) ? shadowSize + 1 : shadowSize); + Matrix oldMatrix = this.Transform; + this.Transform = translateMatrix; + + if (!softShadows) + { + using (Brush softShadowBrush = new SolidBrush((shadowColor.A != 255) ? shadowColor : Color.FromArgb(markerColor.A / 2, shadowColor))) + { + this.FillPolygon(softShadowBrush, points); + } + } + else + { + // Add polygon to the graphics path + GraphicsPath path = new GraphicsPath(); + path.AddPolygon(points); + + // Create path brush + PathGradientBrush shadowBrush = new PathGradientBrush(path); + shadowBrush.CenterColor = shadowColor; + + // Set the color along the entire boundary of the path + Color[] colors = { Color.Transparent }; + shadowBrush.SurroundColors = colors; + shadowBrush.CenterPoint = new PointF(point.X, point.Y); + + // Define brush focus scale + PointF focusScale = new PointF(1 - 2f * shadowSize / rect.Width, 1 - 2f * shadowSize / rect.Height); + if (focusScale.X < 0) + { + focusScale.X = 0; + } + if (focusScale.Y < 0) + { + focusScale.Y = 0; + } + shadowBrush.FocusScales = focusScale; + + // Draw shadow + this.FillPath(shadowBrush, path); + } + + this.Transform = oldMatrix; + } + + this.FillPolygon(brush, points); + this.DrawPolygon(new Pen(markerBorderColor, markerBorderSize), points); + break; + } + default: + { + throw (new InvalidOperationException(SR.ExceptionGraphicsMarkerStyleUnknown)); + } + } + } + + // Restore SmoothingMode + if(forceAntiAlias) + { + this.SmoothingMode = oldSmoothingMode; + } + } + } + + #endregion + + #region String Methods + + /// + /// Measures the specified string when drawn with the specified + /// Font object and formatted with the specified StringFormat object. + /// + /// String to measure. + /// Font object defines the text format of the string. + /// SizeF structure that specifies the maximum layout area for the text. + /// StringFormat object that represents formatting information, such as line spacing, for the string. + /// Text orientation. + /// This method returns a SizeF structure that represents the size, in pixels, of the string specified in the text parameter as drawn with the font parameter and the stringFormat parameter. + internal SizeF MeasureString( + string text, + Font font, + SizeF layoutArea, + StringFormat stringFormat, + TextOrientation textOrientation + ) + { + // Current implementation of the stacked text will simply insert a new + // line character between all characters in the original string. This + // apporach will not allow to show multiple lines of stacked text or + // correctly handle text wrapping. + if (textOrientation == TextOrientation.Stacked) + { + text = GetStackedText(text); + } + return this.MeasureString(text, font, layoutArea, stringFormat); + } + + /// + /// Measures the specified text string when drawn with + /// the specified Font object and formatted with the + /// specified StringFormat object. + /// + /// The string to measure + /// The Font object used to determine the size of the text string. + /// A SizeF structure that specifies the layout rectangle for the text. + /// A StringFormat object that represents formatting information, such as line spacing, for the text string. + /// Text orientation. + /// A SizeF structure that represents the size of text as drawn with font. + internal SizeF MeasureStringRel( + string text, + Font font, + SizeF layoutArea, + StringFormat stringFormat, + TextOrientation textOrientation) + { + // Current implementation of the stacked text will simply insert a new + // line character between all characters in the original string. This + // apporach will not allow to show multiple lines of stacked text or + // correctly handle text wrapping. + if (textOrientation == TextOrientation.Stacked) + { + text = GetStackedText(text); + } + return this.MeasureStringRel(text, font, layoutArea, stringFormat); + } + + /// + /// Draws the specified text string at the specified location with the specified Brush and Font objects using the formatting properties of the specified StringFormat object. + /// + /// String to draw. + /// Font object that defines the text format of the string. + /// Brush object that determines the color and texture of the drawn text. + /// Position of the drawn text in pixels. + /// StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text. + /// Text orientation. + internal void DrawString( + string text, + Font font, + Brush brush, + RectangleF rect, + StringFormat format, + TextOrientation textOrientation + ) + { + // Current implementation of the stacked text will simply insert a new + // line character between all characters in the original string. This + // apporach will not allow to show multiple lines of stacked text or + // correctly handle text wrapping. + if (textOrientation == TextOrientation.Stacked) + { + text = GetStackedText(text); + } + this.DrawString(text, font, brush, rect, format); + } + + /// + /// Draw a string. + /// + /// Text. + /// Text Font. + /// Text Brush. + /// Text Position. + /// Format and text alignment. + /// Text angle. + /// Text orientation. + internal void DrawStringRel( + string text, + System.Drawing.Font font, + System.Drawing.Brush brush, + PointF position, + System.Drawing.StringFormat format, + int angle, + TextOrientation textOrientation + ) + { + // Current implementation of the stacked text will simply insert a new + // line character between all characters in the original string. This + // apporach will not allow to show multiple lines of stacked text or + // correctly handle text wrapping. + if (textOrientation == TextOrientation.Stacked) + { + text = GetStackedText(text); + } + + this.DrawStringRel(text, font, brush, position, format, angle); + } + + /// + /// Draw a string. + /// + /// Text. + /// Text Font. + /// Text Brush. + /// Text Position. + /// Format and text alignment. + /// Text orientation. + internal void DrawStringRel( + string text, + System.Drawing.Font font, + System.Drawing.Brush brush, + RectangleF position, + System.Drawing.StringFormat format, + TextOrientation textOrientation + ) + { + // Current implementation of the stacked text will simply insert a new + // line character between all characters in the original string. This + // apporach will not allow to show multiple lines of stacked text or + // correctly handle text wrapping. + if (textOrientation == TextOrientation.Stacked) + { + text = GetStackedText(text); + } + + this.DrawStringRel(text, font, brush, position, format); + } + + /// + /// Function returned stacked text by inserting new line characters between + /// all characters in the original string. + /// + /// Original text. + /// Stacked text. + internal static string GetStackedText(string text) + { + string result = string.Empty; + foreach (char ch in text) + { + result += ch; + if (ch != '\n') + { + result += '\n'; + } + } + return result; + } + + /// + /// Draw a string and fills it's background + /// + /// The Common elements object. + /// Text. + /// Text Font. + /// Text Brush. + /// Text Position. + /// Format and text alignment. + /// Text angle. + /// Text background position. + /// Back Color + /// Border Color + /// Border Width + /// Border Style + /// Series + /// Point + /// Point index in series + internal void DrawPointLabelStringRel( + CommonElements common, + string text, + System.Drawing.Font font, + System.Drawing.Brush brush, + RectangleF position, + System.Drawing.StringFormat format, + int angle, + RectangleF backPosition, + Color backColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + Series series, + DataPoint point, + int pointIndex) + { + // Start Svg/Flash Selection mode + this.StartHotRegion( point, true ); + + // Draw background + DrawPointLabelBackground( + common, + angle, + PointF.Empty, + backPosition, + backColor, + borderColor, + borderWidth, + borderDashStyle, + series, + point, + pointIndex); + + // End Svg/Flash Selection mode + this.EndHotRegion( ); + + point._lastLabelText = text; + // Draw text + if (IsRightToLeft) + { + // datapoint label alignments should appear as not RTL. + using (StringFormat fmt = (StringFormat)format.Clone()) + { + if (fmt.Alignment == StringAlignment.Far) + { + fmt.Alignment = StringAlignment.Near; + } + else if (fmt.Alignment == StringAlignment.Near) + { + fmt.Alignment = StringAlignment.Far; + } + DrawStringRel(text,font,brush,position,fmt,angle); + } + } + else + DrawStringRel(text, font, brush, position, format, angle); + } + + /// + /// Draw a string and fills it's background + /// + /// The Common elements object. + /// Text. + /// Text Font. + /// Text Brush. + /// Text Position. + /// Format and text alignment. + /// Text angle. + /// Text background position. + /// Back Color + /// Border Color + /// Border Width + /// Border Style + /// Series + /// Point + /// Point index in series + internal void DrawPointLabelStringRel( + CommonElements common, + string text, + System.Drawing.Font font, + System.Drawing.Brush brush, + PointF position, + System.Drawing.StringFormat format, + int angle, + RectangleF backPosition, + Color backColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + Series series, + DataPoint point, + int pointIndex) + { + // Start Svg/Flash Selection mode + this.StartHotRegion( point, true ); + + // Draw background + DrawPointLabelBackground( + common, + angle, + position, + backPosition, + backColor, + borderColor, + borderWidth, + borderDashStyle, + series, + point, + pointIndex); + + // End Svg/Flash Selection mode + this.EndHotRegion( ); + + point._lastLabelText = text; + // Draw text + if (IsRightToLeft) + { + // datapoint label alignments should appear as not RTL + using (StringFormat fmt = (StringFormat)format.Clone()) + { + if (fmt.Alignment == StringAlignment.Far) + { + fmt.Alignment = StringAlignment.Near; + } + else if (fmt.Alignment == StringAlignment.Near) + { + fmt.Alignment = StringAlignment.Far; + } + DrawStringRel(text,font,brush,position,fmt,angle); + } + } + else + DrawStringRel(text,font,brush,position,format,angle); + } + + /// + /// Draw a string and fills it's background + /// + /// The Common elements object. + /// Text angle. + /// Text position. + /// Text background position. + /// Back Color + /// Border Color + /// Border Width + /// Border Style + /// Series + /// Point + /// Point index in series + private void DrawPointLabelBackground( + CommonElements common, + int angle, + PointF textPosition, + RectangleF backPosition, + Color backColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + Series series, + DataPoint point, + int pointIndex) + { + // Draw background + if(!backPosition.IsEmpty) + { + RectangleF backPositionAbs = this.Round(this.GetAbsoluteRectangle(backPosition)); + + // Get rotation point + PointF rotationPoint = PointF.Empty; + if(textPosition.IsEmpty) + { + rotationPoint = new PointF(backPositionAbs.X + backPositionAbs.Width/2f, backPositionAbs.Y + backPositionAbs.Height/2f); + } + else + { + rotationPoint = this.GetAbsolutePoint(textPosition); + } + + // Create a matrix and rotate it. + _myMatrix = this.Transform.Clone(); + _myMatrix.RotateAt( angle, rotationPoint ); + + // Save old state + GraphicsState graphicsState = this.Save(); + + // Set transformatino + this.Transform = _myMatrix; + + // Check for empty colors + if( !backColor.IsEmpty || + !borderColor.IsEmpty) + { + // Fill box around the label + using(Brush brush = new SolidBrush(backColor)) + { + this.FillRectangle(brush, backPositionAbs); + } + + // deliant: Fix VSTS #156433 (2) Data Label Border in core always shows when the style is set to NotSet + // Draw box border + if( borderWidth > 0 && + !borderColor.IsEmpty && borderDashStyle != ChartDashStyle.NotSet) + { + AntiAliasingStyles saveAntiAliasing = this.AntiAliasing; + try + { + this.AntiAliasing = AntiAliasingStyles.None; + using(Pen pen = new Pen(borderColor, borderWidth)) + { + pen.DashStyle = GetPenStyle( borderDashStyle ); + this.DrawRectangle( + pen, + backPositionAbs.X, + backPositionAbs.Y, + backPositionAbs.Width, + backPositionAbs.Height); + } + } + finally + { + this.AntiAliasing = saveAntiAliasing; + } + } + } + else + { + // Draw invisible rectangle to handle tooltips + using(Brush brush = new SolidBrush(Color.Transparent)) + { + this.FillRectangle(brush, backPositionAbs); + } + } + + + // Restore old state + this.Restore(graphicsState); + + // Add point label hot region + if( common != null && + common.ProcessModeRegions) + { +#if !Microsoft_CONTROL + // Remember all point attributes + string oldToolTip = point.IsCustomPropertySet( CommonCustomProperties.ToolTip) ? point.ToolTip : null; + string oldUrl = point.IsCustomPropertySet( CommonCustomProperties.Url) ? point.Url : null; + string oldMapAreaAttributes = point.IsCustomPropertySet( CommonCustomProperties.MapAreaAttributes) ? point.MapAreaAttributes : null; + string oldPostback = point.IsCustomPropertySet( CommonCustomProperties.PostBackValue) ? point.PostBackValue : null; + object oldTag = point.Tag; + // Set label attributes into the point attribute. + // Workaround for the AddHotRegion method limitation. + point.ToolTip = point.LabelToolTip; + point.Url = point.LabelUrl; + point.MapAreaAttributes = point.LabelMapAreaAttributes; + point.PostBackValue = point.PostBackValue; +#endif // !Microsoft_CONTROL + + // Insert area + if(angle == 0) + { + common.HotRegionsList.AddHotRegion( + backPosition, + point, + series.Name, + pointIndex ); + } + else + { + // Convert rectangle to the graphics path and apply rotation transformation + using (GraphicsPath path = new GraphicsPath()) + { + path.AddRectangle(backPositionAbs); + path.Transform(_myMatrix); + + // Add hot region + common.HotRegionsList.AddHotRegion( + path, + false, + this, + point, + series.Name, + pointIndex); + } + } + +#if !Microsoft_CONTROL + // Restore all point attributes + if (oldToolTip != null) point.ToolTip = oldToolTip; else point.ResetToolTip(); + if (oldUrl != null) point.Url = oldUrl; else point.ResetUrl(); + if (oldMapAreaAttributes != null) point.MapAreaAttributes = oldMapAreaAttributes; else point.ResetMapAreaAttributes(); + if (oldPostback != null) point.PostBackValue = oldPostback; else point.ResetPostBackValue(); + point.Tag = oldTag; +#endif // !Microsoft_CONTROL + + // Set new hot region element type + if (common.HotRegionsList.List != null && common.HotRegionsList.List.Count > 0) + { + ((HotRegion)common.HotRegionsList.List[common.HotRegionsList.List.Count - 1]).Type = + ChartElementType.DataPointLabel; + } + } + } + } + + /// + /// Draw a string. + /// + /// Text. + /// Text Font. + /// Text Brush. + /// Text Position. + /// Format and text alignment. + /// Text angle. + internal void DrawStringRel( + string text, + System.Drawing.Font font, + System.Drawing.Brush brush, + PointF position, + System.Drawing.StringFormat format, + int angle + ) + { + DrawStringAbs( + text, + font, + brush, + GetAbsolutePoint(position), + format, + angle); + } + + /// + /// Draw a string. + /// + /// Text. + /// Text Font. + /// Text Brush. + /// Text Position. + /// Format and text alignment. + /// Text angle. + internal void DrawStringAbs( + string text, + System.Drawing.Font font, + System.Drawing.Brush brush, + PointF absPosition, + System.Drawing.StringFormat format, + int angle + ) + { + // Create a matrix and rotate it. + _myMatrix = this.Transform.Clone(); + _myMatrix.RotateAt(angle, absPosition); + + // Save aold state + GraphicsState graphicsState = this.Save(); + + // Set Angle + this.Transform = _myMatrix; + + // Draw text with anti-aliasing + /* + if( (AntiAliasing & AntiAliasing.Text) == AntiAliasing.Text ) + this.TextRenderingHint = TextRenderingHint.AntiAlias; + else + this.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; + */ + + // Draw a string + this.DrawString( text, font, brush, absPosition , format ); + + // Restore old state + this.Restore(graphicsState); + } + + /// + /// This method is used by the axis title hot region generation code. + /// It transforms the centered rectangle the same way as the Axis title text. + /// + /// Title center + /// Title text size + /// Title rotation angle + /// + internal GraphicsPath GetTranformedTextRectPath(PointF center, SizeF size, int angle) + { + // Text hot area is 10px greater than the size of text + size.Width += 10; + size.Height += 10; + + // Get the absolute center and create the centered rectangle points + PointF absCenter = GetAbsolutePoint(center); + PointF[] points = new PointF[] { + new PointF(absCenter.X - size.Width / 2f, absCenter.Y - size.Height / 2f), + new PointF(absCenter.X + size.Width / 2f, absCenter.Y - size.Height / 2f), + new PointF(absCenter.X + size.Width / 2f, absCenter.Y + size.Height / 2f), + new PointF(absCenter.X - size.Width / 2f, absCenter.Y + size.Height / 2f)}; + + //Prepare the same tranformation matrix as used for the axis title + Matrix matrix = this.Transform.Clone(); + matrix.RotateAt(angle, absCenter); + //Tranform the rectangle points + matrix.TransformPoints(points); + + //Return the path consisting of the rect points + GraphicsPath path = new GraphicsPath(); + path.AddLines(points); + path.CloseAllFigures(); + return path; + } + + + + + /// + /// Draw label string. + /// + /// Label axis. + /// Label text row index (0-10). + /// Second row labels mark style. + /// Label mark line color. + /// Label text. + /// Label image name. + /// Label image transparent color. + /// Text bont. + /// Text brush. + /// Text position rectangle. + /// Label text format. + /// Label text angle. + /// Specifies the rectangle where the label text MUST be fitted. + /// Custom Label Item + /// Label is truncated on the left. + /// Label is truncated on the right. + internal void DrawLabelStringRel( + Axis axis, + int labelRowIndex, + LabelMarkStyle labelMark, + Color markColor, + string text, + string image, + Color imageTransparentColor, + System.Drawing.Font font, + System.Drawing.Brush brush, + RectangleF position, + System.Drawing.StringFormat format, + int angle, + RectangleF boundaryRect, + CustomLabel label, + bool truncatedLeft, + bool truncatedRight) + { + Matrix oldTransform; + using (StringFormat drawingFormat = (StringFormat)format.Clone()) + { + SizeF labelSize = SizeF.Empty; + + // Check that rectangle is not empty + if (position.Width == 0 || position.Height == 0) + { + return; + } + + // Find absolute position + RectangleF absPosition = this.GetAbsoluteRectangle(position); + + // Make sure the rectangle is not empty + if (absPosition.Width < 1f) + { + absPosition.Width = 1f; + } + if (absPosition.Height < 1f) + { + absPosition.Height = 1f; + } + +#if DEBUG + // TESTING CODE: Shows labels rectangle position. + // Rectangle rr = Rectangle.Round(absPosition); + // rr.Width = (int)Math.Round(absPosition.Right) - rr.X; + // rr.Height = (int)Math.Round(absPosition.Bottom) - rr.Y; + // this.DrawRectangle(Pens.Red,rr.X, rr.Y, rr.Width, rr.Height); +#endif // DEBUG + + CommonElements common = axis.Common; + if (common.ProcessModeRegions) + { + common.HotRegionsList.AddHotRegion(Rectangle.Round(absPosition), label, ChartElementType.AxisLabels, false, true); + } + + //******************************************************************** + //** Draw labels in the second row + //******************************************************************** + if (labelRowIndex > 0) + { + drawingFormat.LineAlignment = StringAlignment.Center; + drawingFormat.Alignment = StringAlignment.Center; + angle = 0; + + if (axis.AxisPosition == AxisPosition.Left) + { + angle = -90; + } + else if (axis.AxisPosition == AxisPosition.Right) + { + angle = 90; + } + else if (axis.AxisPosition == AxisPosition.Top) + { + } + else if (axis.AxisPosition == AxisPosition.Bottom) + { + } + } + + //******************************************************************** + //** Calculate rotation point + //******************************************************************** + PointF rotationPoint = PointF.Empty; + if (axis.AxisPosition == AxisPosition.Left) + { + rotationPoint.X = absPosition.Right; + rotationPoint.Y = absPosition.Y + absPosition.Height / 2F; + } + else if (axis.AxisPosition == AxisPosition.Right) + { + rotationPoint.X = absPosition.Left; + rotationPoint.Y = absPosition.Y + absPosition.Height / 2F; + } + else if (axis.AxisPosition == AxisPosition.Top) + { + rotationPoint.X = absPosition.X + absPosition.Width / 2F; + rotationPoint.Y = absPosition.Bottom; + } + else if (axis.AxisPosition == AxisPosition.Bottom) + { + rotationPoint.X = absPosition.X + absPosition.Width / 2F; + rotationPoint.Y = absPosition.Top; + } + + //******************************************************************** + //** Adjust rectangle for horisontal axis + //******************************************************************** + if ((axis.AxisPosition == AxisPosition.Top || axis.AxisPosition == AxisPosition.Bottom) && + angle != 0) + { + // Get rectangle center + rotationPoint.X = absPosition.X + absPosition.Width / 2F; + rotationPoint.Y = (axis.AxisPosition == AxisPosition.Top) ? absPosition.Bottom : absPosition.Y; + + // Rotate rectangle 90 degrees + RectangleF newRect = RectangleF.Empty; + newRect.X = absPosition.X + absPosition.Width / 2F; + newRect.Y = absPosition.Y - absPosition.Width / 2F; + newRect.Height = absPosition.Width; + newRect.Width = absPosition.Height; + + // Adjust values for bottom axis + if (axis.AxisPosition == AxisPosition.Bottom) + { + if (angle < 0) + { + newRect.X -= newRect.Width; + } + + // Replace string alignment + drawingFormat.Alignment = StringAlignment.Near; + if (angle < 0) + { + drawingFormat.Alignment = StringAlignment.Far; + } + drawingFormat.LineAlignment = StringAlignment.Center; + } + + // Adjust values for bottom axis + if (axis.AxisPosition == AxisPosition.Top) + { + newRect.Y += absPosition.Height; + if (angle > 0) + { + newRect.X -= newRect.Width; + } + + // Replace string alignment + drawingFormat.Alignment = StringAlignment.Far; + if (angle < 0) + { + drawingFormat.Alignment = StringAlignment.Near; + } + drawingFormat.LineAlignment = StringAlignment.Center; + } + + // Set new label rect + absPosition = newRect; + } + + //******************************************************************** + //** 90 degrees is a special case for vertical axes + //******************************************************************** + if ((axis.AxisPosition == AxisPosition.Left || axis.AxisPosition == AxisPosition.Right) && + (angle == 90 || angle == -90)) + { + // Get rectangle center + rotationPoint.X = absPosition.X + absPosition.Width / 2F; + rotationPoint.Y = absPosition.Y + absPosition.Height / 2F; + + // Rotate rectangle 90 degrees + RectangleF newRect = RectangleF.Empty; + newRect.X = rotationPoint.X - absPosition.Height / 2F; + newRect.Y = rotationPoint.Y - absPosition.Width / 2F; + newRect.Height = absPosition.Width; + newRect.Width = absPosition.Height; + absPosition = newRect; + + // Replace string alignment + StringAlignment align = drawingFormat.Alignment; + drawingFormat.Alignment = drawingFormat.LineAlignment; + drawingFormat.LineAlignment = align; + if (angle == 90) + { + if (drawingFormat.LineAlignment == StringAlignment.Far) + drawingFormat.LineAlignment = StringAlignment.Near; + else if (drawingFormat.LineAlignment == StringAlignment.Near) + drawingFormat.LineAlignment = StringAlignment.Far; + } + if (angle == -90) + { + if (drawingFormat.Alignment == StringAlignment.Far) + drawingFormat.Alignment = StringAlignment.Near; + else if (drawingFormat.Alignment == StringAlignment.Near) + drawingFormat.Alignment = StringAlignment.Far; + } + } + + //******************************************************************** + //** Create a matrix and rotate it. + //******************************************************************** + oldTransform = null; + if (angle != 0) + { + _myMatrix = this.Transform.Clone(); + _myMatrix.RotateAt(angle, rotationPoint); + + // Old angle + oldTransform = this.Transform; + + // Set Angle + this.Transform = _myMatrix; + } + + //******************************************************************** + //** Measure string exact rectangle and adjust label bounding rectangle + //******************************************************************** + RectangleF labelRect = Rectangle.Empty; + float offsetY = 0f; + float offsetX = 0f; + + // Measure text size + labelSize = this.MeasureString(text.Replace("\\n", "\n"), font, absPosition.Size, drawingFormat); + + // Calculate text rectangle + labelRect.Width = labelSize.Width; + labelRect.Height = labelSize.Height; + if (drawingFormat.Alignment == StringAlignment.Far) + { + labelRect.X = absPosition.Right - labelSize.Width; + } + else if (drawingFormat.Alignment == StringAlignment.Near) + { + labelRect.X = absPosition.X; + } + else if (drawingFormat.Alignment == StringAlignment.Center) + { + labelRect.X = absPosition.X + absPosition.Width / 2F - labelSize.Width / 2F; + } + + if (drawingFormat.LineAlignment == StringAlignment.Far) + { + labelRect.Y = absPosition.Bottom - labelSize.Height; + } + else if (drawingFormat.LineAlignment == StringAlignment.Near) + { + labelRect.Y = absPosition.Y; + } + else if (drawingFormat.LineAlignment == StringAlignment.Center) + { + labelRect.Y = absPosition.Y + absPosition.Height / 2F - labelSize.Height / 2F; + } + + //If the angle is not vertical or horizontal + if (angle != 0 && angle != 90 && angle != -90) + { + // Adjust label rectangle so it will not overlap the plotting area + offsetY = (float)Math.Sin((90 - angle) / 180F * Math.PI) * labelRect.Height / 2F; + offsetX = (float)Math.Sin((Math.Abs(angle)) / 180F * Math.PI) * labelRect.Height / 2F; + + if (axis.AxisPosition == AxisPosition.Left) + { + _myMatrix.Translate(-offsetX, 0); + } + else if (axis.AxisPosition == AxisPosition.Right) + { + _myMatrix.Translate(offsetX, 0); + } + else if (axis.AxisPosition == AxisPosition.Top) + { + _myMatrix.Translate(0, -offsetY); + } + else if (axis.AxisPosition == AxisPosition.Bottom) + { + _myMatrix.Translate(0, offsetY); + } + + // Adjust label rectangle so it will be inside boundary + if (boundaryRect != RectangleF.Empty) + { + Region region = new Region(labelRect); + region.Transform(_myMatrix); + + // Extend boundary rectangle to the chart picture border + if (axis.AxisPosition == AxisPosition.Left) + { + boundaryRect.Width += boundaryRect.X; + boundaryRect.X = 0; + } + else if (axis.AxisPosition == AxisPosition.Right) + { + boundaryRect.Width = this._common.Width - boundaryRect.X; + } + else if (axis.AxisPosition == AxisPosition.Top) + { + boundaryRect.Height += boundaryRect.Y; + boundaryRect.Y = 0; + } + else if (axis.AxisPosition == AxisPosition.Bottom) + { + boundaryRect.Height = this._common.Height - boundaryRect.Y; + } + + // Exclude boundary rectangle from the label rectangle + region.Exclude(this.GetAbsoluteRectangle(boundaryRect)); + + // If any part of the label was outside bounding rectangle + if (!region.IsEmpty(Graphics)) + { + this.Transform = oldTransform; + RectangleF truncateRect = region.GetBounds(Graphics); + + float sizeChange = truncateRect.Width / (float)Math.Cos(Math.Abs(angle) / 180F * Math.PI); + if (axis.AxisPosition == AxisPosition.Left) + { + sizeChange -= labelRect.Height * (float)Math.Tan(Math.Abs(angle) / 180F * Math.PI); + absPosition.Y = labelRect.Y; + absPosition.X = labelRect.X + sizeChange; + absPosition.Width = labelRect.Width - sizeChange; + absPosition.Height = labelRect.Height; + } + else if (axis.AxisPosition == AxisPosition.Right) + { + sizeChange -= labelRect.Height * (float)Math.Tan(Math.Abs(angle) / 180F * Math.PI); + absPosition.Y = labelRect.Y; + absPosition.X = labelRect.X; + absPosition.Width = labelRect.Width - sizeChange; + absPosition.Height = labelRect.Height; + } + else if (axis.AxisPosition == AxisPosition.Top) + { + absPosition.Y = labelRect.Y; + absPosition.X = labelRect.X; + absPosition.Width = labelRect.Width - sizeChange; + absPosition.Height = labelRect.Height; + if (angle > 0) + { + absPosition.X += sizeChange; + } + } + else if (axis.AxisPosition == AxisPosition.Bottom) + { + absPosition.Y = labelRect.Y; + absPosition.X = labelRect.X; + absPosition.Width = labelRect.Width - sizeChange; + absPosition.Height = labelRect.Height; + if (angle < 0) + { + absPosition.X += sizeChange; + } + } + } + } + + // Update transformation matrix + this.Transform = _myMatrix; + } + + //******************************************************************** + //** Reserve space on the left for the label iamge + //******************************************************************** + RectangleF absPositionWithoutImage = new RectangleF(absPosition.Location, absPosition.Size); + + System.Drawing.Image labelImage = null; + SizeF imageAbsSize = new SizeF(); + + if (image.Length > 0) + { + labelImage = axis.Common.ImageLoader.LoadImage(label.Image); + + if (labelImage != null) + { + ImageLoader.GetAdjustedImageSize(labelImage, this.Graphics, ref imageAbsSize); + + // Adjust label position using image size + absPositionWithoutImage.Width -= imageAbsSize.Width; + absPositionWithoutImage.X += imageAbsSize.Width; + } + + if (absPositionWithoutImage.Width < 1f) + { + absPositionWithoutImage.Width = 1f; + } + + } + + //******************************************************************** + //** Draw tick marks for labels in second row + //******************************************************************** + if (labelRowIndex > 0 && labelMark != LabelMarkStyle.None) + { + // Make sure that me know the exact size of the text + labelSize = this.MeasureString( + text.Replace("\\n", "\n"), + font, + absPositionWithoutImage.Size, + drawingFormat); + + // Adjust for label image + SizeF labelSizeWithImage = new SizeF(labelSize.Width, labelSize.Height); + if (labelImage != null) + { + labelSizeWithImage.Width += imageAbsSize.Width; + } + + // Draw mark + DrawSecondRowLabelMark( + axis, + markColor, + absPosition, + labelSizeWithImage, + labelMark, + truncatedLeft, + truncatedRight, + oldTransform); + } + + //******************************************************************** + //** Make sure that one line label will not disapear with LineLimit + //** flag on. + //******************************************************************** + if ((drawingFormat.FormatFlags & StringFormatFlags.LineLimit) != 0) + { + // Measure string height out of one character + drawingFormat.FormatFlags ^= StringFormatFlags.LineLimit; + SizeF size = this.MeasureString("I", font, absPosition.Size, drawingFormat); + + // If height of one characte is more than rectangle heigjt - remove LineLimit flag + if (size.Height < absPosition.Height) + { + drawingFormat.FormatFlags |= StringFormatFlags.LineLimit; + } + } + else + { + // Set NoClip flag + if ((drawingFormat.FormatFlags & StringFormatFlags.NoClip) != 0) + { + drawingFormat.FormatFlags ^= StringFormatFlags.NoClip; + } + + // Measure string height out of one character without clipping + SizeF size = this.MeasureString("I", font, absPosition.Size, drawingFormat); + + // Clear NoClip flag + drawingFormat.FormatFlags ^= StringFormatFlags.NoClip; + + // If height of one characte is more than rectangle heigt - set NoClip flag + if (size.Height > absPosition.Height) + { + float delta = size.Height - absPosition.Height; + absPosition.Y -= delta / 2f; + absPosition.Height += delta; + } + } + + //******************************************************************** + //** Draw a string + //******************************************************************** + if (IsRightToLeft) + { + // label alignment on the axis should appear as not RTL. + using (StringFormat fmt = (StringFormat)drawingFormat.Clone()) + { + + if (fmt.Alignment == StringAlignment.Far) + { + fmt.Alignment = StringAlignment.Near; + } + else if (fmt.Alignment == StringAlignment.Near) + { + fmt.Alignment = StringAlignment.Far; + } + this.DrawString(text.Replace("\\n", "\n"), font, brush, + absPositionWithoutImage, + fmt); + + } + } + else + this.DrawString(text.Replace("\\n", "\n"), font, brush, + absPositionWithoutImage, + drawingFormat); + + // Add separate hot region for the label + if (common.ProcessModeRegions) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddRectangle(labelRect); + path.Transform(this.Transform); + string url = string.Empty; + string mapAreaAttributes = string.Empty; + string postbackValue = string.Empty; +#if !Microsoft_CONTROL + url = label.Url; + mapAreaAttributes = label.MapAreaAttributes; + postbackValue = label.PostBackValue; +#endif // !Microsoft_CONTROL + common.HotRegionsList.AddHotRegion( + this, + path, + false, + label.ToolTip, + url, + mapAreaAttributes, + postbackValue, + label, + ChartElementType.AxisLabels); + } + } + + //******************************************************************** + //** Draw an image + //******************************************************************** + if (labelImage != null) + { + // Make sure we no the text size + if (labelSize.IsEmpty) + { + labelSize = this.MeasureString( + text.Replace("\\n", "\n"), + font, + absPositionWithoutImage.Size, + drawingFormat); + } + + // Calculate image rectangle + RectangleF imageRect = new RectangleF( + absPosition.X + (absPosition.Width - imageAbsSize.Width - labelSize.Width) / 2, + absPosition.Y + (absPosition.Height - imageAbsSize.Height) / 2, + imageAbsSize.Width, + imageAbsSize.Height); + + if (drawingFormat.LineAlignment == StringAlignment.Center) + { + imageRect.Y = absPosition.Y + (absPosition.Height - imageAbsSize.Height) / 2; + } + else if (drawingFormat.LineAlignment == StringAlignment.Far) + { + imageRect.Y = absPosition.Bottom - (labelSize.Height + imageAbsSize.Height) / 2; + } + else if (drawingFormat.LineAlignment == StringAlignment.Near) + { + imageRect.Y = absPosition.Top + (labelSize.Height - imageAbsSize.Height) / 2; + } + + if (drawingFormat.Alignment == StringAlignment.Center) + { + imageRect.X = absPosition.X + (absPosition.Width - imageAbsSize.Width - labelSize.Width) / 2; + } + else if (drawingFormat.Alignment == StringAlignment.Far) + { + imageRect.X = absPosition.Right - imageAbsSize.Width - labelSize.Width; + } + else if (drawingFormat.Alignment == StringAlignment.Near) + { + imageRect.X = absPosition.X; + } + + // Create image attribute + ImageAttributes attrib = new ImageAttributes(); + if (imageTransparentColor != Color.Empty) + { + attrib.SetColorKey(imageTransparentColor, imageTransparentColor, ColorAdjustType.Default); + } + + // Draw image + this.DrawImage( + labelImage, + Rectangle.Round(imageRect), + 0, 0, labelImage.Width, labelImage.Height, + GraphicsUnit.Pixel, + attrib); + + // Add separate hot region for the label image + if (common.ProcessModeRegions) + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddRectangle(imageRect); + path.Transform(this.Transform); + string imageUrl = string.Empty; + string imageMapAreaAttributes = string.Empty; + string postbackValue = string.Empty; +#if !Microsoft_CONTROL + imageUrl = label.ImageUrl; + imageMapAreaAttributes = label.ImageMapAreaAttributes; + postbackValue = label.PostBackValue; +#endif // !Microsoft_CONTROL + common.HotRegionsList.AddHotRegion( + this, + path, + false, + string.Empty, + imageUrl, + imageMapAreaAttributes, + postbackValue, + label, + ChartElementType.AxisLabelImage); + } + } + } + } + + // Set Old Angle + if(oldTransform != null) + { + this.Transform = oldTransform; + } + } + + /// + /// Draw box marks for the labels in second row + /// + /// Axis object. + /// Label mark color. + /// Absolute position of the text. + /// Label is truncated on the left. + /// Label is truncated on the right. + /// Original transformation matrix. + private void DrawSecondRowLabelBoxMark( + Axis axis, + Color markColor, + RectangleF absPosition, + bool truncatedLeft, + bool truncatedRight, + Matrix originalTransform) + { + // Remeber current and then reset original matrix + Matrix curentMatrix = this.Transform; + if(originalTransform != null) + { + this.Transform = originalTransform; + } + + // Calculate center of the text rectangle + PointF centerNotRound = new PointF(absPosition.X + absPosition.Width/2F, absPosition.Y + absPosition.Height/2F); + + // Rotate rectangle 90 degrees + if( axis.AxisPosition == AxisPosition.Left || axis.AxisPosition == AxisPosition.Right) + { + RectangleF newRect = RectangleF.Empty; + newRect.X = centerNotRound.X - absPosition.Height / 2F; + newRect.Y = centerNotRound.Y - absPosition.Width / 2F; + newRect.Height = absPosition.Width; + newRect.Width = absPosition.Height; + absPosition = newRect; + } + + // Get axis position + float axisPosRelative = (float)axis.GetAxisPosition(true); + PointF axisPositionAbs = new PointF(axisPosRelative, axisPosRelative); + axisPositionAbs = this.GetAbsolutePoint(axisPositionAbs); + + // Round position to achieve crisp lines with antialiasing + Rectangle absPositionRounded = Rectangle.Round(absPosition); + + // Make sure the right and bottom position is not shifted during rounding + absPositionRounded.Width = (int)Math.Round(absPosition.Right) - absPositionRounded.X; + absPositionRounded.Height = (int)Math.Round(absPosition.Bottom) - absPositionRounded.Y; + + // Create pen + Pen markPen = new Pen( + (markColor.IsEmpty) ? axis.MajorTickMark.LineColor : markColor, + axis.MajorTickMark.LineWidth); + + // Set pen style + markPen.DashStyle = GetPenStyle( axis.MajorTickMark.LineDashStyle ); + + // Draw top/bottom lines + if( axis.AxisPosition == AxisPosition.Left || axis.AxisPosition == AxisPosition.Right) + { + this.DrawLine(markPen, absPositionRounded.Left, absPositionRounded.Top, absPositionRounded.Left, absPositionRounded.Bottom); + this.DrawLine(markPen, absPositionRounded.Right, absPositionRounded.Top, absPositionRounded.Right, absPositionRounded.Bottom); + } + else + { + this.DrawLine(markPen, absPositionRounded.Left, absPositionRounded.Top, absPositionRounded.Right, absPositionRounded.Top); + this.DrawLine(markPen, absPositionRounded.Left, absPositionRounded.Bottom, absPositionRounded.Right, absPositionRounded.Bottom); + } + + // Draw left line + if(!truncatedLeft) + { + if( axis.AxisPosition == AxisPosition.Left || axis.AxisPosition == AxisPosition.Right) + { + this.DrawLine( + markPen, + (axis.AxisPosition == AxisPosition.Left) ? absPositionRounded.Left : absPositionRounded.Right, + absPositionRounded.Bottom, + axisPositionAbs.X, + absPositionRounded.Bottom); + } + else + { + this.DrawLine( + markPen, + absPositionRounded.Left, + (axis.AxisPosition == AxisPosition.Top) ? absPositionRounded.Top : absPositionRounded.Bottom, + absPositionRounded.Left, + axisPositionAbs.Y); + } + } + + // Draw right line + if(!truncatedRight) + { + if( axis.AxisPosition == AxisPosition.Left || axis.AxisPosition == AxisPosition.Right) + { + this.DrawLine( + markPen, + (axis.AxisPosition == AxisPosition.Left) ? absPositionRounded.Left : absPositionRounded.Right, + absPositionRounded.Top, + axisPositionAbs.X, + absPositionRounded.Top); + } + else + { + this.DrawLine( + markPen, + absPositionRounded.Right, + (axis.AxisPosition == AxisPosition.Top) ? absPositionRounded.Top : absPositionRounded.Bottom, + absPositionRounded.Right, + axisPositionAbs.Y); + } + } + + // Dispose Pen + if( markPen != null ) + { + markPen.Dispose(); + } + + // Restore currentmatrix + if(originalTransform != null) + { + this.Transform = curentMatrix; + } + } + + + /// + /// Draw marks for the labels in second row + /// + /// Axis object. + /// Label mark color. + /// Absolute position of the text. + /// Exact mesured size of the text. + /// Label mark style to draw. + /// Label is truncated on the left. + /// Label is truncated on the right. + /// Original transformation matrix. + private void DrawSecondRowLabelMark( + Axis axis, + Color markColor, + RectangleF absPosition, + SizeF labelSize, + LabelMarkStyle labelMark, + bool truncatedLeft, + bool truncatedRight, + Matrix oldTransform) + { + // Do not draw marking line if width is 0 and style or color are not set + if( axis.MajorTickMark.LineWidth == 0 || + axis.MajorTickMark.LineDashStyle == ChartDashStyle.NotSet || + axis.MajorTickMark.LineColor == Color.Empty) + { + return; + } + + // Remember SmoothingMode and turn off anti aliasing for + // vertical or horizontal lines of the label markers. + SmoothingMode oldSmoothingMode = this.SmoothingMode; + this.SmoothingMode = SmoothingMode.None; + + + // Draw box marker + if(labelMark == LabelMarkStyle.Box) + { + DrawSecondRowLabelBoxMark( + axis, + markColor, + absPosition, + truncatedLeft, + truncatedRight, + oldTransform); + } + else + + { + // Calculate center of the text rectangle + Point center = Point.Round(new PointF(absPosition.X + absPosition.Width/2F, absPosition.Y + absPosition.Height/2F)); + + // Round position to achieve crisp lines with antialiasing + Rectangle absPositionRounded = Rectangle.Round(absPosition); + + // Make sure the right and bottom position is not shifted during rounding + absPositionRounded.Width = (int)Math.Round(absPosition.Right) - absPositionRounded.X; + absPositionRounded.Height = (int)Math.Round(absPosition.Bottom) - absPositionRounded.Y; + + + // Arrays of points for the left and right marking lines + PointF[] leftLine = new PointF[3]; + PointF[] rightLine = new PointF[3]; + + // Calculate marking lines coordinates + leftLine[0].X = absPositionRounded.Left; + leftLine[0].Y = absPositionRounded.Bottom; + leftLine[1].X = absPositionRounded.Left; + leftLine[1].Y = center.Y; + leftLine[2].X = (float)Math.Round((double)center.X - labelSize.Width/2F - 1F); + leftLine[2].Y = center.Y; + + rightLine[0].X = absPositionRounded.Right; + rightLine[0].Y = absPositionRounded.Bottom; + rightLine[1].X = absPositionRounded.Right; + rightLine[1].Y = center.Y; + rightLine[2].X = (float)Math.Round((double)center.X + labelSize.Width/2F - 1F); + rightLine[2].Y = center.Y; + + if(axis.AxisPosition == AxisPosition.Bottom) + { + leftLine[0].Y = absPositionRounded.Top; + rightLine[0].Y = absPositionRounded.Top; + } + + // Remove third point to draw only side marks + if(labelMark == LabelMarkStyle.SideMark) + { + leftLine[2] = leftLine[1]; + rightLine[2] = rightLine[1]; + } + + if(truncatedLeft) + { + leftLine[0] = leftLine[1]; + } + if(truncatedRight) + { + rightLine[0] = rightLine[1]; + } + + // Create pen + Pen markPen = new Pen( + (markColor.IsEmpty) ? axis.MajorTickMark.LineColor : markColor, + axis.MajorTickMark.LineWidth); + + // Set pen style + markPen.DashStyle = GetPenStyle( axis.MajorTickMark.LineDashStyle ); + + // Draw marking lines + this.DrawLines(markPen, leftLine); + this.DrawLines(markPen, rightLine); + + // Dispose Pen + if( markPen != null ) + { + markPen.Dispose(); + } + } + + // Restore previous SmoothingMode + this.SmoothingMode = oldSmoothingMode; + } + + /// + /// Measures the specified text string when drawn with + /// the specified Font object and formatted with the + /// specified StringFormat object. + /// + /// The string to measure + /// The Font object used to determine the size of the text string. + /// A SizeF structure that represents the size of text as drawn with font. + internal SizeF MeasureStringRel( string text, Font font ) + { + SizeF newSize; + + // Measure string + newSize = this.MeasureString( text, font ); + + // Convert to relative Coordinates + return GetRelativeSize( newSize ); + } + + /// + /// Measures the specified text string when drawn with + /// the specified Font object and formatted with the + /// specified StringFormat object. + /// + /// The string to measure + /// The Font object used to determine the size of the text string. + /// A SizeF structure that specifies the layout rectangle for the text. + /// A StringFormat object that represents formatting information, such as line spacing, for the text string. + /// A SizeF structure that represents the size of text as drawn with font. + internal SizeF MeasureStringRel( string text, Font font, SizeF layoutArea, StringFormat stringFormat ) + { + SizeF size, newSize; + + // Get absolute coordinates + size = GetAbsoluteSize( layoutArea ); + + newSize = this.MeasureString( text, font, size, stringFormat ); + + // Convert to relative Coordinates + return GetRelativeSize( newSize ); + } + + /// + /// Measures the specified text string when drawn with + /// the specified Font object and formatted with the + /// specified StringFormat object. + /// + /// The string to measure + /// The Font object used to determine the size of the text string. + /// A SizeF structure that represents the size of text as drawn with font. + internal Size MeasureStringAbs( string text, Font font ) + { + // Measure string + SizeF size = this.MeasureString( text, font ); + return new Size( (int)Math.Ceiling(size.Width), (int)Math.Ceiling(size.Height)); + } + + /// + /// Measures the specified text string when drawn with + /// the specified Font object and formatted with the + /// specified StringFormat object. + /// + /// The string to measure + /// The Font object used to determine the size of the text string. + /// A SizeF structure that specifies the layout rectangle for the text. + /// A StringFormat object that represents formatting information, such as line spacing, for the text string. + /// A SizeF structure that represents the size of text as drawn with font. + internal Size MeasureStringAbs( string text, Font font, SizeF layoutArea, StringFormat stringFormat ) + { + SizeF size = this.MeasureString( text, font, layoutArea, stringFormat ); + return new Size( (int)Math.Ceiling(size.Width), (int)Math.Ceiling(size.Height)); + } + + /// + /// Draws the specified text string at the specified location + /// with the specified Brush object and font. The formatting + /// properties in the specified StringFormat object are applied + /// to the text. + /// + /// A string object that specifies the text to draw. + /// A Font object that specifies the font face and size with which to draw the text. + /// A Brush object that determines the color and/or texture of the drawn text. + /// A RectangleF structure that specifies the location of the drawn text. + /// A StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text. + internal void DrawStringRel( string text, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format ) + { + RectangleF rect; + + // Check that rectangle is not empty + if(layoutRectangle.Width == 0 || layoutRectangle.Height == 0) + { + return; + } + + // Get absolute coordinates + rect = GetAbsoluteRectangle( layoutRectangle ); + + // Draw text with anti-aliasing + /* + if( (this.AntiAliasing & AntiAliasing.Text) == AntiAliasing.Text ) + { + this.TextRenderingHint = TextRenderingHint.AntiAlias; + } + else + { + this.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; + } + */ + + this.DrawString( text, font, brush, rect, format ); + } + + + /// + /// Draws the specified text string at the specified location + /// with the specified angle and with the specified Brush object and font. The + /// formatting properties in the specified StringFormat object are applied + /// to the text. + /// + /// A string object that specifies the text to draw. + /// A Font object that specifies the font face and size with which to draw the text. + /// A Brush object that determines the color and/or texture of the drawn text. + /// A RectangleF structure that specifies the location of the drawn text. + /// A StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text. + /// A angle of the text + internal void DrawStringRel( + string text, + Font font, + Brush brush, + RectangleF layoutRectangle, + StringFormat format, + int angle + ) + { + RectangleF rect; + SizeF size; + Matrix oldTransform; + PointF rotationCenter = PointF.Empty; + + // Check that rectangle is not empty + if(layoutRectangle.Width == 0 || layoutRectangle.Height == 0) + { + return; + } + + // Get absolute coordinates + rect = GetAbsoluteRectangle( layoutRectangle ); + + size = this.MeasureString( text, font, rect.Size, format ); + + + // Find the center of rotation + if( format.Alignment == StringAlignment.Near ) + { // Near + rotationCenter.X = rect.X + size.Width / 2; + rotationCenter.Y = ( rect.Bottom + rect.Top ) / 2; + } + else if( format.Alignment == StringAlignment.Far ) + { // Far + rotationCenter.X = rect.Right - size.Width / 2; + rotationCenter.Y = ( rect.Bottom + rect.Top ) / 2; + } + else + { // Center + rotationCenter.X = ( rect.Left + rect.Right ) / 2; + rotationCenter.Y = ( rect.Bottom + rect.Top ) / 2; + } + // Create a matrix and rotate it. + _myMatrix = this.Transform.Clone(); + _myMatrix.RotateAt( angle, rotationCenter); + + // Old angle + oldTransform = this.Transform; + + // Set Angle + this.Transform = _myMatrix; + + // Draw text with anti-aliasing + /* + if( (AntiAliasing & AntiAliasing.Text) == AntiAliasing.Text ) + { + this.TextRenderingHint = TextRenderingHint.AntiAlias; + } + else + { + this.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; + } + */ + + this.DrawString( text, font, brush, rect, format ); + + // Set Old Angle + this.Transform = oldTransform; + } + + #endregion + + #region Rectangle Methods + + /// + /// Draws different shadows to create bar styles. + /// + /// Bar drawing style. + /// True if a vertical bar. + /// Rectangle position. + internal void DrawRectangleBarStyle(BarDrawingStyle barDrawingStyle, bool isVertical, RectangleF rect) + { + // Check if non-default bar drawing style is specified + if(barDrawingStyle != BarDrawingStyle.Default) + { + // Check column/bar size + if(rect.Width > 0 && rect.Height > 0) + { + // Draw gradient(s) + if(barDrawingStyle == BarDrawingStyle.Cylinder) + { + // Calculate gradient position + RectangleF gradientRect = rect; + if(isVertical) + { + gradientRect.Width *= 0.3f; + } + else + { + gradientRect.Height *= 0.3f; + } + if(gradientRect.Width > 0 && gradientRect.Height > 0) + { + this.FillRectangleAbs( + gradientRect, + Color.Transparent, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + (isVertical) ? GradientStyle.LeftRight : GradientStyle.TopBottom, + Color.FromArgb(120, Color.White), + Color.Empty, + 0, + ChartDashStyle.NotSet, + PenAlignment.Inset ); + + + if(isVertical) + { + gradientRect.X += gradientRect.Width + 1f; + gradientRect.Width = rect.Right - gradientRect.X; + } + else + { + gradientRect.Y += gradientRect.Height + 1f; + gradientRect.Height = rect.Bottom - gradientRect.Y; + } + + this.FillRectangleAbs( + gradientRect, + Color.FromArgb(120, Color.White), + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + (isVertical) ? GradientStyle.LeftRight : GradientStyle.TopBottom, + Color.FromArgb(150, Color.Black), + Color.Empty, + 0, + ChartDashStyle.NotSet, + PenAlignment.Inset ); + + } + } + else if(barDrawingStyle == BarDrawingStyle.Emboss) + { + // Calculate width of shadows used to create the effect + float shadowSize = 3f; + if(rect.Width < 6f || rect.Height < 6f) + { + shadowSize = 1f; + } + else if(rect.Width < 15f || rect.Height < 15f) + { + shadowSize = 2f; + } + + // Create and draw left/top path + using(GraphicsPath path = new GraphicsPath()) + { + // Add shadow polygon to the path + PointF[] points = new PointF[] { + new PointF(rect.Left, rect.Bottom), + new PointF(rect.Left, rect.Top), + new PointF(rect.Right, rect.Top), + new PointF(rect.Right - shadowSize, rect.Top + shadowSize), + new PointF(rect.Left + shadowSize, rect.Top + shadowSize), + new PointF(rect.Left + shadowSize, rect.Bottom - shadowSize) }; + path.AddPolygon(points); + + // Create brush + using(SolidBrush leftTopBrush = new SolidBrush(Color.FromArgb(100, Color.White))) + { + // Fill shadow path on the left-bottom side of the bar + this.FillPath(leftTopBrush, path); + } + } + + // Create and draw top/right path + using(GraphicsPath path = new GraphicsPath()) + { + // Add shadow polygon to the path + PointF[] points = new PointF[] { + new PointF(rect.Right, rect.Top), + new PointF(rect.Right, rect.Bottom), + new PointF(rect.Left, rect.Bottom), + new PointF(rect.Left + shadowSize, rect.Bottom - shadowSize), + new PointF(rect.Right - shadowSize, rect.Bottom - shadowSize), + new PointF(rect.Right - shadowSize, rect.Top + shadowSize) }; + path.AddPolygon(points); + + // Create brush + using(SolidBrush bottomRightBrush = new SolidBrush(Color.FromArgb(80, Color.Black))) + { + // Fill shadow path on the left-bottom side of the bar + this.FillPath(bottomRightBrush, path); + } + } + } + else if(barDrawingStyle == BarDrawingStyle.LightToDark) + { + // Calculate width of shadows used to create the effect + float shadowSize = 4f; + if(rect.Width < 6f || rect.Height < 6f) + { + shadowSize = 2f; + } + else if(rect.Width < 15f || rect.Height < 15f) + { + shadowSize = 3f; + } + + // Calculate gradient position + RectangleF gradientRect = rect; + gradientRect.Inflate(-shadowSize, -shadowSize); + if(isVertical) + { + gradientRect.Height = (float)Math.Floor(gradientRect.Height / 3f); + } + else + { + gradientRect.X = gradientRect.Right - (float)Math.Floor(gradientRect.Width / 3f); + gradientRect.Width = (float)Math.Floor(gradientRect.Width / 3f); + } + if(gradientRect.Width > 0 && gradientRect.Height > 0) + { + this.FillRectangleAbs( + gradientRect, + (isVertical) ? Color.FromArgb(120, Color.White) : Color.Transparent, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + (isVertical) ? GradientStyle.TopBottom : GradientStyle.LeftRight, + (isVertical) ? Color.Transparent : Color.FromArgb(120, Color.White), + Color.Empty, + 0, + ChartDashStyle.NotSet, + PenAlignment.Inset ); + + gradientRect = rect; + gradientRect.Inflate(-shadowSize, -shadowSize); + if(isVertical) + { + gradientRect.Y = gradientRect.Bottom - (float)Math.Floor(gradientRect.Height / 3f); + gradientRect.Height = (float)Math.Floor(gradientRect.Height / 3f); + } + else + { + gradientRect.Width = (float)Math.Floor(gradientRect.Width / 3f); + } + + + this.FillRectangleAbs( + gradientRect, + (!isVertical) ? Color.FromArgb(80, Color.Black) : Color.Transparent, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + (isVertical) ? GradientStyle.TopBottom : GradientStyle.LeftRight, + (!isVertical) ? Color.Transparent : Color.FromArgb(80, Color.Black), + Color.Empty, + 0, + ChartDashStyle.NotSet, + PenAlignment.Inset ); + + } + } + else if(barDrawingStyle == BarDrawingStyle.Wedge) + { + // Calculate wedge size to fit the rectangle + float size = (isVertical) ? rect.Width / 2f : rect.Height / 2f; + if(isVertical && 2f * size > rect.Height) + { + size = rect.Height/2f; + } + if(!isVertical && 2f * size > rect.Width) + { + size = rect.Width/2f; + } + + // Draw left/bottom shadow + RectangleF gradientRect = rect; + using(GraphicsPath path = new GraphicsPath()) + { + if(isVertical) + { + path.AddLine(gradientRect.X + gradientRect.Width/2f, gradientRect.Y + size, gradientRect.X + gradientRect.Width/2f, gradientRect.Bottom - size); + path.AddLine(gradientRect.X + gradientRect.Width/2f, gradientRect.Bottom - size, gradientRect.Right, gradientRect.Bottom); + path.AddLine(gradientRect.Right, gradientRect.Bottom, gradientRect.Right, gradientRect.Y); + } + else + { + path.AddLine(gradientRect.X + size, gradientRect.Y + gradientRect.Height/2f, gradientRect.Right - size, gradientRect.Y + gradientRect.Height/2f); + path.AddLine(gradientRect.Right - size, gradientRect.Y + gradientRect.Height/2f, gradientRect.Right, gradientRect.Bottom); + path.AddLine(gradientRect.Right, gradientRect.Bottom, gradientRect.Left, gradientRect.Bottom); + } + path.CloseAllFigures(); + + // Create brush and fill path + using(SolidBrush brush = new SolidBrush(Color.FromArgb(90, Color.Black))) + { + this.FillPath(brush, path); + } + } + + // Draw top/right triangle + using(GraphicsPath path = new GraphicsPath()) + { + if(isVertical) + { + path.AddLine(gradientRect.X, gradientRect.Y, gradientRect.X + gradientRect.Width/2f, gradientRect.Y + size); + path.AddLine(gradientRect.X + gradientRect.Width/2f, gradientRect.Y + size, gradientRect.Right, gradientRect.Y); + } + else + { + path.AddLine(gradientRect.Right, gradientRect.Y, gradientRect.Right - size, gradientRect.Y + gradientRect.Height / 2f); + path.AddLine(gradientRect.Right - size, gradientRect.Y + gradientRect.Height / 2f, gradientRect.Right, gradientRect.Bottom); + } + + // Create brush and fill path + using(SolidBrush brush = new SolidBrush(Color.FromArgb(50, Color.Black))) + { + // Fill shadow path on the left-bottom side of the bar + this.FillPath(brush, path); + + // Draw Lines + using(Pen penDark = new Pen(Color.FromArgb(20, Color.Black), 1)) + { + this.DrawPath(penDark, path); + if(isVertical) + { + this.DrawLine( + penDark, + rect.X + rect.Width/2f, + rect.Y + size, + rect.X + rect.Width/2f, + rect.Bottom - size); + } + else + { + this.DrawLine( + penDark, + rect.X + size, + rect.Y + rect.Height/2f, + rect.X + size, + rect.Bottom - rect.Height/2f); + } + } + + // Draw Lines + using(Pen pen = new Pen(Color.FromArgb(40, Color.White), 1)) + { + this.DrawPath(pen, path); + if(isVertical) + { + this.DrawLine( + pen, + rect.X + rect.Width/2f, + rect.Y + size, + rect.X + rect.Width/2f, + rect.Bottom - size); + } + else + { + this.DrawLine( + pen, + rect.X + size, + rect.Y + rect.Height/2f, + rect.X + size, + rect.Bottom - rect.Height/2f); + } + } + } + } + + // Draw bottom/left triangle + using(GraphicsPath path = new GraphicsPath()) + { + if(isVertical) + { + path.AddLine(gradientRect.X, gradientRect.Bottom, gradientRect.X + gradientRect.Width/2f, gradientRect.Bottom - size); + path.AddLine(gradientRect.X + gradientRect.Width/2f, gradientRect.Bottom - size, gradientRect.Right, gradientRect.Bottom); + } + else + { + path.AddLine(gradientRect.X, gradientRect.Y, gradientRect.X + size, gradientRect.Y + gradientRect.Height / 2f); + path.AddLine(gradientRect.X + size, gradientRect.Y + gradientRect.Height / 2f, gradientRect.X, gradientRect.Bottom); + } + + // Create brush + using(SolidBrush brush = new SolidBrush(Color.FromArgb(50, Color.Black))) + { + // Fill shadow path on the left-bottom side of the bar + this.FillPath(brush, path); + + // Draw edges + using(Pen penDark = new Pen(Color.FromArgb(20, Color.Black), 1)) + { + this.DrawPath(penDark, path); + } + using(Pen pen = new Pen(Color.FromArgb(40, Color.White), 1)) + { + this.DrawPath(pen, path); + } + } + } + } + } + } + } + + /// + /// Draw a bar with shadow. + /// + /// Size of rectangle + /// Color of rectangle + /// Hatch style + /// Back Image + /// Image mode + /// Image transparent color. + /// Image alignment + /// Gradient type + /// Gradient End Color + /// Border Color + /// Border Width + /// Border Style + /// Shadow Color + /// Shadow Offset + /// Pen Alignment + /// Bar drawing style. + /// True if a vertical bar. + internal void FillRectangleRel( RectangleF rectF, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + Color shadowColor, + int shadowOffset, + PenAlignment penAlignment, + BarDrawingStyle barDrawingStyle, + bool isVertical) + { + this.FillRectangleRel( + rectF, + backColor, + backHatchStyle, + backImage, + backImageWrapMode, + backImageTransparentColor, + backImageAlign, + backGradientStyle, + backSecondaryColor, + borderColor, + borderWidth, + borderDashStyle, + shadowColor, + shadowOffset, + penAlignment, + false, + 0, + false, + barDrawingStyle, + isVertical); + } + + /// + /// Draw a bar with shadow. + /// + /// Size of rectangle + /// Color of rectangle + /// Hatch style + /// Back Image + /// Image mode + /// Image transparent color. + /// Image alignment + /// Gradient type + /// Gradient End Color + /// Border Color + /// Border Width + /// Border Style + /// Shadow Color + /// Shadow Offset + /// Pen Alignment + internal void FillRectangleRel( RectangleF rectF, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + Color shadowColor, + int shadowOffset, + PenAlignment penAlignment ) + { + this.FillRectangleRel( + rectF, + backColor, + backHatchStyle, + backImage, + backImageWrapMode, + backImageTransparentColor, + backImageAlign, + backGradientStyle, + backSecondaryColor, + borderColor, + borderWidth, + borderDashStyle, + shadowColor, + shadowOffset, + penAlignment, + false, + 0, + false, + BarDrawingStyle.Default, + true); + } + + /// + /// Draws rectangle or circle (inside rectangle) with shadow. + /// + /// Size of rectangle + /// Color of rectangle + /// Hatch style + /// Back Image + /// Image mode + /// Image transparent color. + /// Image alignment + /// Gradient type + /// Gradient End Color + /// Border Color + /// Border Width + /// Border Style + /// Shadow Color + /// Shadow Offset + /// Pen Alignment + /// Draw circular shape inside the rectangle. + /// Number of sectors in circle when drawing the polygon. + /// 3D Circle must be drawn. + internal void FillRectangleRel( RectangleF rectF, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + Color shadowColor, + int shadowOffset, + PenAlignment penAlignment, + bool circular, + int circularSectorsCount, + bool circle3D) + { + this.FillRectangleRel( + rectF, + backColor, + backHatchStyle, + backImage, + backImageWrapMode, + backImageTransparentColor, + backImageAlign, + backGradientStyle, + backSecondaryColor, + borderColor, + borderWidth, + borderDashStyle, + shadowColor, + shadowOffset, + penAlignment, + circular, + circularSectorsCount, + circle3D, + BarDrawingStyle.Default, + true); + } + + + /// + /// Draws rectangle or circle (inside rectangle) with shadow. + /// + /// Size of rectangle + /// Color of rectangle + /// Hatch style + /// Back Image + /// Image mode + /// Image transparent color. + /// Image alignment + /// Gradient type + /// Gradient End Color + /// Border Color + /// Border Width + /// Border Style + /// Shadow Color + /// Shadow Offset + /// Pen Alignment + /// Draw circular shape inside the rectangle. + /// Number of sectors in circle when drawing the polygon. + /// 3D Circle must be drawn. + /// Bar drawing style. + /// True if a vertical bar. + internal void FillRectangleRel( RectangleF rectF, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + Color shadowColor, + int shadowOffset, + PenAlignment penAlignment, + bool circular, + int circularSectorsCount, + bool circle3D, + BarDrawingStyle barDrawingStyle, + bool isVertical) + { + Brush brush = null; + Brush backBrush = null; + + // Remember SmoothingMode and turn off anti aliasing + SmoothingMode oldSmoothingMode = this.SmoothingMode; + if(!circular) + { + this.SmoothingMode = SmoothingMode.Default; + } + + // Color is empty + if( backColor.IsEmpty ) + { + backColor = Color.White; + } + + if( backSecondaryColor.IsEmpty ) + { + backSecondaryColor = Color.White; + } + + if( borderColor.IsEmpty || borderDashStyle == ChartDashStyle.NotSet) + { + borderWidth = 0; + } + + // Get absolute coordinates + RectangleF rect = GetAbsoluteRectangle( rectF ); + + // Rectangle width and height can not be very small value + if( rect.Width < 1.0F && rect.Width > 0.0F ) + { + rect.Width = 1.0F; + } + + if( rect.Height < 1.0F && rect.Height > 0.0F ) + { + rect.Height = 1.0F; + } + + // Round the values + rect = Round( rect ); + + // For inset alignment resize fill rectangle + RectangleF fillRect; + if( penAlignment == PenAlignment.Inset && + borderWidth > 0) + { + // SVG and Metafiles do not support inset pen styles - use same rectangle + if( this.ActiveRenderingType == RenderingType.Svg || + this.IsMetafile) + { + fillRect = new RectangleF( rect.X, rect.Y, rect.Width, rect.Height); + } + else if (this.Graphics.Transform.Elements[0] != 1f || + this.Graphics.Transform.Elements[3] != 1f) + { + // Do not reduce filling rectangle if scaling is used in the graphics + // transformations. Rounding may cause a 1 pixel gap between the border + // and the filling. + fillRect = new RectangleF( rect.X, rect.Y, rect.Width, rect.Height); + } + else + { + // The fill rectangle is resized because of border size. + fillRect = new RectangleF( + rect.X + borderWidth, + rect.Y + borderWidth, + rect.Width - borderWidth * 2f + 1, + rect.Height - borderWidth * 2f + 1); + } + } + else + { + // The fill rectangle is same + fillRect = rect; + } + + // Fix for issue #6714: + // Make sure the rectangle coordinates fit the control. In same cases rectangle width or + // hight ca be extremly large. Drawing such a rectangle may cause an overflow exception. + // The code below restricts the maximum size to double the chart size. See issue + // description for more information. -AG. + if(fillRect.Width > 2f * this._width) + { + fillRect.Width = 2f * this._width; + } + if(fillRect.Height > 2f * this._height) + { + fillRect.Height = 2f * this._height; + } + + + if( backImage.Length > 0 && backImageWrapMode != ChartImageWrapMode.Unscaled && backImageWrapMode != ChartImageWrapMode.Scaled) + { + backBrush = brush; + brush = GetTextureBrush(backImage, backImageTransparentColor, backImageWrapMode, backColor); + } + else if( backHatchStyle != ChartHatchStyle.None ) + { + brush = GetHatchBrush( backHatchStyle, backColor, backSecondaryColor ); + } + else if( backGradientStyle != GradientStyle.None ) + { + // If a gradient type is set create a brush with gradient + brush = GetGradientBrush( rect, backColor, backSecondaryColor, backGradientStyle ); + } + else + { + // Set a bar color. + if(backColor == Color.Empty || backColor == Color.Transparent) + { + brush = null; + } + else + { + brush = new SolidBrush(backColor); + } + } + + // Draw shadow + FillRectangleShadowAbs( rect, shadowColor, shadowOffset, backColor, circular, circularSectorsCount ); + + // Draw rectangle image + if( backImage.Length > 0 && (backImageWrapMode == ChartImageWrapMode.Unscaled || backImageWrapMode == ChartImageWrapMode.Scaled)) + { + // Load image + System.Drawing.Image image = _common.ImageLoader.LoadImage( backImage ); + + // Prepare image properties (transparent color) + ImageAttributes attrib = new ImageAttributes(); + if(backImageTransparentColor != Color.Empty) + { + attrib.SetColorKey(backImageTransparentColor, backImageTransparentColor, ColorAdjustType.Default); + } + + // Draw scaled image + RectangleF imageRect = new RectangleF(); + imageRect.X = fillRect.X; + imageRect.Y = fillRect.Y; + imageRect.Width = fillRect.Width; + imageRect.Height = fillRect.Height; + + SizeF imageAbsSize = new SizeF(); + + // Calculate unscaled image position + if(backImageWrapMode == ChartImageWrapMode.Unscaled) + { + ImageLoader.GetAdjustedImageSize(image, this.Graphics, ref imageAbsSize); + + // Calculate image position + imageRect.Width = Math.Min(fillRect.Width, imageAbsSize.Width); + imageRect.Height = Math.Min(fillRect.Height, imageAbsSize.Height); + + // Adjust position with alignment property + if(imageRect.Width < fillRect.Width) + { + if(backImageAlign == ChartImageAlignmentStyle.BottomRight || + backImageAlign == ChartImageAlignmentStyle.Right || + backImageAlign == ChartImageAlignmentStyle.TopRight) + { + imageRect.X = fillRect.Right - imageRect.Width; + } + else if(backImageAlign == ChartImageAlignmentStyle.Bottom || + backImageAlign == ChartImageAlignmentStyle.Center || + backImageAlign == ChartImageAlignmentStyle.Top) + { + imageRect.X = fillRect.X + (fillRect.Width - imageRect.Width)/2; + } + } + if(imageRect.Height < fillRect.Height) + { + if(backImageAlign == ChartImageAlignmentStyle.BottomRight || + backImageAlign == ChartImageAlignmentStyle.Bottom || + backImageAlign == ChartImageAlignmentStyle.BottomLeft) + { + imageRect.Y = fillRect.Bottom - imageRect.Height; + } + else if(backImageAlign == ChartImageAlignmentStyle.Left || + backImageAlign == ChartImageAlignmentStyle.Center || + backImageAlign == ChartImageAlignmentStyle.Right) + { + imageRect.Y = fillRect.Y + (fillRect.Height - imageRect.Height)/2; + } + } + + } + + // Fill background with brush + if(brush != null) + { + if(circular) + this.DrawCircleAbs( null, brush, fillRect, circularSectorsCount, circle3D ); + else + this.FillRectangle( brush, fillRect ); + } + + // Draw image + this.DrawImage(image, + new Rectangle((int)Math.Round(imageRect.X),(int)Math.Round(imageRect.Y), (int)Math.Round(imageRect.Width), (int)Math.Round(imageRect.Height)), + 0, 0, + (backImageWrapMode == ChartImageWrapMode.Unscaled) ? imageRect.Width * image.Width / imageAbsSize.Width : image.Width, + (backImageWrapMode == ChartImageWrapMode.Unscaled) ? imageRect.Height * image.Height / imageAbsSize.Height : image.Height, + GraphicsUnit.Pixel, + attrib); + } + // Draw rectangle + else + { + if(backBrush != null && backImageTransparentColor != Color.Empty) + { + // Fill background with brush + if(circular) + this.DrawCircleAbs( null, backBrush, fillRect, circularSectorsCount, circle3D ); + else + this.FillRectangle( backBrush, fillRect ); + } + + if(brush != null) + { + if(circular) + this.DrawCircleAbs( null, brush, fillRect, circularSectorsCount, circle3D ); + else + this.FillRectangle( brush, fillRect ); + } + } + + // Draw different bar style + this.DrawRectangleBarStyle(barDrawingStyle, isVertical, fillRect); + + // Draw border + if( borderWidth > 0 && borderDashStyle != ChartDashStyle.NotSet) + { + // Set a border line color + if(_pen.Color != borderColor) + { + _pen.Color = borderColor; + } + + // Set a border line width + if(_pen.Width != borderWidth) + { + _pen.Width = borderWidth; + } + + // Set pen alignment + if(_pen.Alignment != penAlignment) + { + _pen.Alignment = penAlignment; + } + + // Set a border line style + if(_pen.DashStyle != GetPenStyle( borderDashStyle )) + { + _pen.DashStyle = GetPenStyle( borderDashStyle ); + } + + // Draw border + if(circular) + { + this.DrawCircleAbs( _pen, null, rect, circularSectorsCount, false ); + } + else + { + // NOTE: Rectangle with single pixel inset border is drawn 1 pixel larger + // in the .Net Framework. Increase size by 1 pixel to solve the issue. + if(_pen.Alignment == PenAlignment.Inset && _pen.Width > 1f) + { + rect.Width += 1; + rect.Height += 1; + } + + // Draw rectangle + this.DrawRectangle( _pen, rect.X, rect.Y, rect.Width, rect.Height ); + } + } + + // Dispose Image and Gradient + if(brush != null) + { + brush.Dispose(); + } + + // Return old smoothing mode + this.SmoothingMode = oldSmoothingMode; + } + + /// + /// Draw Shadow for a bar + /// + /// Bar rectangle + /// Shadow Color + /// Shadow Offset + /// Back Color + internal void FillRectangleShadowAbs( + RectangleF rect, + Color shadowColor, + float shadowOffset, + Color backColor) + { + FillRectangleShadowAbs( + rect, + shadowColor, + shadowOffset, + backColor, + false, + 0); + } + + /// + /// Draw Shadow for a bar + /// + /// Bar rectangle + /// Shadow Color + /// Shadow Offset + /// Back Color + /// Draw circular shape inside the rectangle. + /// Number of sectors in circle when drawing the polygon. + internal void FillRectangleShadowAbs( + RectangleF rect, + Color shadowColor, + float shadowOffset, + Color backColor, + bool circular, + int circularSectorsCount) + { + // Do not draw shadoe for empty rectangle + if(rect.Height == 0 || rect.Width == 0 || shadowOffset == 0) + { + return; + } + + // Do not draw shadow if color is IsEmpty or offset is 0 + if (shadowOffset == 0 || shadowColor == Color.Empty) + { + return; + } + + // For non-circualr shadow with transparent background - use clipping + bool clippingUsed = false; + Region oldClipRegion = null; + if (!circular && backColor == Color.Transparent) + { + clippingUsed = true; + oldClipRegion = this.Clip; + Region region = new Region(); + region.MakeInfinite(); + region.Xor(rect); + this.Clip = region; + } + + // Draw usual or "soft" shadows + if(!softShadows || circularSectorsCount > 2) + { + RectangleF absolute; + RectangleF offset = RectangleF.Empty; + + absolute = Round( rect ); + + // Change shadow color + using (SolidBrush shadowBrush = new SolidBrush((shadowColor.A != 255) ? shadowColor : Color.FromArgb(backColor.A / 2, shadowColor))) + { + // Shadow Position + offset.X = absolute.X + shadowOffset; + offset.Y = absolute.Y + shadowOffset; + offset.Width = absolute.Width; + offset.Height = absolute.Height; + + // Draw rectangle + if (circular) + this.DrawCircleAbs(null, shadowBrush, offset, circularSectorsCount, false); + else + this.FillRectangle(shadowBrush, offset); + } + } + else + { + + RectangleF absolute; + RectangleF offset = RectangleF.Empty; + + absolute = Round( rect ); + + + // Shadow Position + offset.X = absolute.X + shadowOffset - 1; + offset.Y = absolute.Y + shadowOffset - 1; + offset.Width = absolute.Width + 2; + offset.Height = absolute.Height + 2; + + // Calculate rounded rect radius + float radius = shadowOffset * 0.7f; + radius = (float)Math.Max(radius, 2f); + radius = (float)Math.Min(radius, offset.Width/4f); + radius = (float)Math.Min(radius, offset.Height/4f); + radius = (float)Math.Ceiling(radius); + if(circular) + { + radius = offset.Width/2f; + } + + // Create rounded rectangle path + GraphicsPath path = new GraphicsPath(); + if(circular && offset.Width != offset.Height) + { + float radiusX = offset.Width/2f; + float radiusY = offset.Height/2f; + path.AddLine(offset.X+radiusX, offset.Y, offset.Right-radiusX, offset.Y); + path.AddArc(offset.Right-2f*radiusX, offset.Y, 2f*radiusX, 2f*radiusY, 270, 90); + path.AddLine(offset.Right, offset.Y + radiusY, offset.Right, offset.Bottom - radiusY); + path.AddArc(offset.Right-2f*radiusX, offset.Bottom-2f*radiusY, 2f*radiusX, 2f*radiusY, 0, 90); + path.AddLine(offset.Right-radiusX, offset.Bottom, offset.X + radiusX, offset.Bottom); + path.AddArc(offset.X, offset.Bottom-2f*radiusY, 2f*radiusX, 2f*radiusY, 90, 90); + path.AddLine(offset.X, offset.Bottom-radiusY, offset.X, offset.Y+radiusY); + path.AddArc(offset.X, offset.Y, 2f*radiusX, 2f*radiusY, 180, 90); + } + else + { + path.AddLine(offset.X+radius, offset.Y, offset.Right-radius, offset.Y); + path.AddArc(offset.Right-2f*radius, offset.Y, 2f*radius, 2f*radius, 270, 90); + path.AddLine(offset.Right, offset.Y + radius, offset.Right, offset.Bottom - radius); + path.AddArc(offset.Right-2f*radius, offset.Bottom-2f*radius, 2f*radius, 2f*radius, 0, 90); + path.AddLine(offset.Right-radius, offset.Bottom, offset.X + radius, offset.Bottom); + path.AddArc(offset.X, offset.Bottom-2f*radius, 2f*radius, 2f*radius, 90, 90); + path.AddLine(offset.X, offset.Bottom-radius, offset.X, offset.Y+radius); + path.AddArc(offset.X, offset.Y, 2f*radius, 2f*radius, 180, 90); + } + + PathGradientBrush shadowBrush = new PathGradientBrush(path); + shadowBrush.CenterColor = shadowColor; + + // Set the color along the entire boundary of the path + Color[] colors = {Color.Transparent}; + shadowBrush.SurroundColors = colors; + shadowBrush.CenterPoint = new PointF(offset.X + offset.Width/2f, offset.Y + offset.Height/2f); + + // Define brush focus scale + PointF focusScale = new PointF(1-2f*shadowOffset/offset.Width, 1-2f*shadowOffset/offset.Height); + if(focusScale.X < 0) + focusScale.X = 0; + if(focusScale.Y < 0) + focusScale.Y = 0; + shadowBrush.FocusScales = focusScale; + + // Draw rectangle + this.FillPath(shadowBrush, path); + } + + // Reset clip region + if (clippingUsed) + { + Region region = this.Clip; + this.Clip = oldClipRegion; + region.Dispose(); + } + } + + /// + /// Gets the path of the polygon which represent the circular area. + /// + /// Circle position. + /// Number of sectors for the polygon. + /// Graphics path of the polygon circle. + internal GraphicsPath GetPolygonCirclePath(RectangleF position, int polygonSectorsNumber) + { + PointF firstPoint = new PointF(position.X + position.Width/2f, position.Y); + PointF centerPoint = new PointF(position.X + position.Width/2f, position.Y + position.Height/2f); + float sectorSize = 0f; + GraphicsPath path = new GraphicsPath(); + PointF prevPoint = PointF.Empty; + float curentSector = 0f; + + // Get sector size + if(polygonSectorsNumber <= 2) + { + // Circle sector size + sectorSize = 1f; + } + else + { + // Polygon sector size + sectorSize = 360f / ((float)polygonSectorsNumber); + } + + // Loop throug all sectors + for(curentSector = 0f; curentSector < 360f; curentSector += sectorSize) + { + // Create matrix + Matrix matrix = new Matrix(); + matrix.RotateAt(curentSector, centerPoint); + + // Get point and rotate it + PointF[] points = new PointF[] { firstPoint }; + matrix.TransformPoints(points); + + // Add point into the path + if(!prevPoint.IsEmpty) + { + path.AddLine(prevPoint, points[0]); + } + + // Remember last point + prevPoint = points[0]; + } + + path.CloseAllFigures(); + + return path; + } + + /// + /// Fills and/or draws border as circle or polygon. + /// + /// Border pen. + /// Border brush. + /// Circle position. + /// Number of sectors for the polygon. + /// Indicates that circle should be 3D.. + internal void DrawCircleAbs(Pen pen, Brush brush, RectangleF position, int polygonSectorsNumber, bool circle3D) + { + bool fill3DCircle = (circle3D && brush != null); + + // Draw 2D circle + if(polygonSectorsNumber <= 2 && !fill3DCircle) + { + if(brush != null) + { + this.FillEllipse(brush, position); + } + if(pen != null) + { + this.DrawEllipse(pen, position); + } + } + + // Draw circle as polygon with specified number of sectors + else + { + PointF firstPoint = new PointF(position.X + position.Width/2f, position.Y); + PointF centerPoint = new PointF(position.X + position.Width/2f, position.Y + position.Height/2f); + float sectorSize = 0f; + PointF prevPoint = PointF.Empty; + float curentSector = 0f; + + using (GraphicsPath path = new GraphicsPath()) + { + // Remember current smoothing mode + SmoothingMode oldMode = this.SmoothingMode; + if (fill3DCircle) + { + this.SmoothingMode = SmoothingMode.None; + } + + // Get sector size + if (polygonSectorsNumber <= 2) + { + // Circle sector size + sectorSize = 1f; + } + else + { + // Polygon sector size + sectorSize = 360f / ((float)polygonSectorsNumber); + } + + // Loop throug all sectors + for (curentSector = 0f; curentSector < 360f; curentSector += sectorSize) + { + // Create matrix + Matrix matrix = new Matrix(); + matrix.RotateAt(curentSector, centerPoint); + + // Get point and rotate it + PointF[] points = new PointF[] { firstPoint }; + matrix.TransformPoints(points); + + // Add point into the path + if (!prevPoint.IsEmpty) + { + path.AddLine(prevPoint, points[0]); + + // Fill each segment separatly for the 3D look + if (fill3DCircle) + { + path.AddLine(points[0], centerPoint); + path.AddLine(centerPoint, prevPoint); + using (Brush sectorBrush = GetSector3DBrush(brush, curentSector, sectorSize)) + { + this.FillPath(sectorBrush, path); + } + path.Reset(); + } + } + + // Remember last point + prevPoint = points[0]; + } + + path.CloseAllFigures(); + + // Fill last segment for the 3D look + if (!prevPoint.IsEmpty && fill3DCircle) + { + path.AddLine(prevPoint, firstPoint); + path.AddLine(firstPoint, centerPoint); + path.AddLine(centerPoint, prevPoint); + using (Brush sectorBrush = GetSector3DBrush(brush, curentSector, sectorSize)) + { + this.FillPath(sectorBrush, path); + } + path.Reset(); + } + + // Restore old mode + if (fill3DCircle) + { + this.SmoothingMode = oldMode; + } + + if (brush != null && !circle3D) + { + this.FillPath(brush, path); + } + if (pen != null) + { + this.DrawPath(pen, path); + } + } + } + } + + /// + /// Creates 3D sector brush. + /// + /// Original brush. + /// Sector position. + /// Sector size. + /// 3D brush. + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", + Justification = "Too large of a code change to justify making this change")] + internal Brush GetSector3DBrush(Brush brush, float curentSector, float sectorSize) + { + // Get color from the brush + Color brushColor = Color.Gray; + if(brush is HatchBrush) + { + brushColor = ((HatchBrush)brush).BackgroundColor; + } + else if(brush is LinearGradientBrush) + { + brushColor = ((LinearGradientBrush)brush).LinearColors[0]; + } + else if(brush is PathGradientBrush) + { + brushColor = ((PathGradientBrush)brush).CenterColor; + } + else if(brush is SolidBrush) + { + brushColor = ((SolidBrush)brush).Color; + } + + // Adjust sector angle + curentSector -= sectorSize / 2f; + + // Make adjustment for polygon circle with 5 segments + // to avoid the issue that bottom segment is too dark + if(sectorSize == 72f && curentSector == 180f) + { + curentSector *= 0.8f; + } + + // No angles more than 180 + if(curentSector > 180) + { + curentSector = 360f - curentSector; + } + curentSector = curentSector / 180F; + + // Get brush + brushColor = GetBrightGradientColor( brushColor, curentSector); + + // Get brush + return new SolidBrush(brushColor); + } + + /// + /// This method creates gradient color with brightness + /// + /// Start color for gradient. + /// Position used between Start and end color. + /// Calculated Gradient color from gradient position + internal Color GetBrightGradientColor( Color beginColor, double position ) + { + double brightness = 0.5; + if( position < brightness ) + { + return GetGradientColor( Color.FromArgb(beginColor.A,255,255,255), beginColor, 1 - brightness + position ); + } + else if( -brightness + position < 1 ) + { + return GetGradientColor( beginColor, Color.Black, -brightness + position); + } + else + { + return Color.FromArgb( beginColor.A, 0, 0, 0 ); + } + } + + /// + /// Draw Rectangle using absolute coordinates. + /// + /// Size of rectangle + /// Color of rectangle + /// Hatch Style + /// Image URL + /// Image Mode + /// Image transparent color. + /// Image alignment. + /// Gradient AxisName + /// End Gradient color + /// Border Color + /// Border Width + /// Border Style + /// Border is outside or inside rectangle + internal void FillRectangleAbs( RectangleF rect, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + PenAlignment penAlignment ) + { + Brush brush = null; + Brush backBrush = null; + + // Turn off Antialias + SmoothingMode oldMode = this.SmoothingMode; + this.SmoothingMode = SmoothingMode.None; + + // Color is empty + if( backColor.IsEmpty ) + backColor = Color.White; + + if( backSecondaryColor.IsEmpty ) + backSecondaryColor = Color.White; + + if( borderColor.IsEmpty ) + { + borderColor = Color.White; + borderWidth = 0; + } + + // Set a border line color + _pen.Color = borderColor; + + // Set a border line width + _pen.Width = borderWidth; + + // Set pen alignment + _pen.Alignment = penAlignment; + + // Set a border line style + _pen.DashStyle = GetPenStyle( borderDashStyle ); + + if( backGradientStyle == GradientStyle.None ) + { + // Set a bar color. + _solidBrush.Color = backColor; + brush = _solidBrush; + } + else + { + // If a gradient type is set create a brush with gradient + brush = GetGradientBrush( rect, backColor, backSecondaryColor, backGradientStyle ); + } + + if( backHatchStyle != ChartHatchStyle.None ) + { + brush = GetHatchBrush( backHatchStyle, backColor, backSecondaryColor ); + } + + if( backImage.Length > 0 && backImageWrapMode != ChartImageWrapMode.Unscaled && backImageWrapMode != ChartImageWrapMode.Scaled) + { + backBrush = brush; + brush = GetTextureBrush(backImage, backImageTransparentColor, backImageWrapMode, backColor ); + } + + // For inset alignment resize fill rectangle + RectangleF fillRect; + + // The fill rectangle is same + fillRect = new RectangleF( rect.X + borderWidth, rect.Y + borderWidth, rect.Width - borderWidth * 2, rect.Height - borderWidth * 2 ); + + // FillRectangle and DrawRectangle works differently with RectangleF. + fillRect.Width += 1; + fillRect.Height += 1; + + // Draw rectangle image + if( backImage.Length > 0 && (backImageWrapMode == ChartImageWrapMode.Unscaled || backImageWrapMode == ChartImageWrapMode.Scaled)) + { + // Load image + System.Drawing.Image image = _common.ImageLoader.LoadImage( backImage ); + + + // Prepare image properties (transparent color) + ImageAttributes attrib = new ImageAttributes(); + if(backImageTransparentColor != Color.Empty) + { + attrib.SetColorKey(backImageTransparentColor, backImageTransparentColor, ColorAdjustType.Default); + } + + // Draw scaled image + RectangleF imageRect = new RectangleF(); + imageRect.X = fillRect.X; + imageRect.Y = fillRect.Y; + imageRect.Width = fillRect.Width; + imageRect.Height = fillRect.Height; + + // Draw unscaled image using align property + if(backImageWrapMode == ChartImageWrapMode.Unscaled) + { + SizeF imageAbsSize = new SizeF(); + + ImageLoader.GetAdjustedImageSize(image, this.Graphics, ref imageAbsSize); + + // Calculate image position + imageRect.Width = imageAbsSize.Width; + imageRect.Height = imageAbsSize.Height; + + // Adjust position with alignment property + if(imageRect.Width < fillRect.Width) + { + if(backImageAlign == ChartImageAlignmentStyle.BottomRight || + backImageAlign == ChartImageAlignmentStyle.Right || + backImageAlign == ChartImageAlignmentStyle.TopRight) + { + imageRect.X = fillRect.Right - imageRect.Width; + } + else if(backImageAlign == ChartImageAlignmentStyle.Bottom || + backImageAlign == ChartImageAlignmentStyle.Center || + backImageAlign == ChartImageAlignmentStyle.Top) + { + imageRect.X = fillRect.X + (fillRect.Width - imageRect.Width)/2; + } + } + if(imageRect.Height < fillRect.Height) + { + if(backImageAlign == ChartImageAlignmentStyle.BottomRight || + backImageAlign == ChartImageAlignmentStyle.Bottom || + backImageAlign == ChartImageAlignmentStyle.BottomLeft) + { + imageRect.Y = fillRect.Bottom - imageRect.Height; + } + else if(backImageAlign == ChartImageAlignmentStyle.Left || + backImageAlign == ChartImageAlignmentStyle.Center || + backImageAlign == ChartImageAlignmentStyle.Right) + { + imageRect.Y = fillRect.Y + (fillRect.Height - imageRect.Height)/2; + } + } + + } + + // Fill background with brush + this.FillRectangle( brush, rect.X, rect.Y, rect.Width + 1, rect.Height + 1); + + // Draw image + this.DrawImage(image, + new Rectangle((int)Math.Round(imageRect.X),(int)Math.Round(imageRect.Y), (int)Math.Round(imageRect.Width), (int)Math.Round(imageRect.Height)), + 0, 0, image.Width, image.Height, + GraphicsUnit.Pixel, + attrib); + } + // Draw rectangle + else + { + if(backBrush != null && backImageTransparentColor != Color.Empty) + { + // Fill background with brush + this.FillRectangle( backBrush, rect.X, rect.Y, rect.Width + 1, rect.Height + 1 ); + } + this.FillRectangle( brush, rect.X, rect.Y, rect.Width + 1, rect.Height + 1 ); + } + + // Set pen alignment + if(borderDashStyle != ChartDashStyle.NotSet) + { + if( borderWidth > 1 ) + this.DrawRectangle( _pen, rect.X, rect.Y, rect.Width + 1, rect.Height + 1 ); + else if( borderWidth == 1 ) + this.DrawRectangle( _pen, rect.X, rect.Y, rect.Width, rect.Height ); + } + + // Dispose Image and Gradient + if( backGradientStyle != GradientStyle.None ) + { + brush.Dispose(); + } + if( backImage.Length > 0 && backImageWrapMode != ChartImageWrapMode.Unscaled && backImageWrapMode != ChartImageWrapMode.Scaled) + { + brush.Dispose(); + } + if( backHatchStyle != ChartHatchStyle.None ) + { + brush.Dispose(); + } + + // Set Old Smoothing Mode + this.SmoothingMode = oldMode; + } + + /// + /// Fills graphics path with shadow using absolute coordinates. + /// + /// Graphics path to fill. + /// Color of rectangle + /// Hatch Style + /// Image URL + /// Image Mode + /// Image transparent color. + /// Image alignment. + /// Gradient AxisName + /// End Gradient color + /// Border Color + /// Border Width + /// Border Style + /// Border is outside or inside rectangle + /// Shadow offset. + /// Shadow color. + internal void DrawPathAbs( + GraphicsPath path, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + PenAlignment penAlignment, + int shadowOffset, + Color shadowColor) + { + // Draw patj shadow + if(shadowOffset != 0 && shadowColor != Color.Transparent) + { + // Save graphics state and apply translate transformation + GraphicsState graphicsState = this.Save(); + this.TranslateTransform(shadowOffset, shadowOffset); + + if(backColor == Color.Transparent && + backSecondaryColor.IsEmpty ) + { + this.DrawPathAbs( + path, + Color.Transparent, + ChartHatchStyle.None, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + shadowColor, + borderWidth, + borderDashStyle, + PenAlignment.Center); + } + else + { + this.DrawPathAbs( + path, + shadowColor, + ChartHatchStyle.None, + String.Empty, + ChartImageWrapMode.Scaled, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + Color.Transparent, + 0, + ChartDashStyle.NotSet, + PenAlignment.Center); + } + + // Restore graphics state + this.Restore(graphicsState); + } + + // Draw path + this.DrawPathAbs( + path, + backColor, + backHatchStyle, + backImage, + backImageWrapMode, + backImageTransparentColor, + backImageAlign, + backGradientStyle, + backSecondaryColor, + borderColor, + borderWidth, + borderDashStyle, + penAlignment); + } + + /// + /// Fills graphics path using absolute coordinates. + /// + /// Graphics path to fill. + /// Color of rectangle + /// Hatch Style + /// Image URL + /// Image Mode + /// Image transparent color. + /// Image alignment. + /// Gradient AxisName + /// End Gradient color + /// Border Color + /// Border Width + /// Border Style + /// Border is outside or inside rectangle + internal void DrawPathAbs( GraphicsPath path, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + PenAlignment penAlignment ) + { + Brush brush = null; + Brush backBrush = null; + + // Color is empty + if( backColor.IsEmpty ) + backColor = Color.White; + + if( backSecondaryColor.IsEmpty ) + backSecondaryColor = Color.White; + + if( borderColor.IsEmpty ) + { + borderColor = Color.White; + borderWidth = 0; + } + + // Set pen properties + _pen.Color = borderColor; + _pen.Width = borderWidth; + _pen.Alignment = penAlignment; + _pen.DashStyle = GetPenStyle( borderDashStyle ); + + if( backGradientStyle == GradientStyle.None ) + { + // Set solid brush color. + _solidBrush.Color = backColor; + brush = _solidBrush; + } + else + { + // If a gradient type is set create a brush with gradient + RectangleF pathRect = path.GetBounds(); + pathRect.Inflate(new SizeF(2,2)); + brush = GetGradientBrush( + pathRect, + backColor, + backSecondaryColor, + backGradientStyle ); + } + + if( backHatchStyle != ChartHatchStyle.None ) + { + brush = GetHatchBrush( backHatchStyle, backColor, backSecondaryColor ); + } + + if( backImage.Length > 0 && backImageWrapMode != ChartImageWrapMode.Unscaled && backImageWrapMode != ChartImageWrapMode.Scaled) + { + backBrush = brush; + brush = GetTextureBrush(backImage, backImageTransparentColor, backImageWrapMode, backColor ); + } + + // For inset alignment resize fill rectangle + RectangleF fillRect = path.GetBounds(); + + // Draw rectangle image + if( backImage.Length > 0 && (backImageWrapMode == ChartImageWrapMode.Unscaled || backImageWrapMode == ChartImageWrapMode.Scaled)) + { + // Load image +System.Drawing.Image image = _common.ImageLoader.LoadImage( backImage ); + + // Prepare image properties (transparent color) + ImageAttributes attrib = new ImageAttributes(); + if(backImageTransparentColor != Color.Empty) + { + attrib.SetColorKey(backImageTransparentColor, backImageTransparentColor, ColorAdjustType.Default); + } + + // Draw scaled image + RectangleF imageRect = new RectangleF(); + imageRect.X = fillRect.X; + imageRect.Y = fillRect.Y; + imageRect.Width = fillRect.Width; + imageRect.Height = fillRect.Height; + + // Draw unscaled image using align property + if(backImageWrapMode == ChartImageWrapMode.Unscaled) + { + SizeF imageSize = new SizeF(); + + ImageLoader.GetAdjustedImageSize(image, this.Graphics, ref imageSize); + + // Calculate image position + imageRect.Width = imageSize.Width; + imageRect.Height = imageSize.Height; + + // Adjust position with alignment property + if(imageRect.Width < fillRect.Width) + { + if(backImageAlign == ChartImageAlignmentStyle.BottomRight || + backImageAlign == ChartImageAlignmentStyle.Right || + backImageAlign == ChartImageAlignmentStyle.TopRight) + { + imageRect.X = fillRect.Right - imageRect.Width; + } + else if(backImageAlign == ChartImageAlignmentStyle.Bottom || + backImageAlign == ChartImageAlignmentStyle.Center || + backImageAlign == ChartImageAlignmentStyle.Top) + { + imageRect.X = fillRect.X + (fillRect.Width - imageRect.Width)/2; + } + } + if(imageRect.Height < fillRect.Height) + { + if(backImageAlign == ChartImageAlignmentStyle.BottomRight || + backImageAlign == ChartImageAlignmentStyle.Bottom || + backImageAlign == ChartImageAlignmentStyle.BottomLeft) + { + imageRect.Y = fillRect.Bottom - imageRect.Height; + } + else if(backImageAlign == ChartImageAlignmentStyle.Left || + backImageAlign == ChartImageAlignmentStyle.Center || + backImageAlign == ChartImageAlignmentStyle.Right) + { + imageRect.Y = fillRect.Y + (fillRect.Height - imageRect.Height)/2; + } + } + + } + + // Fill background with brush + this.FillPath( brush, path ); + + // Draw image + Region oldClipRegion = this.Clip; + this.Clip = new Region(path); + this.DrawImage(image, + new Rectangle((int)Math.Round(imageRect.X),(int)Math.Round(imageRect.Y), (int)Math.Round(imageRect.Width), (int)Math.Round(imageRect.Height)), + 0, 0, image.Width, image.Height, + GraphicsUnit.Pixel, + attrib); + this.Clip = oldClipRegion; + } + + // Draw rectangle + else + { + if(backBrush != null && backImageTransparentColor != Color.Empty) + { + // Fill background with brush + this.FillPath( backBrush, path); + } + this.FillPath( brush, path); + } + + // Draw border + if(borderColor != Color.Empty && borderWidth > 0 && borderDashStyle != ChartDashStyle.NotSet) + { + this.DrawPath( _pen, path ); + } + } + + /// + /// Creates brush with specified properties. + /// + /// Gradient rectangle + /// Color of rectangle + /// Hatch style + /// Back Image + /// Image mode + /// Image transparent color. + /// Gradient type + /// Gradient End Color + /// New brush object. + internal Brush CreateBrush( + RectangleF rect, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + GradientStyle backGradientStyle, + Color backSecondaryColor + ) + { + Brush brush = new SolidBrush(backColor); + + if( backImage.Length > 0 && backImageWrapMode != ChartImageWrapMode.Unscaled && backImageWrapMode != ChartImageWrapMode.Scaled) + { + brush = GetTextureBrush(backImage, backImageTransparentColor, backImageWrapMode, backColor ); + } + else if( backHatchStyle != ChartHatchStyle.None ) + { + brush = GetHatchBrush( backHatchStyle, backColor, backSecondaryColor ); + } + else if( backGradientStyle != GradientStyle.None ) + { + // If a gradient type is set create a brush with gradient + brush = GetGradientBrush( rect, backColor, backSecondaryColor, backGradientStyle ); + } + + return brush; + } + + #endregion + + #region Coordinates converter + + /// + /// This method takes a RectangleF structure that is using absolute coordinates + /// and returns a RectangleF object that uses relative coordinates. + /// + /// RectangleF structure in absolute coordinates. + /// RectangleF structure in relative coordinates. + public RectangleF GetRelativeRectangle( RectangleF rectangle ) + { + // Check arguments + if (rectangle == null) + throw new ArgumentNullException("rectangle"); + + RectangleF relative = RectangleF.Empty; + + // Convert absolute coordinates to relative coordinates + relative.X = rectangle.X * 100F / ((float)(_width - 1)); + relative.Y = rectangle.Y * 100F / ((float)(_height - 1)); + relative.Width = rectangle.Width * 100F / ((float)(_width - 1)); + relative.Height = rectangle.Height * 100F / ((float)(_height - 1)); + + // Return Relative coordinates + return relative; + } + + /// + /// This method takes a PointF object that is using absolute coordinates + /// and returns a PointF object that uses relative coordinates. + /// + /// PointF object in absolute coordinates. + /// PointF object in relative coordinates. + public PointF GetRelativePoint( PointF point ) + { + // Check arguments + if (point == null) + throw new ArgumentNullException("point"); + + PointF relative = PointF.Empty; + + // Convert absolute coordinates to relative coordinates + relative.X = point.X * 100F / ((float)(_width - 1)); + relative.Y = point.Y * 100F / ((float)(_height - 1)); + + // Return Relative coordinates + return relative; + } + + + /// + /// This method takes a SizeF object that uses absolute coordinates + /// and returns a SizeF object that uses relative coordinates. + /// + /// SizeF object in absolute coordinates. + /// SizeF object in relative coordinates. + public SizeF GetRelativeSize( SizeF size ) + { + // Check arguments + if (size == null) + throw new ArgumentNullException("size"); + + SizeF relative = SizeF.Empty; + + // Convert absolute coordinates to relative coordinates + relative.Width = size.Width * 100F / ((float)(_width - 1)); + relative.Height = size.Height * 100F / ((float)(_height - 1)); + + // Return relative coordinates + return relative; + } + + /// + /// This method takes a PointF object and converts its relative coordinates + /// to absolute coordinates. + /// + /// PointF object in relative coordinates. + /// PointF object in absolute coordinates. + public PointF GetAbsolutePoint( PointF point ) + { + // Check arguments + if (point == null) + throw new ArgumentNullException("point"); + + PointF absolute = PointF.Empty; + + // Convert relative coordinates to absolute coordinates + absolute.X = point.X * (_width - 1) / 100F; + absolute.Y = point.Y * (_height - 1) / 100F; + + // Return Absolute coordinates + return absolute; + } + + /// + /// This method takes a RectangleF structure and converts its relative coordinates + /// to absolute coordinates. + /// + /// RectangleF object in relative coordinates. + /// RectangleF object in absolute coordinates. + public RectangleF GetAbsoluteRectangle( RectangleF rectangle ) + { + // Check arguments + if (rectangle == null) + throw new ArgumentNullException("rectangle"); + + RectangleF absolute = RectangleF.Empty; + + // Convert relative coordinates to absolute coordinates + absolute.X = rectangle.X * (_width - 1) / 100F; + absolute.Y = rectangle.Y * (_height - 1) / 100F; + absolute.Width = rectangle.Width * (_width - 1) / 100F; + absolute.Height = rectangle.Height * (_height - 1) / 100F; + + // Return Absolute coordinates + return absolute; + } + + /// + /// This method takes a SizeF object that uses relative coordinates + /// and returns a SizeF object that uses absolute coordinates. + /// + /// SizeF object in relative coordinates. + /// SizeF object in absolute coordinates. + public SizeF GetAbsoluteSize( SizeF size ) + { + // Check arguments + if (size == null) + throw new ArgumentNullException("size"); + + SizeF absolute = SizeF.Empty; + + // Convert relative coordinates to absolute coordinates + absolute.Width = size.Width * (_width - 1) / 100F; + absolute.Height = size.Height * (_height - 1) / 100F; + + // Return Absolute coordinates + return absolute; + } + + + #endregion + + #region Border drawing helper methods + + /// + /// Helper function which creates a rounded rectangle path. + /// + /// Rectangle coordinates. + /// Array of 4 corners radius. + /// Graphics path object. + internal GraphicsPath CreateRoundedRectPath(RectangleF rect, float[] cornerRadius) + { + // Create rounded rectangle path + GraphicsPath path = new GraphicsPath(); + path.AddLine(rect.X+cornerRadius[0], rect.Y, rect.Right-cornerRadius[1], rect.Y); + path.AddArc(rect.Right-2f*cornerRadius[1], rect.Y, 2f*cornerRadius[1], 2f*cornerRadius[2], 270, 90); + path.AddLine(rect.Right, rect.Y + cornerRadius[2], rect.Right, rect.Bottom - cornerRadius[3]); + path.AddArc(rect.Right-2f*cornerRadius[4], rect.Bottom-2f*cornerRadius[3], 2f*cornerRadius[4], 2f*cornerRadius[3], 0, 90); + path.AddLine(rect.Right-cornerRadius[4], rect.Bottom, rect.X + cornerRadius[5], rect.Bottom); + path.AddArc(rect.X, rect.Bottom-2f*cornerRadius[6], 2f*cornerRadius[5], 2f*cornerRadius[6], 90, 90); + path.AddLine(rect.X, rect.Bottom-cornerRadius[6], rect.X, rect.Y+cornerRadius[7]); + path.AddArc(rect.X, rect.Y, 2f*cornerRadius[0], 2f*cornerRadius[7], 180, 90); + + return path; + } + + /// + /// Helper function which draws a shadow of the rounded rect. + /// + /// Rectangle coordinates. + /// Array of 4 corners radius. + /// Rounding radius. + /// Center color. + /// Surrounding color. + /// Shadow scale value. + internal void DrawRoundedRectShadowAbs(RectangleF rect, float[] cornerRadius, float radius, Color centerColor, Color surroundColor, float shadowScale) + { + // Create rounded rectangle path + GraphicsPath path = CreateRoundedRectPath(rect, cornerRadius); + + // Create gradient brush + PathGradientBrush shadowBrush = new PathGradientBrush(path); + shadowBrush.CenterColor = centerColor; + + // Set the color along the entire boundary of the path + Color[] colors = {surroundColor}; + shadowBrush.SurroundColors = colors; + shadowBrush.CenterPoint = new PointF(rect.X + rect.Width/2f, rect.Y + rect.Height/2f); + + // Define brush focus scale + PointF focusScale = new PointF(1-shadowScale*radius/rect.Width, 1-shadowScale*radius/rect.Height); + shadowBrush.FocusScales = focusScale; + + // Draw rounded rectangle + this.FillPath(shadowBrush, path); + + if( path != null ) + { + path.Dispose(); + } + } + + /// + /// Draws 3D border in absolute coordinates. + /// + /// Border skin object. + /// Rectangle of the border (pixel coordinates). + /// Color of rectangle + /// Hatch style + /// Back Image + /// Image mode + /// Image transparent color. + /// Image alignment + /// Gradient type + /// Gradient End Color + /// Border Color + /// Border Width + /// Border Style + internal void Draw3DBorderRel( + BorderSkin borderSkin, + RectangleF rect, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle) + { + Draw3DBorderAbs(borderSkin, GetAbsoluteRectangle(rect), backColor, backHatchStyle, + backImage, backImageWrapMode, backImageTransparentColor, backImageAlign, backGradientStyle, + backSecondaryColor, borderColor, borderWidth, borderDashStyle); + } + + + /// + /// Draws 3D border in absolute coordinates. + /// + /// Border skin object. + /// Rectangle of the border (pixel coordinates). + /// Color of rectangle + /// Hatch style + /// Back Image + /// Image mode + /// Image transparent color. + /// Image alignment + /// Gradient type + /// Gradient End Color + /// Border Color + /// Border Width + /// Border Style + internal void Draw3DBorderAbs( + BorderSkin borderSkin, + RectangleF absRect, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + ChartImageAlignmentStyle backImageAlign, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle) + { + // Check input parameters + if(_common == null || borderSkin.SkinStyle == BorderSkinStyle.None || absRect.Width == 0 || absRect.Height == 0) + { + return; + } + + // Find required border interface + IBorderType borderTypeInterface = _common.BorderTypeRegistry.GetBorderType(borderSkin.SkinStyle.ToString()); + if(borderTypeInterface != null) + { + borderTypeInterface.Resolution = this.Graphics.DpiX; + // Draw border + borderTypeInterface.DrawBorder(this, borderSkin, absRect, backColor, backHatchStyle, backImage, backImageWrapMode, + backImageTransparentColor, backImageAlign, backGradientStyle, backSecondaryColor, + borderColor, borderWidth, borderDashStyle); + } + } + + #endregion + + #region Pie Method + + /// + /// Helper function that retrieves pie drawing style. + /// + /// Data point to get the drawing style for. + /// pie drawing style. + internal static PieDrawingStyle GetPieDrawingStyle(DataPoint point) + { + // Get column drawing style + PieDrawingStyle pieDrawingStyle = PieDrawingStyle.Default; + string styleName = point[CustomPropertyName.PieDrawingStyle]; + if(styleName != null) + { + if(String.Compare(styleName, "Default", StringComparison.OrdinalIgnoreCase) == 0) + { + pieDrawingStyle = PieDrawingStyle.Default; + } + else if (String.Compare(styleName, "SoftEdge", StringComparison.OrdinalIgnoreCase) == 0) + { + pieDrawingStyle = PieDrawingStyle.SoftEdge; + } + else if (String.Compare(styleName, "Concave", StringComparison.OrdinalIgnoreCase) == 0) + { + pieDrawingStyle = PieDrawingStyle.Concave; + } + else + { + throw( new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid( styleName, "PieDrawingStyle"))); + } + } + return pieDrawingStyle; + } + + /// + /// Draws a pie defined by an ellipse specified by a Rectangle structure and two radial lines. + /// + /// Rectangle structure that represents the bounding rectangle that defines the ellipse from which the pie shape comes. + /// Angle measured in degrees clockwise from the x-axis to the first side of the pie shape. + /// Angle measured in degrees clockwise from the startAngle parameter to the second side of the pie shape. + /// Fill color + /// Fill Hatch Style + /// Fill texture + /// Texture image mode + /// Texture transparent color + /// Fill Gradient type + /// Fill Gradient Second Color + /// Border Color + /// Border Width + /// Border Style + /// True if shadow is active + /// True if Doughnut is drawn instead of pie + /// Internal radius of the doughnut + /// Pie drawing style. + internal void DrawPieRel( + RectangleF rect, + float startAngle, + float sweepAngle, + Color backColor, + ChartHatchStyle backHatchStyle, + string backImage, + ChartImageWrapMode backImageWrapMode, + Color backImageTransparentColor, + GradientStyle backGradientStyle, + Color backSecondaryColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + bool shadow, + bool doughnut, + float doughnutRadius, + PieDrawingStyle pieDrawingStyle + ) + { + Pen borderPen = null; // Pen + Brush fillBrush; // Brush + + // Get absolute rectangle + RectangleF absRect = GetAbsoluteRectangle( rect ); + + if( doughnutRadius == 100.0 ) + { + doughnut = false; + } + + if( doughnutRadius == 0.0 ) + { + return; + } + + // Create Brush + if( backHatchStyle != ChartHatchStyle.None ) + { + // Create Hatch Brush + fillBrush = GetHatchBrush( backHatchStyle, backColor, backSecondaryColor ); + } + else if( backGradientStyle != GradientStyle.None ) + { + // Create gradient brush + if( backGradientStyle == GradientStyle.Center ) + { + fillBrush = GetPieGradientBrush( absRect, backColor, backSecondaryColor ); + } + else + { + using (GraphicsPath path = new GraphicsPath()) + { + path.AddPie(absRect.X, absRect.Y, absRect.Width, absRect.Height, startAngle, sweepAngle); + fillBrush = GetGradientBrush(path.GetBounds(), backColor, backSecondaryColor, backGradientStyle); + } + } + } + else if( backImage.Length > 0 && backImageWrapMode != ChartImageWrapMode.Unscaled && backImageWrapMode != ChartImageWrapMode.Scaled ) + { + // Create textured brush + fillBrush = GetTextureBrush(backImage, backImageTransparentColor, backImageWrapMode, backColor ); + } + else + { + // Create solid brush + fillBrush = new SolidBrush( backColor ); + } + + // Create border Pen + borderPen = new Pen( borderColor, borderWidth ); + + // Set a border line style + borderPen.DashStyle = GetPenStyle( borderDashStyle ); + + // Use rounded line joins + borderPen.LineJoin = LineJoin.Round; + + // Draw Doughnut + if( doughnut ) + { + using (GraphicsPath path = new GraphicsPath()) + { + + path.AddArc(absRect.X + absRect.Width * doughnutRadius / 200 - 1, absRect.Y + absRect.Height * doughnutRadius / 200 - 1, absRect.Width - absRect.Width * doughnutRadius / 100 + 2, absRect.Height - absRect.Height * doughnutRadius / 100 + 2, startAngle, sweepAngle); + path.AddArc(absRect.X, absRect.Y, absRect.Width, absRect.Height, startAngle + sweepAngle, -sweepAngle); + + path.CloseFigure(); + + this.FillPath(fillBrush, path); + + + // Draw Pie gradien effects + this.DrawPieGradientEffects(pieDrawingStyle, absRect, startAngle, sweepAngle, doughnutRadius); + + // Draw Doughnut Border + if (!shadow && + borderWidth > 0 && + borderDashStyle != ChartDashStyle.NotSet) + { + this.DrawPath(borderPen, path); + } + } + } + else // Draw Pie + { + + // Draw Soft shadow for pie slice + if( shadow && softShadows ) + { + DrawPieSoftShadow( startAngle, sweepAngle, absRect, backColor ); + } + else + { + // Fill Pie for normal shadow or colored pie slice + this.FillPie( fillBrush, absRect.X, absRect.Y, absRect.Width, absRect.Height, startAngle, sweepAngle ); + + // Draw Pie gradien effects + this.DrawPieGradientEffects( pieDrawingStyle, absRect, startAngle, sweepAngle, -1f); + } + + + // Draw Pie Border + if( !shadow && + borderWidth > 0 && + borderDashStyle != ChartDashStyle.NotSet) + { + this.DrawPie( borderPen, absRect.X, absRect.Y, absRect.Width, absRect.Height, startAngle, sweepAngle ); + } + } + + // Dispose graphics objects + if( borderPen != null ) + { + borderPen.Dispose(); + } + + if( fillBrush != null ) + { + fillBrush.Dispose(); + } + } + + private void DrawPieGradientEffects( + PieDrawingStyle pieDrawingStyle, + RectangleF position, + float startAngle, + float sweepAngle, + float doughnutRadius) + { + if(pieDrawingStyle == PieDrawingStyle.Concave) + { + // Calculate the size of the shadow. Note: For Doughnut chart shadow is drawn + // twice on the outside and inside radius. + float minSize = (float)Math.Min(position.Width, position.Height); + float shadowSize = minSize * 0.05f; + + // Create brush path + RectangleF gradientPath = position; + gradientPath.Inflate(-shadowSize, -shadowSize); + using(GraphicsPath brushPath = new GraphicsPath()) + { + brushPath.AddEllipse(gradientPath); + + // Create shadow path + using(GraphicsPath path = new GraphicsPath()) + { + if(doughnutRadius < 0f) + { + path.AddPie(Rectangle.Round(gradientPath), startAngle, sweepAngle); + } + else + { + path.AddArc( + gradientPath.X + position.Width * doughnutRadius /200 - 1 - shadowSize, + gradientPath.Y + position.Height * doughnutRadius /200 - 1 - shadowSize, + gradientPath.Width - position.Width * doughnutRadius / 100 + 2 + 2f * shadowSize, + gradientPath.Height - position.Height * doughnutRadius / 100 + 2 + 2f * shadowSize, + startAngle, + sweepAngle ); + path.AddArc( gradientPath.X, gradientPath.Y, gradientPath.Width, gradientPath.Height, startAngle + sweepAngle, -sweepAngle ); + } + + // Create linear gradient brush + gradientPath.Inflate(1f, 1f); + using(LinearGradientBrush brush = new LinearGradientBrush( + gradientPath, + Color.Red, + Color.Green, + LinearGradientMode.Vertical) ) + { + ColorBlend colorBlend = new ColorBlend(3); + colorBlend.Colors[0] = Color.FromArgb(100, Color.Black); + colorBlend.Colors[1] = Color.Transparent; + colorBlend.Colors[2] = Color.FromArgb(140, Color.White); + colorBlend.Positions[0] = 0f; + colorBlend.Positions[1] = 0.5f; + colorBlend.Positions[2] = 1f; + brush.InterpolationColors = colorBlend; + + // Fill shadow + this.FillPath( brush, path ); + + } + } + } + } + else if(pieDrawingStyle == PieDrawingStyle.SoftEdge) + { + // Calculate the size of the shadow. Note: For Doughnut chart shadow is drawn + // twice on the outside and inside radius. + float minSize = (float)Math.Min(position.Width, position.Height); + float shadowSize = minSize/10f; + if(doughnutRadius > 0f) + { + shadowSize = (minSize * doughnutRadius / 100f) / 8f; + } + + // Create brush path + using(GraphicsPath brushPath = new GraphicsPath()) + { + brushPath.AddEllipse(position); + + // Create shadow path + using(GraphicsPath path = new GraphicsPath()) + { + path.AddArc( position.X + shadowSize, position.Y + shadowSize, position.Width - shadowSize * 2f, position.Height - shadowSize * 2f, startAngle, sweepAngle ); + path.AddArc( position.X, position.Y, position.Width, position.Height, startAngle + sweepAngle, -sweepAngle ); + path.CloseFigure(); + + // Create shadow brush + using( PathGradientBrush brush = new PathGradientBrush(brushPath) ) + { + brush.CenterColor = Color.Transparent; + brush.SurroundColors = new Color[] { Color.FromArgb(100, Color.Black) }; + + Blend blend = new Blend(3); + blend.Positions[0] = 0f; + blend.Factors[0] = 0f; + blend.Positions[1] = shadowSize / (minSize / 2f); + blend.Factors[1] = 1f; + blend.Positions[2] = 1f; + blend.Factors[2] = 1f; + brush.Blend = blend; + + // Fill shadow + this.FillPath( brush, path ); + } + } + + // Draw inner shadow for the doughnut chart + if(doughnutRadius > 0f) + { + // Create brush path + using(GraphicsPath brushInsidePath = new GraphicsPath()) + { + RectangleF innerPosition = position; + innerPosition.Inflate(- position.Width * doughnutRadius / 200f + shadowSize, -position.Height * doughnutRadius / 200f + shadowSize); + brushInsidePath.AddEllipse(innerPosition); + + // Create shadow path + using(GraphicsPath path = new GraphicsPath()) + { + path.AddArc( innerPosition.X + shadowSize, innerPosition.Y + shadowSize, innerPosition.Width - 2f * shadowSize, innerPosition.Height - 2f * shadowSize, startAngle, sweepAngle ); + path.AddArc( innerPosition.X, innerPosition.Y, innerPosition.Width, innerPosition.Height, startAngle + sweepAngle, -sweepAngle ); + path.CloseFigure(); + + // Create shadow brush + using( PathGradientBrush brushInner = new PathGradientBrush(brushInsidePath) ) + { + brushInner.CenterColor = Color.FromArgb(100, Color.Black); + brushInner.SurroundColors = new Color[] { Color.Transparent }; + + Blend blend = new Blend(3); + blend.Positions[0] = 0f; + blend.Factors[0] = 0f; + blend.Positions[1] = shadowSize / (innerPosition.Width / 2f); + blend.Factors[1] = 1f; + blend.Positions[2] = 1f; + blend.Factors[2] = 1f; + brushInner.Blend = blend; + + // Fill shadow + this.FillPath( brushInner, path ); + } + } + } + } + } + } + } + + /// + /// The soft shadow of the pie + /// + /// Angle measured in degrees clockwise from the x-axis to the first side of the pie shape. + /// Angle measured in degrees clockwise from the startAngle parameter to the second side of the pie shape. + /// Rectangle of the pie in absolute coordinates + /// Fill color + private void DrawPieSoftShadow( float startAngle, float sweepAngle, RectangleF absRect, Color backColor ) + { + GraphicsPath path = new GraphicsPath(); + + path.AddEllipse( absRect.X, absRect.Y, absRect.Width, absRect.Height ); + + PathGradientBrush brush = new PathGradientBrush( path ); + + Color[] colors = { + Color.FromArgb( 0, backColor ), + Color.FromArgb( backColor.A, backColor ), + Color.FromArgb( backColor.A, backColor )}; + + float[] relativePositions = { + 0f, + 0.05f, + 1.0f}; // at the center point. + + ColorBlend colorBlend = new ColorBlend(); + colorBlend.Colors = colors; + colorBlend.Positions = relativePositions; + brush.InterpolationColors = colorBlend; + + this.FillPie( brush, absRect.X, absRect.Y, absRect.Width, absRect.Height, startAngle, sweepAngle ); + } + + #endregion + + #region Arrow Methods + + /// + /// Draw Arrow. + /// + /// Position of the arrow + /// Orientation of the arrow - left, right, top, bottom + /// Arrow style: Triangle, Sharp Triangle, Lines + /// Color of the arrow + /// Line width + /// Line Dash style + /// Distance from the chart area + /// Arrow size + internal void DrawArrowRel( PointF position, ArrowOrientation orientation, AxisArrowStyle type, Color color, int lineWidth, ChartDashStyle lineDashStyle, double shift, double size ) + { + // Check if arrow should be drawn + if(type == AxisArrowStyle.None) + { + return; + } + + // Set a color + using (SolidBrush brush = new SolidBrush(color)) + { + PointF endPoint = PointF.Empty; // End point of axis line + PointF[] points; // arrow points + PointF absolutePosition; // Absolute position of axis + + absolutePosition = GetAbsolutePoint(position); + + // Arrow type is triangle + if (type == AxisArrowStyle.Triangle) + { + points = GetArrowShape(absolutePosition, orientation, shift, size, type, ref endPoint); + + endPoint = GetRelativePoint(endPoint); + + // Draw center line + DrawLineRel(color, lineWidth, lineDashStyle, position, endPoint); + + // Draw arrow + this.FillPolygon(brush, points); + + } + // Arrow type is sharp triangle + else if (type == AxisArrowStyle.SharpTriangle) + { + points = GetArrowShape(absolutePosition, orientation, shift, size, type, ref endPoint); + + endPoint = GetRelativePoint(endPoint); + + // Draw center line + DrawLineRel(color, lineWidth, lineDashStyle, position, endPoint); + + // Draw arrow + this.FillPolygon(brush, points); + + } + // Arrow type is 'Lines' + else if (type == AxisArrowStyle.Lines) + { + points = GetArrowShape(absolutePosition, orientation, shift, size, type, ref endPoint); + + points[0] = GetRelativePoint(points[0]); + points[1] = GetRelativePoint(points[1]); + points[2] = GetRelativePoint(points[2]); + + endPoint = GetRelativePoint(endPoint); + + // Draw arrow + DrawLineRel(color, lineWidth, lineDashStyle, position, endPoint); + DrawLineRel(color, lineWidth, lineDashStyle, points[0], points[2]); + DrawLineRel(color, lineWidth, lineDashStyle, points[1], points[2]); + + } + } + } + + /// + /// This function calculates points for polygon, which represents + /// shape of an arrow. There are four different orientations + /// of arrow and three arrow types. + /// + /// Arrow position + /// Arrow orientation ( Left, Right, Top, Bottom ) + /// Distance from chart area to the arrow + /// Arrow size + /// Arrow style. + /// End point of the axis and the beginning of arrow + /// Polygon points + private PointF[] GetArrowShape( PointF position, ArrowOrientation orientation, double shift, double size, AxisArrowStyle type, ref PointF endPoint ) + { + PointF[] points = new PointF[3]; // Polygon points + double sharp; // Size for sharp triangle + + // Four different orientations for AxisArrowStyle + switch( orientation ) + { + // Top orientation + case ArrowOrientation.Top: + // Get absolute size for arrow + // Arrow size has to have the same shape when width and height + // are changed. When the picture is resized, width of the chart + // picture is used only for arrow size. + size = GetAbsoluteSize( new SizeF((float)size, (float)size) ).Width; + shift = GetAbsoluteSize( new SizeF((float)shift,(float)shift) ).Height; + + // Size for sharp and regular triangle + if( type == AxisArrowStyle.SharpTriangle ) + sharp = size * 4; + else + sharp = size * 2; + + points[0].X = position.X - (float)size; + points[0].Y = position.Y - (float)shift; + points[1].X = position.X + (float)size; + points[1].Y = position.Y - (float)shift; + points[2].X = position.X; + points[2].Y = position.Y - (float)shift - (float)sharp; + // End of the axis line + endPoint.X = position.X; + if( type == AxisArrowStyle.SharpTriangle || type == AxisArrowStyle.Triangle ) + endPoint.Y = points[1].Y; + else + endPoint.Y = points[2].Y; + + break; + // Bottom orientation + case ArrowOrientation.Bottom: + // Get absolute size for arrow + // Arrow size has to have the same shape when width and height + // are changed. When the picture is resized, width of the chart + // picture is used only for arrow size. + size = GetAbsoluteSize( new SizeF((float)size, (float)size) ).Width; + shift = GetAbsoluteSize( new SizeF((float)shift,(float)shift) ).Height; + + // Size for sharp and regular triangle + if( type == AxisArrowStyle.SharpTriangle ) + sharp = size * 4; + else + sharp = size * 2; + + points[0].X = position.X - (float)size; + points[0].Y = position.Y + (float)shift; + points[1].X = position.X + (float)size; + points[1].Y = position.Y + (float)shift; + points[2].X = position.X; + points[2].Y = position.Y + (float)shift + (float)sharp; + // End of the axis line + endPoint.X = position.X; + if( type == AxisArrowStyle.SharpTriangle || type == AxisArrowStyle.Triangle ) + endPoint.Y = points[1].Y; + else + endPoint.Y = points[2].Y; + break; + // Left orientation + case ArrowOrientation.Left: + // Get absolute size for arrow + size = GetAbsoluteSize( new SizeF((float)size, (float)size) ).Width; + shift = GetAbsoluteSize( new SizeF((float)shift,(float)shift) ).Width; + + // Size for sharp and regular triangle + if( type == AxisArrowStyle.SharpTriangle ) + sharp = size * 4; + else + sharp = size * 2; + + points[0].Y = position.Y - (float)size; + points[0].X = position.X - (float)shift; + points[1].Y = position.Y + (float)size; + points[1].X = position.X - (float)shift; + points[2].Y = position.Y; + points[2].X = position.X - (float)shift - (float)sharp; + // End of the axis line + endPoint.Y = position.Y; + if( type == AxisArrowStyle.SharpTriangle || type == AxisArrowStyle.Triangle ) + endPoint.X = points[1].X; + else + endPoint.X = points[2].X; + break; + // Right orientation + case ArrowOrientation.Right: + // Get absolute size for arrow + size = GetAbsoluteSize( new SizeF((float)size, (float)size) ).Width; + shift = GetAbsoluteSize( new SizeF((float)shift,(float)shift) ).Width; + + // Size for sharp and regular triangle + if( type == AxisArrowStyle.SharpTriangle ) + sharp = size * 4; + else + sharp = size * 2; + + points[0].Y = position.Y - (float)size; + points[0].X = position.X + (float)shift; + points[1].Y = position.Y + (float)size; + points[1].X = position.X + (float)shift; + points[2].Y = position.Y; + points[2].X = position.X + (float)shift + (float)sharp; + // End of the axis line + endPoint.Y = position.Y; + if( type == AxisArrowStyle.SharpTriangle || type == AxisArrowStyle.Triangle ) + endPoint.X = points[1].X; + else + endPoint.X = points[2].X; + break; + } + + return points; + } + + #endregion + + #region Other methods and properties + + /// + /// Helper function that retrieves bar drawing style. + /// + /// Data point to get the drawing style for. + /// Bar drawing style. + internal static BarDrawingStyle GetBarDrawingStyle(DataPoint point) + { + // Get column drawing style + BarDrawingStyle barDrawingStyle = BarDrawingStyle.Default; + string styleName = point[CustomPropertyName.DrawingStyle]; + if(styleName != null) + { + if(String.Compare(styleName, "Default", StringComparison.OrdinalIgnoreCase) == 0) + { + barDrawingStyle = BarDrawingStyle.Default; + } + else if (String.Compare(styleName, "Cylinder", StringComparison.OrdinalIgnoreCase) == 0) + { + barDrawingStyle = BarDrawingStyle.Cylinder; + } + else if (String.Compare(styleName, "Emboss", StringComparison.OrdinalIgnoreCase) == 0) + { + barDrawingStyle = BarDrawingStyle.Emboss; + } + else if (String.Compare(styleName, "LightToDark", StringComparison.OrdinalIgnoreCase) == 0) + { + barDrawingStyle = BarDrawingStyle.LightToDark; + } + else if (String.Compare(styleName, "Wedge", StringComparison.OrdinalIgnoreCase) == 0) + { + barDrawingStyle = BarDrawingStyle.Wedge; + } + else + { + throw (new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(styleName, "DrawingStyle"))); + } + } + return barDrawingStyle; + } + + + /// + /// Find rounding coordinates for a rectangle + /// + /// Rectangle which has to be rounded + /// Rounded rectangle + internal RectangleF Round(RectangleF rect) + { + float left = (float)Math.Round( (double)rect.Left ); + float right = (float)Math.Round( (double)rect.Right ); + float top = (float)Math.Round( (double)rect.Top ); + float bottom = (float)Math.Round( (double)rect.Bottom ); + + return new RectangleF( left, top, right - left, bottom - top ); + } + + /// + /// This method takes a given axis value for a specified axis and returns the relative pixel value. + /// + /// Chart area name. + /// An AxisName enum value that identifies the relevant axis. + /// The axis value that needs to be converted to a relative pixel value. + /// The converted axis value, in relative pixel coordinates. + public double GetPositionFromAxis( string chartAreaName, AxisName axis, double axisValue ) + { + if( axis == AxisName.X ) + return _common.ChartPicture.ChartAreas[chartAreaName].AxisX.GetLinearPosition( axisValue ); + + if( axis == AxisName.X2 ) + return _common.ChartPicture.ChartAreas[chartAreaName].AxisX2.GetLinearPosition( axisValue ); + + if( axis == AxisName.Y ) + return _common.ChartPicture.ChartAreas[chartAreaName].AxisY.GetLinearPosition( axisValue ); + + if( axis == AxisName.Y2 ) + return _common.ChartPicture.ChartAreas[chartAreaName].AxisY2.GetLinearPosition( axisValue ); + + return 0; + } + + /// + /// Set picture size + /// + /// Width + /// Height + internal void SetPictureSize( int width, int height ) + { + this._width = width; + this._height = height; + } + + /// + /// Constructor + /// + /// Common elements class + internal ChartGraphics(CommonElements common) + { + // Set Common elements + this._common = common; + base.Common = common; + // Create a pen object + _pen = new Pen(Color.Black); + + // Create a brush object + _solidBrush = new SolidBrush(Color.Black); + } + + /// + /// Chart Graphics Anti alias mode + /// + internal AntiAliasingStyles AntiAliasing + { + get + { + return _antiAliasing; + } + set + { + _antiAliasing = value; + + // Graphics mode not set + if( Graphics == null ) + return; + + // Convert Chart's anti alias enumeration to GDI+ SmoothingMode + if( (_antiAliasing & AntiAliasingStyles.Graphics) == AntiAliasingStyles.Graphics ) + { + this.SmoothingMode = SmoothingMode.AntiAlias; + } + else + { + this.SmoothingMode = SmoothingMode.None; + } + } + } + + /// + /// Gets reusable pen. + /// + internal Pen Pen + { + get { return _pen; } + } + + /// + /// Sets the clipping region of this Graphics object + /// to the rectangle specified by a RectangleF structure. + /// + /// Region rectangle + internal void SetClip( RectangleF region ) + { + this.SetClipAbs( GetAbsoluteRectangle( region ) ); + } + + #endregion + + #region Color manipulation methods + + /// + /// Returns the gradient color from a gradient position. + /// + /// The color from the gradient beginning + /// The color from the gradient end. + /// The relative position. + /// Result color. + static internal Color GetGradientColor(Color beginColor, Color endColor, double relativePosition) + { + // Check if position is valid + if(relativePosition < 0 || relativePosition > 1 || double.IsNaN(relativePosition)) + { + return beginColor; + } + + // Extracts Begin color + int nBRed = beginColor.R; + int nBGreen = beginColor.G; + int nBBlue = beginColor.B; + + // Extracts End color + int nERed = endColor.R; + int nEGreen = endColor.G; + int nEBlue = endColor.B; + + // Gradient positions for Red, Green and Blue colors + double dRRed = nBRed + (nERed - nBRed) * relativePosition; + double dRGreen = nBGreen + (nEGreen - nBGreen) * relativePosition; + double dRBlue = nBBlue + (nEBlue - nBBlue) * relativePosition; + + // Make sure colors are in range from 0 to 255 + if(dRRed > 255.0) + dRRed = 255.0; + if(dRRed < 0.0) + dRRed = 0.0; + if(dRGreen > 255.0) + dRGreen = 255.0; + if(dRGreen < 0.0) + dRGreen = 0.0; + if(dRBlue > 255.0) + dRBlue = 255.0; + if(dRBlue < 0.0) + dRBlue = 0.0; + + // Return a gradient color position + return Color.FromArgb(beginColor.A, (int)dRRed, (int)dRGreen, (int)dRBlue); + } + + #endregion + + #region RightToLeft + /// + /// Returns chart right to left flag + /// + internal bool IsRightToLeft + { + get + { + if (Common == null) + { + return false; + } + return Common.ChartPicture.RightToLeft == RightToLeft.Yes; + } + } + + #endregion //RightToLeft + + #region IDisposable Members + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Free up managed resources + if (_pen != null) + { + _pen.Dispose(); + _pen = null; + } + if (_solidBrush != null) + { + _solidBrush.Dispose(); + _solidBrush = null; + } + if (_myMatrix != null) + { + _myMatrix.Dispose(); + _myMatrix = null; + } + } + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/ChartGraphics3D.cs b/System.Web.DataVisualization/Common/General/ChartGraphics3D.cs new file mode 100644 index 000000000..ea11fb0fa --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ChartGraphics3D.cs @@ -0,0 +1,4735 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartGraphics3D.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ChartGraphics3D, Point3D +// +// Purpose: ChartGraphics3D class is 3D chart rendering engine. +// All chart 3D shapes are drawn in specific order so +// that correct Z order of all shapes is achieved. 3D +// graphics engine do not support shapes intersection. +// 3D shapes are transformed into one or more 2D shapes +// and then drawn with 2D chart graphics engine. +// +// Reviewed: AG - Microsoft 16, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Drawing.Imaging; +using System.ComponentModel; +using System.Collections; +using System.Diagnostics.CodeAnalysis; + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region 3D enumerations + + /// + /// 3D cube surfaces names. + /// + [Flags] + internal enum SurfaceNames + { + /// + /// Front. + /// + Front = 1, + /// + /// Back. + /// + Back = 2, + /// + /// Left. + /// + Left = 4, + /// + /// Right. + /// + Right = 8, + /// + /// Top. + /// + Top = 16, + /// + /// Bottom. + /// + Bottom = 32 + } + + /// + /// This enumeration defines all significant points in a pie + /// slice. Only these points should be transformed for pie + /// chart using Matrix object. + /// + internal enum PiePoints + { + /// + /// Angle 180 Top point on the arc + /// + Top180, + + /// + /// Angle 180 Bottom point on the arc + /// + Bottom180, + + /// + /// Angle 0 Top point on the arc + /// + Top0, + + /// + /// Angle 0 Bottom point on the arc + /// + Bottom0, + + /// + /// Top Start Angle point on the arc + /// + TopStart, + + /// + /// Top End Angle point on the arc + /// + TopEnd, + + /// + /// Bottom Start Angle point on the arc + /// + BottomStart, + + /// + /// Bottom End Angle point on the arc + /// + BottomEnd, + + /// + /// Center Top + /// + TopCenter, + + /// + /// Center Bottom + /// + BottomCenter, + + /// + /// Top Label Line + /// + TopLabelLine, + + /// + /// Top Label Line Out + /// + TopLabelLineout, + + /// + /// Top Label Center + /// + TopLabelCenter, + + /// + /// Top Rectangle Top Left Point + /// + TopRectTopLeftPoint, + + /// + /// Top Rectangle Right Bottom Point + /// + TopRectBottomRightPoint, + + /// + /// Bottom Rectangle Top Left Point + /// + BottomRectTopLeftPoint, + + /// + /// Bottom Rectangle Right Bottom Point + /// + BottomRectBottomRightPoint, + + /// + /// Angle 180 Top point on the Doughnut arc + /// + DoughnutTop180, + + /// + /// Angle 180 Bottom point on the Doughnut arc + /// + DoughnutBottom180, + + /// + /// Angle 0 Top point on the Doughnut arc + /// + DoughnutTop0, + + /// + /// Angle 0 Bottom point on the Doughnut arc + /// + DoughnutBottom0, + + /// + /// Top Start Angle point on the Doughnut arc + /// + DoughnutTopStart, + + /// + /// Top End Angle point on the Doughnut arc + /// + DoughnutTopEnd, + + /// + /// Bottom Start Angle point on the Doughnut arc + /// + DoughnutBottomStart, + + /// + /// Bottom End Angle point on the Doughnut arc + /// + DoughnutBottomEnd, + + /// + /// Doughnut Top Rectangle Top Left Point + /// + DoughnutTopRectTopLeftPoint, + + /// + /// Doughnut Top Rectangle Right Bottom Point + /// + DoughnutTopRectBottomRightPoint, + + /// + /// Doughnut Bottom Rectangle Top Left Point + /// + DoughnutBottomRectTopLeftPoint, + + /// + /// Doughnut Bottom Rectangle Right Bottom Point + /// + DoughnutBottomRectBottomRightPoint, + } + + + /// + /// AxisName of drawing operation. + /// + [Flags] + internal enum DrawingOperationTypes + { + /// + /// Draw element. + /// + DrawElement = 1, + + /// + /// Calculate element path. (for selection or tooltips) + /// + CalcElementPath = 2, + } + + /// + /// AxisName of line segment. + /// + internal enum LineSegmentType + { + /// + /// Only one segment exists. + /// + Single, + + /// + /// First segment. + /// + First, + + /// + /// Middle segment. + /// + Middle, + + /// + /// Last segment. + /// + Last + } + + #endregion + + /// + /// The ChartGraphics class is 3D chart rendering engine. All chart + /// 3D shapes are drawn in specific order so that correct Z order + /// of all shapes is achieved. 3D graphics engine do not support + /// shapes intersection. 3D shapes are transformed into one or + /// more 2D shapes and then drawn with 2D chart graphics engine. + /// + public partial class ChartGraphics + { + #region Fields + + /// + /// Helper field used to store the index of cylinder left/bottom side coordinate. + /// + private int _oppLeftBottomPoint = -1; + + /// + /// Helper field used to store the index of cylinder right/top side coordinate. + /// + private int _oppRigthTopPoint = -1; + + /// + /// Point of the front line from the previous line segment. + /// + internal PointF frontLinePoint1 = PointF.Empty; + + /// + /// Point of the front line from the previous line segment. + /// + internal PointF frontLinePoint2 = PointF.Empty; + + /// + /// Previous line segment pen. + /// + internal Pen frontLinePen = null; + + #endregion + + #region 3D Line drawing methods + + /// + /// Draws grid line in 3D space (on two area scene walls) + /// + /// Chart area. + /// Line color. + /// Line width. + /// Line style. + /// First line point. + /// Second line point. + /// Indicates that grid line is horizontal + /// Common Elements + /// Selected object + internal void Draw3DGridLine( + ChartArea area, + Color color, + int width, + ChartDashStyle style, + PointF point1, + PointF point2, + bool horizontal, + CommonElements common, + object obj + ) + { + float zPositon = area.IsMainSceneWallOnFront() ? area.areaSceneDepth : 0f; + + ChartElementType chartElementType = obj is StripLine ? ChartElementType.StripLines : ChartElementType.Gridlines; + + // Draw strip line on the back/front wall + ((ChartGraphics)this).Draw3DLine( + area.matrix3D, + color, width, style, + new Point3D(point1.X, point1.Y, zPositon), + new Point3D(point2.X, point2.Y, zPositon), + common, + obj, + chartElementType + ); + + if(horizontal) + { + // Draw strip line on the side wall (left or right) + if(area.IsSideSceneWallOnLeft()) + { + point1.X = Math.Min(point1.X, point2.X); + } + else + { + point1.X = Math.Max(point1.X, point2.X); + } + + ((ChartGraphics)this).Draw3DLine( + area.matrix3D, + color, width, style, + new Point3D(point1.X, point1.Y, 0f), + new Point3D(point1.X, point1.Y, area.areaSceneDepth), + common, + obj, + chartElementType + ); + + } + else if(area.IsBottomSceneWallVisible()) + { + // Draw strip line on the bottom wall (if visible) + point1.Y = Math.Max(point1.Y, point2.Y); + + ((ChartGraphics)this).Draw3DLine( + area.matrix3D, + color, width, style, + new Point3D(point1.X, point1.Y, 0f), + new Point3D(point1.X, point1.Y, area.areaSceneDepth), + common, + obj, + chartElementType + ); + } + } + + /// + /// Draws a line connecting the two specified points. + /// + /// Coordinates transformation matrix. + /// Line color. + /// Line width. + /// Line style. + /// A Point that represents the first point to connect. + /// A Point that represents the second point to connect. + /// Common elements + /// Selected object + /// Selected chart element + internal void Draw3DLine( + Matrix3D matrix, + Color color, + int width, + ChartDashStyle style, + Point3D firstPoint, + Point3D secondPoint, + CommonElements common, + object obj, + ChartElementType type + ) + { + + // Transform coordinates + Point3D [] points = new Point3D[] {firstPoint, secondPoint}; + matrix.TransformPoints( points ); + + // Selection mode + if (common.ProcessModeRegions && type != ChartElementType.Nothing) + { + using (GraphicsPath path = new GraphicsPath()) + { + + if (Math.Abs(points[0].X - points[1].X) > Math.Abs(points[0].Y - points[1].Y)) + { + path.AddLine(points[0].X, points[0].Y - 1, points[1].X, points[1].Y - 1); + path.AddLine(points[1].X, points[1].Y + 1, points[0].X, points[0].Y + 1); + path.CloseAllFigures(); + } + else + { + path.AddLine(points[0].X - 1, points[0].Y, points[1].X - 1, points[1].Y); + path.AddLine(points[1].X + 1, points[1].Y, points[0].X + 1, points[0].Y); + path.CloseAllFigures(); + + } + common.HotRegionsList.AddHotRegion(path, true, type, obj); + } + } + + if( common.ProcessModePaint ) + { + // Draw 2D line in 3D space + ((ChartGraphics)this).DrawLineRel(color, width, style, points[0].PointF, points[1].PointF); + } + + } + + #endregion + + #region 3D Pie Drawing methods and enumerations + + + /// + /// This method draw and fill four point polygons which + /// represents sides of a pie slice. + /// + /// Chart Area + /// X angle rotation + /// Start Angle of a pie slice + /// Sweep angle of a pie slice + /// Significant points of a pie slice + /// Brush used for fill + /// Pen used for drawing + /// Chart AxisName is Doughnut + internal void FillPieSides( + ChartArea area, + float inclination, + float startAngle, + float sweepAngle, + PointF [] points, + SolidBrush brush, + Pen pen, + bool doughnut + ) + { + + // Create a graphics path + GraphicsPath path = new GraphicsPath(); + + // Significant Points for Side polygons + PointF topCenter = points[(int)PiePoints.TopCenter]; + PointF bottomCenter = points[(int)PiePoints.BottomCenter]; + PointF topStart = points[(int)PiePoints.TopStart]; + PointF bottomStart = points[(int)PiePoints.BottomStart]; + PointF topEnd = points[(int)PiePoints.TopEnd]; + PointF bottomEnd = points[(int)PiePoints.BottomEnd]; + + // For Doughnut + PointF topDoughnutStart = PointF.Empty; + PointF bottomDoughnutStart = PointF.Empty; + PointF topDoughnutEnd = PointF.Empty; + PointF bottomDoughnutEnd = PointF.Empty; + + if( doughnut ) + { + // For Doughnut + topDoughnutStart = points[(int)PiePoints.DoughnutTopStart]; + bottomDoughnutStart = points[(int)PiePoints.DoughnutBottomStart]; + topDoughnutEnd = points[(int)PiePoints.DoughnutTopEnd]; + bottomDoughnutEnd = points[(int)PiePoints.DoughnutBottomEnd]; + } + + bool startSide = false; + bool endSide = false; + float endAngle = startAngle + sweepAngle; + + // If X angle is negative different side of pie slice is visible. + if (inclination > 0) + { + // Enable start or/and the end side + if( startAngle > -90 && startAngle < 90 || startAngle > 270 && startAngle < 450 ) + { + startSide = true; + } + if( endAngle >= -180 && endAngle < -90 || endAngle > 90 && endAngle < 270 || endAngle > 450 && endAngle <= 540 ) + { + endSide = true; + } + } + else + { + // Enable start or/and the end side + if( startAngle >= -180 && startAngle < -90 || startAngle > 90 && startAngle < 270 || startAngle > 450 && startAngle <= 540 ) + { + startSide = true; + + } + if( endAngle > -90 && endAngle < 90 || endAngle > 270 && endAngle < 450 ) + { + endSide = true; + } + } + + if( startSide ) + { + // ***************************************** + // Draw Start Angle side + // ***************************************** + using (path = new GraphicsPath()) + { + + if (doughnut) + { + // Add Line between The Doughnut Arc and Arc + path.AddLine(topDoughnutStart, topStart); + + // Add Line between The Top Start and Bottom Start + path.AddLine(topStart, bottomStart); + + // Add Line between The Bottom Start and Doughnut Start + path.AddLine(bottomStart, bottomDoughnutStart); + + // Add Line between The Bottom Doughnut Start and The Top Doughnut Start + path.AddLine(bottomDoughnutStart, topDoughnutStart); + } + else + { + // Add Line between The Center and Arc + path.AddLine(topCenter, topStart); + + // Add Line between The Top Start and Bottom Start + path.AddLine(topStart, bottomStart); + + // Add Line between The Bottom Start and The Center Bottom + path.AddLine(bottomStart, bottomCenter); + + // Add Line between The Bottom Center and The Top Center + path.AddLine(bottomCenter, topCenter); + } + // Get surface colors + Color frontLightColor, leftLightColor, topLightColor, backLightColor, rightLightColor, bottomLightColor; + area.matrix3D.GetLight(brush.Color, out frontLightColor, out backLightColor, out leftLightColor, out rightLightColor, out topLightColor, out bottomLightColor); + + Color lightColor; + if (area.Area3DStyle.Inclination < 0) + { + lightColor = bottomLightColor; + } + else + { + lightColor = topLightColor; + } + + // Draw Path + using (Brush lightBrush = new SolidBrush(lightColor)) + { + FillPath(lightBrush, path); + } + + DrawGraphicsPath(pen, path); + } + } + + if( endSide ) + { + // ***************************************** + // Draw End Angle side + // ***************************************** + using (path = new GraphicsPath()) + { + if (doughnut) + { + // Add Line between The Doughnut Arc and Arc + path.AddLine(topDoughnutEnd, topEnd); + + // Add Line between The Top End and Bottom End + path.AddLine(topEnd, bottomEnd); + + // Add Line between The Bottom End and Doughnut End + path.AddLine(bottomEnd, bottomDoughnutEnd); + + // Add Line between The Bottom Doughnut End and The Top Doughnut End + path.AddLine(bottomDoughnutEnd, topDoughnutEnd); + } + else + { + // Add Line between The Center and Arc + path.AddLine(topCenter, topEnd); + + // Add Line between The Top End and Bottom End + path.AddLine(topEnd, bottomEnd); + + // Add Line between The Bottom End and The Center Bottom + path.AddLine(bottomEnd, bottomCenter); + + // Add Line between The Bottom Center and The Top Center + path.AddLine(bottomCenter, topCenter); + + } + + // Get surface colors + Color frontLightColor, leftLightColor, topLightColor, backLightColor, rightLightColor, bottomLightColor; + area.matrix3D.GetLight(brush.Color, out frontLightColor, out backLightColor, out leftLightColor, out rightLightColor, out topLightColor, out bottomLightColor); + + Color lightColor; + if (area.Area3DStyle.Inclination < 0) + { + lightColor = bottomLightColor; + } + else + { + lightColor = topLightColor; + } + + // Draw Path + using (Brush lightBrush = new SolidBrush(lightColor)) + { + FillPath(lightBrush, path); + } + + DrawGraphicsPath(pen, path); + } + } + } + + /// + /// This method Draw and fill pie curves. + /// + /// Chart area used for drawing + /// Data Point + /// Graphic Brush used for drawing + /// Graphic Pen used for drawing + /// Rotated bounded rectangle points + /// Rotated bounded rectangle points + /// Rotated bounded rectangle points + /// Rotated bounded rectangle points + /// Significant pie points + /// Significant pie points + /// Significant pie points + /// Significant pie points + /// Start pie angle + /// End pie angle + /// Data Point Index + internal void FillPieCurve( + ChartArea area, + DataPoint point, + Brush brush, + Pen pen, + PointF topFirstRectPoint, + PointF topSecondRectPoint, + PointF bottomFirstRectPoint, + PointF bottomSecondRectPoint, + PointF topFirstPoint, + PointF topSecondPoint, + PointF bottomFirstPoint, + PointF bottomSecondPoint, + float startAngle, + float sweepAngle, + int pointIndex + ) + { + // Common Elements + CommonElements common = area.Common; + + // Create a graphics path + using (GraphicsPath path = new GraphicsPath()) + { + + // It is enough to transform only two points from + // rectangle. This code will create RectangleF from + // top left and bottom right points. + RectangleF pieTopRectangle = new RectangleF(); + pieTopRectangle.X = topFirstRectPoint.X; + pieTopRectangle.Y = topFirstRectPoint.Y; + pieTopRectangle.Height = topSecondRectPoint.Y - topFirstRectPoint.Y; + pieTopRectangle.Width = topSecondRectPoint.X - topFirstRectPoint.X; + + RectangleF pieBottomRectangle = new RectangleF(); + pieBottomRectangle.X = bottomFirstRectPoint.X; + pieBottomRectangle.Y = bottomFirstRectPoint.Y; + pieBottomRectangle.Height = bottomSecondRectPoint.Y - bottomFirstRectPoint.Y; + pieBottomRectangle.Width = bottomSecondRectPoint.X - bottomFirstRectPoint.X; + + // Angle correction algorithm. After rotation AddArc method should used + // different transformed angles. This method transforms angles. + double angleCorrection = pieTopRectangle.Height / pieTopRectangle.Width; + + float endAngle; + endAngle = AngleCorrection(startAngle + sweepAngle, angleCorrection); + startAngle = AngleCorrection(startAngle, angleCorrection); + + sweepAngle = endAngle - startAngle; + + // Add Line between first points + path.AddLine(topFirstPoint, bottomFirstPoint); + + if (pieBottomRectangle.Height <= 0) + { + // If x angle is 0 this arc will be line in projection. + path.AddLine(bottomFirstPoint.X, bottomFirstPoint.Y, bottomSecondPoint.X, bottomSecondPoint.Y); + } + else + { + // Add Arc + path.AddArc(pieBottomRectangle.X, pieBottomRectangle.Y, pieBottomRectangle.Width, pieBottomRectangle.Height, startAngle, sweepAngle); + } + + // Add Line between second points + path.AddLine(bottomSecondPoint, topSecondPoint); + + if (pieTopRectangle.Height <= 0) + { + // If x angle is 0 this arc will be line in projection. + path.AddLine(topFirstPoint.X, topFirstPoint.Y, topSecondPoint.X, topSecondPoint.Y); + } + else + { + path.AddArc(pieTopRectangle.X, pieTopRectangle.Y, pieTopRectangle.Width, pieTopRectangle.Height, startAngle + sweepAngle, -sweepAngle); + } + + if (common.ProcessModePaint) + { + // Drawing Mode + FillPath(brush, path); + + if (point.BorderColor != Color.Empty && + point.BorderWidth > 0 && + point.BorderDashStyle != ChartDashStyle.NotSet) + { + DrawGraphicsPath(pen, path); + } + + } + if (common.ProcessModeRegions) + { + + + // Check if processing collected data point + if (point.IsCustomPropertySet("_COLLECTED_DATA_POINT")) + { + // Add point to the map area + common.HotRegionsList.AddHotRegion( + (ChartGraphics)this, + path, + false, + point.ReplaceKeywords(point.ToolTip), +#if Microsoft_CONTROL + string.Empty, + string.Empty, + string.Empty, +#else // Microsoft_CONTROL + point.ReplaceKeywords(point.Url), + point.ReplaceKeywords(point.MapAreaAttributes), + point.ReplaceKeywords(point.PostBackValue), +#endif // Microsoft_CONTROL + point, + ChartElementType.DataPoint); + + return; + } + + + + common.HotRegionsList.AddHotRegion( + path, + false, + (ChartGraphics)this, + point, + point.series.Name, + pointIndex); + } + } + } + + /// + /// This method draws projection of 3D pie slice. + /// + /// Chart area used for drawing + /// Data point which creates this pie slice + /// Graphic Brush used for drawing + /// Graphic Pen used for drawing + /// The first point of transformed bounding rectangle + /// The first arc point of pie slice + /// The second point of transformed bounding rectangle + /// The second arc point of pie slice + /// The center point of pie slice + /// Start angle of pie slice + /// The end angle of pie slice + /// Fill pie slice with brush + /// + internal void FillPieSlice( ChartArea area, DataPoint point, SolidBrush brush, Pen pen, PointF firstRectPoint, PointF firstPoint, PointF secondRectPoint, PointF secondPoint, PointF center, float startAngle, float sweepAngle, bool fill, int pointIndex ) + { + // Common elements + CommonElements common = area.Common; + + // Create a graphics path + using (GraphicsPath path = new GraphicsPath()) + { + + // It is enough to transform only two points from + // rectangle. This code will create RectangleF from + // top left and bottom right points. + RectangleF pieRectangle = new RectangleF(); + pieRectangle.X = firstRectPoint.X; + pieRectangle.Y = firstRectPoint.Y; + pieRectangle.Height = secondRectPoint.Y - firstRectPoint.Y; + pieRectangle.Width = secondRectPoint.X - firstRectPoint.X; + + // Angle correction algorithm. After rotation AddArc method should used + // different transformed angles. This method transforms angles. + double angleCorrection = pieRectangle.Height / pieRectangle.Width; + + float endAngle; + endAngle = AngleCorrection(startAngle + sweepAngle, angleCorrection); + startAngle = AngleCorrection(startAngle, angleCorrection); + + sweepAngle = endAngle - startAngle; + + // Add Line between The Center and Arc + path.AddLine(center, firstPoint); + + // Add Arc + if (pieRectangle.Height > 0) + { + // If x angle is 0 this arc will be line in projection. + path.AddArc(pieRectangle.X, pieRectangle.Y, pieRectangle.Width, pieRectangle.Height, startAngle, sweepAngle); + } + + // Add Line between the end of the arc and the centre. + path.AddLine(secondPoint, center); + + if (common.ProcessModePaint) + { + // Get surface colors + Color frontLightColor, leftLightColor, topLightColor, backLightColor, rightLightColor, bottomLightColor; + area.matrix3D.GetLight(brush.Color, out frontLightColor, out backLightColor, out leftLightColor, out rightLightColor, out topLightColor, out bottomLightColor); + + Pen newPen = (Pen)pen.Clone(); + + if (area.Area3DStyle.LightStyle == LightStyle.Realistic && point.BorderColor == Color.Empty) + { + newPen.Color = frontLightColor; + } + + // Drawing Mode + if (fill) + { + using (Brush lightBrush = new SolidBrush(frontLightColor)) + { + FillPath(lightBrush, path); + } + } + + if (point.BorderColor != Color.Empty && + point.BorderWidth > 0 && + point.BorderDashStyle != ChartDashStyle.NotSet) + { + DrawGraphicsPath(newPen, path); + } + } + + if (common.ProcessModeRegions && fill) + { + + + // Check if processing collected data point + if (point.IsCustomPropertySet("_COLLECTED_DATA_POINT")) + { + // Add point to the map area + common.HotRegionsList.AddHotRegion( + (ChartGraphics)this, + path, + false, + point.ReplaceKeywords(point.ToolTip), +#if Microsoft_CONTROL + string.Empty, + string.Empty, + string.Empty, +#else // Microsoft_CONTROL + point.ReplaceKeywords(point.Url), + point.ReplaceKeywords(point.MapAreaAttributes), + point.ReplaceKeywords(point.PostBackValue), +#endif // Microsoft_CONTROL + point, + ChartElementType.DataPoint); + + return; + } + + + + common.HotRegionsList.AddHotRegion(path, false, (ChartGraphics)this, point, point.series.Name, pointIndex); + } + } + } + + /// + /// This method draws projection of 3D pie slice. + /// + /// Chart area used for drawing + /// Data point which creates this Doughnut slice + /// Graphic Brush used for drawing + /// Graphic Pen used for drawing + /// The first point of transformed bounding rectangle + /// The first arc point of Doughnut slice + /// The second point of transformed bounding rectangle + /// The second arc point of Doughnut slice + /// The three point of Doughnut slice + /// The four point of Doughnut slice + /// Start angle of Doughnut slice + /// The end angle of Doughnut slice + /// Fill Doughnut slice with brush + /// Radius for doughnut chart + /// Data Point Index + internal void FillDoughnutSlice( ChartArea area, DataPoint point, SolidBrush brush, Pen pen, PointF firstRectPoint, PointF firstPoint, PointF secondRectPoint, PointF secondPoint, PointF threePoint, PointF fourPoint, float startAngle, float sweepAngle, bool fill, float doughnutRadius, int pointIndex ) + { + // Common Elements + CommonElements common = area.Common; + + doughnutRadius = 1F - doughnutRadius / 100F; + + // Create a graphics path + using (GraphicsPath path = new GraphicsPath()) + { + + // It is enough to transform only two points from + // rectangle. This code will create RectangleF from + // top left and bottom right points. + RectangleF pieRectangle = new RectangleF(); + pieRectangle.X = firstRectPoint.X; + pieRectangle.Y = firstRectPoint.Y; + pieRectangle.Height = secondRectPoint.Y - firstRectPoint.Y; + pieRectangle.Width = secondRectPoint.X - firstRectPoint.X; + + RectangleF pieDoughnutRectangle = new RectangleF(); + pieDoughnutRectangle.X = pieRectangle.X + pieRectangle.Width * (1F - doughnutRadius) / 2F; + pieDoughnutRectangle.Y = pieRectangle.Y + pieRectangle.Height * (1F - doughnutRadius) / 2F; + pieDoughnutRectangle.Height = pieRectangle.Height * doughnutRadius; + pieDoughnutRectangle.Width = pieRectangle.Width * doughnutRadius; + + // Angle correction algorithm. After rotation AddArc method should used + // different transformed angles. This method transforms angles. + double angleCorrection = pieRectangle.Height / pieRectangle.Width; + + float endAngle; + endAngle = AngleCorrection(startAngle + sweepAngle, angleCorrection); + startAngle = AngleCorrection(startAngle, angleCorrection); + + sweepAngle = endAngle - startAngle; + + // Add Line between The Doughnut Arc and Arc + path.AddLine(fourPoint, firstPoint); + + // Add Arc + if (pieRectangle.Height > 0) + { + // If x angle is 0 this arc will be line in projection. + path.AddArc(pieRectangle.X, pieRectangle.Y, pieRectangle.Width, pieRectangle.Height, startAngle, sweepAngle); + } + + // Add Line between the end of the arc and The Doughnut Arc. + path.AddLine(secondPoint, threePoint); + + // Add Doughnut Arc + if (pieDoughnutRectangle.Height > 0) + { + path.AddArc(pieDoughnutRectangle.X, pieDoughnutRectangle.Y, pieDoughnutRectangle.Width, pieDoughnutRectangle.Height, startAngle + sweepAngle, -sweepAngle); + } + + if (common.ProcessModePaint) + { + // Get surface colors + Color frontLightColor, leftLightColor, topLightColor, backLightColor, rightLightColor, bottomLightColor; + area.matrix3D.GetLight(brush.Color, out frontLightColor, out backLightColor, out leftLightColor, out rightLightColor, out topLightColor, out bottomLightColor); + + Pen newPen = (Pen)pen.Clone(); + + if (area.Area3DStyle.LightStyle == LightStyle.Realistic && point.BorderColor == Color.Empty) + { + newPen.Color = frontLightColor; + } + + // Drawing Mode + if (fill) + { + using (Brush lightBrush = new SolidBrush(frontLightColor)) + { + FillPath(lightBrush, path); + } + } + + if (point.BorderColor != Color.Empty && + point.BorderWidth > 0 && + point.BorderDashStyle != ChartDashStyle.NotSet) + { + DrawGraphicsPath(newPen, path); + } + } + + if (common.ProcessModeRegions && fill) + { + + + // Check if processing collected data point + if (point.IsCustomPropertySet("_COLLECTED_DATA_POINT")) + { + // Add point to the map area + common.HotRegionsList.AddHotRegion( + (ChartGraphics)this, + path, + false, + point.ReplaceKeywords(point.ToolTip), +#if Microsoft_CONTROL + string.Empty, + string.Empty, + string.Empty, +#else // Microsoft_CONTROL + point.ReplaceKeywords(point.Url), + point.ReplaceKeywords(point.MapAreaAttributes), + point.ReplaceKeywords(point.PostBackValue), +#endif // Microsoft_CONTROL + point, + ChartElementType.DataPoint); + + return; + } + + + + // Add points to the map area + common.HotRegionsList.AddHotRegion( + path, + false, + (ChartGraphics)this, + point, + point.series.Name, + pointIndex); + } + } + } + + /// + /// Draw Graphics Path. This method is introduced because of + /// bug in DrawPath method when Pen Width is bigger then 1. + /// + /// Pen + /// Graphics Path + private void DrawGraphicsPath( Pen pen, GraphicsPath path ) + { + // Normal case. Very fast Drawing. + if( pen.Width < 2 ) + { + DrawPath( pen, path ); + } + else + { + + // Converts each curve in this path into a sequence + // of connected line segments. Slow Drawing. + path.Flatten(); + + // Set Pen cap + pen.EndCap = LineCap.Round; + pen.StartCap = LineCap.Round; + + PointF [] pathPoints; + + pathPoints = path.PathPoints; + + // Draw any segment as a line. + for( int point = 0; point < path.PathPoints.Length - 1; point++ ) + { + PointF [] points; + + points = new PointF[2]; + points[0] = pathPoints[point]; + points[1] = pathPoints[point+1]; + + DrawLine( pen, points[0], points[1] ); + } + } + } + + /// + /// Angle correction algorithm. After rotation different + /// transformed angle should be used. This method transforms angles. + /// + /// Not transformed angle + /// Correction of bounding rectangle (change between width and height) + /// Transformed angle + private float AngleCorrection( float angle, double correction ) + { + // Make all angles to be between -90 and 90. + if( angle > -90 && angle < 90 ) + { + angle = (float)(Math.Atan( Math.Tan( ( angle ) * Math.PI / 180 ) * correction ) * 180 / Math.PI); + } + else if( angle > -270 && angle < -90 ) + { + angle = angle + 180; + angle = (float)(Math.Atan( Math.Tan( ( angle ) * Math.PI / 180 ) * correction ) * 180 / Math.PI); + angle = angle - 180; + } + else if( angle > 90 && angle < 270 ) + { + angle = angle - 180; + angle = (float)(Math.Atan( Math.Tan( ( angle ) * Math.PI / 180 ) * correction ) * 180 / Math.PI); + angle = angle + 180; + } + else if( angle > 270 && angle < 450 ) + { + angle = angle - 360; + angle = (float)(Math.Atan( Math.Tan( ( angle ) * Math.PI / 180 ) * correction ) * 180 / Math.PI); + angle = angle + 360; + } + else if( angle > 450 ) + { + angle = angle - 540; + angle = (float)(Math.Atan( Math.Tan( ( angle ) * Math.PI / 180 ) * correction ) * 180 / Math.PI); + angle = angle + 540; + } + return angle; + } + + #endregion + + #region 3D Surface drawing methods (used in Line charts) + + /// + /// Draws a 3D polygon defined by 4 points in 2D space. + /// + /// Chart area reference. + /// Coordinates transformation matrix. + /// Name of the surface to draw. + /// Z position of the back side of the 3D surface. + /// Color of rectangle + /// Border Color + /// Border Width + /// First point. + /// Second point. + /// Third point. + /// Fourth point. + /// AxisName of operation Drawing, Calculating Path or Both + /// AxisName of line segment. Used for step lines and splines. + /// Thin border will be drawn on specified sides. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + internal GraphicsPath Draw3DPolygon( + ChartArea area, + Matrix3D matrix, + SurfaceNames surfaceName, + float positionZ, + Color backColor, + Color borderColor, + int borderWidth, + DataPoint3D firstPoint, + DataPoint3D secondPoint, + DataPoint3D thirdPoint, + DataPoint3D fourthPoint, + DrawingOperationTypes operationType, + LineSegmentType lineSegmentType, + SurfaceNames thinBorders) + { + // Create graphics path for selection + bool drawElements = ((operationType & DrawingOperationTypes.DrawElement) == DrawingOperationTypes.DrawElement); + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + //********************************************************************** + //** Prepare, transform polygon coordinates + //********************************************************************** + + // Define 4 points polygon + Point3D [] points3D = new Point3D[4]; + points3D[0] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ); + points3D[1] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ); + points3D[2] = new Point3D((float)thirdPoint.xPosition, (float)thirdPoint.yPosition, positionZ); + points3D[3] = new Point3D((float)fourthPoint.xPosition, (float)fourthPoint.yPosition, positionZ); + + // Transform coordinates + matrix.TransformPoints( points3D ); + + // Get absolute coordinates and create array of PointF + PointF[] polygonPoints = new PointF[4]; + polygonPoints[0] = GetAbsolutePoint(points3D[0].PointF); + polygonPoints[1] = GetAbsolutePoint(points3D[1].PointF); + polygonPoints[2] = GetAbsolutePoint(points3D[2].PointF); + polygonPoints[3] = GetAbsolutePoint(points3D[3].PointF); + + + //********************************************************************** + //** Define drawing colors + //********************************************************************** + bool topIsVisible = IsSurfaceVisible( points3D[0], points3D[1], points3D[2]); + Color polygonColor = matrix.GetPolygonLight( points3D, backColor, topIsVisible, area.Area3DStyle.Rotation, surfaceName, area.ReverseSeriesOrder ); + Color surfaceBorderColor = borderColor; + if(surfaceBorderColor == Color.Empty) + { + // If border color is emty use color slightly darker than main back color + surfaceBorderColor = ChartGraphics.GetGradientColor( backColor, Color.Black, 0.2 ); + } + + //********************************************************************** + //** Draw elements if required. + //********************************************************************** + Pen thickBorderPen = null; + if(drawElements) + { + // Remember SmoothingMode and turn off anti aliasing + SmoothingMode oldSmoothingMode = SmoothingMode; + SmoothingMode = SmoothingMode.Default; + + // Draw the polygon + using (Brush brush = new SolidBrush(polygonColor)) + { + FillPolygon(brush, polygonPoints); + } + + // Return old smoothing mode + SmoothingMode = oldSmoothingMode; + + // Draw thin polygon border of darker color around the whole polygon + if(thinBorders != 0) + { + Pen thinLinePen = new Pen(surfaceBorderColor, 1); + if( (thinBorders & SurfaceNames.Left) != 0 ) + DrawLine(thinLinePen, polygonPoints[3], polygonPoints[0]); + if( (thinBorders & SurfaceNames.Right) != 0 ) + DrawLine(thinLinePen, polygonPoints[1], polygonPoints[2]); + if( (thinBorders & SurfaceNames.Top) != 0 ) + DrawLine(thinLinePen, polygonPoints[0], polygonPoints[1]); + if( (thinBorders & SurfaceNames.Bottom) != 0 ) + DrawLine(thinLinePen, polygonPoints[2], polygonPoints[3]); + } + else if(polygonColor.A == 255) + { + DrawPolygon(new Pen(polygonColor, 1), polygonPoints); + } + + // Create thick border line pen + thickBorderPen = new Pen(surfaceBorderColor, borderWidth); + thickBorderPen.StartCap = LineCap.Round; + thickBorderPen.EndCap = LineCap.Round; + + // Draw thick Top & Bottom lines + DrawLine(thickBorderPen, polygonPoints[0], polygonPoints[1]); + DrawLine(thickBorderPen, polygonPoints[2], polygonPoints[3]); + + // Draw thick Right & Left lines on first & last segments of the line + if(lineSegmentType == LineSegmentType.First) + { + DrawLine(thickBorderPen, polygonPoints[3], polygonPoints[0]); + } + else if(lineSegmentType == LineSegmentType.Last) + { + DrawLine(thickBorderPen, polygonPoints[1], polygonPoints[2]); + } + } + + //********************************************************************** + //** Redraw front line of the previuos line segment. + //********************************************************************** + if(area.Area3DStyle.Perspective == 0) + { + if(frontLinePoint1 != PointF.Empty && frontLinePen != null) + { + if( (frontLinePoint1.X == polygonPoints[0].X && + frontLinePoint1.Y == polygonPoints[0].Y || + frontLinePoint2.X == polygonPoints[1].X && + frontLinePoint2.Y == polygonPoints[1].Y ) || + + (frontLinePoint1.X == polygonPoints[1].X && + frontLinePoint1.Y == polygonPoints[1].Y || + frontLinePoint2.X == polygonPoints[0].X && + frontLinePoint2.Y == polygonPoints[0].Y ) || + + (frontLinePoint1.X == polygonPoints[3].X && + frontLinePoint1.Y == polygonPoints[3].Y || + frontLinePoint2.X == polygonPoints[2].X && + frontLinePoint2.Y == polygonPoints[2].Y) || + + (frontLinePoint1.X == polygonPoints[2].X && + frontLinePoint1.Y == polygonPoints[2].Y || + frontLinePoint2.X == polygonPoints[3].X && + frontLinePoint2.Y == polygonPoints[3].Y) ) + { + // Do not draw the line if it will be overlapped with current + } + else + { + // Draw line !!!! + DrawLine( + frontLinePen, + (float)Math.Round(frontLinePoint1.X), + (float)Math.Round(frontLinePoint1.Y), + (float)Math.Round(frontLinePoint2.X), + (float)Math.Round(frontLinePoint2.Y) ); + } + + // Reset line properties + frontLinePen = null; + frontLinePoint1 = PointF.Empty; + frontLinePoint2 = PointF.Empty; + } + + //********************************************************************** + //** Check if front line should be redrawn whith the next segment. + //********************************************************************** + if(drawElements) + { + // Add top line + frontLinePen = thickBorderPen; + frontLinePoint1 = polygonPoints[0]; + frontLinePoint2 = polygonPoints[1]; + } + } + + // Calculate path for selection + if(resultPath != null) + { + // Add polygon to the path + resultPath.AddPolygon(polygonPoints); + } + + return resultPath; + } + + /// + /// Helper method which returns the splines flatten path. + /// + /// Chart area reference. + /// Z position of the back side of the 3D surface. + /// First point. + /// Second point. + /// Array of points. + /// Line tension. + /// Flatten result path. + /// Indicates that points coordinates should be translated. + /// Index of the Y value to use. + /// Spline path. + internal GraphicsPath GetSplineFlattenPath( + ChartArea area, + float positionZ, + DataPoint3D firstPoint, + DataPoint3D secondPoint, + ArrayList points, + float tension, + bool flatten, + bool translateCoordinates, + int yValueIndex) + { + // Find first spline point index + int firtsSplinePointIndex = (firstPoint.index < secondPoint.index) ? firstPoint.index : secondPoint.index; + --firtsSplinePointIndex; + if(firtsSplinePointIndex >= (points.Count - 2) ) + { + --firtsSplinePointIndex; + } + if(firtsSplinePointIndex < 1) + { + firtsSplinePointIndex = 1; + } + + // Find four points which are required to draw the spline + int pointArrayIndex = int.MinValue; + DataPoint3D [] splineDataPoints = new DataPoint3D[4]; + splineDataPoints[0] = FindPointByIndex(points, firtsSplinePointIndex, null, ref pointArrayIndex); + splineDataPoints[1] = FindPointByIndex(points, firtsSplinePointIndex + 1, null, ref pointArrayIndex); + splineDataPoints[2] = FindPointByIndex(points, firtsSplinePointIndex + 2, null, ref pointArrayIndex); + splineDataPoints[3] = FindPointByIndex(points, firtsSplinePointIndex + 3, null, ref pointArrayIndex); + + // Get offset of spline segment in array + int splineSegmentOffset = 0; + while(splineSegmentOffset < 4) + { + if(splineDataPoints[splineSegmentOffset].index == firstPoint.index || + splineDataPoints[splineSegmentOffset].index == secondPoint.index) + { + break; + } + ++splineSegmentOffset; + } + + // Get number of found points + int nonNullPoints = 2; + if(splineDataPoints[2] != null) + ++nonNullPoints; + if(splineDataPoints[3] != null) + ++nonNullPoints; + + + // Get coordinates and create array of PointF for the front spline + PointF[] polygonPointsFront = new PointF[nonNullPoints]; + if(yValueIndex == 0) + { + polygonPointsFront[0] = new PointF((float)splineDataPoints[0].xPosition, (float)splineDataPoints[0].yPosition); + polygonPointsFront[1] = new PointF((float)splineDataPoints[1].xPosition, (float)splineDataPoints[1].yPosition); + if(nonNullPoints > 2) + polygonPointsFront[2] = new PointF((float)splineDataPoints[2].xPosition, (float)splineDataPoints[2].yPosition); + if(nonNullPoints > 3) + polygonPointsFront[3] = new PointF((float)splineDataPoints[3].xPosition, (float)splineDataPoints[3].yPosition); + } + else + { + // Set active vertical axis + Axis vAxis = (firstPoint.dataPoint.series.YAxisType == AxisType.Primary) ? area.AxisY : area.AxisY2; + + float secondYValue = (float)vAxis.GetPosition(splineDataPoints[0].dataPoint.YValues[yValueIndex]); + polygonPointsFront[0] = new PointF((float)splineDataPoints[0].xPosition, secondYValue); + secondYValue = (float)vAxis.GetPosition(splineDataPoints[1].dataPoint.YValues[yValueIndex]); + polygonPointsFront[1] = new PointF((float)splineDataPoints[1].xPosition, secondYValue); + if(nonNullPoints > 2) + { + secondYValue = (float)vAxis.GetPosition(splineDataPoints[2].dataPoint.YValues[yValueIndex]); + polygonPointsFront[2] = new PointF((float)splineDataPoints[2].xPosition, secondYValue); + } + if(nonNullPoints > 3) + { + secondYValue = (float)vAxis.GetPosition(splineDataPoints[3].dataPoint.YValues[yValueIndex]); + polygonPointsFront[3] = new PointF((float)splineDataPoints[3].xPosition, secondYValue); + } + } + + // Translate points coordinates in 3D space and get absolute coordinate + if(translateCoordinates) + { + // Prepare array of points + Point3D[] points3D = new Point3D[nonNullPoints]; + for(int index = 0; index < nonNullPoints; index++) + { + points3D[index] = new Point3D(polygonPointsFront[index].X, polygonPointsFront[index].Y, positionZ); + } + + // Make coordinates transformation + area.matrix3D.TransformPoints( points3D ); + + // Get absolute values + for(int index = 0; index < nonNullPoints; index++) + { + polygonPointsFront[index] = GetAbsolutePoint(points3D[index].PointF); + } + + } + + // Create graphics path for the front spline surface and flatten it. + GraphicsPath splineSurfacePath = new GraphicsPath(); + splineSurfacePath.AddCurve(polygonPointsFront, splineSegmentOffset, 1, tension); + if(flatten) + { + splineSurfacePath.Flatten(); + } + + // IsReversed points order + if(firstPoint.index > secondPoint.index) + { + splineSurfacePath.Reverse(); + } + + return splineSurfacePath; + } + + /// + /// Draws a 3D spline surface connecting the two specified points in 2D space. + /// Used to draw Spline based charts. + /// + /// Chart area reference. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Name of the surface to draw. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Color of rectangle + /// Border Color + /// Border Width + /// Border Style + /// First point. + /// Second point. + /// Array of points. + /// Index of point to draw. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// Thin border will be drawn on all segments. + /// Thick border will be drawn on all segments. + /// Series are drawn in reversed order. + /// Multiple series are drawn at the same time. + /// Index of the Y value to use. + /// Surface should be clipped inside plotting area. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + internal GraphicsPath Draw3DSplineSurface( + ChartArea area, + Matrix3D matrix, + LightStyle lightStyle, + SurfaceNames surfaceName, + float positionZ, + float depth, + Color backColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + DataPoint3D firstPoint, + DataPoint3D secondPoint, + ArrayList points, + int pointIndex, + float tension, + DrawingOperationTypes operationType, + bool forceThinBorder, + bool forceThickBorder, + bool reversedSeriesOrder, + bool multiSeries, + int yValueIndex, + bool clipInsideArea) + { + // If zero tension is specified - draw a Line Surface + if(tension == 0f) + { + return Draw3DSurface( + area, + matrix, + lightStyle, + surfaceName, + positionZ, + depth, + backColor, + borderColor, + borderWidth, + borderDashStyle, + firstPoint, + secondPoint, + points, + pointIndex, + tension, + operationType, + LineSegmentType.Single, + forceThinBorder, + forceThickBorder, + reversedSeriesOrder, + multiSeries, + yValueIndex, + clipInsideArea); + } + + // Create graphics path for selection + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + // Get spline flatten path + GraphicsPath splineSurfacePath = GetSplineFlattenPath( + area, positionZ, + firstPoint, secondPoint, points, tension, true, false, yValueIndex); + + // Check if reversed drawing order required + bool reversed = false; + if((pointIndex + 1) < points.Count) + { + DataPoint3D p = (DataPoint3D)points[pointIndex + 1]; + if(p.index == firstPoint.index) + { + reversed = true; + } + } + + if(reversed) + { + splineSurfacePath.Reverse(); + } + + // Loop through all segment lines the spline consists off + PointF[] splinePathPoints = splineSurfacePath.PathPoints; + DataPoint3D dp1 = new DataPoint3D(); + DataPoint3D dp2 = new DataPoint3D(); + LineSegmentType lineSegmentType = LineSegmentType.Middle; + for(int pIndex = 1; pIndex < splinePathPoints.Length; pIndex++) + { + bool forceSegmentThinBorder = false; + bool forceSegmentThickBorder = false; + + // Calculate surface coordinates + if(!reversed) + { + dp1.index = firstPoint.index; + dp1.dataPoint = firstPoint.dataPoint; + dp1.xPosition = splinePathPoints[pIndex - 1].X; + dp1.yPosition = splinePathPoints[pIndex - 1].Y; + + dp2.index = secondPoint.index; + dp2.index = secondPoint.index; + dp2.xPosition = splinePathPoints[pIndex].X; + dp2.yPosition = splinePathPoints[pIndex].Y; + } + else + { + dp2.index = firstPoint.index; + dp2.dataPoint = firstPoint.dataPoint; + dp2.xPosition = splinePathPoints[pIndex - 1].X; + dp2.yPosition = splinePathPoints[pIndex - 1].Y; + + dp1.index = secondPoint.index; + dp1.dataPoint = secondPoint.dataPoint; + dp1.xPosition = splinePathPoints[pIndex].X; + dp1.yPosition = splinePathPoints[pIndex].Y; + } + + // Get sefment type + lineSegmentType = LineSegmentType.Middle; + if(pIndex == 1) + { + if(!reversed) + lineSegmentType = LineSegmentType.First; + else + lineSegmentType = LineSegmentType.Last; + + forceSegmentThinBorder = forceThinBorder; + forceSegmentThickBorder = forceThickBorder; + } + else if(pIndex == splinePathPoints.Length - 1) + { + if(!reversed) + lineSegmentType = LineSegmentType.Last; + else + lineSegmentType = LineSegmentType.First; + + forceSegmentThinBorder = forceThinBorder; + forceSegmentThickBorder = forceThickBorder; + } + + // Draw flat surface + GraphicsPath segmentResultPath = Draw3DSurface( + area, + matrix, + lightStyle, + surfaceName, + positionZ, + depth, + backColor, + borderColor, + borderWidth, + borderDashStyle, + dp1, + dp2, + points, + pointIndex, + 0f, + operationType, + lineSegmentType, + forceSegmentThinBorder, + forceSegmentThickBorder, + reversedSeriesOrder, + multiSeries, + yValueIndex, + clipInsideArea); + + // Add selection path + if(resultPath != null && segmentResultPath != null && segmentResultPath.PointCount > 0) + { + resultPath.AddPath(segmentResultPath, true); + } + + } + + return resultPath; + } + + + /// + /// Draws a 3D surface connecting the two specified points in 2D space. + /// Used to draw Line based charts. + /// + /// Chart area reference. + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Name of the surface to draw. + /// Z position of the back side of the 3D surface. + /// Depth of the 3D surface. + /// Color of rectangle + /// Border Color + /// Border Width + /// Border Style + /// First point. + /// Second point. + /// Array of points. + /// Index of point to draw. + /// Line tension. + /// AxisName of operation Drawing, Calculating Path or Both + /// AxisName of line segment. Used for step lines and splines. + /// Thin border will be drawn on all segments. + /// Thick border will be drawn on all segments. + /// Series are drawn in reversed order. + /// Multiple series are drawn at the same time. + /// Index of the Y value to use. + /// Surface should be clipped inside plotting area. + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + internal GraphicsPath Draw3DSurface( + ChartArea area, + Matrix3D matrix, + LightStyle lightStyle, + SurfaceNames surfaceName, + float positionZ, + float depth, + Color backColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + DataPoint3D firstPoint, + DataPoint3D secondPoint, + ArrayList points, + int pointIndex, + float tension, + DrawingOperationTypes operationType, + LineSegmentType lineSegmentType, + bool forceThinBorder, + bool forceThickBorder, + bool reversedSeriesOrder, + bool multiSeries, + int yValueIndex, + bool clipInsideArea) + { + // If non-zero tension is specified - draw a Spline Surface + if(tension != 0f) + { + return Draw3DSplineSurface( + area, + matrix, + lightStyle, + surfaceName, + positionZ, + depth, + backColor, + borderColor, + borderWidth, + borderDashStyle, + firstPoint, + secondPoint, + points, + pointIndex, + tension, + operationType, + forceThinBorder, + forceThickBorder, + reversedSeriesOrder, + multiSeries, + yValueIndex, + clipInsideArea); + } + + //********************************************************************** + //** Create graphics path for selection + //********************************************************************** + bool drawElements = ((operationType & DrawingOperationTypes.DrawElement) == DrawingOperationTypes.DrawElement); + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + //********************************************************************** + //** Check surface coordinates + //********************************************************************** + if((decimal)firstPoint.xPosition == (decimal)secondPoint.xPosition && + (decimal)firstPoint.yPosition == (decimal)secondPoint.yPosition) + { + return resultPath; + } + + //********************************************************************** + //** Clip surface + //********************************************************************** + + // Check if line between the first and second points intersects with + // plotting area top or bottom boundary + if(clipInsideArea) + { + //**************************************************************** + //** Round plot are position and point coordinates + //**************************************************************** + int decimals = 3; + decimal plotAreaPositionX = Math.Round((decimal)area.PlotAreaPosition.X, decimals); + decimal plotAreaPositionY = Math.Round((decimal)area.PlotAreaPosition.Y, decimals); + decimal plotAreaPositionRight = Math.Round((decimal)area.PlotAreaPosition.Right, decimals); + decimal plotAreaPositionBottom = Math.Round((decimal)area.PlotAreaPosition.Bottom, decimals); + + // Make area a little bit bigger + plotAreaPositionX -= 0.001M; + plotAreaPositionY -= 0.001M; + plotAreaPositionRight += 0.001M; + plotAreaPositionBottom += 0.001M; + + // Chech data points X values + if((decimal)firstPoint.xPosition < plotAreaPositionX || + (decimal)firstPoint.xPosition > plotAreaPositionRight || + (decimal)secondPoint.xPosition < plotAreaPositionX || + (decimal)secondPoint.xPosition > plotAreaPositionRight ) + { + // Check if surface completly out of the plot area + if((decimal)firstPoint.xPosition < plotAreaPositionX && + (decimal)secondPoint.xPosition < plotAreaPositionX) + { + return resultPath; + } + // Check if surface completly out of the plot area + if((decimal)firstPoint.xPosition > plotAreaPositionRight && + (decimal)secondPoint.xPosition > plotAreaPositionRight) + { + return resultPath; + } + + // Only part of the surface is outside - fix X value and adjust Y value + if((decimal)firstPoint.xPosition < plotAreaPositionX) + { + firstPoint.yPosition = ((double)plotAreaPositionX - secondPoint.xPosition) / + (firstPoint.xPosition - secondPoint.xPosition) * + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.yPosition; + firstPoint.xPosition = (double)plotAreaPositionX; + } + else if((decimal)firstPoint.xPosition > plotAreaPositionRight) + { + firstPoint.yPosition = ((double)plotAreaPositionRight - secondPoint.xPosition) / + (firstPoint.xPosition - secondPoint.xPosition) * + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.yPosition; + firstPoint.xPosition = (double)plotAreaPositionRight; + } + if((decimal)secondPoint.xPosition < plotAreaPositionX) + { + secondPoint.yPosition = ((double)plotAreaPositionX - secondPoint.xPosition) / + (firstPoint.xPosition - secondPoint.xPosition) * + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.yPosition; + secondPoint.xPosition = (double)plotAreaPositionX; + } + else if((decimal)secondPoint.xPosition > plotAreaPositionRight) + { + secondPoint.yPosition = ((double)plotAreaPositionRight - secondPoint.xPosition) / + (firstPoint.xPosition - secondPoint.xPosition) * + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.yPosition; + secondPoint.xPosition = (double)plotAreaPositionRight; + } + } + + // Chech data points Y values + if((decimal)firstPoint.yPosition < plotAreaPositionY || + (decimal)firstPoint.yPosition > plotAreaPositionBottom || + (decimal)secondPoint.yPosition < plotAreaPositionY || + (decimal)secondPoint.yPosition > plotAreaPositionBottom ) + { + // Remember previous y positions + double prevFirstPointY = firstPoint.yPosition; + double prevSecondPointY = secondPoint.yPosition; + + // Check if whole line is outside plotting region + bool surfaceCompletlyOutside = false; + if((decimal)firstPoint.yPosition < plotAreaPositionY && + (decimal)secondPoint.yPosition < plotAreaPositionY) + { + surfaceCompletlyOutside = true; + firstPoint.yPosition = (double)plotAreaPositionY; + secondPoint.yPosition = (double)plotAreaPositionY; + } + if((decimal)firstPoint.yPosition > plotAreaPositionBottom && + (decimal)secondPoint.yPosition > plotAreaPositionBottom) + { + surfaceCompletlyOutside = true; + firstPoint.yPosition = (double)plotAreaPositionBottom; + secondPoint.yPosition = (double)plotAreaPositionBottom; + } + + // Calculate color used to draw "cut" surfaces + Color cutSurfaceBackColor = ChartGraphics.GetGradientColor(backColor, Color.Black, 0.5); + Color cutSurfaceBorderColor = ChartGraphics.GetGradientColor(borderColor, Color.Black, 0.5); + + // Draw just one surface + if(surfaceCompletlyOutside) + { + resultPath = this.Draw3DSurface( + area, matrix, lightStyle, surfaceName, positionZ, depth, + cutSurfaceBackColor, cutSurfaceBorderColor, borderWidth, borderDashStyle, + firstPoint, secondPoint, + points, pointIndex, tension, operationType, lineSegmentType, + forceThinBorder, forceThickBorder, reversedSeriesOrder, + multiSeries, yValueIndex, clipInsideArea); + + // Restore previous y positions + firstPoint.yPosition = prevFirstPointY; + secondPoint.yPosition = prevSecondPointY; + + return resultPath; + } + + // Get intersection point + DataPoint3D intersectionPoint = new DataPoint3D(); + intersectionPoint.yPosition = (double)plotAreaPositionY; + if((decimal)firstPoint.yPosition > plotAreaPositionBottom || + (decimal)secondPoint.yPosition > plotAreaPositionBottom ) + { + intersectionPoint.yPosition = (double)plotAreaPositionBottom; + } + intersectionPoint.xPosition = (intersectionPoint.yPosition - secondPoint.yPosition) * + (firstPoint.xPosition - secondPoint.xPosition) / + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.xPosition; + + // Check if there are 2 intersection points (3 segments) + int segmentNumber = 2; + DataPoint3D intersectionPoint2 = null; + if( ((decimal)firstPoint.yPosition < plotAreaPositionY && + (decimal)secondPoint.yPosition > plotAreaPositionBottom) || + ((decimal)firstPoint.yPosition > plotAreaPositionBottom && + (decimal)secondPoint.yPosition < plotAreaPositionY)) + { + segmentNumber = 3; + intersectionPoint2 = new DataPoint3D(); + if((decimal)intersectionPoint.yPosition == plotAreaPositionY) + { + intersectionPoint2.yPosition = (double)plotAreaPositionBottom; + } + else + { + intersectionPoint2.yPosition = (double)plotAreaPositionY; + } + intersectionPoint2.xPosition = (intersectionPoint2.yPosition - secondPoint.yPosition) * + (firstPoint.xPosition - secondPoint.xPosition) / + (firstPoint.yPosition - secondPoint.yPosition) + + secondPoint.xPosition; + + // Switch intersection points + if((decimal)firstPoint.yPosition > plotAreaPositionBottom) + { + DataPoint3D tempPoint = new DataPoint3D(); + tempPoint.xPosition = intersectionPoint.xPosition; + tempPoint.yPosition = intersectionPoint.yPosition; + intersectionPoint.xPosition = intersectionPoint2.xPosition; + intersectionPoint.yPosition = intersectionPoint2.yPosition; + intersectionPoint2.xPosition = tempPoint.xPosition; + intersectionPoint2.yPosition = tempPoint.yPosition; + } + } + + + // Adjust points Y values + bool firstSegmentVisible = true; + if((decimal)firstPoint.yPosition < plotAreaPositionY) + { + firstSegmentVisible = false; + firstPoint.yPosition = (double)plotAreaPositionY; + } + else if((decimal)firstPoint.yPosition > plotAreaPositionBottom) + { + firstSegmentVisible = false; + firstPoint.yPosition = (double)plotAreaPositionBottom; + } + if((decimal)secondPoint.yPosition < plotAreaPositionY) + { + secondPoint.yPosition = (double)plotAreaPositionY; + } + else if((decimal)secondPoint.yPosition > plotAreaPositionBottom) + { + secondPoint.yPosition = (double)plotAreaPositionBottom; + } + + // Check if reversed drawing order required + bool reversed = false; + if((pointIndex + 1) < points.Count) + { + DataPoint3D p = (DataPoint3D)points[pointIndex + 1]; + if(p.index == firstPoint.index) + { + reversed = true; + } + } + + // Draw surfaces in 2 or 3 segments + for(int segmentIndex = 0; segmentIndex < 3; segmentIndex++) + { + GraphicsPath segmentPath = null; + if(segmentIndex == 0 && !reversed || + segmentIndex == 2 && reversed) + { + // Draw first segment + if(intersectionPoint2 == null) + { + intersectionPoint2 = intersectionPoint; + } + intersectionPoint2.dataPoint = secondPoint.dataPoint; + intersectionPoint2.index = secondPoint.index; + + segmentPath = this.Draw3DSurface( + area, matrix, lightStyle, surfaceName, positionZ, depth, + (firstSegmentVisible && segmentNumber != 3) ? backColor : cutSurfaceBackColor, + (firstSegmentVisible && segmentNumber != 3) ? borderColor : cutSurfaceBorderColor, + borderWidth, borderDashStyle, + firstPoint, intersectionPoint2, + points, pointIndex, tension, operationType, lineSegmentType, + forceThinBorder, forceThickBorder, reversedSeriesOrder, + multiSeries, yValueIndex, clipInsideArea); + } + + if(segmentIndex == 1 && intersectionPoint2 != null && segmentNumber == 3) + { + // Draw middle segment + intersectionPoint2.dataPoint = secondPoint.dataPoint; + intersectionPoint2.index = secondPoint.index; + + segmentPath = this.Draw3DSurface( + area, matrix, lightStyle, surfaceName, positionZ, depth, + backColor, + borderColor, + borderWidth, borderDashStyle, + intersectionPoint, intersectionPoint2, + points, pointIndex, tension, operationType, lineSegmentType, + forceThinBorder, forceThickBorder, reversedSeriesOrder, + multiSeries, yValueIndex, clipInsideArea); + } + + if(segmentIndex == 2 && !reversed || + segmentIndex == 0 && reversed) + { + // Draw second segment + intersectionPoint.dataPoint = firstPoint.dataPoint; + intersectionPoint.index = firstPoint.index; + + segmentPath = this.Draw3DSurface( + area, matrix, lightStyle, surfaceName, positionZ, depth, + (!firstSegmentVisible && segmentNumber != 3) ? backColor : cutSurfaceBackColor, + (!firstSegmentVisible && segmentNumber != 3) ? borderColor : cutSurfaceBorderColor, + borderWidth, borderDashStyle, + intersectionPoint, secondPoint, + points, pointIndex, tension, operationType, lineSegmentType, + forceThinBorder, forceThickBorder, reversedSeriesOrder, + multiSeries, yValueIndex, clipInsideArea); + } + + // Add segment path + if(resultPath != null && segmentPath != null && segmentPath.PointCount > 0) + { + resultPath.SetMarkers(); + resultPath.AddPath(segmentPath, true); + } + } + + // Restore previous y positions + firstPoint.yPosition = prevFirstPointY; + secondPoint.yPosition = prevSecondPointY; + + return resultPath; + } + } + + //********************************************************************** + //** Prepare, transform polygon coordinates + //********************************************************************** + + // Define 4 points polygon + Point3D [] points3D = new Point3D[4]; + points3D[0] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ + depth); + points3D[1] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ + depth); + points3D[2] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ); + points3D[3] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ); + + // Transform coordinates + matrix.TransformPoints( points3D ); + + // Get absolute coordinates and create array of PointF + PointF[] polygonPoints = new PointF[4]; + polygonPoints[0] = GetAbsolutePoint(points3D[0].PointF); + polygonPoints[1] = GetAbsolutePoint(points3D[1].PointF); + polygonPoints[2] = GetAbsolutePoint(points3D[2].PointF); + polygonPoints[3] = GetAbsolutePoint(points3D[3].PointF); + + //********************************************************************** + //** Define drawing colors + //********************************************************************** + bool topIsVisible = IsSurfaceVisible( points3D[0], points3D[1], points3D[2]); + Color polygonColor = matrix.GetPolygonLight( points3D, backColor, topIsVisible, area.Area3DStyle.Rotation, surfaceName, area.ReverseSeriesOrder ); + Color surfaceBorderColor = borderColor; + if(surfaceBorderColor == Color.Empty) + { + // If border color is emty use color slightly darker than main back color + surfaceBorderColor = ChartGraphics.GetGradientColor( backColor, Color.Black, 0.2 ); + } + + //********************************************************************** + //** Draw elements if required. + //********************************************************************** + Pen thinBorderPen = new Pen(surfaceBorderColor, 1); + if(drawElements) + { + // Draw the polygon + if(backColor != Color.Transparent) + { + // Remember SmoothingMode and turn off anti aliasing + SmoothingMode oldSmoothingMode = SmoothingMode; + SmoothingMode = SmoothingMode.Default; + + // Draw the polygon + using (Brush brush = new SolidBrush(polygonColor)) + { + FillPolygon(brush, polygonPoints); + } + + // Return old smoothing mode + SmoothingMode = oldSmoothingMode; + } + + // Draw thin polygon border of darker color + if(forceThinBorder || forceThickBorder) + { + if(forceThickBorder) + { + Pen linePen = new Pen(surfaceBorderColor, borderWidth); + linePen.StartCap = LineCap.Round; + linePen.EndCap = LineCap.Round; + + DrawLine(linePen, polygonPoints[0], polygonPoints[1]); + DrawLine(linePen, polygonPoints[2], polygonPoints[3]); + DrawLine(linePen, polygonPoints[3], polygonPoints[0]); + DrawLine(linePen, polygonPoints[1], polygonPoints[2]); + } + else + { + // Front & Back lines + DrawLine(thinBorderPen, polygonPoints[0], polygonPoints[1]); + DrawLine(thinBorderPen, polygonPoints[2], polygonPoints[3]); + if(lineSegmentType == LineSegmentType.First) + { + // Left line + DrawLine(thinBorderPen, polygonPoints[3], polygonPoints[0]); + } + else if(lineSegmentType == LineSegmentType.Last) + { + // Right Line + DrawLine(thinBorderPen, polygonPoints[1], polygonPoints[2]); + } + else + { + // Left & Right lines + DrawLine(thinBorderPen, polygonPoints[3], polygonPoints[0]); + DrawLine(thinBorderPen, polygonPoints[1], polygonPoints[2]); + } + } + + } + else + { + // Draw thin polygon border of same color (solves anti-aliasing issues) + if(polygonColor.A == 255) + { + DrawPolygon(new Pen(polygonColor, 1), polygonPoints); + } + + // Draw thin Front & Back lines + DrawLine(thinBorderPen, polygonPoints[0], polygonPoints[1]); + DrawLine(thinBorderPen, polygonPoints[2], polygonPoints[3]); + } + } + + //********************************************************************** + //** Draw thick border line on visible sides + //********************************************************************** + Pen thickBorderPen = null; + if(borderWidth > 1 && !forceThickBorder) + { + // Create thick border line pen + thickBorderPen = new Pen(surfaceBorderColor, borderWidth); + thickBorderPen.StartCap = LineCap.Round; + thickBorderPen.EndCap = LineCap.Round; + + //**************************************************************** + //** Switch first and second points. + //**************************************************************** + if(firstPoint.index > secondPoint.index) + { + DataPoint3D tempPoint = firstPoint; + firstPoint = secondPoint; + secondPoint = tempPoint; + } + + //********************************************************************** + //** Check if there are visible (non-empty) lines to the left & right + //** of the current line. + //********************************************************************** + + // Get visibility of bounding rectangle + float minX = (float)Math.Min(points3D[0].X, points3D[1].X); + float minY = (float)Math.Min(points3D[0].Y, points3D[1].Y); + float maxX = (float)Math.Max(points3D[0].X, points3D[1].X); + float maxY = (float)Math.Max(points3D[0].Y, points3D[1].Y); + RectangleF position = new RectangleF(minX, minY, maxX - minX, maxY - minY); + SurfaceNames visibleSurfaces = GetVisibleSurfaces(position,positionZ,depth,matrix); + + // Check left line visibility + bool thickBorderOnLeft = false; + bool thickBorderOnRight = false; + + if(lineSegmentType != LineSegmentType.Middle) + { + LineSegmentType tempLineSegmentType = LineSegmentType.Single; + + // Check left line visibility + thickBorderOnLeft = (ChartGraphics.ShouldDrawLineChartSurface( + area, + reversedSeriesOrder, + SurfaceNames.Left, + visibleSurfaces, + polygonColor, + points, + firstPoint, + secondPoint, + multiSeries, + ref tempLineSegmentType) == 2); + + + // Check right line visibility + thickBorderOnRight = (ChartGraphics.ShouldDrawLineChartSurface( + area, + reversedSeriesOrder, + SurfaceNames.Right, + visibleSurfaces, + polygonColor, + points, + firstPoint, + secondPoint, + multiSeries, + ref tempLineSegmentType) == 2); + } + + // Switch left & right border if series is reversed + if(reversedSeriesOrder) + { + bool tempVal = thickBorderOnLeft; + thickBorderOnLeft = thickBorderOnRight; + thickBorderOnRight = tempVal; + } + + // Draw thick border for single segment lines only + // or for the first & last segment + if(lineSegmentType != LineSegmentType.First && lineSegmentType != LineSegmentType.Single) + { + thickBorderOnLeft = false; + } + if(lineSegmentType != LineSegmentType.Last && lineSegmentType != LineSegmentType.Single) + { + thickBorderOnRight = false; + } + + //********************************************************************** + //** Draw border on the front side of line surface (only when visible) + //********************************************************************** + if( matrix.Perspective != 0 || + (matrix.AngleX != 90 && matrix.AngleX != -90 && + matrix.AngleY != 90 && matrix.AngleY != -90 && + matrix.AngleY != 180 && matrix.AngleY != -180)) + { + // Draw thick line on the front side of the line surface + if(drawElements) + { + DrawLine( + thickBorderPen, + (float)Math.Round(polygonPoints[0].X), + (float)Math.Round(polygonPoints[0].Y), + (float)Math.Round(polygonPoints[1].X), + (float)Math.Round(polygonPoints[1].Y) ); + } + + // Calculate path for selection + if(resultPath != null) + { + // Add front line to the path + resultPath.AddLine( + (float)Math.Round(polygonPoints[0].X), + (float)Math.Round(polygonPoints[0].Y), + (float)Math.Round(polygonPoints[1].X), + (float)Math.Round(polygonPoints[1].Y)); + } + } + + + //********************************************************************** + //** Draw border on the left side of line surface (only when visible) + //********************************************************************** + + // Use flat end for Right & Left border + thickBorderPen.EndCap = LineCap.Flat; + + // Draw border on the left side + if (matrix.Perspective != 0 || (matrix.AngleX != 90 && matrix.AngleX != -90)) + { + if(thickBorderOnLeft) + { + if(drawElements) + { + DrawLine( + thickBorderPen, + (float)Math.Round(polygonPoints[3].X), + (float)Math.Round(polygonPoints[3].Y), + (float)Math.Round(polygonPoints[0].X), + (float)Math.Round(polygonPoints[0].Y) ); + } + + // Calculate path for selection + if(resultPath != null) + { + // Add left line to the path + resultPath.AddLine( + (float)Math.Round(polygonPoints[3].X), + (float)Math.Round(polygonPoints[3].Y), + (float)Math.Round(polygonPoints[0].X), + (float)Math.Round(polygonPoints[0].Y)); + } + } + } + + //********************************************************************** + //** Draw border on the right side of the line surface + //********************************************************************** + if (matrix.Perspective != 0 || (matrix.AngleX != 90 && matrix.AngleX != -90)) + { + if(thickBorderOnRight) + { + if(drawElements) + { + DrawLine( + thickBorderPen, + (float)Math.Round(polygonPoints[1].X), + (float)Math.Round(polygonPoints[1].Y), + (float)Math.Round(polygonPoints[2].X), + (float)Math.Round(polygonPoints[2].Y) ); + } + + // Calculate path for selection + if(resultPath != null) + { + // Add right line to the path + resultPath.AddLine( + (float)Math.Round(polygonPoints[1].X), + (float)Math.Round(polygonPoints[1].Y), + (float)Math.Round(polygonPoints[2].X), + (float)Math.Round(polygonPoints[2].Y)); + } + } + } + } + + //********************************************************************** + // Redraw front line of the previuos line segment. + // Solves 3D visibility problem between wide border line and line surface. + //********************************************************************** + if( area.Area3DStyle.Perspective == 0 ) + { + if(frontLinePoint1 != PointF.Empty && frontLinePen != null) + { + // Draw line + DrawLine( + frontLinePen, + (float)Math.Round(frontLinePoint1.X), + (float)Math.Round(frontLinePoint1.Y), + (float)Math.Round(frontLinePoint2.X), + (float)Math.Round(frontLinePoint2.Y) ); + + // Reset line properties + frontLinePen = null; + frontLinePoint1 = PointF.Empty; + frontLinePoint2 = PointF.Empty; + } + + //********************************************************************** + //** Check if front line should be redrawn whith the next segment. + //********************************************************************** + if(drawElements) + { + frontLinePen = (borderWidth > 1) ? thickBorderPen : thinBorderPen; + frontLinePoint1 = polygonPoints[0]; + frontLinePoint2 = polygonPoints[1]; + } + } + + //********************************************************************** + //** Calculate path for selection + //********************************************************************** + if(resultPath != null) + { + // Widen all the lines currently in the path + if(thickBorderPen != null) + { + try + { + resultPath.Widen(thickBorderPen); + } + catch (OutOfMemoryException) + { + // GraphicsPath.Widen incorrectly throws OutOfMemoryException + // catching here and reacting by not widening + } + catch (ArgumentException) + { + } + } + + // Add polygon to the path + resultPath.AddPolygon(polygonPoints); + } + + return resultPath; + } + + + + /// + /// Helper method, which indicates if area chart surface should be drawn or not. + /// + /// Chart area object. + /// Series are drawn in reversed order. + /// Surface name. + /// Visible surfaces of the bounding rectangle. + /// Point back color. + /// Array of all points. + /// First point. + /// Second point. + /// Indicates that multiple series are painted at the same time (stacked or side-by-side). + /// Returns line segment type. + /// Function retrns 0, 1 or 2. 0 - Do not draw surface, 1 - draw on the back, 2 - draw in front. + static internal int ShouldDrawLineChartSurface( + ChartArea area, + bool reversedSeriesOrder, + SurfaceNames surfaceName, + SurfaceNames boundaryRectVisibleSurfaces, + Color color, + ArrayList points, + DataPoint3D firstPoint, + DataPoint3D secondPoint, + bool multiSeries, + ref LineSegmentType lineSegmentType) + { + int result = 0; + Series series = firstPoint.dataPoint.series; + + // Set active horizontal/vertical axis + Axis hAxis = (series.XAxisType == AxisType.Primary) ? area.AxisX : area.AxisX2; + double hAxisMin = hAxis.ViewMinimum; + double hAxisMax = hAxis.ViewMaximum; + + //**************************************************************** + //** Check if data point and it's neigbours have non-transparent + //** colors. + //**************************************************************** + + // Check if point main color has transparency + bool transparent = color.A != 255; + + // Check if points on the left and right side exsit and are transparent + bool leftPointVisible = false; + bool rightPointVisible = false; + if( surfaceName == SurfaceNames.Left ) + { + // Find Left point + DataPoint3D leftPoint = null, leftPointAttr = null; + int pointArrayIndex = int.MinValue; + if(!reversedSeriesOrder) + { + leftPoint = ChartGraphics.FindPointByIndex(points, Math.Min(firstPoint.index, secondPoint.index) - 1, (multiSeries) ? secondPoint : null, ref pointArrayIndex); + leftPointAttr = ChartGraphics.FindPointByIndex(points, Math.Min(firstPoint.index, secondPoint.index), (multiSeries) ? secondPoint : null, ref pointArrayIndex); + } + else + { + leftPoint = ChartGraphics.FindPointByIndex(points, Math.Max(firstPoint.index, secondPoint.index) + 1, (multiSeries) ? secondPoint : null, ref pointArrayIndex); + leftPointAttr = leftPoint; + } + if(leftPoint != null) + { + if(leftPointAttr.dataPoint.IsEmpty) + { + if(leftPointAttr.dataPoint.series.EmptyPointStyle.Color == color || + leftPointAttr.dataPoint.series.EmptyPointStyle.Color.A == 255) + { + leftPointVisible = true; + } + } + else + { + if(leftPointAttr.dataPoint.Color == color || + leftPointAttr.dataPoint.Color.A == 255) + { + leftPointVisible = true; + } + } + + // Check if found point is outside the scaleView + double xValue = (leftPoint.indexedSeries) ? leftPoint.index : leftPoint.dataPoint.XValue; + if(xValue > hAxisMax || xValue < hAxisMin) + { + DataPoint3D currentPoint = null; + if(reversedSeriesOrder) + { + currentPoint = (firstPoint.index > secondPoint.index) ? firstPoint : secondPoint; + } + else + { + currentPoint = (firstPoint.index < secondPoint.index) ? firstPoint : secondPoint; + } + double currentXValue = (currentPoint.indexedSeries) ? currentPoint.index : currentPoint.dataPoint.XValue; + if(currentXValue > hAxisMax || currentXValue < hAxisMin) + { + leftPointVisible = false; + } + } + } + } + + // Find Right point + if( surfaceName == SurfaceNames.Right ) + { + DataPoint3D rightPoint = null, rightPointAttr = null; + int pointArrayIndex = int.MinValue; + if(!reversedSeriesOrder) + { + rightPoint = ChartGraphics.FindPointByIndex(points, Math.Max(firstPoint.index, secondPoint.index) + 1, (multiSeries) ? secondPoint : null, ref pointArrayIndex); + rightPointAttr = rightPoint; + } + else + { + rightPoint = ChartGraphics.FindPointByIndex(points, Math.Min(firstPoint.index, secondPoint.index) - 1, (multiSeries) ? secondPoint : null, ref pointArrayIndex); + rightPointAttr = ChartGraphics.FindPointByIndex(points, Math.Min(firstPoint.index, secondPoint.index), (multiSeries) ? secondPoint : null, ref pointArrayIndex); + } + if(rightPoint != null) + { + if(rightPointAttr.dataPoint.IsEmpty) + { + if(rightPointAttr.dataPoint.series.EmptyPointStyle.Color == color || + rightPointAttr.dataPoint.series.EmptyPointStyle.Color.A == 255) + { + rightPointVisible = true; + } + } + else + { + if(rightPointAttr.dataPoint.Color == color || + rightPointAttr.dataPoint.Color.A == 255) + { + rightPointVisible = true; + } + } + + // Check if found point is outside the scaleView + double xValue = (rightPoint.indexedSeries) ? rightPoint.index : rightPoint.dataPoint.XValue; + if(xValue > hAxisMax || xValue < hAxisMin) + { + DataPoint3D currentPoint = null; + if(reversedSeriesOrder) + { + currentPoint = (firstPoint.index > secondPoint.index) ? firstPoint : secondPoint; + } + else + { + currentPoint = (firstPoint.index < secondPoint.index) ? firstPoint : secondPoint; + } + double currentXValue = (currentPoint.indexedSeries) ? currentPoint.index : currentPoint.dataPoint.XValue; + if(currentXValue > hAxisMax || currentXValue < hAxisMin) + { + rightPointVisible = false; + } + } + } + } + + //**************************************************************** + //** Get line segment + //**************************************************************** + if( surfaceName == SurfaceNames.Left && !leftPointVisible) + { + if(lineSegmentType == LineSegmentType.Middle) + { + lineSegmentType = LineSegmentType.First; + } + else if(lineSegmentType == LineSegmentType.Last) + { + lineSegmentType = LineSegmentType.Single; + } + } + if( surfaceName == SurfaceNames.Right && !rightPointVisible) + { + if(lineSegmentType == LineSegmentType.Middle) + { + lineSegmentType = LineSegmentType.Last; + } + else if(lineSegmentType == LineSegmentType.First) + { + lineSegmentType = LineSegmentType.Single; + } + } + + + //**************************************************************** + //** Check surfaces visibility + //**************************************************************** + if( surfaceName == SurfaceNames.Top ) + { + result = ((boundaryRectVisibleSurfaces & SurfaceNames.Top) == SurfaceNames.Top) ? 2 : 1; + } + if( surfaceName == SurfaceNames.Bottom ) + { + result = ((boundaryRectVisibleSurfaces & SurfaceNames.Bottom) == SurfaceNames.Bottom) ? 2 : 1; + // Draw invisible bottom surface only if chart is transparent + if(result == 1 && !transparent) + { + result = 0; + } + } + if( surfaceName == SurfaceNames.Front ) + { + result = ((boundaryRectVisibleSurfaces & SurfaceNames.Front) == SurfaceNames.Front) ? 2 : 1; + // Draw invisible front surface only if chart is transparent + if(result == 1 && !transparent) + { + result = 0; + } + } + if( surfaceName == SurfaceNames.Back ) + { + result = ((boundaryRectVisibleSurfaces & SurfaceNames.Back) == SurfaceNames.Back) ? 2 : 1; + // Draw invisible back surface only if chart is transparent + if(result == 1 && !transparent) + { + result = 0; + } + } + if( surfaceName == SurfaceNames.Left ) + { + result = ((boundaryRectVisibleSurfaces & SurfaceNames.Left) == SurfaceNames.Left) ? 2 : 1; + // Draw invisible left surface only if point to the left is transparent + if(leftPointVisible) + { + result = 0; + } + } + if( surfaceName == SurfaceNames.Right ) + { + result = ((boundaryRectVisibleSurfaces & SurfaceNames.Right) == SurfaceNames.Right) ? 2 : 1; + // Draw invisible right surface only if point to the right is transparent + if(rightPointVisible) + { + result = 0; + } + } + + return result; + } + + + /// + /// Helper method which finds point in the list by it's real index. + /// + /// List of points. + /// Required index. + /// Neighbor point of the same series. + /// Neighbor point index in the array list. + /// Data point found. + internal static DataPoint3D FindPointByIndex(ArrayList points, int index, DataPoint3D neighborDataPoint, ref int neighborPointIndex) + { + // Try to look around the neighbor point index + if(neighborPointIndex != int.MinValue) + { + // Try getting the next point + if(neighborPointIndex < (points.Count - 2)) + { + DataPoint3D point = (DataPoint3D)points[neighborPointIndex + 1]; + + // Check required point index for the first point + if( point.index == index && + (neighborDataPoint == null || String.Compare(neighborDataPoint.dataPoint.series.Name, point.dataPoint.series.Name, StringComparison.Ordinal) == 0)) + { + ++neighborPointIndex; + return point; + } + } + + // Try getting the prev point + if(neighborPointIndex > 0) + { + DataPoint3D point = (DataPoint3D)points[neighborPointIndex - 1]; + + // Check required point index for the first point + if( point.index == index && + (neighborDataPoint == null || String.Compare(neighborDataPoint.dataPoint.series.Name, point.dataPoint.series.Name, StringComparison.Ordinal) == 0)) + { + --neighborPointIndex; + return point; + } + } + + } + + // Loop through all points + neighborPointIndex = 0; + foreach(DataPoint3D point3D in points) + { + // Check required point index for the first point + if(point3D.index == index) + { + // Check if point belongs to the same series + if(neighborDataPoint != null) + { + if (String.Compare(neighborDataPoint.dataPoint.series.Name, point3D.dataPoint.series.Name, StringComparison.Ordinal) != 0) + { + ++neighborPointIndex; + continue; + } + } + + // Point found + return (DataPoint3D)point3D; + } + + ++neighborPointIndex; + } + + // Data point was not found + return null; + } + + + #endregion + + #region 3D Rectangle drawing methods + + /// + /// Function is used to calculate the coordinates of the 2D rectangle in 3D space + /// and either draw it or/and calculate the bounding path for selection. + /// + /// Position of 2D rectangle. + /// Z position of the back side of the 3D rectangle. + /// Depth of the 3D rectangle. + /// Coordinate transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Color of rectangle + /// Border Color + /// Border Width + /// Border Style + /// AxisName of operation Drawing, Calculating Path or Both + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + internal GraphicsPath Fill3DRectangle( + RectangleF position, + float positionZ, + float depth, + Matrix3D matrix, + LightStyle lightStyle, + Color backColor, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + DrawingOperationTypes operationType) + { + return Fill3DRectangle( + position, + positionZ, + depth, + matrix, + lightStyle, + backColor, + 0f, + 0f, + borderColor, + borderWidth, + borderDashStyle, + BarDrawingStyle.Default, + false, + operationType); + } + + /// + /// Function is used to calculate the coordinates of the 2D rectangle in 3D space + /// and either draw it or/and calculate the bounding path for selection. + /// + /// Position of 2D rectangle. + /// Z position of the back side of the 3D rectangle. + /// Depth of the 3D rectangle. + /// Coordinate transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Color of rectangle + /// Top (or right in bar chart) darkening effect. + /// Bottom (or left in bar chart) darkening effect. + /// Border Color + /// Border Width + /// Border Style + /// Bar drawing style. + /// Defines if bar is vertical or horizontal. + /// AxisName of operation Drawing, Calculating Path or Both + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + internal GraphicsPath Fill3DRectangle( + RectangleF position, + float positionZ, + float depth, + Matrix3D matrix, + LightStyle lightStyle, + Color backColor, + float topRightDarkening, + float bottomLeftDarkening, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + BarDrawingStyle barDrawingStyle, + bool veticalOrientation, + DrawingOperationTypes operationType) + { + + // Check if special drawing is required + if(barDrawingStyle == BarDrawingStyle.Cylinder) + { + // Draw as 3D cylinder + return Fill3DRectangleAsCylinder( + position, + positionZ, + depth, + matrix, + lightStyle, + backColor, + topRightDarkening, + bottomLeftDarkening, + borderColor, + borderWidth, + borderDashStyle, + veticalOrientation, + operationType); + } + + // Declare variables + Point3D[] cubePoints = new Point3D[8]; + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + // Front Side + cubePoints[0] = new Point3D( position.X, position.Y, positionZ + depth ); + cubePoints[1] = new Point3D( position.X, position.Bottom, positionZ + depth ); + cubePoints[2] = new Point3D( position.Right, position.Bottom, positionZ + depth ); + cubePoints[3] = new Point3D( position.Right, position.Y, positionZ + depth ); + + // Back Side + cubePoints[4] = new Point3D( position.X, position.Y, positionZ ); + cubePoints[5] = new Point3D( position.X, position.Bottom, positionZ ); + cubePoints[6] = new Point3D( position.Right, position.Bottom, positionZ ); + cubePoints[7] = new Point3D( position.Right, position.Y, positionZ ); + + // Tranform cube coordinates + matrix.TransformPoints( cubePoints ); + + // For lightStyle style Non, Border color always exist. + if( lightStyle == LightStyle.None && + (borderWidth == 0 || borderDashStyle == ChartDashStyle.NotSet || borderColor == Color.Empty) ) + { + borderColor = ChartGraphics.GetGradientColor( backColor, Color.Black, 0.5 ); + } + + // Get surface colors + Color frontLightColor, leftLightColor, topLightColor, backLightColor, rightLightColor, bottomLightColor; + matrix.GetLight( backColor, out frontLightColor, out backLightColor, out leftLightColor, out rightLightColor, out topLightColor, out bottomLightColor ); + + // Darken colors by specified values + if(topRightDarkening != 0f) + { + if(veticalOrientation) + { + topLightColor = ChartGraphics.GetGradientColor(topLightColor, Color.Black, topRightDarkening); + } + else + { + rightLightColor = ChartGraphics.GetGradientColor(rightLightColor, Color.Black, topRightDarkening); + } + } + if(bottomLeftDarkening != 0f) + { + if(veticalOrientation) + { + bottomLightColor = ChartGraphics.GetGradientColor(bottomLightColor, Color.Black, bottomLeftDarkening); + } + else + { + leftLightColor = ChartGraphics.GetGradientColor(leftLightColor, Color.Black, bottomLeftDarkening); + } + } + + + // Check visible surfaces + SurfaceNames visibleSurfaces = GetVisibleSurfacesWithPerspective(position,positionZ,depth,matrix); + + // Draw all invisible surfaces first (if semi-transparent color is used) + for(int drawVisible = 0; drawVisible <= 1; drawVisible++) + { + // Do not draw invisible surfaces for solid colors + if(drawVisible == 0 && backColor.A == 255) + { + continue; + } + + // Check visibility of all surfaces and draw them + for(int surfaceIndex = (int)SurfaceNames.Front; surfaceIndex <= (int)SurfaceNames.Bottom; surfaceIndex *= 2) + { + SurfaceNames currentSurface = (SurfaceNames)surfaceIndex; + + // If width, height or depth of the cube (3DRectangle) is zero graphical path + // should contain only one surface with 4 points. + if(depth == 0.0 && currentSurface != SurfaceNames.Front) + { + continue; + } + if(position.Width == 0.0 && currentSurface != SurfaceNames.Left && currentSurface != SurfaceNames.Right) + { + continue; + } + if(position.Height == 0.0 && currentSurface != SurfaceNames.Top && currentSurface != SurfaceNames.Bottom) + { + continue; + } + + // Check if surface is visible or semi-transparent color is used + bool isVisible = (visibleSurfaces & currentSurface) != 0; + if(isVisible && drawVisible == 1 || + !isVisible && drawVisible == 0) + { + // Fill surface coordinates and color + PointF [] pointsSurface = new PointF[4]; + Color surfaceColor = backColor; + + switch(currentSurface) + { + case(SurfaceNames.Front): + surfaceColor = frontLightColor; + pointsSurface[0] = new PointF(cubePoints[0].X, cubePoints[0].Y); + pointsSurface[1] = new PointF(cubePoints[1].X, cubePoints[1].Y); + pointsSurface[2] = new PointF(cubePoints[2].X, cubePoints[2].Y); + pointsSurface[3] = new PointF(cubePoints[3].X, cubePoints[3].Y); + break; + case(SurfaceNames.Back): + surfaceColor = backLightColor; + pointsSurface[0] = new PointF(cubePoints[4].X, cubePoints[4].Y); + pointsSurface[1] = new PointF(cubePoints[5].X, cubePoints[5].Y); + pointsSurface[2] = new PointF(cubePoints[6].X, cubePoints[6].Y); + pointsSurface[3] = new PointF(cubePoints[7].X, cubePoints[7].Y); + break; + case(SurfaceNames.Left): + surfaceColor = leftLightColor; + pointsSurface[0] = new PointF(cubePoints[0].X, cubePoints[0].Y); + pointsSurface[1] = new PointF(cubePoints[1].X, cubePoints[1].Y); + pointsSurface[2] = new PointF(cubePoints[5].X, cubePoints[5].Y); + pointsSurface[3] = new PointF(cubePoints[4].X, cubePoints[4].Y); + break; + case(SurfaceNames.Right): + surfaceColor = rightLightColor; + pointsSurface[0] = new PointF(cubePoints[3].X, cubePoints[3].Y); + pointsSurface[1] = new PointF(cubePoints[2].X, cubePoints[2].Y); + pointsSurface[2] = new PointF(cubePoints[6].X, cubePoints[6].Y); + pointsSurface[3] = new PointF(cubePoints[7].X, cubePoints[7].Y); + break; + case(SurfaceNames.Top): + surfaceColor = topLightColor; + pointsSurface[0] = new PointF(cubePoints[0].X, cubePoints[0].Y); + pointsSurface[1] = new PointF(cubePoints[3].X, cubePoints[3].Y); + pointsSurface[2] = new PointF(cubePoints[7].X, cubePoints[7].Y); + pointsSurface[3] = new PointF(cubePoints[4].X, cubePoints[4].Y); + break; + case(SurfaceNames.Bottom): + surfaceColor = bottomLightColor; + pointsSurface[0] = new PointF(cubePoints[1].X, cubePoints[1].Y); + pointsSurface[1] = new PointF(cubePoints[2].X, cubePoints[2].Y); + pointsSurface[2] = new PointF(cubePoints[6].X, cubePoints[6].Y); + pointsSurface[3] = new PointF(cubePoints[5].X, cubePoints[5].Y); + break; + } + + // Covert coordinates to absolute + for(int pointIndex = 0; pointIndex < pointsSurface.Length; pointIndex++) + { + pointsSurface[pointIndex] = GetAbsolutePoint(pointsSurface[pointIndex]); + } + + // Draw surface + if( (operationType & DrawingOperationTypes.DrawElement) == DrawingOperationTypes.DrawElement) + { + // Draw only completly visible surfaces + if((visibleSurfaces & currentSurface) != 0) + { + using (Brush brush = new SolidBrush(surfaceColor)) + { + FillPolygon(brush, pointsSurface); + } + + // Check if any additional drawing should be done + if(currentSurface == SurfaceNames.Front && + barDrawingStyle != BarDrawingStyle.Default && + barDrawingStyle != BarDrawingStyle.Cylinder) + { + this.DrawBarStyleGradients(matrix, barDrawingStyle, position, positionZ, depth, veticalOrientation); + } + } + + // Draw surface border + using (Pen pen = new Pen(borderColor, borderWidth)) + { + pen.DashStyle = GetPenStyle(borderDashStyle); + if (lightStyle != LightStyle.None && + (borderWidth == 0 || borderDashStyle == ChartDashStyle.NotSet || borderColor == Color.Empty)) + { + // Draw line of the same color inside the bar + pen.Color = surfaceColor; + pen.Width = 1; + pen.Alignment = PenAlignment.Inset; + } + + pen.StartCap = LineCap.Round; + pen.EndCap = LineCap.Round; + DrawLine(pen, pointsSurface[0], pointsSurface[1]); + DrawLine(pen, pointsSurface[1], pointsSurface[2]); + DrawLine(pen, pointsSurface[2], pointsSurface[3]); + DrawLine(pen, pointsSurface[3], pointsSurface[0]); + } + } + + // Add surface coordinate to the path + if( (operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + { + // Only if surface is completly visible + if((visibleSurfaces & currentSurface) != 0) + { + resultPath.SetMarkers(); + resultPath.AddPolygon(pointsSurface); + } + } + + } + } + } + + return resultPath; + } + + /// + /// Draws special bar style effect on the front surface of the bar. + /// + /// Drawing matrix. + /// Bar drawing style. + /// Position in relative coordinates + /// Z position. + /// Depth. + /// Defines if bar is vertical or horizontal. + private void DrawBarStyleGradients( + Matrix3D matrix, + BarDrawingStyle barDrawingStyle, + RectangleF position, + float positionZ, + float depth, + bool isVertical) + { + if(barDrawingStyle == BarDrawingStyle.Wedge) + { + // Calculate wedge size to fit the rectangle + RectangleF positionAbs = GetAbsoluteRectangle(position); + float size = (isVertical) ? positionAbs.Width / 2f : positionAbs.Height / 2f; + if(isVertical && 2f * size > positionAbs.Height) + { + size = positionAbs.Height/2f; + } + if(!isVertical && 2f * size > positionAbs.Width) + { + size = positionAbs.Width/2f; + } + SizeF sizeRel = GetRelativeSize(new SizeF(size, size)); + + // Make 3D convertion of the key points + Point3D[] gradientPoints = new Point3D[6]; + gradientPoints[0] = new Point3D( position.Left, position.Top, positionZ + depth ); + gradientPoints[1] = new Point3D( position.Left, position.Bottom, positionZ + depth ); + gradientPoints[2] = new Point3D( position.Right, position.Bottom, positionZ + depth ); + gradientPoints[3] = new Point3D( position.Right, position.Top, positionZ + depth ); + if(isVertical) + { + gradientPoints[4] = new Point3D( position.X + position.Width / 2f, position.Top + sizeRel.Height, positionZ + depth ); + gradientPoints[5] = new Point3D( position.X + position.Width / 2f, position.Bottom - sizeRel.Height, positionZ + depth ); + } + else + { + gradientPoints[4] = new Point3D( position.X + sizeRel.Width, position.Top + position.Height / 2f, positionZ + depth ); + gradientPoints[5] = new Point3D( position.Right - sizeRel.Width, position.Top + position.Height / 2f, positionZ + depth ); + } + + // Tranform cube coordinates + matrix.TransformPoints( gradientPoints ); + + // Convert points to absolute + PointF [] gradientPointsAbs = new PointF[6]; + for(int index = 0; index < gradientPoints.Length; index++) + { + gradientPointsAbs[index] = GetAbsolutePoint(gradientPoints[index].PointF); + } + + + // Draw left/bottom shadow + using(GraphicsPath path = new GraphicsPath()) + { + if(isVertical) + { + path.AddLine(gradientPointsAbs[4], gradientPointsAbs[5]); + path.AddLine(gradientPointsAbs[5], gradientPointsAbs[2]); + path.AddLine(gradientPointsAbs[2], gradientPointsAbs[3]); + } + else + { + path.AddLine(gradientPointsAbs[4], gradientPointsAbs[5]); + path.AddLine(gradientPointsAbs[5], gradientPointsAbs[2]); + path.AddLine(gradientPointsAbs[2], gradientPointsAbs[1]); + } + path.CloseAllFigures(); + + // Create brush and fill path + using(SolidBrush brush = new SolidBrush(Color.FromArgb(90, Color.Black))) + { + this.FillPath(brush, path); + } + } + + // Draw top/right triangle + using(GraphicsPath path = new GraphicsPath()) + { + if(isVertical) + { + path.AddLine(gradientPointsAbs[0], gradientPointsAbs[4]); + path.AddLine(gradientPointsAbs[4], gradientPointsAbs[3]); + } + else + { + path.AddLine(gradientPointsAbs[3], gradientPointsAbs[5]); + path.AddLine(gradientPointsAbs[5], gradientPointsAbs[2]); + } + + // Create brush and fill path + using(SolidBrush brush = new SolidBrush(Color.FromArgb(50, Color.Black))) + { + // Fill shadow path on the left-bottom side of the bar + this.FillPath(brush, path); + + // Draw Lines + using(Pen penDark = new Pen(Color.FromArgb(20, Color.Black), 1)) + { + this.DrawPath(penDark, path); + this.DrawLine( + penDark, + gradientPointsAbs[4], + gradientPointsAbs[5]); + } + + // Draw Lines + using(Pen pen = new Pen(Color.FromArgb(40, Color.White), 1)) + { + this.DrawPath(pen, path); + this.DrawLine( + pen, + gradientPointsAbs[4], + gradientPointsAbs[5]); + } + } + } + + // Draw bottom/left triangle + using(GraphicsPath path = new GraphicsPath()) + { + if(isVertical) + { + path.AddLine(gradientPointsAbs[1], gradientPointsAbs[5]); + path.AddLine(gradientPointsAbs[5], gradientPointsAbs[2]); + } + else + { + path.AddLine(gradientPointsAbs[0], gradientPointsAbs[4]); + path.AddLine(gradientPointsAbs[4], gradientPointsAbs[1]); + } + + // Create brush + using(SolidBrush brush = new SolidBrush(Color.FromArgb(50, Color.Black))) + { + // Fill shadow path on the left-bottom side of the bar + this.FillPath(brush, path); + + // Draw edges + using(Pen penDark = new Pen(Color.FromArgb(20, Color.Black), 1)) + { + this.DrawPath(penDark, path); + } + using(Pen pen = new Pen(Color.FromArgb(40, Color.White), 1)) + { + this.DrawPath(pen, path); + } + } + } + + + } + else if(barDrawingStyle == BarDrawingStyle.LightToDark) + { + // Calculate width of shadows used to create the effect + RectangleF positionAbs = GetAbsoluteRectangle(position); + float shadowSizeAbs = 5f; + if(positionAbs.Width < 6f || positionAbs.Height < 6f) + { + shadowSizeAbs = 2f; + } + else if(positionAbs.Width < 15f || positionAbs.Height < 15f) + { + shadowSizeAbs = 3f; + } + SizeF shadowSizeRel = GetRelativeSize(new SizeF(shadowSizeAbs, shadowSizeAbs)); + + // Calculate gradient position + RectangleF gradientRect = position; + gradientRect.Inflate(-shadowSizeRel.Width, -shadowSizeRel.Height); + if(isVertical) + { + gradientRect.Height = (float)Math.Floor(gradientRect.Height / 3f); + } + else + { + gradientRect.X = gradientRect.Right - (float)Math.Floor(gradientRect.Width / 3f); + gradientRect.Width = (float)Math.Floor(gradientRect.Width / 3f); + } + + + // Top gradient + Point3D[] gradientPoints = new Point3D[4]; + gradientPoints[0] = new Point3D( gradientRect.Left, gradientRect.Top, positionZ + depth ); + gradientPoints[1] = new Point3D( gradientRect.Left, gradientRect.Bottom, positionZ + depth ); + gradientPoints[2] = new Point3D( gradientRect.Right, gradientRect.Bottom, positionZ + depth ); + gradientPoints[3] = new Point3D( gradientRect.Right, gradientRect.Top, positionZ + depth ); + + // Tranform cube coordinates + matrix.TransformPoints( gradientPoints ); + + // Convert points to absolute + PointF [] gradientPointsAbs = new PointF[4]; + for(int index = 0; index < gradientPoints.Length; index++) + { + gradientPointsAbs[index] = GetAbsolutePoint(gradientPoints[index].PointF); + } + + // Create and draw top path + using(GraphicsPath path = new GraphicsPath()) + { + path.AddPolygon(gradientPointsAbs); + RectangleF bounds = path.GetBounds(); + bounds.Width += 1f; + bounds.Height += 1f; + + // Create brush + if(bounds.Width > 0f && bounds.Height > 0f) + { + using(LinearGradientBrush topBrush = new LinearGradientBrush( + bounds, + (!isVertical) ? Color.Transparent : Color.FromArgb(120, Color.White), + (!isVertical) ? Color.FromArgb(120, Color.White) : Color.Transparent, + (isVertical) ? LinearGradientMode.Vertical : LinearGradientMode.Horizontal)) + { + // Fill shadow path on the top side of the bar + this.FillPath(topBrush, path); + } + } + } + + + + // Calculate gradient position for the bottom gradient + gradientRect = position; + gradientRect.Inflate(-shadowSizeRel.Width, -shadowSizeRel.Height); + if(isVertical) + { + gradientRect.Y = gradientRect.Bottom - (float)Math.Floor(gradientRect.Height / 3f); + gradientRect.Height = (float)Math.Floor(gradientRect.Height / 3f); + } + else + { + gradientRect.Width = (float)Math.Floor(gradientRect.Width / 3f); + } + + + // Top gradient + gradientPoints = new Point3D[4]; + gradientPoints[0] = new Point3D( gradientRect.Left, gradientRect.Top, positionZ + depth ); + gradientPoints[1] = new Point3D( gradientRect.Left, gradientRect.Bottom, positionZ + depth ); + gradientPoints[2] = new Point3D( gradientRect.Right, gradientRect.Bottom, positionZ + depth ); + gradientPoints[3] = new Point3D( gradientRect.Right, gradientRect.Top, positionZ + depth ); + + // Tranform cube coordinates + matrix.TransformPoints( gradientPoints ); + + // Convert points to absolute + gradientPointsAbs = new PointF[4]; + for(int index = 0; index < gradientPoints.Length; index++) + { + gradientPointsAbs[index] = GetAbsolutePoint(gradientPoints[index].PointF); + } + + // Create and draw top path + using(GraphicsPath path = new GraphicsPath()) + { + path.AddPolygon(gradientPointsAbs); + RectangleF bounds = path.GetBounds(); + bounds.Width += 1f; + bounds.Height += 1f; + + // Create brush + if(bounds.Width > 0f && bounds.Height > 0f) + { + using(LinearGradientBrush topBrush = new LinearGradientBrush( + bounds, + (isVertical) ? Color.Transparent : Color.FromArgb(80, Color.Black), + (isVertical) ? Color.FromArgb(80, Color.Black) : Color.Transparent, + (isVertical) ? LinearGradientMode.Vertical : LinearGradientMode.Horizontal)) + { + // Fill shadow path on the top side of the bar + this.FillPath(topBrush, path); + } + } + } + + } + else if(barDrawingStyle == BarDrawingStyle.Emboss) + { + // Calculate width of shadows used to create the effect + RectangleF positionAbs = GetAbsoluteRectangle(position); + float shadowSizeAbs = 4f; + if(positionAbs.Width < 6f || positionAbs.Height < 6f) + { + shadowSizeAbs = 2f; + } + else if(positionAbs.Width < 15f || positionAbs.Height < 15f) + { + shadowSizeAbs = 3f; + } + SizeF shadowSizeRel = GetRelativeSize(new SizeF(shadowSizeAbs, shadowSizeAbs)); + + // Left/top Side + Point3D[] gradientPoints = new Point3D[6]; + gradientPoints[0] = new Point3D( position.Left, position.Bottom, positionZ + depth ); + gradientPoints[1] = new Point3D( position.Left, position.Top, positionZ + depth ); + gradientPoints[2] = new Point3D( position.Right, position.Top, positionZ + depth ); + gradientPoints[3] = new Point3D( position.Right - shadowSizeRel.Width, position.Top + shadowSizeRel.Height, positionZ + depth ); + gradientPoints[4] = new Point3D( position.Left + shadowSizeRel.Width, position.Top + shadowSizeRel.Height, positionZ + depth ); + gradientPoints[5] = new Point3D( position.Left + shadowSizeRel.Width, position.Bottom - shadowSizeRel.Height, positionZ + depth ); + + // Tranform cube coordinates + matrix.TransformPoints( gradientPoints ); + + // Convert points to absolute + PointF [] gradientPointsAbs = new PointF[6]; + for(int index = 0; index < gradientPoints.Length; index++) + { + gradientPointsAbs[index] = GetAbsolutePoint(gradientPoints[index].PointF); + } + + // Create and draw left/top path + using(GraphicsPath path = new GraphicsPath()) + { + path.AddPolygon(gradientPointsAbs); + + // Create brush + using(SolidBrush leftTopBrush = new SolidBrush(Color.FromArgb(100, Color.White))) + { + // Fill shadow path on the left-bottom side of the bar + this.FillPath(leftTopBrush, path); + } + } + + // Right/bottom Side + gradientPoints[0] = new Point3D( position.Right, position.Top, positionZ + depth ); + gradientPoints[1] = new Point3D( position.Right, position.Bottom, positionZ + depth ); + gradientPoints[2] = new Point3D( position.Left, position.Bottom, positionZ + depth ); + gradientPoints[3] = new Point3D( position.Left + shadowSizeRel.Width, position.Bottom - shadowSizeRel.Height, positionZ + depth ); + gradientPoints[4] = new Point3D( position.Right - shadowSizeRel.Width, position.Bottom - shadowSizeRel.Height, positionZ + depth ); + gradientPoints[5] = new Point3D( position.Right - shadowSizeRel.Width, position.Top + shadowSizeRel.Height, positionZ + depth ); + + // Tranform cube coordinates + matrix.TransformPoints( gradientPoints ); + + // Convert points to absolute + for(int index = 0; index < gradientPoints.Length; index++) + { + gradientPointsAbs[index] = GetAbsolutePoint(gradientPoints[index].PointF); + } + + // Create and draw left/top path + using(GraphicsPath path = new GraphicsPath()) + { + path.AddPolygon(gradientPointsAbs); + + // Create brush + using(SolidBrush bottomRightBrush = new SolidBrush(Color.FromArgb(80, Color.Black))) + { + // Fill shadow path on the left-bottom side of the bar + this.FillPath(bottomRightBrush, path); + } + } + } + } + + #endregion + + #region 3D markers drawing methods + + /// + /// Draw marker using absolute coordinates of the center. + /// + /// Coordinates transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Z position of the 3D marker center. + /// Coordinates of the center. + /// Marker style. + /// Marker size. + /// Marker color. + /// Marker border color. + /// Marker border size. + /// Marker image name. + /// Marker image transparent color. + /// Marker shadow size. + /// Marker shadow color. + /// Rectangle to which marker image should be scaled. + /// AxisName of operation Drawing, Calculating Path or Both + /// Returns elemnt shape path if operationType parameter is set to ElementPath, otherwise Null. + internal GraphicsPath DrawMarker3D( + Matrix3D matrix, + LightStyle lightStyle, + float positionZ, + PointF point, + MarkerStyle markerStyle, + int markerSize, + Color markerColor, + Color markerBorderColor, + int markerBorderSize, + string markerImage, + Color markerImageTransparentColor, + int shadowSize, + Color shadowColor, + RectangleF imageScaleRect, + DrawingOperationTypes operationType ) + { + ChartGraphics graph = (ChartGraphics)this; + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + //************************************************************ + //** Transform marker position in 3D space + //************************************************************ + // Get projection coordinates + Point3D[] marker3DPosition = new Point3D[1]; + marker3DPosition[0] = new Point3D(point.X, point.Y, positionZ); + + // Transform coordinates of the marker center + matrix.TransformPoints(marker3DPosition); + PointF markerRotatedPosition = marker3DPosition[0].PointF; + + // Translate to absolute coordinates + markerRotatedPosition = graph.GetAbsolutePoint(markerRotatedPosition); + + //************************************************************ + //** For those markers that do not have a 3D version - draw the same as in 2D + //************************************************************ + if(markerImage.Length > 0 || + !(markerStyle == MarkerStyle.Circle || + markerStyle == MarkerStyle.Square) ) + { + // Call 2D version of the method + if( (operationType & DrawingOperationTypes.DrawElement) == DrawingOperationTypes.DrawElement) + { + graph.DrawMarkerAbs(markerRotatedPosition, markerStyle, markerSize, markerColor, markerBorderColor, markerBorderSize, markerImage, markerImageTransparentColor, shadowSize, shadowColor, imageScaleRect, false); + } + + // Prepare marker path + if( (operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + { + RectangleF rect = RectangleF.Empty; + rect.X = markerRotatedPosition.X - ((float)markerSize)/2F; + rect.Y = markerRotatedPosition.Y - ((float)markerSize)/2F; + rect.Width = markerSize; + rect.Height = markerSize; + resultPath.AddRectangle(rect); + } + + return resultPath; + } + + //************************************************************ + //** Draw marker + //************************************************************ + // Check if marker properties are set + if (markerStyle != MarkerStyle.None && markerSize > 0 && markerColor != Color.Empty) + { + // Create solid color brush + using (SolidBrush brush = new SolidBrush(markerColor)) + { + + // Calculate marker rectangle + RectangleF rect = RectangleF.Empty; + rect.X = markerRotatedPosition.X - ((float)markerSize) / 2F; + rect.Y = markerRotatedPosition.Y - ((float)markerSize) / 2F; + rect.Width = markerSize; + rect.Height = markerSize; + + // Calculate relative marker size + SizeF markerRelativeSize = graph.GetRelativeSize(new SizeF(markerSize, markerSize)); + + // Draw marker depending on style + switch (markerStyle) + { + case (MarkerStyle.Circle): + { + if ((operationType & DrawingOperationTypes.DrawElement) == DrawingOperationTypes.DrawElement) + { + // Draw marker shadow + if (shadowSize != 0 && shadowColor != Color.Empty) + { + if (!graph.softShadows) + { + using (Brush shadowBrush = new SolidBrush((shadowColor.A != 255) ? shadowColor : Color.FromArgb(markerColor.A / 2, shadowColor))) + { + RectangleF shadowRect = rect; + shadowRect.X += shadowSize; + shadowRect.Y += shadowSize; + graph.FillEllipse(shadowBrush, shadowRect); + } + } + else + { + // Add circle to the graphics path + using (GraphicsPath path = new GraphicsPath()) + { + path.AddEllipse(rect.X + shadowSize - 1, rect.Y + shadowSize - 1, rect.Width + 2, rect.Height + 2); + + // Create path brush + using (PathGradientBrush shadowBrush = new PathGradientBrush(path)) + { + shadowBrush.CenterColor = shadowColor; + + // Set the color along the entire boundary of the path + Color[] colors = { Color.Transparent }; + shadowBrush.SurroundColors = colors; + shadowBrush.CenterPoint = new PointF(markerRotatedPosition.X, markerRotatedPosition.Y); + + // Define brush focus scale + PointF focusScale = new PointF(1 - 2f * shadowSize / rect.Width, 1 - 2f * shadowSize / rect.Height); + if (focusScale.X < 0) + { + focusScale.X = 0; + } + if (focusScale.Y < 0) + { + focusScale.Y = 0; + } + shadowBrush.FocusScales = focusScale; + + // Draw shadow + graph.FillPath(shadowBrush, path); + } + } + } + } + + // Create path gradient brush + using (GraphicsPath brushPath = new GraphicsPath()) + { + RectangleF rectLightCenter = new RectangleF(rect.Location, rect.Size); + rectLightCenter.Inflate(rectLightCenter.Width / 4f, rectLightCenter.Height / 4f); + brushPath.AddEllipse(rectLightCenter); + using (PathGradientBrush circleBrush = new PathGradientBrush(brushPath)) + { + circleBrush.CenterColor = ChartGraphics.GetGradientColor(markerColor, Color.White, 0.85); + circleBrush.SurroundColors = new Color[] { markerColor }; + + // Calculate the center point of the gradient + Point3D[] centerPoint = new Point3D[] { new Point3D(point.X, point.Y, positionZ + markerRelativeSize.Width) }; + matrix.TransformPoints(centerPoint); + centerPoint[0].PointF = graph.GetAbsolutePoint(centerPoint[0].PointF); + circleBrush.CenterPoint = centerPoint[0].PointF; + + // Draw circle (sphere) + graph.FillEllipse(circleBrush, rect); + graph.DrawEllipse(new Pen(markerBorderColor, markerBorderSize), rect); + } + } + } + + // Prepare marker path + if ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + { + resultPath.AddEllipse(rect); + } + + break; + } + case (MarkerStyle.Square): + { + + // Calculate marker non-rotated rectangle + RectangleF rectNonRotated = RectangleF.Empty; + rectNonRotated.X = point.X - ((float)markerRelativeSize.Width) / 2F; + rectNonRotated.Y = point.Y - ((float)markerRelativeSize.Height) / 2F; + rectNonRotated.Width = markerRelativeSize.Width; + rectNonRotated.Height = markerRelativeSize.Height; + + // Draw 3D bar + resultPath = this.Fill3DRectangle( + rectNonRotated, + positionZ - markerRelativeSize.Width / 2f, + markerRelativeSize.Width, + matrix, + lightStyle, + markerColor, + markerBorderColor, + markerBorderSize, + ChartDashStyle.Solid, + operationType); + + break; + } + default: + { + throw (new InvalidOperationException(SR.ExceptionGraphics3DMarkerStyleUnknown)); + } + } + } + } + + return resultPath; + } + + #endregion + + #region 3D cube surface visibility methods + + /// + /// Returns visible surfaces of the 3D cube. + /// + /// 2D rectangle coordinates. + /// Z coordinate of the back side of the cube. + /// Cube depth. + /// Coordinate transformation matrix. + /// Visible surfaces. + internal SurfaceNames GetVisibleSurfaces( + RectangleF position, + float positionZ, + float depth, + Matrix3D matrix + ) + { + // Check if perspective is used + if(matrix.Perspective != 0) + { + // More sofisticated algorithm must be used for visibility detection. + return GetVisibleSurfacesWithPerspective(position, positionZ, depth, matrix); + } + + // Front surface is always visible + SurfaceNames result = SurfaceNames.Front; + + // Left and Right surfaces depend on the Y axis angle + if (matrix.AngleY > 0) + { + result |= SurfaceNames.Right; + } + else if (matrix.AngleY < 0) + { + result |= SurfaceNames.Left; + } + + // Top and Bottom surfaces depend on the X axis angle + if (matrix.AngleX > 0) + { + result |= SurfaceNames.Top; + } + else if (matrix.AngleX < 0) + { + result |= SurfaceNames.Bottom; + } + + return result; + } + + /// + /// Returns visible surfaces of the 3D cube. + /// This method takes in consideration the perspective. + /// + /// 2D rectangle coordinates. + /// Z coordinate of the back side of the cube. + /// Cube depth. + /// Coordinate transformation matrix. + /// Visible surfaces. + internal SurfaceNames GetVisibleSurfacesWithPerspective( + RectangleF position, + float positionZ, + float depth, + Matrix3D matrix) + { + // Create cube coordinates in 3D space + Point3D[] cubePoints = new Point3D[8]; + + // Front Side + cubePoints[0] = new Point3D( position.X, position.Y, positionZ + depth ); + cubePoints[1] = new Point3D( position.X, position.Bottom, positionZ + depth ); + cubePoints[2] = new Point3D( position.Right, position.Bottom, positionZ + depth ); + cubePoints[3] = new Point3D( position.Right, position.Y, positionZ + depth ); + + // Back Side + cubePoints[4] = new Point3D( position.X, position.Y, positionZ ); + cubePoints[5] = new Point3D( position.X, position.Bottom, positionZ ); + cubePoints[6] = new Point3D( position.Right, position.Bottom, positionZ ); + cubePoints[7] = new Point3D( position.Right, position.Y, positionZ ); + + // Tranform coordinates + matrix.TransformPoints( cubePoints ); + + // Detect surfaces visibility + return GetVisibleSurfacesWithPerspective(cubePoints); + } + + /// + /// Returns visible surfaces of the 3D cube. + /// This method takes in consideration the perspective. + /// + /// Array of 8 points which define the cube. + /// Visible surfaces. + internal SurfaceNames GetVisibleSurfacesWithPerspective(Point3D[] cubePoints) + { + // Check imput array size + if(cubePoints.Length != 8) + { + throw (new ArgumentException(SR.ExceptionGraphics3DCoordinatesInvalid, "cubePoints")); + } + + // Detect surfaces visibility + SurfaceNames result = 0; + + // Check the front side + if(IsSurfaceVisible(cubePoints[0],cubePoints[3],cubePoints[2])) + { + result |= SurfaceNames.Front; + } + // Check the back side + if(IsSurfaceVisible(cubePoints[4],cubePoints[5],cubePoints[6])) + { + result |= SurfaceNames.Back; + } + + // Check the left side + if(IsSurfaceVisible(cubePoints[0],cubePoints[1],cubePoints[5])) + { + result |= SurfaceNames.Left; + } + + // Check the right side + if(IsSurfaceVisible(cubePoints[3],cubePoints[7],cubePoints[6])) + { + result |= SurfaceNames.Right; + } + + // Check the top side + if(IsSurfaceVisible(cubePoints[4],cubePoints[7],cubePoints[3])) + { + result |= SurfaceNames.Top; + } + + // Check the bottom side + if(IsSurfaceVisible(cubePoints[1],cubePoints[2],cubePoints[6])) + { + result |= SurfaceNames.Bottom; + } + + return result; + } + + /// + /// Checks surface visibility using 3 points and clockwise points index rotation. + /// + /// First point. + /// Second point. + /// Third point. + /// True if surface is visible + internal static bool IsSurfaceVisible( Point3D first, Point3D second, Point3D tree ) + { + // Check if points are oriented clocwise in 2D projection. + // If points are clockwise the surface is visible. + float a = ( first.Y - second.Y ) / ( first.X - second.X ); + float b = first.Y - a * first.X; + if( first.X == second.X ) + { + if( first.Y > second.Y ) + { + if( tree.X > first.X ) + { + return true; + } + else + { + return false; + } + } + else + { + if( tree.X > first.X ) + { + return false; + } + else + { + return true; + } + } + } + else if ( first.X < second.X ) + { + if( tree.Y < a * tree.X + b ) + { + return false; + } + else + { + return true; + } + } + else + { + if( tree.Y <= a * tree.X + b ) + { + return true; + } + else + { + return false; + } + } + } + + #endregion + + #region Line intersection helper method + + /// + /// Gets intersection point of two lines + /// + /// First X value of first line. + /// First Y value of first line. + /// Second X value of first line. + /// Second Y value of first line. + /// First X value of second line. + /// First Y value of second line. + /// Second X value of second line. + /// Second Y value of second line. + /// Intersection coordinates. + internal static PointF GetLinesIntersection(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) + { + PointF result = PointF.Empty; + + // Special case for horizontal & vertical lines + if(x1 == x2 && y3 == y4) + { + result.X = x1; + result.Y = y3; + return result; + } + else if(y1 == y2 && x3 == x4) + { + result.X = x3; + result.Y = y1; + return result; + } + else if(x1 == x2) + { + result.X = x1; + result.Y = (result.X - x3) * (y4 - y3); + result.Y /= x4 - x3; + result.Y += y3; + return result; + } + else if(x3 == x4) + { + result.X = x3; + result.Y = (result.X - x1) * (y2 - y1); + result.Y /= x2 - x1; + result.Y += y1; + return result; + } + + // Calculate line eqaution + float a1 = ( y1 - y2 ) / ( x1 - x2 ); + float b1 = y1 - a1 * x1; + float a2 = ( y3 - y4 ) / ( x3 - x4 ); + float b2 = y3 - a2 * x3; + + // Calculate intersection point + result.X = (b2 - b1)/(a1 - a2); + result.Y = a1*result.X + b1; + + return result; + } + + #endregion + + #region 3D Cylinder drawing methods + + + /// + /// Function is used to calculate the coordinates of the 2D rectangle in 3D space + /// and either draw it or/and calculate the bounding path for selection. + /// + /// Position of 2D rectangle. + /// Z position of the back side of the 3D rectangle. + /// Depth of the 3D rectangle. + /// Coordinate transformation matrix. + /// LightStyle style (None, Simplistic, Realistic). + /// Color of rectangle + /// Top (or right in bar chart) darkening effect. + /// Bottom (or left in bar chart) darkening effect. + /// Border Color + /// Border Width + /// Border Style + /// Defines if bar is vertical or horizontal. + /// AxisName of operation Drawing, Calculating Path or Both + /// Returns elemnt shape path if operationType parameter is set to CalcElementPath, otherwise Null. + internal GraphicsPath Fill3DRectangleAsCylinder( + RectangleF position, + float positionZ, + float depth, + Matrix3D matrix, + LightStyle lightStyle, + Color backColor, + float topRightDarkening, + float bottomLeftDarkening, + Color borderColor, + int borderWidth, + ChartDashStyle borderDashStyle, + bool veticalOrientation, + DrawingOperationTypes operationType) + { + Point3D[] cubePoints = new Point3D[8]; + GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + ? new GraphicsPath() : null; + + //******************************************************* + //** Define coordinates to draw the cylinder + //******************************************************* + if(veticalOrientation) + { + cubePoints[0] = new Point3D( position.X, position.Y, positionZ + depth / 2f ); + cubePoints[1] = new Point3D( position.X, position.Bottom, positionZ + depth / 2f ); + cubePoints[2] = new Point3D( position.Right, position.Bottom, positionZ + depth / 2f ); + cubePoints[3] = new Point3D( position.Right, position.Y, positionZ + depth / 2f ); + + float middleXValue = position.X + position.Width / 2f; + cubePoints[4] = new Point3D( middleXValue, position.Y, positionZ + depth ); + cubePoints[5] = new Point3D( middleXValue, position.Bottom, positionZ + depth ); + cubePoints[6] = new Point3D( middleXValue, position.Bottom, positionZ ); + cubePoints[7] = new Point3D( middleXValue, position.Y, positionZ ); + } + else + { + cubePoints[0] = new Point3D( position.Right, position.Y, positionZ + depth / 2f ); + cubePoints[1] = new Point3D( position.X, position.Y, positionZ + depth / 2f ); + cubePoints[2] = new Point3D( position.X, position.Bottom, positionZ + depth / 2f ); + cubePoints[3] = new Point3D( position.Right, position.Bottom, positionZ + depth / 2f ); + + float middleYValue = position.Y + position.Height / 2f; + cubePoints[4] = new Point3D( position.Right, middleYValue, positionZ + depth ); + cubePoints[5] = new Point3D( position.X, middleYValue, positionZ + depth ); + cubePoints[6] = new Point3D( position.X, middleYValue, positionZ ); + cubePoints[7] = new Point3D( position.Right, middleYValue, positionZ ); + } + + // Tranform cylinder coordinates + matrix.TransformPoints( cubePoints ); + + // Covert coordinates to absolute + for(int pointIndex = 0; pointIndex < cubePoints.Length; pointIndex++) + { + cubePoints[pointIndex].PointF = GetAbsolutePoint(cubePoints[pointIndex].PointF); + } + + //******************************************************* + //** Get cylinder colors. + //******************************************************* + if( lightStyle == LightStyle.None && + (borderWidth == 0 || borderDashStyle == ChartDashStyle.NotSet || borderColor == Color.Empty) ) + { + borderColor = ChartGraphics.GetGradientColor( backColor, Color.Black, 0.5 ); + } + + // Get surface colors + Color frontLightColor, leftLightColor, topLightColor, backLightColor, rightLightColor, bottomLightColor; + matrix.GetLight( backColor, out frontLightColor, out backLightColor, out leftLightColor, out rightLightColor, out topLightColor, out bottomLightColor ); + + // Darken colors by specified values + if(topRightDarkening != 0f) + { + if(veticalOrientation) + { + topLightColor = ChartGraphics.GetGradientColor(topLightColor, Color.Black, topRightDarkening); + } + else + { + rightLightColor = ChartGraphics.GetGradientColor(rightLightColor, Color.Black, topRightDarkening); + } + } + if(bottomLeftDarkening != 0f) + { + if(veticalOrientation) + { + bottomLightColor = ChartGraphics.GetGradientColor(bottomLightColor, Color.Black, bottomLeftDarkening); + } + else + { + leftLightColor = ChartGraphics.GetGradientColor(leftLightColor, Color.Black, bottomLeftDarkening); + } + } + + //******************************************************* + //** Check visible surfaces + //******************************************************* + SurfaceNames visibleSurfaces = GetVisibleSurfacesWithPerspective(position,positionZ,depth,matrix); + + // Front surface is always visible in cylinder + if( (visibleSurfaces & SurfaceNames.Front) != SurfaceNames.Front) + { + visibleSurfaces |= SurfaceNames.Front; + } + + //******************************************************* + //** Create flattened paths for the sides of the + //** cylinder (top,bottom/left,rigth) + //******************************************************* + PointF[] sidePoints = new PointF[4]; + sidePoints[0] = cubePoints[6].PointF; + sidePoints[1] = cubePoints[1].PointF; + sidePoints[2] = cubePoints[5].PointF; + sidePoints[3] = cubePoints[2].PointF; + GraphicsPath bottomLeftSide = new GraphicsPath(); + bottomLeftSide.AddClosedCurve(sidePoints, 0.8f); + bottomLeftSide.Flatten(); + sidePoints[0] = cubePoints[7].PointF; + sidePoints[1] = cubePoints[0].PointF; + sidePoints[2] = cubePoints[4].PointF; + sidePoints[3] = cubePoints[3].PointF; + GraphicsPath topRigthSide = new GraphicsPath(); + topRigthSide.AddClosedCurve(sidePoints, 0.8f); + topRigthSide.Flatten(); + + //******************************************************* + //** Find cylinder angle + //******************************************************* + float cylinderAngle = 90f; + if(cubePoints[5].PointF.Y != cubePoints[4].PointF.Y) + { + cylinderAngle = (float)Math.Atan( + (cubePoints[4].PointF.X - cubePoints[5].PointF.X) / + (cubePoints[5].PointF.Y - cubePoints[4].PointF.Y) ); + cylinderAngle = (float)Math.Round(cylinderAngle * 180f / (float)Math.PI); + } + + //******************************************************* + //** Draw all invisible surfaces first (if semi-transparent color is used) + //******************************************************* + for(int drawVisible = 0; drawVisible <= 1; drawVisible++) + { + // Do not draw invisible surfaces for solid colors + if(drawVisible == 0 && backColor.A == 255) + { + continue; + } + + // Check visibility of all surfaces and draw them + for(int surfaceIndex = (int)SurfaceNames.Front; surfaceIndex <= (int)SurfaceNames.Bottom; surfaceIndex *= 2) + { + SurfaceNames currentSurface = (SurfaceNames)surfaceIndex; + + // Check if surface is visible or semi-transparent color is used + bool isVisible = (visibleSurfaces & currentSurface) != 0; + if(isVisible && drawVisible == 1 || + !isVisible && drawVisible == 0) + { + // Fill surface coordinates and color + GraphicsPath pathToDraw = null; + Color surfaceColor = backColor; + + // Declare a special brush for the front surface + Brush frontSurfaceBrush = null; + + switch(currentSurface) + { + case(SurfaceNames.Front): + { + // Set front surface color + surfaceColor = backColor; + + // Add ellipse segment of the cylinder on top/rigth (reversed) + pathToDraw = new GraphicsPath(); + PointF leftSideLinePoint = PointF.Empty; + PointF rightSideLinePoint = PointF.Empty; + AddEllipseSegment( + pathToDraw, + topRigthSide, + bottomLeftSide, + (matrix.Perspective == 0) ? veticalOrientation : false, + cylinderAngle, + out leftSideLinePoint, + out rightSideLinePoint); + pathToDraw.Reverse(); + + // Add ellipse segment of the cylinder on bottom/left + PointF leftOppSideLinePoint = PointF.Empty; + PointF rightOppSideLinePoint = PointF.Empty; + AddEllipseSegment( + pathToDraw, + bottomLeftSide, + topRigthSide, + (matrix.Perspective == 0) ? veticalOrientation : false, + cylinderAngle, + out leftOppSideLinePoint, + out rightOppSideLinePoint); + pathToDraw.CloseAllFigures(); + + // Reset indexes of opposite side points + this._oppLeftBottomPoint = -1; + this._oppRigthTopPoint = -1; + + // Create gradient brush for the front surface + if(lightStyle != LightStyle.None) + { + RectangleF boundsRect = pathToDraw.GetBounds(); + if(boundsRect.Height > 0 && boundsRect.Width > 0) + { + Color lightColor = ChartGraphics.GetGradientColor( backColor, Color.White, 0.3 ); + Color darkColor = ChartGraphics.GetGradientColor( backColor, Color.Black, 0.3 ); + + // Create gradient + if(!leftSideLinePoint.IsEmpty && + !rightSideLinePoint.IsEmpty && + !leftOppSideLinePoint.IsEmpty && + !rightOppSideLinePoint.IsEmpty) + { + PointF boundsRectMiddlePoint = PointF.Empty; + boundsRectMiddlePoint.X = boundsRect.X + boundsRect.Width/2f; + boundsRectMiddlePoint.Y = boundsRect.Y + boundsRect.Height/2f; + + PointF centralLinePoint = PointF.Empty; + double centralLineAngle = ((cylinderAngle) * Math.PI / 180f); + if(cylinderAngle == 0 || cylinderAngle == 180 || cylinderAngle == -180) + { + centralLinePoint.X = boundsRectMiddlePoint.X + 100f; + centralLinePoint.Y = boundsRectMiddlePoint.Y; + } + else if(cylinderAngle == 90 || cylinderAngle == -90) + { + centralLinePoint.X = boundsRectMiddlePoint.X; + centralLinePoint.Y = boundsRectMiddlePoint.Y + 100f; + } + else if(cylinderAngle > -45 && cylinderAngle < 45) + { + centralLinePoint.X = boundsRectMiddlePoint.X + 100f; + centralLinePoint.Y = (float)(Math.Tan(centralLineAngle) * centralLinePoint.X); + centralLinePoint.Y += (float)(boundsRectMiddlePoint.Y - Math.Tan(centralLineAngle) * boundsRectMiddlePoint.X); + } + else + { + centralLinePoint.Y = boundsRectMiddlePoint.Y + 100f; + centralLinePoint.X = (float)(centralLinePoint.Y - (boundsRectMiddlePoint.Y - Math.Tan(centralLineAngle) * boundsRectMiddlePoint.X)); + centralLinePoint.X /= (float)(Math.Tan(centralLineAngle)); + } + + + PointF middlePoint1 = ChartGraphics.GetLinesIntersection( + boundsRectMiddlePoint.X, boundsRectMiddlePoint.Y, + centralLinePoint.X, centralLinePoint.Y, + leftSideLinePoint.X, leftSideLinePoint.Y, + leftOppSideLinePoint.X, leftOppSideLinePoint.Y); + + PointF middlePoint2 = ChartGraphics.GetLinesIntersection( + boundsRectMiddlePoint.X, boundsRectMiddlePoint.Y, + centralLinePoint.X, centralLinePoint.Y, + rightSideLinePoint.X, rightSideLinePoint.Y, + rightOppSideLinePoint.X, rightOppSideLinePoint.Y); + + // Gradient points can not have same coordinates + if(middlePoint1.X != middlePoint2.X || middlePoint1.Y != middlePoint2.Y) + { + frontSurfaceBrush = new LinearGradientBrush( + middlePoint1, + middlePoint2, + lightColor, + darkColor); + + + ColorBlend colorBlend = new ColorBlend(5); + colorBlend.Colors[0] = darkColor; + colorBlend.Colors[1] = darkColor; + colorBlend.Colors[2] = lightColor; + colorBlend.Colors[3] = darkColor; + colorBlend.Colors[4] = darkColor; + + colorBlend.Positions[0] = 0.0f; + colorBlend.Positions[1] = 0.0f; + colorBlend.Positions[2] = 0.5f; + colorBlend.Positions[3] = 1.0f; + colorBlend.Positions[4] = 1.0f; + + ((LinearGradientBrush)frontSurfaceBrush).InterpolationColors = colorBlend; + } + } + + } + } + + break; + } + case(SurfaceNames.Top): + if(veticalOrientation) + { + surfaceColor = topLightColor; + pathToDraw = topRigthSide; + } + break; + case(SurfaceNames.Bottom): + if(veticalOrientation) + { + surfaceColor = bottomLightColor; + pathToDraw = bottomLeftSide; + } + break; + case(SurfaceNames.Right): + if(!veticalOrientation) + { + surfaceColor = rightLightColor; + pathToDraw = topRigthSide; + } + break; + case(SurfaceNames.Left): + if(!veticalOrientation) + { + surfaceColor = leftLightColor; + pathToDraw = bottomLeftSide; + } + break; + } + + + //******************************************************* + //** Draw surface + //******************************************************* + if(pathToDraw != null) + { + if( (operationType & DrawingOperationTypes.DrawElement) == DrawingOperationTypes.DrawElement) + { + // Draw only completly visible surfaces + if((visibleSurfaces & currentSurface) != 0) + { + using (Brush brush = new SolidBrush(surfaceColor)) + { + FillPath( (frontSurfaceBrush == null) ? brush : frontSurfaceBrush, pathToDraw ); + } + } + + // Draw surface border + using (Pen pen = new Pen(borderColor, borderWidth)) + { + pen.DashStyle = GetPenStyle(borderDashStyle); + if (lightStyle != LightStyle.None && + (borderWidth == 0 || borderDashStyle == ChartDashStyle.NotSet || borderColor == Color.Empty)) + { + // Draw line of the darker color inside the cylinder + pen.Color = frontSurfaceBrush == null ? surfaceColor : ChartGraphics.GetGradientColor(backColor, Color.Black, 0.3); + pen.Width = 1; + pen.Alignment = PenAlignment.Inset; + } + + pen.StartCap = LineCap.Round; + pen.EndCap = LineCap.Round; + pen.LineJoin = LineJoin.Bevel; + DrawPath(pen, pathToDraw); + } + } + + // Add surface coordinate to the path + if( (operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) + { + // Only if surface is completly visible + if((visibleSurfaces & currentSurface) != 0) + { + if(pathToDraw != null && pathToDraw.PointCount > 0) + { + resultPath.AddPath(pathToDraw, true); + resultPath.SetMarkers(); + } + } + } + } + + } + } + } + + return resultPath; + } + + /// + /// Adds segment of the ellipse to form the front surface of the cylinder + /// + internal void AddEllipseSegment( + GraphicsPath resultPath, + GraphicsPath ellipseFlattenPath, + GraphicsPath oppositeEllipseFlattenPath, + bool veticalOrientation, + float cylinderAngle, + out PointF leftSideLinePoint, + out PointF rightSideLinePoint) + { + // Initialize return values + leftSideLinePoint = PointF.Empty; + rightSideLinePoint = PointF.Empty; + + // Check if input path is empty + if(ellipseFlattenPath.PointCount == 0) + { + return; + } + + // Find the index the left/bottom most and right/top most point in flatten array of ellipse points + int leftBottomPoint = 0; + int rigthTopPoint = 0; + PointF[] ellipsePoints = ellipseFlattenPath.PathPoints; + + + if(veticalOrientation) + { + for(int pointIndex = 1; pointIndex < ellipsePoints.Length; pointIndex++) + { + if(ellipsePoints[leftBottomPoint].X > ellipsePoints[pointIndex].X) + { + leftBottomPoint = pointIndex; + } + if(ellipsePoints[rigthTopPoint].X < ellipsePoints[pointIndex].X) + { + rigthTopPoint = pointIndex; + } + } + } + else + { + bool doneFlag = false; + leftBottomPoint = -1; + rigthTopPoint = -1; + + if(this._oppLeftBottomPoint != -1 && this._oppRigthTopPoint != -1) + { + // Get index from previously calculated values + leftBottomPoint = this._oppLeftBottomPoint; + rigthTopPoint = this._oppRigthTopPoint; + } + else + { + // Loop through first ellipse points + PointF[] oppositeEllipsePoints = oppositeEllipseFlattenPath.PathPoints; + for(int pointIndex = 0; !doneFlag && pointIndex < ellipsePoints.Length; pointIndex++) + { + // Loop through opposite ellipse points + for(int pointOppositeIndex = 0; !doneFlag && pointOppositeIndex < oppositeEllipsePoints.Length; pointOppositeIndex++) + { + bool closeToVertical = false; + bool pointsOnLeft = false; + bool pointsOnRight = false; + + //if(cylinderAngle == 0 || cylinderAngle == 180 || cylinderAngle == -180) + if(cylinderAngle > -30 && cylinderAngle < 30) + { + closeToVertical = true; + } + + if(closeToVertical) + { + if(oppositeEllipsePoints[pointOppositeIndex].Y == ellipsePoints[pointIndex].Y) + { + continue; + } + + float linePointX = oppositeEllipsePoints[pointOppositeIndex].X - ellipsePoints[pointIndex].X; + linePointX /= oppositeEllipsePoints[pointOppositeIndex].Y - ellipsePoints[pointIndex].Y; + + // Check if this line has any points to the right/left + for(int innerPointIndex = 0; innerPointIndex < ellipsePoints.Length; innerPointIndex++) + { + // Skip points used to define line function + if(innerPointIndex == pointIndex) + { + continue; + } + + float x = linePointX; + x *= ellipsePoints[innerPointIndex].Y - ellipsePoints[pointIndex].Y; + x += ellipsePoints[pointIndex].X; + + if(x > ellipsePoints[innerPointIndex].X) + { + pointsOnLeft = true; + } + if(x < ellipsePoints[innerPointIndex].X) + { + pointsOnRight = true; + } + if(pointsOnLeft && pointsOnRight) + { + break; + } + } + + if(pointsOnLeft == false || pointsOnRight == false) + { + for(int innerPointIndex = 0; innerPointIndex < oppositeEllipsePoints.Length; innerPointIndex++) + { + // Skip points used to define line function + if(innerPointIndex == pointOppositeIndex) + { + continue; + } + + float x = linePointX; + x *= oppositeEllipsePoints[innerPointIndex].Y - ellipsePoints[pointIndex].Y; + x += ellipsePoints[pointIndex].X; + + if(x > oppositeEllipsePoints[innerPointIndex].X) + { + pointsOnLeft = true; + } + if(x < oppositeEllipsePoints[innerPointIndex].X) + { + pointsOnRight = true; + } + if(pointsOnLeft && pointsOnRight) + { + break; + } + } + } + } + else + { + if(oppositeEllipsePoints[pointOppositeIndex].X == ellipsePoints[pointIndex].X) + { + continue; + } + + float linePointY = oppositeEllipsePoints[pointOppositeIndex].Y - ellipsePoints[pointIndex].Y; + linePointY /= oppositeEllipsePoints[pointOppositeIndex].X - ellipsePoints[pointIndex].X; + + // Check if this line has any points to the right/left + for(int innerPointIndex = 0; innerPointIndex < ellipsePoints.Length; innerPointIndex++) + { + // Skip points used to define line function + if(innerPointIndex == pointIndex) + { + continue; + } + + float y = linePointY; + y *= ellipsePoints[innerPointIndex].X - ellipsePoints[pointIndex].X; + y += ellipsePoints[pointIndex].Y; + + if(y > ellipsePoints[innerPointIndex].Y) + { + pointsOnLeft = true; + } + if(y < ellipsePoints[innerPointIndex].Y) + { + pointsOnRight = true; + } + if(pointsOnLeft && pointsOnRight) + { + break; + } + } + + if(pointsOnLeft == false || pointsOnRight == false) + { + for(int innerPointIndex = 0; innerPointIndex < oppositeEllipsePoints.Length; innerPointIndex++) + { + // Skip points used to define line function + if(innerPointIndex == pointOppositeIndex) + { + continue; + } + + float y = linePointY; + y *= oppositeEllipsePoints[innerPointIndex].X - ellipsePoints[pointIndex].X; + y += ellipsePoints[pointIndex].Y; + + if(y > oppositeEllipsePoints[innerPointIndex].Y) + { + pointsOnLeft = true; + } + if(y < oppositeEllipsePoints[innerPointIndex].Y) + { + pointsOnRight = true; + } + if(pointsOnLeft && pointsOnRight) + { + break; + } + } + } + } + + if(!pointsOnLeft && leftBottomPoint == -1) + { + leftBottomPoint = pointIndex; + this._oppLeftBottomPoint = pointOppositeIndex; + } + if(!pointsOnRight && rigthTopPoint == -1) + { + rigthTopPoint = pointIndex; + this._oppRigthTopPoint = pointOppositeIndex; + } + + if(leftBottomPoint >= 0 && rigthTopPoint >= 0) + { + doneFlag = true; + + if(closeToVertical) + { + if(ellipsePoints[leftBottomPoint].Y > oppositeEllipsePoints[this._oppLeftBottomPoint].Y) + { + int temp = leftBottomPoint; + leftBottomPoint = rigthTopPoint; + rigthTopPoint = temp; + + temp = this._oppLeftBottomPoint; + this._oppLeftBottomPoint = this._oppRigthTopPoint; + this._oppRigthTopPoint = temp; + } + } + + } + } + } + } + } + + // Point indexes were not found + if(leftBottomPoint == rigthTopPoint || + rigthTopPoint == -1 || + leftBottomPoint == -1) + { + return; + } + + // Set left\right line coordinates + leftSideLinePoint = ellipsePoints[leftBottomPoint]; + rightSideLinePoint = ellipsePoints[rigthTopPoint]; + + // Add required ellipse segment to the result path + for(int pointIndex = leftBottomPoint + 1; pointIndex != rigthTopPoint + 1; pointIndex++) + { + if(pointIndex > ellipsePoints.Length - 1) + { + resultPath.AddLine(ellipsePoints[ellipsePoints.Length - 1], ellipsePoints[0]); + pointIndex = 0; + continue; + } + resultPath.AddLine(ellipsePoints[pointIndex - 1], ellipsePoints[pointIndex]); + } + } + + #endregion + } + + /// + /// The Point3D class represents point coordinates in 3D space. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class Point3D + { + #region Fields + + // Point X and Y coordinates + private PointF _coordXY = new PointF(0f, 0f); + + // Point Z coordinate (depth) + private float _coordZ = 0; + + #endregion + + #region Properties + + /// + /// Gets or sets the X coordinate of the point. + /// + [ + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributePoint3D_X") + ] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "X")] + public float X + { + get + { + return this._coordXY.X; + } + set + { + this._coordXY.X = value; + } + } + + /// + /// Gets or sets the Y coordinate of the point. + /// + [ + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributePoint3D_Y") + ] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Y")] + public float Y + { + get + { + return this._coordXY.Y; + } + set + { + this._coordXY.Y = value; + } + } + + /// + /// Gets or sets the Z coordinate of the point. + /// + [ + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributePoint3D_Z") + ] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Z")] + public float Z + { + get + { + return this._coordZ; + } + set + { + this._coordZ = value; + } + } + + /// + /// Gets or sets a PointF structure, which stores the X and Y coordinates of a 3D point. + /// + [ + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributePoint3D_PointF") + ] + public PointF PointF + { + get + { + return this._coordXY; + } + set + { + this._coordXY = new PointF(value.X, value.Y); + } + } + + #endregion + + #region Constructors + + /// + /// Public constructor. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X, Y and Z are cartesian coordinates and well understood")] + public Point3D(float x, float y, float z) + { + this._coordXY = new PointF(x, y); + this._coordZ = z; + } + + /// + /// Public constructor. + /// + public Point3D( ) + { + + } + + #endregion // Constructor + } +} diff --git a/System.Web.DataVisualization/Common/General/ChartRenderingEngine.cs b/System.Web.DataVisualization/Common/General/ChartRenderingEngine.cs new file mode 100644 index 000000000..37bbcf168 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ChartRenderingEngine.cs @@ -0,0 +1,853 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartRenderingEngine.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ChartRenderingEngine, ValueA, PointA, RectangleA, +// ColorA +// +// Purpose: ChartRenderingEngine class provides a common interface +// to the graphics rendering and animation engines. +// Internally it uses SvgChartGraphics, FlashGraphics or +// GdiGraphics classes depending on the ActiveRenderingType +// property settings. +// +// ValueA, PointA, RectangleA and ColorA classes are +// used to store data about animated values like colors +// position or rectangles. They store starting value/time, +// end value/time, repeat flags and other settings. These +// clases are used with animation engines. +// +// Reviwed: AG - Jul 15, 2003 +// AG - Microsoft 16, 2007 +// +//=================================================================== + + +#region Used namespaces + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Drawing.Imaging; +using System.ComponentModel; +using System.Collections; +using System.Xml; +using System.IO; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL + +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else +using System.Web.UI.DataVisualization.Charting.Utilities; +using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Enumerations + + /// + /// Specify Rendering AxisName + /// + internal enum RenderingType + { + /// + /// GDI+ AxisName + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gdi")] + Gdi, + + /// + /// SVG AxisName + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Svg")] + Svg, + } + + #endregion // Enumerations + + /// + /// The ChartGraphics class provides a common interface to the + /// graphics rendering. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public partial class ChartGraphics + { + #region Fields + + // Current rendering type + private RenderingType _activeRenderingType = RenderingType.Gdi; + + // GDI+ rendering engine + private GdiGraphics _gdiGraphics = new GdiGraphics(); + + // Document title used for SVG rendering + //private string documentTitle = string.Empty; + + // True if text should be clipped + internal bool IsTextClipped = false; + + #endregion // Fields + + #region Drawing Methods + + /// + /// Draws a line connecting two PointF structures. + /// + /// Pen object that determines the color, width, and style of the line. + /// PointF structure that represents the first point to connect. + /// PointF structure that represents the second point to connect. + internal void DrawLine( + Pen pen, + PointF pt1, + PointF pt2 + ) + { + RenderingObject.DrawLine( pen, pt1, pt2 ); + } + + /// + /// Draws a line connecting the two points specified by coordinate pairs. + /// + /// Pen object that determines the color, width, and style of the line. + /// x-coordinate of the first point. + /// y-coordinate of the first point. + /// x-coordinate of the second point. + /// y-coordinate of the second point. + internal void DrawLine( + Pen pen, + float x1, + float y1, + float x2, + float y2 + ) + { + RenderingObject.DrawLine( pen, x1, y1, x2, y2 ); + } + + /// + /// Draws the specified portion of the specified Image object at the specified location and with the specified size. + /// + /// Image object to draw. + /// Rectangle structure that specifies the location and size of the drawn image. The image is scaled to fit the rectangle. + /// x-coordinate of the upper-left corner of the portion of the source image to draw. + /// y-coordinate of the upper-left corner of the portion of the source image to draw. + /// Width of the portion of the source image to draw. + /// Height of the portion of the source image to draw. + /// Member of the GraphicsUnit enumeration that specifies the units of measure used to determine the source rectangle. + /// ImageAttributes object that specifies recoloring and gamma information for the image object. + internal void DrawImage( + System.Drawing.Image image, + Rectangle destRect, + int srcX, + int srcY, + int srcWidth, + int srcHeight, + GraphicsUnit srcUnit, + ImageAttributes imageAttr + ) + { + RenderingObject.DrawImage( + image, + destRect, + srcX, + srcY, + srcWidth, + srcHeight, + srcUnit, + imageAttr + ); + } + + /// + /// Draws an ellipse defined by a bounding rectangle specified by + /// a pair of coordinates, a height, and a width. + /// + /// Pen object that determines the color, width, and style of the ellipse. + /// x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse. + /// y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse. + /// Width of the bounding rectangle that defines the ellipse. + /// Height of the bounding rectangle that defines the ellipse. + internal void DrawEllipse( + Pen pen, + float x, + float y, + float width, + float height + ) + { + RenderingObject.DrawEllipse( pen, x, y, width, height ); + } + + /// + /// Draws a cardinal spline through a specified array of PointF structures + /// using a specified tension. The drawing begins offset from + /// the beginning of the array. + /// + /// Pen object that determines the color, width, and height of the curve. + /// Array of PointF structures that define the spline. + /// Offset from the first element in the array of the points parameter to the starting point in the curve. + /// Number of segments after the starting point to include in the curve. + /// Value greater than or equal to 0.0F that specifies the tension of the curve. + internal void DrawCurve( + Pen pen, + PointF[] points, + int offset, + int numberOfSegments, + float tension + ) + { + ChartGraphics chartGraphics = this as ChartGraphics; + if (chartGraphics == null || !chartGraphics.IsMetafile) + { + RenderingObject.DrawCurve(pen, points, offset, numberOfSegments, tension); + } + else + { + // Special handling required for the metafiles. We cannot pass large array of + // points because they will be persisted inside EMF file and cause exponential + // increase in emf file size. Draw curve method uses additional 2, 3 or 4 points + // depending on which segement is drawn. + PointF[] pointsExact = null; + if (offset == 0 && numberOfSegments == points.Length - 1) + { + // In case the array contains the minimum required number of points + // to draw segments - just call the curve drawing method + RenderingObject.DrawCurve(pen, points, offset, numberOfSegments, tension); + } + else + { + if (offset == 0 && numberOfSegments < points.Length - 1) + { + // Segment is at the beginning of the array with more points following + pointsExact = new PointF[numberOfSegments + 2]; + for (int index = 0; index < numberOfSegments + 2; index++) + { + pointsExact[index] = points[index]; + } + } + else if (offset > 0 && (offset + numberOfSegments) == points.Length - 1) + { + // Segment is at the end of the array with more points prior to it + pointsExact = new PointF[numberOfSegments + 2]; + for (int index = 0; index < numberOfSegments + 2; index++) + { + pointsExact[index] = points[offset + index - 1]; + } + offset = 1; + } + else if (offset > 0 && (offset + numberOfSegments) < points.Length - 1) + { + // Segment in the middle of the array with points prior and following it + pointsExact = new PointF[numberOfSegments + 3]; + for (int index = 0; index < numberOfSegments + 3; index++) + { + pointsExact[index] = points[offset + index - 1]; + } + offset = 1; + } + + // Render the curve using minimum number of required points in the array + RenderingObject.DrawCurve(pen, pointsExact, offset, numberOfSegments, tension); + } + } + } + + /// + /// Draws a rectangle specified by a coordinate pair, a width, and a height. + /// + /// Pen object that determines the color, width, and style of the rectangle. + /// x-coordinate of the upper-left corner of the rectangle to draw. + /// y-coordinate of the upper-left corner of the rectangle to draw. + /// Width of the rectangle to draw. + /// Height of the rectangle to draw. + internal void DrawRectangle( + Pen pen, + int x, + int y, + int width, + int height + ) + { + RenderingObject.DrawRectangle( pen, x, y, width, height ); + } + + /// + /// Draws a polygon defined by an array of PointF structures. + /// + /// Pen object that determines the color, width, and style of the polygon. + /// Array of PointF structures that represent the vertices of the polygon. + internal void DrawPolygon( + Pen pen, + PointF[] points + ) + { + RenderingObject.DrawPolygon( pen, points ); + } + + /// + /// Draws the specified text string in the specified rectangle with the specified Brush and Font objects using the formatting properties of the specified StringFormat object. + /// + /// String to draw. + /// Font object that defines the text format of the string. + /// Brush object that determines the color and texture of the drawn text. + /// RectangleF structure that specifies the location of the drawn text. + /// StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text. + internal void DrawString( + string s, + Font font, + Brush brush, + RectangleF layoutRectangle, + StringFormat format + ) + { + using (StringFormat fmt = (StringFormat)format.Clone()) + { + if ( IsRightToLeft ) + fmt.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + if (!IsTextClipped && (fmt.FormatFlags & StringFormatFlags.NoClip) != StringFormatFlags.NoClip) + fmt.FormatFlags |= StringFormatFlags.NoClip; + RenderingObject.DrawString(s, font, brush, layoutRectangle, fmt); + } + } + + /// + /// Draws the specified text string at the specified location with the specified Brush and Font objects using the formatting properties of the specified StringFormat object. + /// + /// String to draw. + /// Font object that defines the text format of the string. + /// Brush object that determines the color and texture of the drawn text. + /// PointF structure that specifies the upper-left corner of the drawn text. + /// StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text. + internal void DrawString( + string s, + Font font, + Brush brush, + PointF point, + StringFormat format + ) + { + if (IsRightToLeft) + { + using (StringFormat fmt = (StringFormat)format.Clone()) + { + fmt.FormatFlags |= StringFormatFlags.DirectionRightToLeft; + if (fmt.Alignment == StringAlignment.Far) + { + fmt.Alignment = StringAlignment.Near; + } + else if (fmt.Alignment == StringAlignment.Near) + { + fmt.Alignment = StringAlignment.Far; + } + RenderingObject.DrawString(s, font, brush, point, fmt); + } + } + else + RenderingObject.DrawString(s, font, brush, point, format); + } + + /// + /// Draws the specified portion of the specified Image object at the specified location and with the specified size. + /// + /// Image object to draw. + /// Rectangle structure that specifies the location and size of the drawn image. The image is scaled to fit the rectangle. + /// x-coordinate of the upper-left corner of the portion of the source image to draw. + /// y-coordinate of the upper-left corner of the portion of the source image to draw. + /// Width of the portion of the source image to draw. + /// Height of the portion of the source image to draw. + /// Member of the GraphicsUnit enumeration that specifies the units of measure used to determine the source rectangle. + /// ImageAttributes object that specifies recoloring and gamma information for the image object. + internal void DrawImage( + System.Drawing.Image image, + Rectangle destRect, + float srcX, + float srcY, + float srcWidth, + float srcHeight, + GraphicsUnit srcUnit, + ImageAttributes imageAttrs + ) + { + RenderingObject.DrawImage( image, destRect, srcX, srcY, srcWidth, srcHeight, srcUnit, imageAttrs ); + } + + /// + /// Draws a rectangle specified by a coordinate pair, a width, and a height. + /// + /// A Pen object that determines the color, width, and style of the rectangle. + /// The x-coordinate of the upper-left corner of the rectangle to draw. + /// The y-coordinate of the upper-left corner of the rectangle to draw. + /// The width of the rectangle to draw. + /// The height of the rectangle to draw. + internal void DrawRectangle( + Pen pen, + float x, + float y, + float width, + float height + ) + { + RenderingObject.DrawRectangle( pen, x, y, width, height ); + } + + /// + /// Draws a GraphicsPath object. + /// + /// Pen object that determines the color, width, and style of the path. + /// GraphicsPath object to draw. + internal void DrawPath( + Pen pen, + GraphicsPath path + ) + { + // Check if path is empty + if(path == null || + path.PointCount == 0) + { + return; + } + + RenderingObject.DrawPath( pen, path ); + } + + /// + /// Draws a pie shape defined by an ellipse specified by a coordinate pair, a width, and a height and two radial lines. + /// + /// Pen object that determines the color, width, and style of the pie shape. + /// x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// Width of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// Height of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// Angle measured in degrees clockwise from the x-axis to the first side of the pie shape. + /// Angle measured in degrees clockwise from the startAngle parameter to the second side of the pie shape. + internal void DrawPie( + Pen pen, + float x, + float y, + float width, + float height, + float startAngle, + float sweepAngle + ) + { + RenderingObject.DrawPie( pen, x, y, width, height, startAngle, sweepAngle ); + } + + /// + /// Draws an ellipse defined by a bounding RectangleF. + /// + /// Pen object that determines the color, width, and style of the ellipse. + /// RectangleF structure that defines the boundaries of the ellipse. + internal void DrawEllipse( + Pen pen, + RectangleF rect + ) + { + RenderingObject.DrawEllipse( pen, rect ); + } + + /// + /// Draws a series of line segments that connect an array of PointF structures. + /// + /// Pen object that determines the color, width, and style of the line segments. + /// Array of PointF structures that represent the points to connect. + internal void DrawLines( + Pen pen, + PointF[] points + ) + { + RenderingObject.DrawLines( pen, points ); + } + + #endregion // Drawing Methods + + #region Filling Methods + + /// + /// Fills the interior of an ellipse defined by a bounding rectangle + /// specified by a RectangleF structure. + /// + /// Brush object that determines the characteristics of the fill. + /// RectangleF structure that represents the bounding rectangle that defines the ellipse. + internal void FillEllipse( + Brush brush, + RectangleF rect + ) + { + RenderingObject.FillEllipse( brush, rect ); + } + + /// + /// Fills the interior of a GraphicsPath object. + /// + /// Brush object that determines the characteristics of the fill. + /// GraphicsPath object that represents the path to fill. + internal void FillPath( + Brush brush, + GraphicsPath path + ) + { + // Check if path is empty + if(path == null || + path.PointCount == 0) + { + return; + } + + RenderingObject.FillPath( brush, path ); + } + + /// + /// Fills the interior of a Region object. + /// + /// Brush object that determines the characteristics of the fill. + /// Region object that represents the area to fill. + internal void FillRegion( + Brush brush, + Region region + ) + { + RenderingObject.FillRegion( brush, region ); + } + + /// + /// Fills the interior of a rectangle specified by a RectangleF structure. + /// + /// Brush object that determines the characteristics of the fill. + /// RectangleF structure that represents the rectangle to fill. + internal void FillRectangle( + Brush brush, + RectangleF rect + ) + { + RenderingObject.FillRectangle( brush, rect ); + } + + /// + /// Fills the interior of a rectangle specified by a pair of coordinates, a width, and a height. + /// + /// Brush object that determines the characteristics of the fill. + /// x-coordinate of the upper-left corner of the rectangle to fill. + /// y-coordinate of the upper-left corner of the rectangle to fill. + /// Width of the rectangle to fill. + /// Height of the rectangle to fill. + internal void FillRectangle( + Brush brush, + float x, + float y, + float width, + float height + ) + { + RenderingObject.FillRectangle( brush, x, y, width, height ); + } + + /// + /// Fills the interior of a polygon defined by an array of points specified by PointF structures . + /// + /// Brush object that determines the characteristics of the fill. + /// Array of PointF structures that represent the vertices of the polygon to fill. + internal void FillPolygon( + Brush brush, + PointF[] points + ) + { + RenderingObject.FillPolygon( brush, points ); + } + + /// + /// Fills the interior of a pie section defined by an ellipse + /// specified by a pair of coordinates, a width, and a height + /// and two radial lines. + /// + /// Brush object that determines the characteristics of the fill. + /// x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie section comes. + /// y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie section comes. + /// Width of the bounding rectangle that defines the ellipse from which the pie section comes. + /// Height of the bounding rectangle that defines the ellipse from which the pie section comes. + /// Angle in degrees measured clockwise from the x-axis to the first side of the pie section. + /// Angle in degrees measured clockwise from the startAngle parameter to the second side of the pie section. + internal void FillPie( + Brush brush, + float x, + float y, + float width, + float height, + float startAngle, + float sweepAngle + ) + { + RenderingObject.FillPie( brush, x, y, width, height, startAngle, sweepAngle ); + } + + #endregion // Filling Methods + + #region Other Methods + + /// + /// This method starts SVG Selection mode + /// + /// The location of the referenced object, expressed as a URI reference. + /// Title which could be used for tooltips. + internal void StartHotRegion( string url, string title ) + { + RenderingObject.BeginSelection( url, title ); + } + + /// + /// This method starts SVG Selection mode + /// + /// Data Point which properties are used for SVG selection + internal void StartHotRegion(DataPoint point) + { + StartHotRegion( point, false ); + } + + /// + /// This method starts SVG Selection mode + /// + /// Data Point which properties are used for SVG selection + /// Indicates if point label region is processed. + internal void StartHotRegion(DataPoint point, bool labelRegion) + { + string hRef = string.Empty; + string tooltip = (labelRegion) ? point.LabelToolTip : point.ToolTip; +#if !Microsoft_CONTROL + hRef = (labelRegion) ? point.LabelUrl : point.Url; +#endif + if(hRef.Length > 0 || tooltip.Length > 0) + { + RenderingObject.BeginSelection( + point.ReplaceKeywords( hRef ), + point.ReplaceKeywords( tooltip ) ); + } + } + + /// + /// This method stops SVG Selection mode + /// + internal void EndHotRegion() + { + RenderingObject.EndSelection(); + } + + /// + /// Measures the specified string when drawn with the specified + /// Font object and formatted with the specified StringFormat object. + /// + /// String to measure. + /// Font object defines the text format of the string. + /// SizeF structure that specifies the maximum layout area for the text. + /// StringFormat object that represents formatting information, such as line spacing, for the string. + /// This method returns a SizeF structure that represents the size, in pixels, of the string specified in the text parameter as drawn with the font parameter and the stringFormat parameter. + internal SizeF MeasureString( + string text, + Font font, + SizeF layoutArea, + StringFormat stringFormat + ) + { + return RenderingObject.MeasureString( text, font, layoutArea, stringFormat ); + } + + /// + /// Measures the specified string when drawn with the specified + /// Font object and formatted with the specified StringFormat object. + /// + /// String to measure. + /// Font object defines the text format of the string. + /// This method returns a SizeF structure that represents the size, in pixels, of the string specified in the text parameter as drawn with the font parameter and the stringFormat parameter. + internal SizeF MeasureString( + string text, + Font font + ) + { + return RenderingObject.MeasureString( text, font ); + } + + /// + /// Saves the current state of this Graphics object and identifies the saved state with a GraphicsState object. + /// + /// This method returns a GraphicsState object that represents the saved state of this Graphics object. + internal GraphicsState Save() + { + return RenderingObject.Save(); + } + + /// + /// Restores the state of this Graphics object to the state represented by a GraphicsState object. + /// + /// GraphicsState object that represents the state to which to restore this Graphics object. + internal void Restore( + GraphicsState gstate + ) + { + RenderingObject.Restore( gstate ); + } + + /// + /// Resets the clip region of this Graphics object to an infinite region. + /// + internal void ResetClip() + { + RenderingObject.ResetClip(); + } + + /// + /// Sets the clipping region of this Graphics object to the rectangle specified by a RectangleF structure. + /// + /// RectangleF structure that represents the new clip region. + internal void SetClipAbs(RectangleF rect) + { + RenderingObject.SetClip( rect ); + } + + /// + /// Prepends the specified translation to the transformation matrix of this Graphics object. + /// + /// x component of the translation. + /// y component of the translation. + internal void TranslateTransform( + float dx, + float dy + ) + { + RenderingObject.TranslateTransform( dx, dy ); + } + + #endregion // Other Methods + + #region Properties + + /// + /// Gets current rendering object. + /// + internal IChartRenderingEngine RenderingObject + { + get + { + return _gdiGraphics; + } + } + + /// + /// Gets the active rendering type. + /// + internal RenderingType ActiveRenderingType + { + get + { + return _activeRenderingType; + } + } + + /// + /// Gets or sets the rendering mode for text associated with this Graphics object. + /// + internal TextRenderingHint TextRenderingHint + { + get + { + return RenderingObject.TextRenderingHint; + } + set + { + RenderingObject.TextRenderingHint = value; + } + } + + /// + /// Gets or sets the world transformation for this Graphics object. + /// + internal Matrix Transform + { + get + { + return RenderingObject.Transform; + } + set + { + RenderingObject.Transform = value; + } + } + + /// + /// Gets or sets the rendering quality for this Graphics object. + /// + internal SmoothingMode SmoothingMode + { + get + { + return RenderingObject.SmoothingMode; + } + set + { + RenderingObject.SmoothingMode = value; + } + } + + /// + /// Gets or sets a Region object that limits the drawing region of this Graphics object. + /// + internal Region Clip + { + get + { + return RenderingObject.Clip; + } + set + { + RenderingObject.Clip = value; + } + } + + /// + /// Gets a value indicating whether the clipping region of this Graphics object is empty. + /// + internal bool IsClipEmpty { + get + { + return RenderingObject.IsClipEmpty; + } + } + + /// + /// Gets or sets the reference to the Graphics object. + /// + public Graphics Graphics + { + get + { + return RenderingObject.Graphics; + } + set + { + RenderingObject.Graphics = value; + } + } + + #endregion // Properties + } +} diff --git a/System.Web.DataVisualization/Common/General/ChartSerializer.cs b/System.Web.DataVisualization/Common/General/ChartSerializer.cs new file mode 100644 index 000000000..5e2626673 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ChartSerializer.cs @@ -0,0 +1,789 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ChartSerializer.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ChartSerializer +// +// Purpose: Serialization saves the state of the chart and also +// provides the ability to load the serialized data back +// into the chart. All chart properties can be persisted, +// including the chart's data. +// +// ChartSerializer class only provides serialization API +// for the user and actual serialization is performed by +// XmlFormatSerializer or BinaryFormatserializer classes +// depending on the Format property. +// +// Reviewed: AG - Jul 31, 2002 +// GS - Aug 7, 2002 +// AG - Microsoft 15, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.IO; +using System.Xml; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Serialization enumeration + + /// + /// An enumeration of the formats of the chart serializer. + /// + public enum SerializationFormat + { + /// + /// XML serializer format. + /// + Xml, + + /// + /// Binary serializer format. + /// + Binary + } + + + /// + /// An enumeration of chart serializable content definition flags + /// + [Flags] + public enum SerializationContents + { + /// + /// Default content. + /// + Default = 1, + + /// + /// Serialize only series data. + /// + Data = 2, + + /// + /// Serialize chart visual appearance (e.g. Colors, Line Styles). + /// + Appearance = 4, + + /// + /// All content is serialized. + /// + All = Default | Data | Appearance + + } + + #endregion + + /// + /// ChartSerializer class provides chart serialization. + /// + [ + SRDescription("DescriptionAttributeChartSerializer_ChartSerializer"), + DefaultProperty("Format"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class ChartSerializer + { + #region Private fields + + // Reference to the service container + private IServiceContainer _serviceContainer = null; + + // Reference to the chart object + private Chart _chart = null; + + // Reference to the serializer object + + private SerializerBase _serializer = new XmlFormatSerializer(); + + // Format of the serializer in use + private SerializationFormat _format = SerializationFormat.Xml; + + // Serialization content + private SerializationContents _content = SerializationContents .Default; + + #endregion + + #region Constructors and Service Provider methods + + /// + /// Default constructor is unavailable + /// + private ChartSerializer() + { + } + + /// + /// Internal constructor + /// + /// Service container reference. + internal ChartSerializer(IServiceContainer container) + { + if(container == null) + { + throw(new ArgumentNullException(SR.ExceptionInvalidServiceContainer)); + } + _serviceContainer = container; + } + + /// + /// Returns ChartSerializer service object + /// + /// Requested service type. + /// ChartSerializer service object. + internal object GetService(Type serviceType) + { + if(serviceType == typeof(ChartSerializer)) + { + return this; + } + throw (new ArgumentException( SR.ExceptionChartSerializerUnsupportedType( serviceType.ToString()))); + } + + #endregion + + #region Public properties + + /// + /// Gets or sets the serializable content. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(typeof(SerializationContents ), "Default"), + SRDescription("DescriptionAttributeChartSerializer_Content") + ] + public SerializationContents Content + { + get + { + return _content; + } + set + { + // Set content value + _content = value; + + // Automatically set SerializableContent and NonSerializableContent properties + SetSerializableContent(); + } + } + + /// + /// Gets or sets the format used to serialize the chart data. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(typeof(SerializationFormat), "Xml"), + SRDescription("DescriptionAttributeChartSerializer_Format") + ] + public SerializationFormat Format + { + get + { + return _format; + } + set + { + if(_format != value) + { + _format = value; + + // Create new serializer object + SerializerBase newSerializer = null; + + if(_format == SerializationFormat.Binary) + { + newSerializer = new BinaryFormatSerializer(); + } + else + { + newSerializer = new XmlFormatSerializer(); + } + // Copy serializer settings + newSerializer.IsUnknownAttributeIgnored = _serializer.IsUnknownAttributeIgnored; + newSerializer.NonSerializableContent = _serializer.NonSerializableContent; + newSerializer.IsResetWhenLoading = _serializer.IsResetWhenLoading; + newSerializer.SerializableContent = _serializer.SerializableContent; + _serializer = newSerializer; + } + } + } + + /// + /// Gets or sets a flag which indicates whether object properties are reset to default + /// values before loading. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(true), + SRDescription("DescriptionAttributeChartSerializer_ResetWhenLoading") + ] + public bool IsResetWhenLoading + { + get + { + return _serializer.IsResetWhenLoading; + } + set + { + _serializer.IsResetWhenLoading = value; + } + } + + + + /// + /// Gets or sets a flag which indicates whether unknown XML properties and elements will be + /// ignored without throwing an exception. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(false), + SRDescription("DescriptionAttributeChartSerializer_IgnoreUnknownXmlAttributes") + ] + public bool IsUnknownAttributeIgnored + { + get + { + return _serializer.IsUnknownAttributeIgnored; + } + set + { + _serializer.IsUnknownAttributeIgnored = value; + } + } + + /// + /// Gets or sets a flag which indicates whether chart + /// serializer is working in template creation mode. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(false), + SRDescription("DescriptionAttributeChartSerializer_TemplateMode") + ] + public bool IsTemplateMode + { + get + { + return _serializer.IsTemplateMode; + } + set + { + _serializer.IsTemplateMode = value; + } + } + + + + /// + /// Gets or sets the chart properties that can be serialized. + /// Comma separated list of serializable (Save/Load/Reset) properties. + /// "ClassName.PropertyName,[ClassName.PropertyName]". + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(""), + SRDescription("DescriptionAttributeChartSerializer_SerializableContent") + ] + public string SerializableContent + { + get + { + return _serializer.SerializableContent; + } + set + { + _serializer.SerializableContent = value; + } + } + + /// + /// Gets or sets the chart properties that will not be serialized. + /// Comma separated list of non-serializable (Save/Load/Reset) properties. + /// "ClassName.PropertyName,[ClassName.PropertyName]". + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(""), + SRDescription("DescriptionAttributeChartSerializer_NonSerializableContent") + ] + public string NonSerializableContent + { + get + { + return _serializer.NonSerializableContent; + } + set + { + _serializer.NonSerializableContent = value; + } + } + + #endregion + + #region Public methods + + /// + /// This method resets all properties of the chart to default values. By setting Content or + /// SerializableContent/NonSerializableContent properties, specific set of + /// properties can be reset. + /// + public void Reset() + { + // Set serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = true; + GetChartObject().serializationStatus = SerializationStatus.Resetting; + } + + // Reset properties + _serializer.ResetObjectProperties(GetChartObject()); + + // Clear serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = false; + GetChartObject().serializationStatus = SerializationStatus.None; + } + } + + /// + /// This method saves all properties of the chart into a file. By setting Content or + /// SerializableContent/NonSerializableContent properties, specific set of + /// properties can be saved. + /// + /// The file name used to write the data. + public void Save(string fileName) + { + //Check arguments + if (fileName == null) + throw new ArgumentNullException("fileName"); + + // Set serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = true; + GetChartObject().serializationStatus = SerializationStatus.Saving; + //GetChartObject().BeginInit(); + } + + // Reset all auto-detected properties values + GetChartObject().ResetAutoValues(); + + // Serialize chart data + _serializer.Serialize(GetChartObject(), fileName); + + // Clear serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = false; + GetChartObject().serializationStatus = SerializationStatus.None; + //GetChartObject().EndInit(); + } + } + + /// + /// This method saves all properties of the chart into a stream. By setting Content or + /// SerializableContent/NonSerializableContent properties, specific set of + /// properties can be saved. + /// + /// The stream where to save the data. + public void Save(Stream stream) + { + //Check arguments + if (stream == null) + throw new ArgumentNullException("stream"); + + // Set serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = true; + GetChartObject().serializationStatus = SerializationStatus.Saving; + //GetChartObject().BeginInit(); + } + + // Reset all auto-detected properties values + GetChartObject().ResetAutoValues(); + + // Serialize chart data + _serializer.Serialize(GetChartObject(), stream); + + // Clear serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = false; + GetChartObject().serializationStatus = SerializationStatus.None; + //GetChartObject().EndInit(); + } + } + + /// + /// This method saves all properties of the chart into an XML writer. By setting Content or + /// SerializableContent/NonSerializableContent properties, specific set of + /// properties can be saved. + /// + /// XML writer to save the data. + public void Save(XmlWriter writer) + { + //Check arguments + if (writer == null) + throw new ArgumentNullException("writer"); + + // Set serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = true; + GetChartObject().serializationStatus = SerializationStatus.Saving; + //GetChartObject().BeginInit(); + } + + // Reset all auto-detected properties values + GetChartObject().ResetAutoValues(); + + // Serialize chart data + _serializer.Serialize(GetChartObject(), writer); + + // Clear serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = false; + GetChartObject().serializationStatus = SerializationStatus.None; + //GetChartObject().EndInit(); + } + } + + /// + /// This method saves all properties of the chart into a text writer. By setting Content or + /// SerializableContent/NonSerializableContent properties, specific set of + /// properties can be saved. + /// + /// Text writer to save the data. + public void Save(TextWriter writer) + { + //Check arguments + if (writer == null) + throw new ArgumentNullException("writer"); + + // Set serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = true; + GetChartObject().serializationStatus = SerializationStatus.Saving; + //GetChartObject().BeginInit(); + } + + // Reset all auto-detected properties values + GetChartObject().ResetAutoValues(); + + // Serialize chart data + _serializer.Serialize(GetChartObject(), writer); + + // Clear serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = false; + GetChartObject().serializationStatus = SerializationStatus.None; + //GetChartObject().EndInit(); + } + } + + /// + /// This method loads all properties of the chart from a file. By setting Content or + /// SerializableContent/NonSerializableContent properties, specific set of + /// properties can be loaded. + /// + /// The file to load the data from. + public void Load(string fileName) + { + //Check arguments + if (fileName == null) + throw new ArgumentNullException("fileName"); + + // Set serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = true; + GetChartObject().serializationStatus = SerializationStatus.Loading; + } + + _serializer.Deserialize(GetChartObject(), fileName); + + // Clear serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = false; + GetChartObject().serializationStatus = SerializationStatus.None; + } + } + + + /// + /// This method loads all properties of the chart from a stream. By setting Content or + /// SerializableContent/NonSerializableContent properties, specific set of + /// properties can be loaded. + /// + /// The stream to load the data from. + public void Load(Stream stream) + { + //Check arguments + if (stream == null) + throw new ArgumentNullException("stream"); + + // Set serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = true; + GetChartObject().serializationStatus = SerializationStatus.Loading; + } + + _serializer.Deserialize(GetChartObject(), stream); + + // Clear serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = false; + GetChartObject().serializationStatus = SerializationStatus.None; + } + } + + /// + /// This method loads all properties of the chart from an XML reader. By setting Content or + /// SerializableContent/NonSerializableContent properties, specific set of + /// properties can be loaded. + /// + /// The XML reader to load the data from. + public void Load(XmlReader reader) + { + //Check arguments + if (reader == null) + throw new ArgumentNullException("reader"); + + // Set serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = true; + GetChartObject().serializationStatus = SerializationStatus.Loading; + } + + _serializer.Deserialize(GetChartObject(), reader); + + // Clear serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = false; + GetChartObject().serializationStatus = SerializationStatus.None; + } + } + + /// + /// This method loads all properties of the chart from the text reader. By setting Content or + /// SerializableContent/NonSerializableContent properties, specific set of + /// properties can be loaded. + /// + /// The text reader to load the data from. + public void Load(TextReader reader) + { + //Check arguments + if (reader == null) + throw new ArgumentNullException("reader"); + + // Set serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = true; + GetChartObject().serializationStatus = SerializationStatus.Loading; + } + + _serializer.Deserialize(GetChartObject(), reader); + + // Clear serializing flag + if(GetChartObject() != null) + { + GetChartObject().serializing = false; + GetChartObject().serializationStatus = SerializationStatus.None; + } + } + + #endregion + + #region Protected helper methods + + /// + /// Sets SerializableContent and NonSerializableContent properties + /// depending on the flags in the Content property. + /// + internal void SetSerializableContent() + { + // Reset content definition strings + this.SerializableContent = ""; + this.NonSerializableContent = ""; + + // Loop through all enumeration flags + Array enumValues = Enum.GetValues(typeof(SerializationContents )); + foreach(object flagObject in enumValues) + { + if(flagObject is SerializationContents ) + { + // Check if flag currently set + SerializationContents flag = (SerializationContents )flagObject; + if((this.Content & flag) == flag && + flag != SerializationContents .All && + this.Content != SerializationContents .All) + { + // Add comma at the end of existing string + if(this.NonSerializableContent.Length != 0) + { + this.NonSerializableContent += ", "; + } + + // Add serializable class/properties names + this.NonSerializableContent += GetContentString(flag, false); + this.NonSerializableContent = this.NonSerializableContent.TrimStart(','); + + // Add comma at the end of existing string + if(this.SerializableContent.Length != 0) + { + this.SerializableContent += ", "; + } + + // Add serializable class/properties names + this.SerializableContent += GetContentString(flag, true); + this.SerializableContent = this.SerializableContent.TrimStart(','); + } + } + } + } + + + /// + /// Return a serializable or non serializable class/properties names + /// for the specific flag. + /// + /// Serializable content + /// True - get serializable string, False - non serializable. + /// Serializable or non serializable string with class/properties names. + protected string GetContentString(SerializationContents content, bool serializable) + { + switch(content) + { + case(SerializationContents .All): + return ""; + case(SerializationContents .Default): + return ""; + case(SerializationContents .Data): + if(serializable) + { + return + "Chart.BuildNumber, " + + "Chart.Series, " + + "Series.Points, " + + "Series.Name, " + + "DataPoint.XValue, " + + "DataPoint.YValues," + + "DataPoint.LabelStyle," + + "DataPoint.AxisLabel," + + "DataPoint.LabelFormat," + + "DataPoint.IsEmpty, " + + "Series.YValuesPerPoint, " + + "Series.IsXValueIndexed, " + + "Series.XValueType, " + + "Series.YValueType"; + } + return ""; + case(SerializationContents .Appearance): + if(serializable) + { + return + "Chart.BuildNumber, " + + "*.Name*, " + + "*.Fore*, " + + "*.Back*, " + + "*.Border*, " + + "*.Line*, " + + "*.Frame*, " + + "*.PageColor*, " + + "*.SkinStyle*, " + + "*.Palette, " + + "*.PaletteCustomColors, " + + "*.Font*, " + + "*.*Font, " + + "*.Color, " + + "*.Shadow*, " + + "*.MarkerColor, " + + "*.MarkerStyle, " + + "*.MarkerSize, " + + "*.MarkerBorderColor, " + + "*.MarkerImage, " + + "*.MarkerImageTransparentColor, " + + "*.LabelBackColor, " + + "*.LabelBorder*, " + + "*.Enable3D, " + + "*.IsRightAngleAxes, " + + "*.IsClustered, " + + "*.LightStyle, " + + "*.Perspective, " + + "*.Inclination, " + + "*.Rotation, " + + "*.PointDepth, " + + "*.PointGapDepth, " + + "*.WallWidth"; + } + return ""; + + default: + throw (new InvalidOperationException(SR.ExceptionChartSerializerContentFlagUnsupported)); + } + } + + /// + /// Returns chart object for serialization. + /// + /// Chart object. + internal Chart GetChartObject() + { + if(_chart == null) + { + _chart = (Chart)_serviceContainer.GetService(typeof(Chart)); + } + return _chart; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/CommonElements.cs b/System.Web.DataVisualization/Common/General/CommonElements.cs new file mode 100644 index 000000000..cdbb898c9 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/CommonElements.cs @@ -0,0 +1,327 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: CommonElements.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: CommonElements +// +// Purpose: CommonElements class provides references to common +// chart classes like DataManager, ChartTypeRegistry, +// ImageLoader and others. It is passed to different +// chart elements to simplify access to those common +// classes. +// +// Reviewed: GS - August 2, 2002 +// AG - August 8, 2002 +// AG - Microsoft 15, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.ComponentModel.Design; +using System.Drawing.Drawing2D; +using System.Drawing; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Formulas; +#else + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.Borders3D; + using System.Web.UI.DataVisualization.Charting.Formulas; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// CommonElements class provides references to common chart classes like + /// DataManager, ChartTypeRegistry, ImageLoader and others. It is passed + /// to different chart elements to simplify access to those common classes. + /// + internal class CommonElements + { + #region Fields + + private Chart _chart; + private ChartImage _chartPicture; + + // Reference to Chart Graphics Object + internal ChartGraphics graph = null; + + /// + /// Service Container + /// + internal IServiceContainer container = null; + + /// + /// Indicates painting mode + /// + internal bool processModePaint = true; + + /// + /// Indicates selection mode + /// + internal bool processModeRegions = false; + + // Private Fields + private int _width = 0; + private int _height = 0; + + #endregion + + #region Properties + + /// + /// Reference to the Data Manager + /// + internal DataManager DataManager + { + get + { + return (DataManager)container.GetService(typeof(DataManager)); + } + } + + /// + /// True if painting mode is active + /// + public bool ProcessModePaint + { + get + { + return processModePaint; + } + } + + /// + /// True if Hot region or image maps mode is active + /// + public bool ProcessModeRegions + { + get + { + return processModeRegions; + } + } + + /// + /// Reference to the hot regions object + /// + public HotRegionsList HotRegionsList + { + get + { + return ChartPicture.hotRegionsList; + } + } + + /// + /// Reference to the Data Manipulator + /// + public DataManipulator DataManipulator + { + get + { + return ChartPicture.DataManipulator; + } + } + + /// + /// Reference to the ImageLoader + /// + internal ImageLoader ImageLoader + { + get + { + return (ImageLoader)container.GetService(typeof(ImageLoader)); + } + } + + /// + /// Reference to the Chart + /// + internal Chart Chart + { + get + { + if (_chart==null) + _chart = (Chart)container.GetService(typeof(Chart)); + return _chart; + } + } + + /// + /// Reference to the ChartTypeRegistry + /// + internal ChartTypeRegistry ChartTypeRegistry + { + get + { + return (ChartTypeRegistry)container.GetService(typeof(ChartTypeRegistry)); + } + } + + /// + /// Reference to the BorderTypeRegistry + /// + internal BorderTypeRegistry BorderTypeRegistry + { + get + { + return (BorderTypeRegistry)container.GetService(typeof(BorderTypeRegistry)); + } + } + + /// + /// Reference to the FormulaRegistry + /// + internal FormulaRegistry FormulaRegistry + { + get + { + return (FormulaRegistry)container.GetService(typeof(FormulaRegistry)); + } + } + + + + /// + /// Reference to the ChartPicture + /// + internal ChartImage ChartPicture + { + get + { + if (_chartPicture ==null) + _chartPicture = (ChartImage)container.GetService(typeof(ChartImage)); + return _chartPicture; + } + } + + /// + /// Width of the chart picture + /// + internal int Width + { + get + { + return _width; + } + set + { + _width = value; + } + } + + /// + /// Height of the chart picture + /// + internal int Height + { + get + { + return _height; + } + set + { + _height = value; + } + } + + #endregion + + #region Methods + + /// + /// Constructor + /// + /// Service container. + internal CommonElements(IServiceContainer container) + { + this.container = container; + } + + + #endregion + + #region String convertion helper methods + + /// + /// Converts string to double. + /// + /// String to convert. + /// Double result. + internal static double ParseDouble(string stringToParse) + { + return ParseDouble(stringToParse, false); + } + /// + /// Converts string to double. + /// + /// String to convert. + /// if set to true the exception thrown. + /// Double result. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Double.TryParse(System.String,System.Globalization.NumberStyles,System.IFormatProvider,System.Double@)")] + internal static double ParseDouble(string stringToParse, bool throwException) + { + Double result = 0.0; + + if (throwException) + { + result = double.Parse(stringToParse, NumberStyles.Any, CultureInfo.InvariantCulture); + } + else + { + bool parseSucceed = double.TryParse(stringToParse, NumberStyles.Any, CultureInfo.InvariantCulture, out result); + if (!parseSucceed) + { + double.TryParse(stringToParse, NumberStyles.Any, CultureInfo.CurrentCulture, out result); + } + } + return result; + } + + /// + /// Converts string to double. + /// + /// String to convert. + /// Double result. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Single.TryParse(System.String,System.Globalization.NumberStyles,System.IFormatProvider,System.Single@)")] + internal static float ParseFloat(string stringToParse) + { + float result = 0f; + bool parseSucceed = float.TryParse(stringToParse, NumberStyles.Any, CultureInfo.InvariantCulture, out result); + + if (!parseSucceed) + { + float.TryParse(stringToParse, NumberStyles.Any, CultureInfo.CurrentCulture, out result); + } + + return result; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/Constants.cs b/System.Web.DataVisualization/Common/General/Constants.cs new file mode 100644 index 000000000..c28cff6be --- /dev/null +++ b/System.Web.DataVisualization/Common/General/Constants.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; + +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor,deliant + +#if WINFORMS_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + + internal static class Constants + { + public const string AutoValue = "Auto"; + public const string NotSetValue = "NotSet"; + public const string MinValue = "Min"; + public const string MaxValue = "Max"; + } + +} + diff --git a/System.Web.DataVisualization/Common/General/DataManipulator.cs b/System.Web.DataVisualization/Common/General/DataManipulator.cs new file mode 100644 index 000000000..bdd7033d6 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/DataManipulator.cs @@ -0,0 +1,3495 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: DataManipulator.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: DataManipulator, IDataPointFilter +// +// Purpose: DataManipulator class exposes to the user methods +// to perform data filtering, grouping, inserting +// empty points, sorting and exporting data. +// +// It also expose financial and statistical formulas +// through the DataFormula base class. +// +// Reviewed: AG - Jul 31, 2002; +// GS - Aug 7, 2002 +// AG - Microsoft 15, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Data; +using System.Drawing.Drawing2D; +using System.Drawing.Design; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + #region Data manipulation enumerations + + /// + /// Grouping functions types + /// + internal enum GroupingFunction + { + /// + /// Not defined + /// + None, + /// + /// Minimum value of the group + /// + Min, + /// + /// Maximum value of the group + /// + Max, + /// + /// Average value of the group + /// + Ave, + /// + /// Total of all values of the group + /// + Sum, + /// + /// Value of the first point in the group + /// + First, + /// + /// Value of the last point in the group + /// + Last, + /// + /// Value of the center point in the group + /// + Center, + /// + /// High, Low, Open, Close values in the group + /// + HiLoOpCl, + /// + /// High, Low values in the group + /// + HiLo, + /// + /// Number of points in the group + /// + Count, + /// + /// Number of unique points in the group + /// + DistinctCount, + /// + /// Variance of points in the group + /// + Variance, + /// + /// Deviation of points in the group + /// + Deviation + } + + /// + /// An enumeration of units of measurement for intervals. + /// + public enum IntervalType + { + /// + /// Interval in numbers. + /// + Number, + /// + /// Interval in years. + /// + Years, + /// + /// Interval in months. + /// + Months, + /// + /// Interval in weeks. + /// + Weeks, + /// + /// Interval in days. + /// + Days, + /// + /// Interval in hours. + /// + Hours, + /// + /// Interval in minutes. + /// + Minutes, + /// + /// Interval in seconds. + /// + Seconds, + /// + /// Interval in milliseconds. + /// + Milliseconds + } + + /// + /// An enumeration of units of measurement for date ranges. + /// + public enum DateRangeType + { + /// + /// Range defined in years. + /// + Year, + /// + /// Range defined in months. + /// + Month, + /// + /// Range defined in days of week. + /// + DayOfWeek, + /// + /// Range defined in days of month. + /// + DayOfMonth, + /// + /// Range defined in hours. + /// + Hour, + /// + /// Range defined in minutes. + /// + Minute + } + + /// + /// An enumeration of methods of comparison. + /// + public enum CompareMethod + { + /// + /// One value is more than the other value. + /// + MoreThan, + /// + /// One value is less than the other value. + /// + LessThan, + /// + /// One value is equal the other value. + /// + EqualTo, + /// + /// One value is more or equal to the other value. + /// + MoreThanOrEqualTo, + /// + /// One value is less or equal to the other value. + /// + LessThanOrEqualTo, + /// + /// One value is not equal to the other value. + /// + NotEqualTo + } + + #endregion + + #region Data points filtering inteface + + /// + /// The IDataPointFilter interface is used for filtering series data points. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public interface IDataPointFilter + { + /// + /// Checks if the specified data point must be filtered. + /// + /// Data point object. + /// Series of the point. + /// Index of the point in the series. + /// True if point must be removed + bool FilterDataPoint(DataPoint point, Series series, int pointIndex); + } + + #endregion + + /// + /// The DataManipulator class is used at runtime to perform data manipulation + /// operations, and is exposed via the DataManipulator property of the + /// root Chart object. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class DataManipulator : DataFormula + { + #region Fields + + // Indicates that filtering do not remove points, just mark them as empty + private bool _filterSetEmptyPoints = false; + + // Indicates that points that match the criteria must be filtered out + private bool _filterMatchedPoints = true; + + #endregion // Fields + + #region Data manipulator helper functions + + /// + /// Helper function that converts one series or a comma separated + /// list of series names into the Series array. + /// + /// Series or string of series names. + /// If series with this name do not exist - create new. + /// Array of series. + internal Series[] ConvertToSeriesArray(object obj, bool createNew) + { + Series[] array = null; + + if(obj == null) + { + return null; + } + + // Parameter is one series + if(obj.GetType() == typeof(Series)) + { + array = new Series[1]; + array[0] = (Series)obj; + } + + // Parameter is a string (comma separated series names) + else if(obj.GetType() == typeof(string)) + { + string series = (string)obj; + int index = 0; + + // "*" means process all series from the collection + if(series == "*") + { + // Create array of series + array = new Series[Common.DataManager.Series.Count]; + + // Add all series from the collection + foreach(Series s in Common.DataManager.Series) + { + array[index] = s; + ++index; + } + } + + // Comma separated list + else if(series.Length > 0) + { + // Replace commas in value string + series = series.Replace("\\,", "\\x45"); + series = series.Replace("\\=", "\\x46"); + + // Split string by comma + string[] seriesNames = series.Split(','); + + // Create array of series + array = new Series[seriesNames.Length]; + + // Find series by name + foreach(string s in seriesNames) + { + // Put pack a comma character + string seriesName = s.Replace("\\x45", ","); + seriesName = seriesName.Replace("\\x46", "="); + + try + { + array[index] = Common.DataManager.Series[seriesName.Trim()]; + } + catch(System.Exception) + { + if(createNew) + { + Series newSeries = new Series(seriesName.Trim()); + Common.DataManager.Series.Add(newSeries); + array[index] = newSeries; + } + else + { + throw; + } + } + + ++index; + } + } + } + + return array; + } + + /// + /// Public constructor + /// + public DataManipulator() + { + } + + #endregion + + #region Series points sorting methods + + /// + /// Sort series data points in specified order. + /// + /// Sorting order. + /// Value to sort by. + /// Series array to sort. + private void Sort(PointSortOrder pointSortOrder, string sortBy, Series[] series) + { + // Check arguments + if (sortBy == null) + throw new ArgumentNullException("sortBy"); + if (series == null) + throw new ArgumentNullException("series"); + + // Check array of series + if(series.Length == 0) + { + return; + } + + // Sort series + DataPointComparer comparer = new DataPointComparer(series[0], pointSortOrder, sortBy); + this.Sort(comparer, series); + } + + /// + /// Sort series data points in specified order. + /// + /// Comparing interface. + /// Series array to sort. + private void Sort(IComparer comparer, Series[] series) + { + // Check arguments + if (comparer == null) + throw new ArgumentNullException("comparer"); + if (series == null) + throw new ArgumentNullException("series"); + + //************************************************** + //** Check array of series + //************************************************** + if(series.Length == 0) + { + return; + } + + //************************************************** + //** If we sorting more than one series + //************************************************** + if(series.Length > 1) + { + // Check if series X values are aligned + this.CheckXValuesAlignment(series); + + // Apply points indexes to the first series + int pointIndex = 0; + foreach(DataPoint point in series[0].Points) + { + point["_Index"] = pointIndex.ToString(System.Globalization.CultureInfo.InvariantCulture); + ++pointIndex; + } + } + + //************************************************** + //** Sort first series + //************************************************** + series[0].Sort(comparer); + + //************************************************** + //** If we sorting more than one series + //************************************************** + if(series.Length > 1) + { + // Sort other series (depending on the first) + int toIndex = 0; + int fromIndex = 0; + foreach(DataPoint point in series[0].Points) + { + // Move point from index is stored in point attribute (as index before sorting) + fromIndex = int.Parse(point["_Index"], System.Globalization.CultureInfo.InvariantCulture); + + // Move points in series + for(int seriesIndex = 1; seriesIndex < series.Length; seriesIndex++) + { + series[seriesIndex].Points.Insert(toIndex, series[seriesIndex].Points[toIndex + fromIndex]); + } + + // Increase move point to index + ++toIndex; + } + + // Remove extra points from series + for(int seriesIndex = 1; seriesIndex < series.Length; seriesIndex++) + { + while(series[seriesIndex].Points.Count > series[0].Points.Count) + { + series[seriesIndex].Points.RemoveAt(series[seriesIndex].Points.Count - 1); + } + } + + //************************************************** + //** Remove points index attribute + //************************************************** + foreach(DataPoint point in series[0].Points) + { + point.DeleteCustomProperty("_Index"); + } + } + } + + #endregion + + #region Series points sorting overloaded methods + + /// + /// Sort the series' data points in specified order. + /// + /// Sorting order. + /// Value to sort by. + /// Comma separated series names to sort. + public void Sort(PointSortOrder pointSortOrder, string sortBy, string seriesName) + { + // Check arguments + if (seriesName == null) + throw new ArgumentNullException("seriesName"); + + Sort(pointSortOrder, sortBy, ConvertToSeriesArray(seriesName, false)); + } + + /// + /// Sort the series' data points in specified order. + /// + /// Sorting order. + /// Series to sort. + public void Sort(PointSortOrder pointSortOrder, Series series) + { + // Check arguments + if (series == null) + throw new ArgumentNullException("series"); + + Sort(pointSortOrder, "Y", ConvertToSeriesArray(series, false)); + } + + /// + /// Sort the series' data points in specified order. + /// + /// Sorting order. + /// Comma separated series names to sort. + public void Sort(PointSortOrder pointSortOrder, string seriesName) + { + // Check arguments + if (seriesName == null) + throw new ArgumentNullException("seriesName"); + + Sort(pointSortOrder, "Y", ConvertToSeriesArray(seriesName, false)); + } + + /// + /// Sort the series' data points in specified order. + /// + /// Sorting order. + /// Value to sort by. + /// Series to sort. + public void Sort(PointSortOrder pointSortOrder, string sortBy, Series series) + { + // Check arguments + if (series == null) + throw new ArgumentNullException("series"); + + Sort(pointSortOrder, sortBy, ConvertToSeriesArray(series, false)); + } + + /// + /// Sort the series' data points in specified order. + /// + /// IComparer interface. + /// Series to sort. + public void Sort(IComparer comparer, Series series) + { + // Check arguments - comparer is checked in the private override of Sort + if (series == null) + throw new ArgumentNullException("series"); + + Sort(comparer, ConvertToSeriesArray(series, false)); + } + + /// + /// Sort the series' data points in specified order. + /// + /// Comparing interface. + /// Comma separated series names to sort. + public void Sort(IComparer comparer, string seriesName) + { + // Check arguments - comparer is checked in the private override of Sort + if (seriesName == null) + throw new ArgumentNullException("seriesName"); + + Sort(comparer, ConvertToSeriesArray(seriesName, false)); + } + + #endregion + + #region Insert empty data points method + + /// + /// Insert empty data points using specified interval. + /// + /// Interval size. + /// Interval type. + /// Interval offset size. + /// Interval offset type. + /// Check intervals from this X value. + /// Check intervals until this X value. + /// Series array. + private void InsertEmptyPoints( + double interval, + IntervalType intervalType, + double intervalOffset, + IntervalType intervalOffsetType, + double fromXValue, + double toXValue, + Series[] series) + { + // Check the arguments + if (interval <= 0) + throw new ArgumentOutOfRangeException("interval"); + + //************************************************** + //** Automaticly detect minimum and maximum values + //************************************************** + double fromX = Math.Min(fromXValue, toXValue); + double toX = Math.Max(fromXValue, toXValue); + bool fromIsNaN = double.IsNaN(fromX); + bool toIsNaN = double.IsNaN(toX); + foreach(Series ser in series) + { + if(ser.Points.Count >= 1) + { + if(toIsNaN) + { + if(double.IsNaN(toX)) + { + toX = ser.Points[ser.Points.Count - 1].XValue; + } + else + { + toX = Math.Max(toX, ser.Points[ser.Points.Count - 1].XValue); + } + } + if(fromIsNaN) + { + if(double.IsNaN(fromX)) + { + fromX = ser.Points[0].XValue; + } + else + { + fromX = Math.Min(fromX, ser.Points[0].XValue); + } + } + if(fromX > toX) + { + double tempValue = fromX; + fromX = toX; + toX = tempValue; + } + } + } + + //************************************************** + //** Automaticly adjust the beginning interval and + //** offset + //************************************************** + double nonAdjustedFromX = fromX; + fromX = ChartHelper.AlignIntervalStart(fromX, interval, ConvertIntervalType(intervalType)); + + // Add offset to the start position + if( intervalOffset != 0 ) + { + fromX = fromX + ChartHelper.GetIntervalSize(fromX, intervalOffset, ConvertIntervalType(intervalOffsetType), null, 0, DateTimeIntervalType.Number, true, false); + } + + + //************************************************** + //** Loop through all series + //************************************************** + foreach(Series ser in series) + { + //************************************************** + //** Loop through all data points + //************************************************** + int numberOfPoints = 0; + int lastInsertPoint = 0; + double currentPointValue = fromX; + while(currentPointValue <= toX) + { + //************************************************** + //** Check that X value is in range + //************************************************** + bool outOfRange = false; + if(double.IsNaN(fromXValue) && currentPointValue < nonAdjustedFromX || + !double.IsNaN(fromXValue) && currentPointValue < fromXValue) + { + outOfRange = true; + } + else if(currentPointValue > toXValue) + { + outOfRange = true; + } + + + // Current X value is in range of points values + if(!outOfRange) + { + //************************************************** + //** Find required X value + //************************************************** + int insertPosition = lastInsertPoint; + for(int pointIndex = lastInsertPoint; pointIndex < ser.Points.Count; pointIndex++) + { + // Value was found + if(ser.Points[pointIndex].XValue == currentPointValue) + { + insertPosition = -1; + break; + } + + // Save point index where we should insert new empty point + if(ser.Points[pointIndex].XValue > currentPointValue) + { + insertPosition = pointIndex; + break; + } + + // Insert as last point + if(pointIndex == (ser.Points.Count - 1)) + { + insertPosition = ser.Points.Count; + } + } + + //************************************************** + //** Required value was not found - insert empty data point + //************************************************** + if(insertPosition != -1) + { + lastInsertPoint = insertPosition; + ++numberOfPoints; + DataPoint dataPoint = new DataPoint(ser); + dataPoint.XValue = currentPointValue; + dataPoint.IsEmpty = true; + ser.Points.Insert(insertPosition, dataPoint); + } + } + + //************************************************** + //** Determine next required data point + //************************************************** + currentPointValue += ChartHelper.GetIntervalSize(currentPointValue, + interval, + ConvertIntervalType(intervalType)); + + + //************************************************** + //** Check if we exceed number of empty points + //** we can add. + //************************************************** + if(numberOfPoints > 1000) + { + currentPointValue = toX + 1; + continue; + } + } + } + } + + /// + /// Helper function which converts IntervalType enumeration + /// into DateTimeIntervalType enumeration. + /// + /// Interval type value. + /// Date time interval type value. + private DateTimeIntervalType ConvertIntervalType(IntervalType type) + { + switch(type) + { + case(IntervalType.Milliseconds): + return DateTimeIntervalType.Milliseconds; + case(IntervalType.Seconds): + return DateTimeIntervalType.Seconds; + case(IntervalType.Days): + return DateTimeIntervalType.Days; + case(IntervalType.Hours): + return DateTimeIntervalType.Hours; + case(IntervalType.Minutes): + return DateTimeIntervalType.Minutes; + case(IntervalType.Months): + return DateTimeIntervalType.Months; + case(IntervalType.Number): + return DateTimeIntervalType.Number; + case(IntervalType.Weeks): + return DateTimeIntervalType.Weeks; + case(IntervalType.Years): + return DateTimeIntervalType.Years; + } + + return DateTimeIntervalType.Auto; + } + + #endregion + + #region Insert empty data points overloaded methods + + /// + /// Insert empty data points using the specified interval. + /// + /// Interval size. + /// Interval type. + /// Series to insert the empty points. + public void InsertEmptyPoints( + double interval, + IntervalType intervalType, + Series series) + { + InsertEmptyPoints(interval, intervalType, 0, IntervalType.Number, series); + } + + /// + /// Insert empty data points using the specified interval. + /// + /// Interval size. + /// Interval type. + /// Name of series to insert the empty points. + public void InsertEmptyPoints( + double interval, + IntervalType intervalType, + string seriesName) + { + InsertEmptyPoints(interval, intervalType, 0, IntervalType.Number, seriesName); + } + + /// + /// Insert empty data points using the specified interval. + /// + /// Interval size. + /// Interval type. + /// Interval offset size. + /// Interval offset type. + /// Name of series to insert the empty points. + public void InsertEmptyPoints( + double interval, + IntervalType intervalType, + double intervalOffset, + IntervalType intervalOffsetType, + string seriesName) + { + InsertEmptyPoints(interval, intervalType, intervalOffset, intervalOffsetType, double.NaN, double.NaN, seriesName); + } + + /// + /// Insert empty data points using the specified interval. + /// + /// Interval size. + /// Interval type. + /// Interval offset size. + /// Interval offset type. + /// Series to insert the empty points. + public void InsertEmptyPoints( + double interval, + IntervalType intervalType, + double intervalOffset, + IntervalType intervalOffsetType, + Series series) + { + InsertEmptyPoints(interval, intervalType, intervalOffset, intervalOffsetType, double.NaN, double.NaN, series); + } + + /// + /// Insert empty data points using the specified interval. + /// + /// Interval size. + /// Interval type. + /// Interval offset size. + /// Interval offset type. + /// Check intervals from this X value. + /// Check intervals until this X value. + /// Name of series to insert the empty points. + public void InsertEmptyPoints( + double interval, + IntervalType intervalType, + double intervalOffset, + IntervalType intervalOffsetType, + double fromXValue, + double toXValue, + string seriesName) + { + // Check arguments + if (seriesName == null) + throw new ArgumentNullException("seriesName"); + + InsertEmptyPoints( + interval, + intervalType, + intervalOffset, + intervalOffsetType, + fromXValue, + toXValue, + ConvertToSeriesArray(seriesName, false)); + } + + + /// + /// Insert empty data points using the specified interval. + /// + /// Interval size. + /// Interval type. + /// Interval offset size. + /// Interval offset type. + /// Check intervals from this X value. + /// Check intervals until this X value. + /// Series to insert the empty points. + public void InsertEmptyPoints( + double interval, + IntervalType intervalType, + double intervalOffset, + IntervalType intervalOffsetType, + double fromXValue, + double toXValue, + Series series) + { + // Check arguments + if (series == null) + throw new ArgumentNullException("series"); + + InsertEmptyPoints( + interval, + intervalType, + intervalOffset, + intervalOffsetType, + fromXValue, + toXValue, + ConvertToSeriesArray(series, false)); + } + + + #endregion + + #region Series data exporting methods + + /// + /// Export series data into the DataSet object. + /// + /// Array of series which should be exported. + /// Data set object with series data. + internal DataSet ExportSeriesValues(Series[] series) + { + //***************************************************** + //** Create DataSet object + //***************************************************** + DataSet dataSet = new DataSet(); + dataSet.Locale = System.Globalization.CultureInfo.CurrentCulture; + // If input series are specified + if(series != null) + { + // Export each series in the loop + foreach(Series ser in series) + { + + //***************************************************** + //** Check if all X values are zeros + //***************************************************** + bool zeroXValues = true; + foreach( DataPoint point in ser.Points ) + { + if( point.XValue != 0.0 ) + { + zeroXValues = false; + break; + } + } + + // Added 10 May 2005, DT - dataset after databinding + // to string x value returns X as indexes + if (zeroXValues && ser.XValueType == ChartValueType.String) + { + zeroXValues = false; + } + + //***************************************************** + //** Create new table for the series + //***************************************************** + DataTable seriesTable = new DataTable(ser.Name); + seriesTable.Locale = System.Globalization.CultureInfo.CurrentCulture; + + //***************************************************** + //** Add X column into data table schema + //***************************************************** + Type columnType = typeof(double); + if(ser.IsXValueDateTime()) + { + columnType = typeof(DateTime); + } + else if(ser.XValueType == ChartValueType.String) + { + columnType = typeof(string); + } + seriesTable.Columns.Add("X", columnType); + + + //***************************************************** + //** Add Y column(s) into data table schema + //***************************************************** + columnType = typeof(double); + if(ser.IsYValueDateTime()) + { + columnType = typeof(DateTime); + } + else if(ser.YValueType == ChartValueType.String) + { + columnType = typeof(string); + } + for(int yIndex = 0; yIndex < ser.YValuesPerPoint; yIndex++) + { + if(yIndex == 0) + { + seriesTable.Columns.Add("Y", columnType); + } + else + { + seriesTable.Columns.Add("Y" + (yIndex + 1).ToString(System.Globalization.CultureInfo.InvariantCulture), columnType); + } + } + + + //***************************************************** + //** Fill data table's rows + //***************************************************** + double pointIndex = 1.0; + foreach(DataPoint point in ser.Points) + { + if(!point.IsEmpty || !this.IsEmptyPointIgnored) + { + DataRow dataRow = seriesTable.NewRow(); + + // Set row X value + object xValue = point.XValue; + if(ser.IsXValueDateTime()) + { + if (Double.IsNaN(point.XValue)) + xValue = DBNull.Value; + else + xValue = DateTime.FromOADate(point.XValue); + } + else if(ser.XValueType == ChartValueType.String) + { + xValue = point.AxisLabel; + } + dataRow["X"] = (zeroXValues) ? pointIndex : xValue; + + // Set row Y value(s) + for(int yIndex = 0; yIndex < ser.YValuesPerPoint; yIndex++) + { + object yValue = point.YValues[yIndex]; + if(!point.IsEmpty) + { + if(ser.IsYValueDateTime()) + { + if (Double.IsNaN(point.YValues[yIndex])) + xValue = DBNull.Value; + else + yValue = DateTime.FromOADate(point.YValues[yIndex]); + } + else if(ser.YValueType == ChartValueType.String) + { + yValue = point.AxisLabel; + } + } + else if(!this.IsEmptyPointIgnored) + { + // Special handling of empty points + yValue = DBNull.Value; + } + + if(yIndex == 0) + { + dataRow["Y"] = yValue; + } + else + { + dataRow["Y" + (yIndex + 1).ToString(System.Globalization.CultureInfo.InvariantCulture)] = yValue; + } + } + + // Add row to the table + seriesTable.Rows.Add(dataRow); + + ++pointIndex; + } + } + + // Accept changes + seriesTable.AcceptChanges(); + + //***************************************************** + //** Add data table into the data set + //***************************************************** + dataSet.Tables.Add(seriesTable); + } + } + + return dataSet; + } + + #endregion + + #region Series data exporting overloaded methods + + /// + /// Export all series from the collection into the DataSet object. + /// + /// Dataset object with series data. + public DataSet ExportSeriesValues() + { + return ExportSeriesValues("*"); + } + + /// + /// Export series data into the DataSet object. + /// + /// Comma separated list of series names to be exported. + /// Dataset object with series data. + public DataSet ExportSeriesValues(string seriesNames) + { + // Check arguments + if (seriesNames == null) + throw new ArgumentNullException(seriesNames); + + return ExportSeriesValues(ConvertToSeriesArray(seriesNames, false)); + } + + /// + /// Export series data into the DataSet object. + /// + /// Series to be exported. + /// Dataset object with series data. + public DataSet ExportSeriesValues(Series series) + { + // Check arguments + if (series == null) + throw new ArgumentNullException("series"); + + return ExportSeriesValues(ConvertToSeriesArray(series, false)); + } + + #endregion + + #region Filtering properties + + /// + /// Gets or sets a flag which indicates whether points filtered by + /// the Filter or FilterTopN methods are removed or marked as empty. + /// If set to true, filtered points are marked as empty; otherwise they are removed. + /// This property defaults to be false. + /// + public bool FilterSetEmptyPoints + { + get + { + return _filterSetEmptyPoints; + } + set + { + _filterSetEmptyPoints = value; + } + } + + /// + /// Gets or sets a value that determines if points are filtered + /// if they match criteria that is specified in Filter method calls. + /// If set to true, points that match specified criteria are filtered. + /// If set to false, points that do not match the criteria are filtered. + /// This property defaults to be true. + /// + public bool FilterMatchedPoints + { + get + { + return _filterMatchedPoints; + } + set + { + _filterMatchedPoints = value; + } + } + + #endregion + + #region Filtering methods + + /// + /// Keeps only N top/bottom points of the series + /// + /// Number of top/bottom points to return. + /// Input series array. + /// Output series array. + /// Defines which value of the point use in comparison (X, Y, Y2, ...). + /// Indicate that N top values must be retrieved, otherwise N bottom values. + private void FilterTopN(int pointCount, + Series[] inputSeries, + Series[] outputSeries, + string usingValue, + bool getTopValues) + { + // Check input/output series arrays + CheckSeriesArrays(inputSeries, outputSeries); + + // Check input series alignment + CheckXValuesAlignment(inputSeries); + + if(pointCount <= 0) + { + throw (new ArgumentOutOfRangeException("pointCount", SR.ExceptionDataManipulatorPointCountIsZero)); + } + + //************************************************** + //** Filter points in the first series and remove + //** in all + //************************************************** + + // Define an output series array + Series[] output = new Series[inputSeries.Length]; + for(int seriesIndex = 0; seriesIndex < inputSeries.Length; seriesIndex++) + { + output[seriesIndex] = inputSeries[seriesIndex]; + if(outputSeries != null && outputSeries.Length > seriesIndex) + { + output[seriesIndex] = outputSeries[seriesIndex]; + } + + // Remove all points from the output series + if(output[seriesIndex] != inputSeries[seriesIndex]) + { + output[seriesIndex].Points.Clear(); + + // Make sure there is enough Y values per point + output[seriesIndex].YValuesPerPoint = inputSeries[seriesIndex].YValuesPerPoint; + + // Copy X values type + if(output[seriesIndex].XValueType == ChartValueType.Auto || output[seriesIndex].autoXValueType) + { + output[seriesIndex].XValueType = inputSeries[seriesIndex].XValueType; + output[seriesIndex].autoXValueType = true; + } + // Copy Y values type + if(output[seriesIndex].YValueType == ChartValueType.Auto || output[seriesIndex].autoYValueType) + { + output[seriesIndex].YValueType = inputSeries[seriesIndex].YValueType; + output[seriesIndex].autoYValueType = true; + } + + // Copy input points into output + foreach(DataPoint point in inputSeries[seriesIndex].Points) + { + output[seriesIndex].Points.Add(point.Clone()); + } + } + + } + + // No points to filter + if(inputSeries[0].Points.Count == 0) + { + return; + } + + //************************************************** + //** Sort input data + //************************************************** + this.Sort((getTopValues) ? PointSortOrder.Descending : PointSortOrder.Ascending, + usingValue, + output); + + //************************************************** + //** Get top/bottom points + //************************************************** + // Process all series + for(int seriesIndex = 0; seriesIndex < inputSeries.Length; seriesIndex++) + { + // Only keep N first points + while(output[seriesIndex].Points.Count > pointCount) + { + if(this.FilterSetEmptyPoints) + { + output[seriesIndex].Points[pointCount].IsEmpty = true; + ++pointCount; + } + else + { + output[seriesIndex].Points.RemoveAt(pointCount); + } + } + } + } + + /// + /// Filter data points using IDataPointFilter interface + /// + /// Data points filtering interface. + /// Input series array. + /// Output series array. + private void Filter(IDataPointFilter filterInterface, + Series[] inputSeries, + Series[] outputSeries) + { + //************************************************** + //** Check input/output series arrays + //************************************************** + CheckSeriesArrays(inputSeries, outputSeries); + + CheckXValuesAlignment(inputSeries); + + if(filterInterface == null) + { + throw(new ArgumentNullException("filterInterface")); + } + + //************************************************** + //** Filter points in the first series and remove + //** in all + //************************************************** + + // Define an output series array + Series[] output = new Series[inputSeries.Length]; + for(int seriesIndex = 0; seriesIndex < inputSeries.Length; seriesIndex++) + { + output[seriesIndex] = inputSeries[seriesIndex]; + if(outputSeries != null && outputSeries.Length > seriesIndex) + { + output[seriesIndex] = outputSeries[seriesIndex]; + } + + // Remove all points from the output series + if(output[seriesIndex] != inputSeries[seriesIndex]) + { + output[seriesIndex].Points.Clear(); + + // Make sure there is enough Y values per point + output[seriesIndex].YValuesPerPoint = inputSeries[seriesIndex].YValuesPerPoint; + + // Copy X values type + if(output[seriesIndex].XValueType == ChartValueType.Auto || output[seriesIndex].autoXValueType) + { + output[seriesIndex].XValueType = inputSeries[seriesIndex].XValueType; + output[seriesIndex].autoXValueType = true; + } + // Copy Y values type + if(output[seriesIndex].YValueType == ChartValueType.Auto || output[seriesIndex].autoYValueType) + { + output[seriesIndex].YValueType = inputSeries[seriesIndex].YValueType; + output[seriesIndex].autoYValueType = true; + } + + } + + } + + // No points to filter + if(inputSeries[0].Points.Count == 0) + { + return; + } + + //************************************************** + //** Loop through all points of the first input series + //************************************************** + int originalPointIndex = 0; + for(int pointIndex = 0; pointIndex < inputSeries[0].Points.Count; pointIndex++, originalPointIndex++) + { + bool pointRemoved = false; + + // Check if point match the criteria + bool matchCriteria = filterInterface.FilterDataPoint( + inputSeries[0].Points[pointIndex], + inputSeries[0], + originalPointIndex) == this.FilterMatchedPoints; + + + // Process all series + for(int seriesIndex = 0; seriesIndex < inputSeries.Length; seriesIndex++) + { + bool seriesMatchCriteria = matchCriteria; + if(output[seriesIndex] != inputSeries[seriesIndex]) + { + if(seriesMatchCriteria && !this.FilterSetEmptyPoints) + { + // Don't do anything... + seriesMatchCriteria = false; + } + else + { + // Copy point into the output series for all series + output[seriesIndex].Points.Add(inputSeries[seriesIndex].Points[pointIndex].Clone()); + } + } + + + // If point match the criteria + if(seriesMatchCriteria) + { + // Set point's empty flag + if(this.FilterSetEmptyPoints) + { + output[seriesIndex].Points[pointIndex].IsEmpty = true; + for(int valueIndex = 0; valueIndex < output[seriesIndex].Points[pointIndex].YValues.Length; valueIndex++) + { + output[seriesIndex].Points[pointIndex].YValues[valueIndex] = 0.0; + } + } + + // Remove point + else + { + output[seriesIndex].Points.RemoveAt(pointIndex); + pointRemoved = true; + } + } + } + + // Adjust index because of the removed point + if(pointRemoved) + { + --pointIndex; + } + } + } + + /// + /// Data point filter. + /// Filters points using element type and index + /// + private class PointElementFilter : IDataPointFilter + { + // Private fields + private DataManipulator _dataManipulator = null; + private DateRangeType _dateRange; + private int[] _rangeElements = null; + + // Default constructor is not accesiable + private PointElementFilter() + { + } + + /// + /// Public constructor. + /// + /// Data manipulator object. + /// Range type. + /// Range elements to filter. + public PointElementFilter(DataManipulator dataManipulator, DateRangeType dateRange, string rangeElements) + { + this._dataManipulator = dataManipulator; + this._dateRange = dateRange; + this._rangeElements = dataManipulator.ConvertElementIndexesToArray(rangeElements); + } + + /// + /// Data points filtering method. + /// + /// Data point. + /// Data point series. + /// Data point index. + /// Indicates that point should be filtered. + public bool FilterDataPoint(DataPoint point, Series series, int pointIndex) + { + return _dataManipulator.CheckFilterElementCriteria( + this._dateRange, + this._rangeElements, + point); + } + } + + /// + /// Data point filter. + /// Filters points using point values + /// + private class PointValueFilter : IDataPointFilter + { + // Private fields + private CompareMethod _compareMethod; + private string _usingValue; + private double _compareValue; + + /// + /// Default constructor is not accessible + /// + private PointValueFilter() + { + } + + /// + /// Public constructor. + /// + /// Comparing method. + /// Comparing constant. + /// Value used in comparison. + public PointValueFilter(CompareMethod compareMethod, + double compareValue, + string usingValue) + { + this._compareMethod = compareMethod; + this._usingValue = usingValue; + this._compareValue = compareValue; + } + + /// + /// IDataPointFilter interface method implementation + /// + /// Data point. + /// Data point series. + /// Data point index. + /// Indicates that point should be filtered. + public bool FilterDataPoint(DataPoint point, Series series, int pointIndex) + { + // Check if point match the criteria + bool matchCriteria = false; + switch(_compareMethod) + { + case(CompareMethod.EqualTo): + matchCriteria = point.GetValueByName(_usingValue) + == _compareValue; + break; + case(CompareMethod.LessThan): + matchCriteria = point.GetValueByName(_usingValue) + < _compareValue; + break; + case(CompareMethod.LessThanOrEqualTo): + matchCriteria = point.GetValueByName(_usingValue) + <= _compareValue; + break; + case(CompareMethod.MoreThan): + matchCriteria = point.GetValueByName(_usingValue) + > _compareValue; + break; + case(CompareMethod.MoreThanOrEqualTo): + matchCriteria = point.GetValueByName(_usingValue) + >= _compareValue; + break; + case(CompareMethod.NotEqualTo): + matchCriteria = point.GetValueByName(_usingValue) + != _compareValue; + break; + } + + return matchCriteria; + } + } + + /// + /// Helper function to convert elements indexes from a string + /// into an array of integers + /// + /// Element indexes string. Ex:"3,5,6-9,15" + /// Array of integer indexes. + private int[] ConvertElementIndexesToArray(string rangeElements) + { + // Split input string by comma + string[] indexes = rangeElements.Split(','); + + // Check if there are items in the array + if(indexes.Length == 0) + { + throw (new ArgumentException(SR.ExceptionDataManipulatorIndexUndefined, "rangeElements")); + } + + // Allocate memory for the result array + int[] result = new int[indexes.Length * 2]; + + // Process each element index + int index = 0; + foreach(string str in indexes) + { + // Check if it's a simple index or a range + if(str.IndexOf('-') != -1) + { + string[] rangeIndex = str.Split('-'); + if(rangeIndex.Length == 2) + { + // Convert to integer + try + { + result[index] = Int32.Parse(rangeIndex[0], System.Globalization.CultureInfo.InvariantCulture); + result[index + 1] = Int32.Parse(rangeIndex[1], System.Globalization.CultureInfo.InvariantCulture); + + if(result[index + 1] < result[index]) + { + int temp = result[index]; + result[index] = result[index + 1]; + result[index + 1] = temp; + } + } + catch(System.Exception) + { + throw (new ArgumentException(SR.ExceptionDataManipulatorIndexFormatInvalid, "rangeElements")); + } + } + else + { + throw (new ArgumentException(SR.ExceptionDataManipulatorIndexFormatInvalid, "rangeElements")); + } + } + else + { + // Convert to integer + try + { + result[index] = Int32.Parse(str, System.Globalization.CultureInfo.InvariantCulture); + result[index + 1] = result[index]; + } + catch(System.Exception) + { + throw (new ArgumentException(SR.ExceptionDataManipulatorIndexFormatInvalid, "rangeElements")); + } + } + + index += 2; + } + + return result; + } + + /// + /// Helper function, which checks if specified point matches the criteria + /// + /// Element type. + /// Array of element indexes ranges (pairs). + /// Data point to check. + /// True if point matches the criteria. + private bool CheckFilterElementCriteria( + DateRangeType dateRange, + int[] rangeElements, + DataPoint point) + { + // Conver X value to DateTime + DateTime dateTimeValue = DateTime.FromOADate(point.XValue); + + for(int index = 0; index < rangeElements.Length; index += 2) + { + switch(dateRange) + { + case(DateRangeType.Year): + if(dateTimeValue.Year >= rangeElements[index] && + dateTimeValue.Year <= rangeElements[index+1]) + return true; + break; + case(DateRangeType.Month): + if(dateTimeValue.Month >= rangeElements[index] && + dateTimeValue.Month <= rangeElements[index+1]) + return true; + break; + case(DateRangeType.DayOfWeek): + if((int)dateTimeValue.DayOfWeek >= rangeElements[index] && + (int)dateTimeValue.DayOfWeek <= rangeElements[index+1]) + return true; + break; + case(DateRangeType.DayOfMonth): + if(dateTimeValue.Day >= rangeElements[index] && + dateTimeValue.Day <= rangeElements[index+1]) + return true; + break; + case(DateRangeType.Hour): + if(dateTimeValue.Hour >= rangeElements[index] && + dateTimeValue.Hour <= rangeElements[index+1]) + return true; + break; + case(DateRangeType.Minute): + if(dateTimeValue.Minute >= rangeElements[index] && + dateTimeValue.Minute <= rangeElements[index+1]) + return true; + break; + } + } + + return false; + } + + #endregion + + #region Filtering overloaded methods + + /// + /// Filters a series' data points, either removing the specified points + /// or marking them as empty for the given date/time ranges. + /// + /// Element type. + /// Specifies the elements within the date/time range + /// (specified by the dateRange parameter) that will be filtered. Can be a single value (e.g. "7"), + /// comma-separated values (e.g. "5,6"), a range of values (e.g. 9-11), + /// or any variation thereof (e.g. "5,6,9-11"). + /// Comma separated list of input series names. + /// Comma separated list of output series names, to store the output. + public void Filter(DateRangeType dateRange, + string rangeElements, + string inputSeriesNames, + string outputSeriesNames) + { + // Check arguments + if (rangeElements == null) + throw new ArgumentNullException("rangeElements"); + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + + // Filter points using filtering interface + Filter(new PointElementFilter(this, dateRange, rangeElements), + ConvertToSeriesArray(inputSeriesNames, false), + ConvertToSeriesArray(outputSeriesNames, true)); + } + + /// + /// Filters a series' data points, either removing the specified points + /// or marking them as empty for the given date/time ranges. + /// The Series object that is filtered is used to store the modified data. + /// + /// Element type. + /// Specifies the elements within the date/time range + /// (specified by the dateRange parameter) that will be filtered. Can be a single value (e.g. "7"), + /// comma-separated values (e.g. "5,6"), a range of values (e.g. 9-11), + /// or any variation thereof (e.g. "5,6,9-11"). + /// Input series. + public void Filter(DateRangeType dateRange, + string rangeElements, + Series inputSeries) + { + // Check arguments + if (rangeElements == null) + throw new ArgumentNullException("rangeElements"); + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + Filter(dateRange, rangeElements, inputSeries, null); + } + + /// + /// Filters a series' data points, either removing the specified points + /// or marking them as empty for the given date/time ranges. + /// + /// Element type. + /// Specifies the elements within the date/time range + /// (specified by the dateRange parameter) that will be filtered. Can be a single value (e.g. "7"), + /// comma-separated values (e.g. "5,6"), a range of values (e.g. 9-11), + /// or any variation thereof (e.g. "5,6,9-11"). + /// Input series. + /// Output series. + public void Filter(DateRangeType dateRange, + string rangeElements, + Series inputSeries, + Series outputSeries) + { + // Check arguments + if (rangeElements == null) + throw new ArgumentNullException("rangeElements"); + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + // Filter points using filtering interface + Filter(new PointElementFilter(this, dateRange, rangeElements), + ConvertToSeriesArray(inputSeries, false), + ConvertToSeriesArray(outputSeries, false)); + } + + /// + /// Filters a series' data points, either removing the specified points + /// or marking them as empty for the given date/time ranges. + /// The filtered Series objects are used to store the modified data. + /// + /// Element type. + /// Specifies the elements within the date/time range + /// (specified by the dateRange parameter) that will be filtered. Can be a single value (e.g. "7"), + /// comma-separated values (e.g. "5,6"), a range of values (e.g. 9-11), + /// or any variation thereof (e.g. "5,6,9-11"). + /// Comma separated list of input series names. + public void Filter(DateRangeType dateRange, + string rangeElements, + string inputSeriesNames) + { + // Check arguments + if (rangeElements == null) + throw new ArgumentNullException("rangeElements"); + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + + Filter(dateRange, + rangeElements, + inputSeriesNames, + ""); + } + + /// + /// Filters a series' data points by applying a filtering rule to the first Y-value of data points. + /// The Series object that is filtered is used to store the modified data. + /// + /// Value comparing method. + /// Value to compare with. + /// Input series. + public void Filter(CompareMethod compareMethod, + double compareValue, + Series inputSeries) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + Filter(compareMethod, + compareValue, + inputSeries, + null, + "Y"); + } + + /// + /// Filters a series' data points by applying a filtering rule to the first Y-value of data points. + /// + /// Value comparing method. + /// Value to compare with. + /// Input series. + /// Output series. + public void Filter(CompareMethod compareMethod, + double compareValue, + Series inputSeries, + Series outputSeries) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + // Filter points using filtering interface + Filter(new PointValueFilter(compareMethod, compareValue, "Y"), + ConvertToSeriesArray(inputSeries, false), + ConvertToSeriesArray(outputSeries, false)); + } + + /// + /// Filters a series' data points by applying a filtering rule to the specified value for comparison. + /// + /// Value comparing method. + /// Value to compare with. + /// Input series. + /// Output series. + /// The data point value that the filtering rule is applied to. Can be X, Y, Y2, Y3, etc. + public void Filter(CompareMethod compareMethod, + double compareValue, + Series inputSeries, + Series outputSeries, + string usingValue) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + if (usingValue == null) + throw new ArgumentNullException("usingValue"); + + // Filter points using filtering interface + Filter(new PointValueFilter(compareMethod, compareValue, usingValue), + ConvertToSeriesArray(inputSeries, false), + ConvertToSeriesArray(outputSeries, false)); + } + + /// + /// Filters one or more series by applying a filtering rule to the first Y-value of the first series' data points. + /// The filtered Series objects are used to store the modified data. + /// + /// Value comparing method. + /// Value to compare with. + /// Comma separated list of input series names. + public void Filter(CompareMethod compareMethod, + double compareValue, + string inputSeriesNames) + { + // Check arguments + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + + Filter(compareMethod, + compareValue, + inputSeriesNames, + "", + "Y"); + } + + /// + /// Filters one or more series by applying a filtering rule to the first Y-value of the first series' data points. + /// + /// Value comparing method. + /// Value to compare with. + /// Comma separated list of input series names. + /// Comma separated list of output series names. + public void Filter(CompareMethod compareMethod, + double compareValue, + string inputSeriesNames, + string outputSeriesNames) + { + // Check arguments + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + + // Filter points using filtering interface + Filter(new PointValueFilter(compareMethod, compareValue, "Y"), + ConvertToSeriesArray(inputSeriesNames, false), + ConvertToSeriesArray(outputSeriesNames, true)); + } + + /// + /// Filters one or more series by applying a filtering rule to the specified value of the first series' data points. + /// + /// Value comparing method. + /// Value to compare with. + /// Comma separated input series names. + /// Comma separated output series names. + /// The data point value that the filtering rule is applied to. Can be X, Y, Y2, Y3, etc. + public void Filter(CompareMethod compareMethod, + double compareValue, + string inputSeriesNames, + string outputSeriesNames, + string usingValue) + { + // Check arguments + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + if (usingValue == null) + throw new ArgumentNullException("usingValue"); + + // Filter points using filtering interface + Filter(new PointValueFilter(compareMethod, compareValue, usingValue), + ConvertToSeriesArray(inputSeriesNames, false), + ConvertToSeriesArray(outputSeriesNames, true)); + } + + /// + /// Filters all data points in one or more series except for a specified number of points. + /// The points that are not filtered correspond to points in the first input series that have the largest or smallest values. + /// + /// The number of data points that the filtering operation will not remove. + /// Comma separated list of input series names. + /// Comma separated list of output series names. + /// The data point value that the filtering rule is applied to. Can be X, Y, Y2, Y3, etc. + /// The largest values are kept if set to true; otherwise the smallest values are kept. + public void FilterTopN(int pointCount, + string inputSeriesNames, + string outputSeriesNames, + string usingValue, + bool getTopValues) + { + // Check arguments + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + if (usingValue == null) + throw new ArgumentNullException("usingValue"); + + FilterTopN(pointCount, + ConvertToSeriesArray(inputSeriesNames, false), + ConvertToSeriesArray(outputSeriesNames, true), + usingValue, + getTopValues); + } + + /// + /// Filters out all data points in a series except for a specified number of points with the largest (first) Y-values. + /// The Series object that is filtered is used to store the modified data. + /// + /// The number of data points that the filtering operation will not remove. + /// Input series. + public void FilterTopN(int pointCount, + Series inputSeries) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + FilterTopN(pointCount, + ConvertToSeriesArray(inputSeries, false), + null, + "Y", + true); + } + + /// + /// Filters all data points in a series except for a specified number of points with the largest first Y-values. + /// + /// The number of data points that the filtering operation will not remove. + /// Input series. + /// Output series. + public void FilterTopN(int pointCount, + Series inputSeries, + Series outputSeries) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + FilterTopN(pointCount, + ConvertToSeriesArray(inputSeries, false), + ConvertToSeriesArray(outputSeries, false), + "Y", + true); + } + + /// + /// Filters all data points in a series except for a specified number of points with the largest values. + /// + /// The number of data points that the filtering operation will not remove. + /// Input series. + /// Output series. + /// The data point value that the filtering rule is applied to. Can be X, Y, Y2, Y3, etc. + public void FilterTopN(int pointCount, + Series inputSeries, + Series outputSeries, + string usingValue) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + if (usingValue == null) + throw new ArgumentNullException("usingValue"); + + FilterTopN(pointCount, + ConvertToSeriesArray(inputSeries, false), + ConvertToSeriesArray(outputSeries, false), + usingValue, + true); + } + + /// + /// Filters all data points in a series except for a specified number of points with the smallest or largest values. + /// + /// The number of data points that the filtering operation will not remove. + /// Input series. + /// Output series. + /// The data point value that the filtering rule is applied to. Can be X, Y, Y2, Y3, etc. + /// The largest values are kept if set to true; otherwise the smallest values are kept. + public void FilterTopN(int pointCount, + Series inputSeries, + Series outputSeries, + string usingValue, + bool getTopValues) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + if (usingValue == null) + throw new ArgumentNullException("usingValue"); + + FilterTopN(pointCount, + ConvertToSeriesArray(inputSeries, false), + ConvertToSeriesArray(outputSeries, false), + usingValue, + getTopValues); + } + + /// + /// Filters all data points in one or more series except for a specified number of points. + /// The points that are not filtered correspond to points in the first series that have the largest first Y-values. + /// The Series objects that are filtered are used to store the modified data. + /// + /// The number of data points that the filtering operation will not remove. + /// Comma separated list of input series names. + public void FilterTopN(int pointCount, + string inputSeriesNames) + { + // Check arguments + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + + FilterTopN(pointCount, + ConvertToSeriesArray(inputSeriesNames, false), + null, + "Y", + true); + } + + /// + /// Filters out data points in one or more series except for a specified number of points. + /// The points that aren't filtered correspond to points in the first series that have the largest first Y-values. + /// + /// The number of data points that the filtering operation will not remove. + /// Comma separated list of input series names. + /// Comma separated list of output series names. + public void FilterTopN(int pointCount, + string inputSeriesNames, + string outputSeriesNames) + { + // Check arguments + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + + FilterTopN(pointCount, + ConvertToSeriesArray(inputSeriesNames, false), + ConvertToSeriesArray(outputSeriesNames, true), + "Y", + true); + } + + /// + /// Filters all data points in one or more series except for a specified number of points. + /// The points that are not filtered correspond to points in the first series that have the largest values. + /// + /// The number of data points that the filtering operation will not remove. + /// Comma separated list of input series names. + /// Comma separated list of output series names. + /// The data point value that the filtering rule is applied to. Can be X, Y, Y2, Y3, etc. + public void FilterTopN(int pointCount, + string inputSeriesNames, + string outputSeriesNames, + string usingValue) + { + // Check arguments + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + if (usingValue == null) + throw new ArgumentNullException("usingValue"); + + FilterTopN(pointCount, + ConvertToSeriesArray(inputSeriesNames, false), + ConvertToSeriesArray(outputSeriesNames, true), + usingValue, + true); + } + + + /// + /// Performs custom filtering on a series' data points. + /// The Series object that is filtered is used to store the modified data. + /// + /// Filtering interface. + /// Input series. + public void Filter(IDataPointFilter filterInterface, + Series inputSeries) + { + // Check arguments + if (filterInterface == null) + throw new ArgumentNullException("filterInterface"); + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + Filter(filterInterface, + ConvertToSeriesArray(inputSeries, false), + null); + } + + /// + /// Performs custom filtering on a series' data points. + /// + /// Filtering interface. + /// Input series. + /// Output series. + public void Filter(IDataPointFilter filterInterface, + Series inputSeries, + Series outputSeries) + { + // Check arguments + if (filterInterface == null) + throw new ArgumentNullException("filterInterface"); + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + Filter(filterInterface, + ConvertToSeriesArray(inputSeries, false), + ConvertToSeriesArray(outputSeries, false)); + } + + /// + /// Performs custom filtering on one or more series' data points, based on the first series' points. + /// The filtered series are also used to store the modified data. + /// + /// Filtering interface. + /// Comma separated list of input series names. + public void Filter(IDataPointFilter filterInterface, + string inputSeriesNames) + { + // Check arguments + if (filterInterface == null) + throw new ArgumentNullException("filterInterface"); + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + + Filter(filterInterface, + ConvertToSeriesArray(inputSeriesNames, false), + null); + } + + /// + /// Performs custom filtering on one or more series' data points, based on the first series' points. + /// + /// Filtering interface. + /// Comma separated list of input series names. + /// Comma separated list of output series names. + public void Filter(IDataPointFilter filterInterface, + string inputSeriesNames, + string outputSeriesNames) + { + // Check arguments + if (filterInterface == null) + throw new ArgumentNullException("filterInterface"); + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + + Filter(filterInterface, + ConvertToSeriesArray(inputSeriesNames, false), + ConvertToSeriesArray(outputSeriesNames, true)); + } + + #endregion + + #region Grouping methods + + /// + /// Class stores information about the grouping function type and + /// index of output value. + /// + private class GroupingFunctionInfo + { + // AxisName of the grouping function + internal GroupingFunction function = GroupingFunction.None; + + // Index of the Y value for storing results + internal int outputIndex = 0; + + /// + /// Constructor. + /// + internal GroupingFunctionInfo() + { + } + } + + /// + /// Grouping by X value, when it’s a string (stored in AxisLabel property). + /// + /// Grouping formula. + /// Array of input series. + /// Array of output series. + private void GroupByAxisLabel(string formula, Series[] inputSeries, Series[] outputSeries) + { + // Check arguments + if (formula == null) + throw new ArgumentNullException("formula"); + + //************************************************** + //** Check input/output series arrays + //************************************************** + CheckSeriesArrays(inputSeries, outputSeries); + + //************************************************** + //** Check and parse formula + //************************************************** + int outputValuesNumber = 1; + GroupingFunctionInfo[] functions = GetGroupingFunctions(inputSeries, formula, out outputValuesNumber); + + //************************************************** + //** Loop through all input series + //************************************************** + for(int seriesIndex = 0; seriesIndex < inputSeries.Length; seriesIndex++) + { + // Define an input and output series + Series input = inputSeries[seriesIndex]; + Series output = input; + if(outputSeries != null && seriesIndex < outputSeries.Length) + { + output = outputSeries[seriesIndex]; + + // Remove all points from the output series + if(output.Name != input.Name) + { + output.Points.Clear(); + + // Copy X values type + if(output.XValueType == ChartValueType.Auto || output.autoXValueType) + { + output.XValueType = input.XValueType; + output.autoXValueType = true; + } + // Copy Y values type + if(output.YValueType == ChartValueType.Auto || output.autoYValueType) + { + output.YValueType = input.YValueType; + output.autoYValueType = true; + } + + } + } + + // Copy input data into temp storage + if(input != output) + { + Series inputTemp = new Series("Temp", input.YValuesPerPoint); + foreach(DataPoint point in input.Points) + { + DataPoint dp = new DataPoint(inputTemp); + dp.AxisLabel = point.AxisLabel; + dp.XValue = point.XValue; + point.YValues.CopyTo(dp.YValues, 0); + dp.IsEmpty = point.IsEmpty; + inputTemp.Points.Add(dp); + } + input = inputTemp; + } + + // No points to group + if(input.Points.Count == 0) + { + continue; + } + + // Make sure there is enough Y values per point + output.YValuesPerPoint = outputValuesNumber - 1; + + //************************************************** + //** Sort input data by axis label + //************************************************** + input.Sort(PointSortOrder.Ascending, "AxisLabel"); + + //************************************************** + //** Initialize interval & value tracking variables + //************************************************** + int intervalFirstIndex = 0; + int intervalLastIndex = 0; + + //************************************************** + //** Allocate array for storing temp. + //** values of the point + //************************************************** + double[] pointTempValues = new double[outputValuesNumber]; + + //************************************************** + //** Loop through the series points + //************************************************** + string currentLabel = null; + bool lastPoint = false; + int emptyPointsSkipped = 0; + for(int pointIndex = 0; pointIndex <= input.Points.Count && !lastPoint; pointIndex++) + { + bool endOfInterval = false; + + //************************************************** + //** Check if it's the last point + //************************************************** + if(pointIndex == input.Points.Count) + { + // End of the group interval detected + lastPoint = true; + intervalLastIndex = pointIndex - 1; + pointIndex = intervalLastIndex; + endOfInterval = true; + } + + // Set current axis label + if(!endOfInterval && currentLabel == null) + { + currentLabel = input.Points[pointIndex].AxisLabel; + } + + //************************************************** + //** Check if current point X value is inside current group + //************************************************** + if(!endOfInterval && input.Points[pointIndex].AxisLabel != currentLabel) + { + // End of the group interval detected + intervalLastIndex = pointIndex - 1; + endOfInterval = true; + } + + //************************************************** + //** Process data at end of the interval + //************************************************** + if(endOfInterval) + { + // Finalize the calculation + ProcessPointValues( + functions, + pointTempValues, + inputSeries[seriesIndex], + input.Points[pointIndex], + pointIndex, + intervalFirstIndex, + intervalLastIndex, + true, + ref emptyPointsSkipped); + + //************************************************** + //** Calculate the X values + //************************************************** + if(functions[0].function == GroupingFunction.Center) + { + pointTempValues[0] = + (inputSeries[seriesIndex].Points[intervalFirstIndex].XValue + + inputSeries[seriesIndex].Points[intervalLastIndex].XValue) / 2.0; + } + else if(functions[0].function == GroupingFunction.First) + { + pointTempValues[0] = + inputSeries[seriesIndex].Points[intervalFirstIndex].XValue; + } + if(functions[0].function == GroupingFunction.Last) + { + pointTempValues[0] = + inputSeries[seriesIndex].Points[intervalLastIndex].XValue; + } + + //************************************************** + //** Create new point object + //************************************************** + DataPoint newPoint = new DataPoint(); + newPoint.ResizeYValueArray(outputValuesNumber - 1); + newPoint.XValue = pointTempValues[0]; + newPoint.AxisLabel = currentLabel; + for(int i = 1; i < pointTempValues.Length; i++) + { + newPoint.YValues[i - 1] = pointTempValues[i]; + } + + //************************************************** + //** Remove grouped points if output and input + //** series are the same + //************************************************** + int newPointIndex = output.Points.Count; + if(output == input) + { + newPointIndex = intervalFirstIndex; + pointIndex = newPointIndex + 1; + + // Remove grouped points + for(int removedPoint = intervalFirstIndex; removedPoint <= intervalLastIndex; removedPoint++) + { + output.Points.RemoveAt(intervalFirstIndex); + } + } + + //************************************************** + //** Add point to the output series + //************************************************** + output.Points.Insert(newPointIndex, newPoint); + + + // Set new group interval indexes + intervalFirstIndex = pointIndex; + intervalLastIndex = pointIndex; + + // Reset number of skipped points + emptyPointsSkipped = 0; + currentLabel = null; + + // Process point once again + --pointIndex; + + continue; + } + + //************************************************** + //** Use current point values in the formula + //************************************************** + ProcessPointValues( + functions, + pointTempValues, + inputSeries[seriesIndex], + input.Points[pointIndex], + pointIndex, + intervalFirstIndex, + intervalLastIndex, + false, + ref emptyPointsSkipped); + } + } + } + + /// + /// Groups series points in the interval with offset + /// + /// Grouping formula. + /// Interval size. + /// Interval type. + /// Interval offset size. + /// Interval offset type. + /// Array of input series. + /// Array of output series. + private void Group(string formula, + double interval, + IntervalType intervalType, + double intervalOffset, + IntervalType intervalOffsetType, + Series[] inputSeries, + Series[] outputSeries) + { + // Check arguments + if (formula == null) + throw new ArgumentNullException("formula"); + + //************************************************** + //** Check input/output series arrays + //************************************************** + CheckSeriesArrays(inputSeries, outputSeries); + + //************************************************** + //** Check and parse formula + //************************************************** + int outputValuesNumber = 1; + GroupingFunctionInfo[] functions = GetGroupingFunctions(inputSeries, formula, out outputValuesNumber); + + //************************************************** + //** Loop through all input series + //************************************************** + for(int seriesIndex = 0; seriesIndex < inputSeries.Length; seriesIndex++) + { + // Define an input and output series + Series input = inputSeries[seriesIndex]; + Series output = input; + if(outputSeries != null && seriesIndex < outputSeries.Length) + { + output = outputSeries[seriesIndex]; + + // Remove all points from the output series + if(output.Name != input.Name) + { + output.Points.Clear(); + + // Copy X values type + if(output.XValueType == ChartValueType.Auto || output.autoXValueType) + { + output.XValueType = input.XValueType; + output.autoXValueType = true; + } + // Copy Y values type + if(output.YValueType == ChartValueType.Auto || output.autoYValueType) + { + output.YValueType = input.YValueType; + output.autoYValueType = true; + } + + } + } + + // No points to group + if(input.Points.Count == 0) + { + continue; + } + + // Make sure there is enough Y values per point + output.YValuesPerPoint = outputValuesNumber - 1; + + //************************************************** + //** Initialize interval & value tracking variables + //************************************************** + int intervalFirstIndex = 0; + int intervalLastIndex = 0; + double intervalFrom = 0; + double intervalTo = 0; + + // Set interval start point + intervalFrom = input.Points[0].XValue; + + // Adjust start point depending on the interval type + intervalFrom = ChartHelper.AlignIntervalStart(intervalFrom, interval, ConvertIntervalType(intervalType)); + + // Add offset to the start position + double offsetFrom = 0; + if( intervalOffset != 0 ) + { + offsetFrom = intervalFrom + ChartHelper.GetIntervalSize(intervalFrom, + intervalOffset, + ConvertIntervalType(intervalOffsetType)); + + // Check if there are points left outside first group + if(input.Points[0].XValue < offsetFrom) + { + if(intervalType == IntervalType.Number) + { + intervalFrom = offsetFrom + ChartHelper.GetIntervalSize(offsetFrom, + -interval, + ConvertIntervalType(intervalType)); + } + else + { + intervalFrom = offsetFrom - ChartHelper.GetIntervalSize(offsetFrom, + interval, + ConvertIntervalType(intervalType)); + } + intervalTo = offsetFrom; + + } + else + { + intervalFrom = offsetFrom; + intervalTo = intervalFrom + ChartHelper.GetIntervalSize(intervalFrom, interval, ConvertIntervalType(intervalType)); + } + } + else + { + intervalTo = intervalFrom + ChartHelper.GetIntervalSize(intervalFrom, interval, ConvertIntervalType(intervalType)); + } + + //************************************************** + //** Allocate array for storing temp. + //** values of the point + //************************************************** + double[] pointTempValues = new double[outputValuesNumber]; + + + //************************************************** + //** Loop through the series points + //************************************************** + bool lastPoint = false; + int emptyPointsSkipped = 0; + int pointsNumberInInterval = 0; + for(int pointIndex = 0; pointIndex <= input.Points.Count && !lastPoint; pointIndex++) + { + bool endOfInterval = false; + + //************************************************** + //** Check if series is sorted by X value + //************************************************** + if(pointIndex > 0 && pointIndex < input.Points.Count) + { + if(input.Points[pointIndex].XValue < input.Points[pointIndex - 1].XValue) + { + throw (new InvalidOperationException(SR.ExceptionDataManipulatorGroupedSeriesNotSorted)); + } + } + + //************************************************** + //** Check if it's the last point + //************************************************** + if(pointIndex == input.Points.Count) + { + // End of the group interval detected + lastPoint = true; + intervalLastIndex = pointIndex - 1; + pointIndex = intervalLastIndex; + endOfInterval = true; + } + + //************************************************** + //** Check if current point X value is inside current group + //************************************************** + if(!endOfInterval && input.Points[pointIndex].XValue >= intervalTo) + { + // End of the group interval detected + if(pointIndex == 0) + { + continue; + } + intervalLastIndex = pointIndex - 1; + endOfInterval = true; + } + + //************************************************** + //** Process data at end of the interval + //************************************************** + if(endOfInterval) + { + // Add grouped point only if there are non empty points in the interval + if(pointsNumberInInterval > emptyPointsSkipped) + { + // Finalize the calculation + ProcessPointValues( + functions, + pointTempValues, + inputSeries[seriesIndex], + input.Points[pointIndex], + pointIndex, + intervalFirstIndex, + intervalLastIndex, + true, + ref emptyPointsSkipped); + + //************************************************** + //** Calculate the X values + //************************************************** + if(functions[0].function == GroupingFunction.Center) + { + pointTempValues[0] = (intervalFrom + intervalTo) / 2.0; + } + else if(functions[0].function == GroupingFunction.First) + { + pointTempValues[0] = intervalFrom; + } + if(functions[0].function == GroupingFunction.Last) + { + pointTempValues[0] = intervalTo; + } + + //************************************************** + //** Create new point object + //************************************************** + DataPoint newPoint = new DataPoint(); + newPoint.ResizeYValueArray(outputValuesNumber - 1); + newPoint.XValue = pointTempValues[0]; + for(int i = 1; i < pointTempValues.Length; i++) + { + newPoint.YValues[i - 1] = pointTempValues[i]; + } + + //************************************************** + //** Remove grouped points if output and input + //** series are the same + //************************************************** + int newPointIndex = output.Points.Count; + if(output == input) + { + newPointIndex = intervalFirstIndex; + pointIndex = newPointIndex + 1; + + // Remove grouped points + for(int removedPoint = intervalFirstIndex; removedPoint <= intervalLastIndex; removedPoint++) + { + output.Points.RemoveAt(intervalFirstIndex); + } + } + + //************************************************** + //** Add point to the output series + //************************************************** + output.Points.Insert(newPointIndex, newPoint); + } + + // Set new From To values of the group interval + intervalFrom = intervalTo; + intervalTo = intervalFrom + ChartHelper.GetIntervalSize(intervalFrom, interval, ConvertIntervalType(intervalType)); + + // Set new group interval indexes + intervalFirstIndex = pointIndex; + intervalLastIndex = pointIndex; + + // Reset number of points in the interval + pointsNumberInInterval = 0; + + // Reset number of skipped points + emptyPointsSkipped = 0; + + // Process point once again + --pointIndex; + + continue; + } + + //************************************************** + //** Use current point values in the formula + //************************************************** + ProcessPointValues( + functions, + pointTempValues, + inputSeries[seriesIndex], + input.Points[pointIndex], + pointIndex, + intervalFirstIndex, + intervalLastIndex, + false, + ref emptyPointsSkipped); + + // Increase number of points in the group + ++pointsNumberInInterval; + } + } + } + + /// + /// Adds current point values to the temp. formula results. + /// + /// Array of functions type. + /// Temp. point values. + /// Point series. + /// Current point. + /// Current point index. + /// Index of the first point in the interval. + /// Index of the last point in the interval. + /// Indicates that interval processing is finished. + /// Number of skipped points in the interval. + private void ProcessPointValues( + GroupingFunctionInfo[] functions, + double[] pointTempValues, + Series series, + DataPoint point, + int pointIndex, + int intervalFirstIndex, + int intervalLastIndex, + bool finalPass, + ref int numberOfEmptyPoints) + { + //******************************************************************* + //** Initialize temp data if it's the first point in the interval + //******************************************************************* + if(pointIndex == intervalFirstIndex && !finalPass) + { + // Initialize values depending on the function type + int funcIndex = 0; + foreach(GroupingFunctionInfo functionInfo in functions) + { + // Check that we do not exced number of input values + if(funcIndex > point.YValues.Length) + { + break; + } + + // Initialize with zero + pointTempValues[functionInfo.outputIndex] = 0; + + // Initialize with custom value depending on the formula + if(functionInfo.function == GroupingFunction.Min) + { + pointTempValues[functionInfo.outputIndex] = double.MaxValue; + } + + else if(functionInfo.function == GroupingFunction.Max) + { + pointTempValues[functionInfo.outputIndex] = double.MinValue; + } + + else if(functionInfo.function == GroupingFunction.First) + { + if(funcIndex == 0) + { + pointTempValues[0] = point.XValue; + } + else + { + pointTempValues[functionInfo.outputIndex] = point.YValues[funcIndex-1]; + } + } + + else if(functionInfo.function == GroupingFunction.HiLo || + functionInfo.function == GroupingFunction.HiLoOpCl) + { + // Hi + pointTempValues[functionInfo.outputIndex] = double.MinValue; + //Lo + pointTempValues[functionInfo.outputIndex + 1] = double.MaxValue; + if(functionInfo.function == GroupingFunction.HiLoOpCl) + { + //Open + pointTempValues[functionInfo.outputIndex + 2] = point.YValues[funcIndex-1]; + //Close + pointTempValues[functionInfo.outputIndex + 3] = 0; + } + } + + // Increase current function index + ++funcIndex; + } + } + + //******************************************************************* + //** Add points values using formula + //******************************************************************* + if(!finalPass) + { + //******************************************************************* + //** Ignore empty points + //******************************************************************* + if(point.IsEmpty && this.IsEmptyPointIgnored) + { + ++numberOfEmptyPoints; + return; + } + + //******************************************************************* + //** Loop through each grouping function + //******************************************************************* + int funcIndex = 0; + foreach(GroupingFunctionInfo functionInfo in functions) + { + // Check that we do not exced number of input values + if(funcIndex > point.YValues.Length) + { + break; + } + + // Process point values depending on the formula + if(functionInfo.function == GroupingFunction.Min && + (!point.IsEmpty && this.IsEmptyPointIgnored)) + { + pointTempValues[functionInfo.outputIndex] = + Math.Min(pointTempValues[functionInfo.outputIndex], point.YValues[funcIndex-1]); + } + + else if(functionInfo.function == GroupingFunction.Max) + { + pointTempValues[functionInfo.outputIndex] = + Math.Max(pointTempValues[functionInfo.outputIndex], point.YValues[funcIndex-1]); + } + + else if(functionInfo.function == GroupingFunction.Ave || + functionInfo.function == GroupingFunction.Sum) + { + if(funcIndex == 0) + { + pointTempValues[0] += point.XValue; + } + else + { + pointTempValues[functionInfo.outputIndex] += point.YValues[funcIndex-1]; + } + } + + else if(functionInfo.function == GroupingFunction.Variance || + functionInfo.function == GroupingFunction.Deviation) + { + pointTempValues[functionInfo.outputIndex] += point.YValues[funcIndex-1]; + } + + else if(functionInfo.function == GroupingFunction.Last) + { + if(funcIndex == 0) + { + pointTempValues[0] = point.XValue; + } + else + { + pointTempValues[functionInfo.outputIndex] = point.YValues[funcIndex-1]; + } + } + + else if(functionInfo.function == GroupingFunction.Count) + { + pointTempValues[functionInfo.outputIndex] += 1; + } + + else if(functionInfo.function == GroupingFunction.HiLo || + functionInfo.function == GroupingFunction.HiLoOpCl) + { + // Hi + pointTempValues[functionInfo.outputIndex] = + Math.Max(pointTempValues[functionInfo.outputIndex], point.YValues[funcIndex-1]); + // Lo + pointTempValues[functionInfo.outputIndex + 1] = + Math.Min(pointTempValues[functionInfo.outputIndex + 1], point.YValues[funcIndex-1]); + if(functionInfo.function == GroupingFunction.HiLoOpCl) + { + // Close + pointTempValues[functionInfo.outputIndex + 3] = point.YValues[funcIndex-1]; + } + } + + // Increase current function index + ++funcIndex; + } + } + + + //******************************************************************* + //** Adjust formula results at final pass + //******************************************************************* + if(finalPass) + { + int funcIndex = 0; + foreach(GroupingFunctionInfo functionInfo in functions) + { + // Check that we do not exceed number of input values + if(funcIndex > point.YValues.Length) + { + break; + } + + if(functionInfo.function == GroupingFunction.Ave) + { + pointTempValues[functionInfo.outputIndex] /= intervalLastIndex - intervalFirstIndex - numberOfEmptyPoints + 1; + } + + if(functionInfo.function == GroupingFunction.DistinctCount) + { + // Initialize value with zero + pointTempValues[functionInfo.outputIndex] = 0; + + // Create a list of uniques values + ArrayList uniqueValues = new ArrayList(intervalLastIndex - intervalFirstIndex + 1); + + // Second pass through inteval points required for calculations + for(int secondPassIndex = intervalFirstIndex; secondPassIndex <= intervalLastIndex; secondPassIndex++) + { + // Ignore empty points + if(series.Points[secondPassIndex].IsEmpty && this.IsEmptyPointIgnored) + { + continue; + } + + // Check if current value is in the unique list + if(!uniqueValues.Contains(series.Points[secondPassIndex].YValues[funcIndex-1])) + { + uniqueValues.Add(series.Points[secondPassIndex].YValues[funcIndex-1]); + } + } + + // Get count of unique values + pointTempValues[functionInfo.outputIndex] = uniqueValues.Count; + } + + else if(functionInfo.function == GroupingFunction.Variance || + functionInfo.function == GroupingFunction.Deviation) + { + // Calculate average first + double average = pointTempValues[functionInfo.outputIndex] / (intervalLastIndex - intervalFirstIndex - numberOfEmptyPoints + 1); + + // Second pass through inteval points required for calculations + pointTempValues[functionInfo.outputIndex] = 0; + for(int secondPassIndex = intervalFirstIndex; secondPassIndex <= intervalLastIndex; secondPassIndex++) + { + // Ignore empty points + if(series.Points[secondPassIndex].IsEmpty && this.IsEmptyPointIgnored) + { + continue; + } + + pointTempValues[functionInfo.outputIndex] += + Math.Pow(series.Points[secondPassIndex].YValues[funcIndex-1] - average, 2); + } + + // Divide by points number + pointTempValues[functionInfo.outputIndex] /= + intervalLastIndex - intervalFirstIndex - numberOfEmptyPoints + 1; + + // If calculating the deviation - take a square root of variance + if(functionInfo.function == GroupingFunction.Deviation) + { + pointTempValues[functionInfo.outputIndex] = + Math.Sqrt(pointTempValues[functionInfo.outputIndex]); + } + } + + // Increase current function index + ++funcIndex; + } + } + + } + + /// + /// Checks the formula format and returns an array of formula types + /// for each X and each Y value of the input series. + /// + /// Array of input series. + /// Formula string. + /// Number of values in output series. + /// Array of functions for each Y value. + private GroupingFunctionInfo[] GetGroupingFunctions(Series[] inputSeries, string formula, out int outputValuesNumber) + { + // Get maximum number of Y values in all series + int numberOfYValues = 0; + foreach(Series series in inputSeries) + { + numberOfYValues = (int)Math.Max(numberOfYValues, series.YValuesPerPoint); + } + + // Allocate memory for the result array for X and each Y values + GroupingFunctionInfo[] result = new GroupingFunctionInfo[numberOfYValues + 1]; + for(int index = 0 ; index < result.Length; index++) + { + result[index] = new GroupingFunctionInfo(); + } + + // Split formula by comma + string[] valueFormulas = formula.Split(','); + + // At least one formula must be specified + if(valueFormulas.Length == 0) + { + throw (new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaUndefined)); + } + + // Check each formula in the array + GroupingFunctionInfo defaultFormula = new GroupingFunctionInfo(); + foreach(string s in valueFormulas) + { + // Trim white space and make upper case + string formulaString = s.Trim(); + formulaString = formulaString.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + // Get value index and formula type from the string + int valueIndex = 1; + GroupingFunction formulaType = ParseFormulaAndValueType(formulaString, out valueIndex); + + // Save the default (first) formula + if(defaultFormula.function == GroupingFunction.None) + { + defaultFormula.function = formulaType; + } + + // Check that value index do not exceed the max values number + if(valueIndex >= result.Length) + { + throw(new ArgumentException(SR.ExceptionDataManipulatorYValuesIndexExceeded( formulaString ))); + } + + // Check if formula for this value type was already set + if(result[valueIndex].function != GroupingFunction.None) + { + throw (new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaAlreadyDefined(formulaString))); + } + + // Set formula type + result[valueIndex].function = formulaType; + } + + // Apply default formula for non set X value + if(result[0].function == GroupingFunction.None) + { + result[0].function = GroupingFunction.First; + } + + // Apply default formula for all non set Y values + for(int funcIndex = 1; funcIndex < result.Length; funcIndex++) + { + if(result[funcIndex].function == GroupingFunction.None) + { + result[funcIndex].function = defaultFormula.function; + } + } + + // Specify output value index + outputValuesNumber = 0; + for(int funcIndex = 0; funcIndex < result.Length; funcIndex++) + { + result[funcIndex].outputIndex = outputValuesNumber; + + if(result[funcIndex].function == GroupingFunction.HiLoOpCl) + { + outputValuesNumber += 3; + } + else if(result[funcIndex].function == GroupingFunction.HiLo) + { + outputValuesNumber += 1; + } + + ++outputValuesNumber; + } + + // X value formula can be FIRST, LAST and AVE + if(result[0].function != GroupingFunction.First && + result[0].function != GroupingFunction.Last && + result[0].function != GroupingFunction.Center) + { + throw (new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaUnsupported)); + } + + return result; + } + + /// + /// Parse one formula with optional value prefix. + /// Example: "Y2:MAX" + /// + /// One formula name with optional value prefix. + /// Return value index. + /// Formula type. + private GroupingFunction ParseFormulaAndValueType(string formulaString, out int valueIndex) + { + // Initialize value index as first Y value (default) + valueIndex = 1; + + // Split formula by optional ':' character + string[] formulaParts = formulaString.Split(':'); + + // There must be at least one and no more than two result strings + if(formulaParts.Length < 1 && formulaParts.Length > 2) + { + throw(new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaFormatInvalid( formulaString ))); + } + + // Check specified value type + if(formulaParts.Length == 2) + { + if(formulaParts[0] == "X") + { + valueIndex = 0; + } + else if(formulaParts[0].StartsWith("Y", StringComparison.Ordinal)) + { + formulaParts[0] = formulaParts[0].TrimStart('Y'); + + if(formulaParts[0].Length == 0) + { + valueIndex = 1; + } + else + { + // Try to convert the rest of the string to integer + try + { + valueIndex = Int32.Parse(formulaParts[0], System.Globalization.CultureInfo.InvariantCulture); + } + catch(System.Exception) + { + throw (new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaFormatInvalid( formulaString ))); + } + } + } + else + { + throw (new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaFormatInvalid( formulaString ))); + } + } + + // Check formula name + if(formulaParts[formulaParts.Length - 1] == "MIN") + return GroupingFunction.Min; + else if(formulaParts[formulaParts.Length - 1] == "MAX") + return GroupingFunction.Max; + else if(formulaParts[formulaParts.Length - 1] == "AVE") + return GroupingFunction.Ave; + else if(formulaParts[formulaParts.Length - 1] == "SUM") + return GroupingFunction.Sum; + else if(formulaParts[formulaParts.Length - 1] == "FIRST") + return GroupingFunction.First; + else if(formulaParts[formulaParts.Length - 1] == "LAST") + return GroupingFunction.Last; + else if(formulaParts[formulaParts.Length - 1] == "HILOOPCL") + return GroupingFunction.HiLoOpCl; + else if(formulaParts[formulaParts.Length - 1] == "HILO") + return GroupingFunction.HiLo; + else if(formulaParts[formulaParts.Length - 1] == "COUNT") + return GroupingFunction.Count; + else if(formulaParts[formulaParts.Length - 1] == "DISTINCTCOUNT") + return GroupingFunction.DistinctCount; + else if(formulaParts[formulaParts.Length - 1] == "VARIANCE") + return GroupingFunction.Variance; + else if(formulaParts[formulaParts.Length - 1] == "DEVIATION") + return GroupingFunction.Deviation; + else if(formulaParts[formulaParts.Length - 1] == "CENTER") + return GroupingFunction.Center; + + // Invalid formula name + throw (new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaNameInvalid(formulaString))); + } + + /// + /// Checks if input/output series parameters are correct. + /// If not - fires an exception + /// + /// Input series array. + /// Output series array. + private void CheckSeriesArrays(Series[] inputSeries, Series[] outputSeries) + { + // At least one series must be in the input series + if(inputSeries == null || inputSeries.Length == 0) + { + throw (new ArgumentException(SR.ExceptionDataManipulatorGroupingInputSeriesUndefined)); + } + + // Output series must be empty or have the same number of items + if(outputSeries != null && outputSeries.Length != inputSeries.Length) + { + throw (new ArgumentException(SR.ExceptionDataManipulatorGroupingInputOutputSeriesNumberMismatch)); + } + } + + #endregion + + #region Grouping overloaded methods + + /// + /// Groups data using one or more formulas. + /// The series that is grouped is cleared of its original data, and used to store the new data points. + /// + /// Grouping formula. + /// Interval size. + /// Interval type. + /// Input series. + public void Group(string formula, + double interval, + IntervalType intervalType, + Series inputSeries) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + Group(formula, interval, intervalType, inputSeries, null); + } + + /// + /// Groups data using one or more formulas. + /// Series are cleared of their original data and used to store the new data points. + /// + /// Grouping formula. + /// Interval size. + /// Interval type. + /// Comma separated list of input series names. + public void Group(string formula, + double interval, + IntervalType intervalType, + string inputSeriesName) + { + // Check arguments + if (inputSeriesName == null) + throw new ArgumentNullException("inputSeriesName"); + + Group(formula, interval, intervalType, inputSeriesName, ""); + } + + /// + /// Groups data using one or more formulas. + /// The series that is grouped is cleared of its original data, and used to store the new data points. + /// + /// Grouping formula. + /// Interval size. + /// Interval type. + /// Interval offset size. + /// Interval offset type. + /// Input series. + public void Group(string formula, + double interval, + IntervalType intervalType, + double intervalOffset, + IntervalType intervalOffsetType, + Series inputSeries) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + Group(formula, interval, intervalType, intervalOffset, intervalOffsetType, inputSeries, null); + } + + /// + /// Groups data using one or more formulas. + /// Series are cleared of their original data and used to store the new data points. + /// + /// Grouping formula. + /// Interval size. + /// Interval type. + /// Interval offset size. + /// Interval offset type. + /// Comma separated list of input series names. + public void Group(string formula, + double interval, + IntervalType intervalType, + double intervalOffset, + IntervalType intervalOffsetType, + string inputSeriesName) + { + // Check arguments + if (inputSeriesName == null) + throw new ArgumentNullException("inputSeriesName"); + + Group(formula, interval, intervalType, intervalOffset, intervalOffsetType, inputSeriesName, ""); + } + + /// + /// Groups series data by axis labels using one or more formulas. + /// Output series are used to store the grouped data points. + /// + /// Grouping formula. + /// Comma separated list of input series names. + /// Comma separated list of output series names. + public void GroupByAxisLabel(string formula, string inputSeriesName, string outputSeriesName) + { + // Check arguments + if (inputSeriesName == null) + throw new ArgumentNullException("inputSeriesName"); + + GroupByAxisLabel(formula, + ConvertToSeriesArray(inputSeriesName, false), + ConvertToSeriesArray(outputSeriesName, true)); + } + + /// + /// Groups a series' data by axis labels using one or more formulas. + /// The series is cleared of its original data, and then used to store the new data points. + /// + /// Grouping formula. + /// Input data series. + public void GroupByAxisLabel(string formula, Series inputSeries) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + GroupByAxisLabel(formula, inputSeries, null); + } + + /// + /// Groups series data by axis labels using one or more formulas. + /// Each series that is grouped is cleared of its original data, and used to store the new data points. + /// + /// Grouping formula. + /// Comma separated list of input series names. + public void GroupByAxisLabel(string formula, string inputSeriesName) + { + // Check arguments + if (inputSeriesName == null) + throw new ArgumentNullException("inputSeriesName"); + + GroupByAxisLabel(formula, inputSeriesName, null); + } + + + /// + /// Groups series using one or more formulas. + /// Output series are used to store the grouped data points, and an offset can be used for intervals. + /// + /// Grouping formula. + /// Interval size. + /// Interval type. + /// Interval offset size. + /// Interval offset type. + /// Comma separated list of input series names. + /// Comma separated list of output series names. + public void Group(string formula, + double interval, + IntervalType intervalType, + double intervalOffset, + IntervalType intervalOffsetType, + string inputSeriesName, + string outputSeriesName) + { + // Check arguments + if (inputSeriesName == null) + throw new ArgumentNullException("inputSeriesName"); + + Group(formula, + interval, + intervalType, + intervalOffset, + intervalOffsetType, + ConvertToSeriesArray(inputSeriesName, false), + ConvertToSeriesArray(outputSeriesName, true)); + } + + /// + /// Groups a series' data using one or more formulas. + /// An output series is used to store the grouped data points. + /// + /// Grouping formula. + /// Interval size. + /// Interval type. + /// Input data series. + /// Output data series. + public void Group(string formula, + double interval, + IntervalType intervalType, + Series inputSeries, + Series outputSeries) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + Group(formula, interval, intervalType, 0, IntervalType.Number, inputSeries, outputSeries); + } + + /// + /// Groups data for series using one or more formulas. + /// Output series are used to store the grouped data points. + /// + /// Grouping formula. + /// Interval size. + /// Interval type. + /// Comma separated list of input series names. + /// Comma separated list of output series names. + public void Group(string formula, + double interval, + IntervalType intervalType, + string inputSeriesName, + string outputSeriesName) + { + // Check arguments + if (inputSeriesName == null) + throw new ArgumentNullException("inputSeriesName"); + + Group(formula, interval, intervalType, 0, IntervalType.Number, inputSeriesName, outputSeriesName); + } + + /// + /// Groups a series using one or more formulas. + /// An output series is used to store the grouped data points, and an offset can be used for intervals. + /// + /// Grouping formula. + /// Interval size. + /// Interval type. + /// Interval offset size. + /// Interval offset type. + /// Input data series. + /// Output data series. + public void Group(string formula, + double interval, + IntervalType intervalType, + double intervalOffset, + IntervalType intervalOffsetType, + Series inputSeries, + Series outputSeries) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + Group(formula, + interval, + intervalType, + intervalOffset, + intervalOffsetType, + ConvertToSeriesArray(inputSeries, false), + ConvertToSeriesArray(outputSeries, false)); + } + + /// + /// Groups a series' data by axis labels using one or more formulas. + /// An output series is used to store the grouped data points. + /// + /// Grouping formula. + /// Input data series. + /// Output data series. + public void GroupByAxisLabel(string formula, Series inputSeries, Series outputSeries) + { + // Check arguments + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + + GroupByAxisLabel(formula, + ConvertToSeriesArray(inputSeries, false), + ConvertToSeriesArray(outputSeries, false)); + } + + #endregion + } +} + diff --git a/System.Web.DataVisualization/Common/General/FormulaData.cs b/System.Web.DataVisualization/Common/General/FormulaData.cs new file mode 100644 index 000000000..fbaf12bbc --- /dev/null +++ b/System.Web.DataVisualization/Common/General/FormulaData.cs @@ -0,0 +1,1312 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: DataFormula.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: DataFormula +// +// Purpose: DataFormula class provides properties and methods, +// which prepare series data for technical analyses +// and time series and forecasting formulas and prepare +// output data to be displayed as a chart. +// +// Reviewed: GS - August 6, 2002 +// AG - August 7, 2002 +// AG - Microsoft 15, 2007 +// +//=================================================================== + +#region Used Namespace +using System; +using System.Drawing; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Collections.Generic; +#endregion + +#if Microsoft_CONTROL +using System.Windows.Forms.DataVisualization.Charting.Formulas; + +namespace System.Windows.Forms.DataVisualization.Charting +#else +using System.Web.UI.DataVisualization.Charting.Formulas; + +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + #region Financial Formula Name enumeration + + /// + /// An enumeration of financial formula names. + /// + public enum FinancialFormula + { + /// + /// Accumulation Distribution formula. This indicator uses a relationship + /// between volume and prices to estimate the strength of price movements, + /// and if volume is increased, there is a high probability that prices will go up. + /// + AccumulationDistribution, + + /// + /// Average True Range indicator. It measures commitment and compares + /// the range between the High, Low and Close prices. + /// + AverageTrueRange, + + /// + /// Bollinger Bands indicators. They are plotted at standard deviation levels + /// above and below a simple moving average. + /// + BollingerBands, + + /// + /// Chaikin Oscillator indicator. It is the difference between a 3-day + /// exponential moving average and a 10-day exponential moving average + /// applied to the Accumulation Distribution. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Chaikin")] + ChaikinOscillator, + + /// + /// Commodity Channel Index. It compares prices with their moving averages. + /// + CommodityChannelIndex, + + /// + /// Detrended Price Oscillator. It attempts to remove trend from prices. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Detrended")] + DetrendedPriceOscillator, + + /// + /// Ease of Movement deals with the relationship between volume and price change, + /// and uses volume to indicate how strong a trend is for prices. + /// + EaseOfMovement, + + /// + /// Envelopes are plotted above and below a moving average using a specified percentage + /// as the shift. + /// + Envelopes, + + /// + /// An Exponential Moving Average is an average of data calculated over a period of time + /// where the most recent days have more weight. + /// + ExponentialMovingAverage, + + /// + /// Forecasting. It predicts future values using historical observations. + /// + Forecasting, + + /// + /// Moving Average Convergence/Divergence indicator. It compares two + /// moving averages of prices and is used with a 9-day Exponential + /// Moving average as a signal, which indicates buying and selling moments. + /// + MovingAverageConvergenceDivergence, + + /// + /// The Mass Index is used to predict trend reversal by comparing the + /// difference and range between High and Low prices. + /// + MassIndex, + + /// + /// Median prices are mid-point values of daily prices and can be used + /// as a filter for trend indicators. + /// + MedianPrice, + + /// + /// The Money Flow indicator compares upward changes and downward changes + /// of volume-weighted typical prices. + /// + MoneyFlow, + + /// + /// The Negative Volume Index should be used together with the Positive Volume index, + /// and the Negative Volume Index only changes if the volume decreases from the previous day. + /// + NegativeVolumeIndex, + + /// + /// The On Balance Volume indicator measures positive and negative volume flow. + /// + OnBalanceVolume, + + /// + /// The Performance indicator compares a current closing price (or any other price) with + /// the first closing value (from the first time period). + /// + Performance, + + /// + /// The Positive Volume Index should be used together with the Negative Volume index. + /// The Positive volume index only changes if the volume decreases from the previous day. + /// + PositiveVolumeIndex, + + /// + /// The Price Volume Trend is a cumulative volume total that is calculated using + /// relative changes of the closing price, and should be used with other indicators. + /// + PriceVolumeTrend, + + /// + /// The Rate of Change indicator compares a specified closing price with the current price. + /// + RateOfChange, + + /// + /// The Relative Strength Index is a momentum oscillator that compares upward movements + /// of the closing price with downward movements, and results in values that range from 0 to 100. + /// + RelativeStrengthIndex, + + /// + /// A Simple Moving Average is an average of data calculated over a period of time. + /// The moving average is the most popular price indicator used in technical analysis, + /// and can be used with any price (e.g. Hi, Low, Open and Close) + /// or it can be applied to other indicators. + /// + MovingAverage, + + /// + /// Standard deviation is used to indicate volatility, and measures + /// the difference between values (e.g. closing price) and their moving average. + /// + StandardDeviation, + + /// + /// The Stochastic Indicator helps to find trend reversal by searching in a period for + /// when the closing prices are close to low prices in an upward trending market + /// and for when the closing prices are close to high prices in a downward trending market. + /// + StochasticIndicator, + + /// + /// A Triangular Moving Average is an average of data calculated over a period of time + /// where the middle portion of data has more weight. + /// + TriangularMovingAverage, + + /// + /// The Triple Exponential Moving Average is based on a triple moving average of the closing Price. + /// Its purpose is to eliminate short cycles. This indicator keeps the closing price + /// in trends that are shorter than the specified period. + /// + TripleExponentialMovingAverage, + + /// + /// Typical price is the average value of daily prices, and can be used as a filter for trend indicators. + /// + TypicalPrice, + + /// + /// The Volatility Chaikins indicator measures the difference between High and Low prices, + /// and is used to indicate tops or bottoms of the market. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Chaikins")] + VolatilityChaikins, + + /// + /// The Volume oscillator attempts to identify trends in volume by comparing two moving averages: + /// one with a short period and another with a longer period. + /// + VolumeOscillator, + + /// + /// The Weighted Close formula calculates the average value of daily prices. + /// The only difference between Typical Price and the Weighted Close is that the closing price + /// has extra weight, and is considered the most important price. + /// + WeightedClose, + + /// + /// A Weighted Moving Average is an average of data calculated over a period of time, + /// where greater weight is attached to the most recent data. + /// + WeightedMovingAverage, + + /// + /// William's %R is a momentum indicator, and is used to measure overbought and oversold levels. + /// + WilliamsR + } + + #endregion // Financial Formula Name enumeration + + /// + /// The DataFormula class provides properties and methods, which prepare series + /// data for technical analysis, apply formulas on the series data + /// and prepare output data to be displayed as a chart. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class DataFormula + { + #region Data Formulas fields + + internal const string IndexedSeriesLabelsSourceAttr = "__IndexedSeriesLabelsSource__"; + + //*********************************************************** + //** Private data members, which store properties values + //*********************************************************** + private bool _isEmptyPointIgnored = true; + + private string[] _extraParameters; + + /// + /// All X values are zero. + /// + private bool _zeroXValues = false; + + /// + /// Utility class for Statistical formulas + /// + private StatisticFormula _statistics; + + /// + /// Reference to the Common elements + /// + internal CommonElements Common; + + + #endregion + + #region Data Formulas methods + + /// + /// Default constructor + /// + public DataFormula() + { + _statistics = new StatisticFormula(this); + + _extraParameters = new string[1]; + _extraParameters[0] = false.ToString(System.Globalization.CultureInfo.InvariantCulture); + } + + /// + /// This method calls a method from a formula module with + /// specified name. + /// + /// Formula Name + /// Formula parameters + /// Comma separated input data series names and optional X and Y values names. + /// Comma separated output data series names and optional X and Y values names. + internal void Formula(string formulaName, string parameters, string inputSeries, string outputSeries) + { + // Array of series + Series[] inSeries; + Series[] outSeries; + + // Commented out as InsertEmptyDataPoints is currently commented out. + // This field is not used anywhere else, but we might need it if we uncomment all ---- code parts in this method. (krisztb 4/29/08) + // True if formulas are statistical + //bool statisticalFormulas = false; + + // Array of Y value indexes + int[] inValueIndexes; + int[] outValueIndexes; + + // Matrix with double values ( used in formula modules ) + double[][] inValues; + double[][] inNoEmptyValues; + double[][] outValues = null; + string[][] outLabels = null; + + // Array with parameters + string[] parameterList; + + // Split comma separated parameter list in the array of strings. + SplitParameters(parameters, out parameterList); + + // Split comma separated series and Y values list in the array of + // Series and indexes to Y values. + ConvertToArrays(inputSeries, out inSeries, out inValueIndexes, true); + ConvertToArrays(outputSeries, out outSeries, out outValueIndexes, false); + + // Create indexes if all x values are 0 + //ConvertZeroXToIndex( ref inSeries ); + + // Set X value AxisName for output series. + foreach (Series outSeriesItem in outSeries) + { + if (inSeries[0] != null) + { + outSeriesItem.XValueType = inSeries[0].XValueType; + } + } + + // This method will convert array of Series and array of Y value + // indexes to matrix of double values. + GetDoubleArray(inSeries, inValueIndexes, out inValues); + + // Remove columns with empty values from matrix + if (!DifferentNumberOfSeries(inValues)) + { + RemoveEmptyValues(inValues, out inNoEmptyValues); + } + else + { + inNoEmptyValues = inValues; + } + + // Call a formula from formula modules + string moduleName = null; + for (int module = 0; module < Common.FormulaRegistry.Count; module++) + { + moduleName = Common.FormulaRegistry.GetModuleName(module); + Common.FormulaRegistry.GetFormulaModule(moduleName).Formula(formulaName, inNoEmptyValues, out outValues, parameterList, _extraParameters, out outLabels); + + // Commented out as InsertEmptyDataPoints is currently commented out (see next block). + // It set the statisticalFormulas field that was used to test whether to insert empty data points. (krisztb 4/29/08) + //if( outValues != null ) + //{ + // if (moduleName == SR.FormulaNameStatisticalAnalysis) + // { + // statisticalFormulas = true; + // } + // break; + //} + + // Check if formula was found by detecting output + if (outValues != null) + { + // Exit the loop + break; + } + } + + if (outValues == null) + throw new ArgumentException(SR.ExceptionFormulaNotFound(formulaName)); + + // Insert empty data points + + // + // This has been commented out as InsertEmptyDataPoints is currently commented out. + // In its current implementation it didn't do anything other than assign the second + // parameter to the third, so ultimately it was a no op. --Microsoft 4/21/08 + // + //if( !statisticalFormulas ) + //{ + // InsertEmptyDataPoints( inValues, outValues, out outValues ); + //} + + // Fill Series with results from matrix with double values using Y value indexes. + SetDoubleArray(outSeries, outValueIndexes, outValues, outLabels); + + if (_zeroXValues) + { + // we have indexed series : proceed to align output series. + foreach (Series series in outSeries) + { + if (series.Points.Count > 0) + { + // get the last xValue: the formula processing is + double topXValue = series.Points[series.Points.Count - 1].XValue; + this.Common.Chart.DataManipulator.InsertEmptyPoints(1, IntervalType.Number, 0, IntervalType.Number, 1, topXValue, series); + foreach (DataPoint point in series.Points) + { + point.XValue = 0; + } + } + } + } + // Copy axis labels from the original series into the calculated series + CopyAxisLabels(inSeries, outSeries); + } + + /// + /// Copy axis labels from the original series into the calculated series + /// + /// array of input series + /// array of output series + private void CopyAxisLabels(Series[] inSeries, Series[] outSeries) + { + //Loop through the pairs of input and output series + int seriesIndex = 0; + while (seriesIndex < inSeries.Length && seriesIndex < outSeries.Length) + { + Series inputSeries = inSeries[seriesIndex]; + Series outputSeries = outSeries[seriesIndex]; + + //Depending on whether or not the source series has X Values we need to use two different search algorithms + if (_zeroXValues) + { //If we have the empty XValues then the source series should have all the AxisLabels + // -- set the indexed series labels source + outputSeries[DataFormula.IndexedSeriesLabelsSourceAttr] = inputSeries.Name; + } + else + { //If the source series has XValues - loop through the input series points looking for the points with AxisLabels set + int outIndex = 0; + foreach (DataPoint inputPoint in inputSeries.Points) + { + if (!String.IsNullOrEmpty(inputPoint.AxisLabel)) + { + //If the Axis label is set we need to find the corresponding point by the X value + //Most probably the points are in the same order so lets first try the corresponding point in the output series + if (outIndex < outputSeries.Points.Count && inputPoint.XValue == outputSeries.Points[outIndex].XValue) + { // Yes, the corresponding point in the outputSeries has the same XValue as inputPoint -> copy axis label + outputSeries.Points[outIndex].AxisLabel = inputPoint.AxisLabel; + } + else + { + //The correspong point has a different x value -> lets go through output series and find the value with the same X + outIndex = 0; + foreach (DataPoint outputPoint in outputSeries.Points) + { + if (inputPoint.XValue == outputPoint.XValue) + { //Found the point with the same XValue - copy axis label and break + outputPoint.AxisLabel = inputPoint.AxisLabel; + break; + } + outIndex++; + } + } + } + outIndex++; + } + } + //Sync next pair of input and output series... + seriesIndex++; + } + } + + + /// + /// This method will set series X and Y values from matrix of + /// double values. + /// + /// Array of output series + /// Array of Y value indexes + /// Array of doubles which will be used to fill series + /// Array of labels + internal void SetDoubleArray(Series[] outputSeries, int[] valueIndex, double[][] outputValues, string[][] outputLabels) + { + // Validation + if (outputSeries.Length != valueIndex.Length) + { + throw new ArgumentException(SR.ExceptionFormulaDataItemsNumberMismatch); + } + + // Number of output series is not correct + if (outputSeries.Length < outputValues.Length - 1) + { + throw new ArgumentException(SR.ExceptionFormulaDataOutputSeriesNumberYValuesIncorrect); + } + + int seriesIndex = 0; + foreach (Series series in outputSeries) + { + if (seriesIndex + 1 > outputValues.Length - 1) + { + break; + } + + // If there is different number of data points. + if (series.Points.Count != outputValues[seriesIndex].Length) + { + // Delete all points + series.Points.Clear(); + } + + // Set the number of y values + if (series.YValuesPerPoint < valueIndex[seriesIndex]) + { + series.YValuesPerPoint = valueIndex[seriesIndex]; + } + + for (int pointIndex = 0; pointIndex < outputValues[0].Length; pointIndex++) + { + // Create a new series and fill data + if (series.Points.Count != outputValues[seriesIndex].Length) + { + // Add data points to series. + series.Points.AddXY(outputValues[0][pointIndex], 0); + + // Set Labels + if (outputLabels != null) + { + series.Points[pointIndex].Label = outputLabels[seriesIndex][pointIndex]; + } + + // Set empty data points or Y values + if (Double.IsNaN(outputValues[seriesIndex + 1][pointIndex])) + series.Points[pointIndex].IsEmpty = true; + else + series.Points[pointIndex].YValues[valueIndex[seriesIndex] - 1] = outputValues[seriesIndex + 1][pointIndex]; + } + // Use existing series and set Y values. + else + { + if (series.Points[pointIndex].XValue != outputValues[0][pointIndex] && !_zeroXValues) + { + throw new InvalidOperationException(SR.ExceptionFormulaXValuesNotAligned); + } + + // Set empty data points or Y values + if (Double.IsNaN(outputValues[seriesIndex + 1][pointIndex])) + series.Points[pointIndex].IsEmpty = true; + else + { + series.Points[pointIndex].YValues[valueIndex[seriesIndex] - 1] = outputValues[seriesIndex + 1][pointIndex]; + + // Set Labels + if (outputLabels != null) + { + series.Points[pointIndex].Label = outputLabels[seriesIndex][pointIndex]; + } + } + } + } + seriesIndex++; + } + } + + /// + /// This method will convert a string with information about + /// series and y values to two arrays. The first array will + /// contain series and the second array will contain + /// corresponding indexes to y values for every series. + /// The arrays have to have the same number of items. + /// + /// A string with information about series and Y values + /// Array of Data Series + /// Array of Y value indexes + /// Do not create new series if input series are used + private void ConvertToArrays(string inputString, out Series[] seiesArray, out int[] valueArray, bool inputSeries) + { + // Split string by comma + string[] subStrings = inputString.Split(','); + + // Create array of series + seiesArray = new Series[subStrings.Length]; + + // Create array of integers - values + valueArray = new int[subStrings.Length]; + + int index = 0; + + foreach (string str in subStrings) + { + string[] parts = str.Split(':'); + + + // There must be at least one and no more than two result strings + if (parts.Length < 1 && parts.Length > 2) + { + throw (new ArgumentException(SR.ExceptionFormulaDataFormatInvalid(str))); + } + + // Initialize value index as first Y value (default) + int valueIndex = 1; + + // Check specified value type + if (parts.Length == 2) + { + if (parts[1].StartsWith("Y", StringComparison.Ordinal)) + { + parts[1] = parts[1].TrimStart('Y'); + + if (parts[1].Length == 0) + { + valueIndex = 1; + } + else + { + // Try to convert the rest of the string to integer + try + { + valueIndex = Int32.Parse(parts[1], System.Globalization.CultureInfo.InvariantCulture); + } + catch (System.Exception) + { + throw (new ArgumentException(SR.ExceptionFormulaDataFormatInvalid(str))); + } + } + } + else + { + throw (new ArgumentException(SR.ExceptionFormulaDataSeriesNameNotFound(str))); + } + } + + // Set Y value indexes + valueArray[index] = valueIndex; + + // Set series + try + { + seiesArray[index] = Common.DataManager.Series[parts[0].Trim()]; + } + catch (System.Exception) + { + // Series doesn't exist. + if (!inputSeries) + { + // Create a new series if output series + Common.DataManager.Series.Add(new Series(parts[0])); + seiesArray[index] = Common.DataManager.Series[parts[0]]; + } + else + throw (new ArgumentException(SR.ExceptionFormulaDataSeriesNameNotFoundInCollection(str))); + } + index++; + } + } + + + /// + /// Returns Jagged Arrays of doubles from array of series. + /// A jagged array is merely an array of arrays and + /// it doesn't have to be square. The first item is array of + /// X values from the first series + /// + /// Array of Data Series + /// Array with indexes which represent value from data point: 0 = X, 1 = Y, 2 = Y2, 3 = Y3 + /// Jagged Arrays of doubles + private void GetDoubleArray(Series[] inputSeries, int[] valueIndex, out double[][] output) + { + GetDoubleArray(inputSeries, valueIndex, out output, false); + } + + /// + /// Returns Jagged Arrays of doubles from array of series. + /// A jagged array is merely an array of arrays and + /// it doesn't have to be square. The first item is array of + /// X values from the first series + /// + /// Array of Data Series + /// Array with indexes which represent value from data point: 0 = X, 1 = Y, 2 = Y2, 3 = Y3 + /// Jagged Arrays of doubles + /// Ignore Zero X values + private void GetDoubleArray(Series[] inputSeries, int[] valueIndex, out double[][] output, bool ignoreZeroX) + { + // Allocate a memory. + output = new double[inputSeries.Length + 1][]; + + // Check the length of the array of series and array of value indexes. + if (inputSeries.Length != valueIndex.Length) + { + throw new ArgumentException(SR.ExceptionFormulaDataItemsNumberMismatch2); + } + + // Find Maximum number of data points + int maxNumOfPoints = int.MinValue; + Series seriesWidthMaxPoints = null; + foreach (Series series in inputSeries) + { + if (maxNumOfPoints < series.Points.Count) + { + maxNumOfPoints = series.Points.Count; + seriesWidthMaxPoints = series; + } + } + + // ********************************************************* + // Set X values + // ********************************************************* + + // Check if all X values are zero + foreach (DataPoint point in inputSeries[0].Points) + { + _zeroXValues = true; + + if (point.XValue != 0.0) + { + _zeroXValues = false; + break; + } + } + + if (_zeroXValues && !ignoreZeroX) + { + // Check X values input alignment + CheckXValuesAlignment(inputSeries); + } + + + // Data point index + int indexPoint = 0; + + // Allocate memory for X values. + output[0] = new double[maxNumOfPoints]; + + // Data Points loop + foreach (DataPoint point in seriesWidthMaxPoints.Points) + { + // Set X value + if (_zeroXValues) + output[0][indexPoint] = (double)indexPoint + 1.0; + else + output[0][indexPoint] = point.XValue; + + // Increase data point index. + indexPoint++; + } + + // ********************************************************* + // Set Y values + // ********************************************************* + // Data Series Loop + int indexSeries = 1; + foreach (Series series in inputSeries) + { + output[indexSeries] = new double[series.Points.Count]; + indexPoint = 0; + + // Data Points loop + foreach (DataPoint point in series.Points) + { + // Set Y values + if (point.IsEmpty) + // IsEmpty data point + output[indexSeries][indexPoint] = double.NaN; + else + { + try + { + output[indexSeries][indexPoint] = point.YValues[valueIndex[indexSeries - 1] - 1]; + } + catch (System.Exception) + { + throw new ArgumentException(SR.ExceptionFormulaYIndexInvalid); + } + } + + // Increase data point index. + indexPoint++; + } + // Increase data series index. + indexSeries++; + } + } + + /// + /// Merge, split or move Y values of the series. + /// + /// Comma separated list of input data series names and optional X and Y values names. + /// Comma separated list of output data series names and optional X and Y values names. + public void CopySeriesValues(string inputSeries, string outputSeries) + { + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + if (outputSeries == null) + throw new ArgumentNullException("outputSeries"); + + Series[] inSeries; + Series[] outSeries; + int[] inValueIndexes; + int[] outValueIndexes; + double[][] inValues; + double[][] outValues; + + // Convert string with information about series and Y values + // to array of series and indexes to Y values. + ConvertToArrays(inputSeries, out inSeries, out inValueIndexes, true); + ConvertToArrays(outputSeries, out outSeries, out outValueIndexes, false); + + // The number of input and output series are different. + if (inSeries.Length != outSeries.Length) + { + throw new ArgumentException(SR.ExceptionFormulaInputOutputSeriesMismatch); + } + + // Check if output series points exist. If they do not exist + // create data points which are copy of Input series data points + for (int indexSeries = 0; indexSeries < inSeries.Length; indexSeries++) + { + Series[] series = new Series[2]; + series[0] = inSeries[indexSeries]; + series[1] = outSeries[indexSeries]; + if (series[1].Points.Count == 0) + { + foreach (DataPoint point in series[0].Points) + { + DataPoint clonePoint = point.Clone(); + clonePoint.series = series[1]; + series[1].Points.Add(clonePoint); + } + } + } + + // Check alignment of X values. + for (int indexSeries = 0; indexSeries < inSeries.Length; indexSeries++) + { + Series[] series = new Series[2]; + series[0] = inSeries[indexSeries]; + series[1] = outSeries[indexSeries]; + CheckXValuesAlignment(series); + } + + // Covert Series X and Y values to arrays of doubles + GetDoubleArray(inSeries, inValueIndexes, out inValues, true); + + outValues = new double[inValues.Length][]; + + // Copy Series X and Y values. + for (int seriesIndex = 0; seriesIndex < inValues.Length; seriesIndex++) + { + outValues[seriesIndex] = new double[inValues[seriesIndex].Length]; + for (int pointIndex = 0; pointIndex < inValues[seriesIndex].Length; pointIndex++) + { + outValues[seriesIndex][pointIndex] = inValues[seriesIndex][pointIndex]; + } + } + + // Copy Series X and Y value Types. + for (int seriesIndx = 0; seriesIndx < inSeries.Length; seriesIndx++) + { + // X value type + if (outSeries[seriesIndx].XValueType == ChartValueType.Auto) + { + outSeries[seriesIndx].XValueType = inSeries[seriesIndx].XValueType; + outSeries[seriesIndx].autoXValueType = inSeries[seriesIndx].autoXValueType; + } + + // Y value type. + if (outSeries[seriesIndx].YValueType == ChartValueType.Auto) + { + outSeries[seriesIndx].YValueType = inSeries[seriesIndx].YValueType; + outSeries[seriesIndx].autoYValueType = inSeries[seriesIndx].autoYValueType; + } + + seriesIndx++; + } + + SetDoubleArray(outSeries, outValueIndexes, outValues, null); + } + + + /// + /// This method will first copy input matrix to output matrix + /// then will remove columns, which have + /// one or more empty values (NaN) from the output matrix. This + /// method will set all values from column of input matrix + /// to be empty (NaN) if one or more values of that column + /// are empty. + /// + /// Input matrix with empty values + /// Output matrix without empty values + private void RemoveEmptyValues(double[][] input, out double[][] output) + { + // Allocate memory + output = new double[input.Length][]; + int seriesIndex = 0; + + int numberOfRows = 0; + + // Set Nan for all data points with same index in input array + // Data point loop + for (int pointIndex = 0; pointIndex < input[0].Length; pointIndex++) + { + bool isEmpty = false; + // Series loop + // Find empty data point with same point index + for (seriesIndex = 0; seriesIndex < input.Length; seriesIndex++) + { + if (seriesIndex >= input[seriesIndex].Length) + continue; + if (Double.IsNaN(input[seriesIndex][pointIndex])) + isEmpty = true; + } + + if (!isEmpty) + { + numberOfRows++; + } + + // There is empty data point + if (isEmpty) + { + // Set all points with same index to be empty + for (seriesIndex = 1; seriesIndex < input.Length; seriesIndex++) + { + input[seriesIndex][pointIndex] = Double.NaN; + } + } + } + + // Copy input matrix to output matrix without empty columns. + for (seriesIndex = 0; seriesIndex < input.Length; seriesIndex++) + { + output[seriesIndex] = new double[numberOfRows]; + int outPointIndex = 0; + for (int pointIndex = 0; pointIndex < input[0].Length; pointIndex++) + { + if (pointIndex >= input[seriesIndex].Length) + continue; + if (!double.IsNaN(input[1][pointIndex])) + { + output[seriesIndex][outPointIndex] = input[seriesIndex][pointIndex]; + outPointIndex++; + } + } + } + } + + + /* + /// + /// This method will compare a input matrix with empty data + /// points and output matrix without empty data points and + /// add empty data points to output matrix according to + /// input matrix empty data point positions. + /// + /// Matrix With input data + /// Matrix without empty data points + /// New Matrix with inserted data points + */ + //private void InsertEmptyDataPoints( double [][] input, double [][] inputWithoutEmpty, out double [][] output ) + //{ + + + // *** NOTE *** + // + // + // This method is only called in one location as of this writing. + // Therefore the entire method is being commented out for now. We wish + // to preserve the code itself as it may be re-implemented in the future. + // --Microsoft 4/21/08 + // + // ************ + + + + //output = inputWithoutEmpty; + //return; + + // + // NOTE: Inserting empty points in the result data after applying the formula + // causes issues. The algorithm below do not cover most of the common spzces + // and as a result the formula data is completly destroyed. + // + // By removing this code the result data set will have "missing" points instaed + // of empty. + // - AG + // + + /* + + // Input matrix can have only empty rows. If one value + // is empty all values from a row have to be empty. + + // Find the number of empty rows + int NumberOfEmptyRows = 0; + foreach( double val in input[1] ) + { + if( Double.IsNaN( val ) ) + { + NumberOfEmptyRows++; + } + } + + if( NumberOfEmptyRows == 0 || + inputWithoutEmpty[0].Length > input[0].Length) + { + output = inputWithoutEmpty; + return; + } + + output = new double[input.Length][]; + // Series loop + for( int seriesIndex = 0; seriesIndex < input.Length; seriesIndex++ ) + { + int inputPointIndex = 0; + int emptyPointIndex = 0; + + // Skip input index if points are not aligned . + while( input[0][inputPointIndex] != inputWithoutEmpty[0][0] && inputPointIndex < input[0].Length ) + { + inputPointIndex++; + } + + output[seriesIndex] = new double[inputWithoutEmpty[0].Length + NumberOfEmptyRows - inputPointIndex]; + + // Data Point loop + for( int pointIndex = 0; pointIndex < output[seriesIndex].Length; pointIndex++ ) + { + if( inputPointIndex < input[0].Length && + inputPointIndex < input[1].Length ) + { + // If the point Y value is empty (NaN) insert empty (NaN) for all values. + if( double.IsNaN( input[1][inputPointIndex] ) ) + { + output[seriesIndex][pointIndex] = input[seriesIndex][inputPointIndex]; + emptyPointIndex--; + } + else if( input[0][inputPointIndex] == inputWithoutEmpty[0][emptyPointIndex] ) + { + output[seriesIndex][pointIndex] = inputWithoutEmpty[seriesIndex][emptyPointIndex]; + } + else + { + output[0][pointIndex] = inputWithoutEmpty[0][emptyPointIndex]; + output[seriesIndex][pointIndex] = inputWithoutEmpty[seriesIndex][emptyPointIndex]; + } + } + else + { + output[seriesIndex][pointIndex] = inputWithoutEmpty[seriesIndex][emptyPointIndex]; + } + + inputPointIndex++; + emptyPointIndex++; + } + } + */ + //} + + + /// + /// This method splits a string with comma separated + /// parameters to the array of strings with parameters. + /// + /// a string with comma separated parameters + /// the array of strings with parameters + private void SplitParameters(string parameters, out string[] parameterList) + { + // Split string by comma + parameterList = parameters.Split(','); + + for (Int32 i = 0; i < parameterList.Length; i++) + { + parameterList[i] = parameterList[i].Trim(); + } + + } + + /// + /// Check if series have different number of series. + /// + /// Input series. + /// true if there is different number of series. + private static bool DifferentNumberOfSeries(double[][] input) + { + for (int index = 0; index < input.Length - 1; index++) + { + if (input[index].Length != input[index + 1].Length) + { + return true; + } + } + return false; + } + + /// + /// This method will check if X values from different series + /// are aligned. + /// + /// Array of series + internal void CheckXValuesAlignment(Series[] series) + { + // Check aligment only if more than 1 series provided + if (series.Length > 1) + { + // Series loop + for (int seriesIndex = 0; seriesIndex < series.Length - 1; seriesIndex++) + { + // Check the number of data points + if (series[seriesIndex].Points.Count != series[seriesIndex + 1].Points.Count) + { + throw new ArgumentException(SR.ExceptionFormulaDataSeriesAreNotAlignedDifferentDataPoints(series[seriesIndex].Name, series[seriesIndex + 1].Name)); + } + + // Data points loop + for (int pointIndex = 0; pointIndex < series[seriesIndex].Points.Count; pointIndex++) + { + // Check X values. + if (series[seriesIndex].Points[pointIndex].XValue != series[seriesIndex + 1].Points[pointIndex].XValue) + throw new ArgumentException(SR.ExceptionFormulaDataSeriesAreNotAlignedDifferentXValues(series[seriesIndex].Name, series[seriesIndex + 1].Name)); + + } + } + } + } + + + #endregion + + #region Data Formulas Financial methods + /// + /// This method calls a method from a formula module with + /// specified name. + /// + /// Formula Name + /// Input series + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void FinancialFormula(FinancialFormula formulaName, Series inputSeries) + { + FinancialFormula(formulaName, inputSeries, inputSeries); + } + + /// + /// This method calls a method from a formula module with + /// specified name. + /// + /// Formula Name + /// Input series + /// Output series + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void FinancialFormula(FinancialFormula formulaName, Series inputSeries, Series outputSeries) + { + FinancialFormula(formulaName, "", inputSeries, outputSeries); + } + + + /// + /// This method calls a method from a formula module with + /// specified name. + /// + /// Formula Name + /// Formula parameters + /// Input series + /// Output series + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void FinancialFormula(FinancialFormula formulaName, string parameters, Series inputSeries, Series outputSeries) + { + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + if (outputSeries == null) + throw new ArgumentNullException("outputSeries"); + FinancialFormula(formulaName, parameters, inputSeries.Name, outputSeries.Name); + } + + + /// + /// This method calls a method from a formula module with + /// specified name. + /// + /// Formula Name + /// Comma separated list of input series names and optional X and Y values names. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void FinancialFormula(FinancialFormula formulaName, string inputSeries) + { + FinancialFormula(formulaName, inputSeries, inputSeries); + } + + + /// + /// This method calls a method from a formula module with + /// specified name. + /// + /// Formula Name + /// Comma separated list of input series names and optional X and Y values names. + /// Comma separated list of output series names and optional X and Y values names. + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void FinancialFormula(FinancialFormula formulaName, string inputSeries, string outputSeries) + { + FinancialFormula(formulaName, "", inputSeries, outputSeries); + } + + /// + /// This method calls a method from a formula module with + /// specified name. + /// + /// Formula Name + /// Formula parameters + /// Comma separated list of input series names and optional X and Y values names. + /// Comma separated list of output series names and optional X and Y values names. + public void FinancialFormula(FinancialFormula formulaName, string parameters, string inputSeries, string outputSeries) + { + if (inputSeries == null) + throw new ArgumentNullException("inputSeries"); + if (outputSeries == null) + throw new ArgumentNullException("outputSeries"); + + // Get formula info + FormulaInfo formulaInfo = FormulaHelper.GetFormulaInfo(formulaName); + + // Provide default parameters if necessary + if (string.IsNullOrEmpty(parameters)) + { + parameters = formulaInfo.SaveParametersToString(); + } + else + { + formulaInfo.CheckParameterString(parameters); + } + + // Fix the InputSeries and Outputseries for cases when the series field names are not provided + SeriesFieldList inputFields = SeriesFieldList.FromString(this.Common.Chart, inputSeries, formulaInfo.InputFields); + SeriesFieldList outputFields = SeriesFieldList.FromString(this.Common.Chart, outputSeries, formulaInfo.OutputFields); + + if (inputFields != null) inputSeries = inputFields.ToString(); + if (outputFields != null) outputSeries = outputFields.ToString(); + + Formula(formulaName.ToString(), parameters, inputSeries, outputSeries); + } + #endregion + + #region Data Formulas properties + + /// + /// Gets or sets a flag which indicates whether + /// empty points are ignored while performing calculations; + /// otherwise, empty points are treated as zeros. + /// + public bool IsEmptyPointIgnored + { + get + { + return _isEmptyPointIgnored; + } + set + { + _isEmptyPointIgnored = value; + } + } + + + + /// + /// Gets or sets a flag which indicates whether + /// to start formulas like rolling average from zero. + /// + public bool IsStartFromFirst + { + get + { + return bool.Parse(_extraParameters[0]); + } + set + { + if (value) + _extraParameters[0] = true.ToString(System.Globalization.CultureInfo.InvariantCulture); + else + _extraParameters[0] = false.ToString(System.Globalization.CultureInfo.InvariantCulture); + } + } + + /// + /// Returns a reference to the statistical utility class. + /// + public StatisticFormula Statistics + { + get + { + return _statistics; + } + } + + + #endregion + } + + + +} diff --git a/System.Web.DataVisualization/Common/General/GdiGraphics.cs b/System.Web.DataVisualization/Common/General/GdiGraphics.cs new file mode 100644 index 000000000..361b55cd3 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/GdiGraphics.cs @@ -0,0 +1,732 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: GdiGraphics.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: GdiGraphics +// +// Purpose: GdiGraphics class is chart GDI+ rendering engine. It +// implements IChartRenderingEngine interface by mapping +// its methods to the drawing methods of GDI+. This +// rendering engine do not support animation. +// +// Reviwed: AG - Jul 15, 2003 +// AG - Microsoft 14, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Drawing.Imaging; +using System.ComponentModel; +using System.Collections; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL + +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else + //using System.Web.UI.DataVisualization.Charting.Utilities; + //using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// GdiGraphics class is chart GDI+ rendering engine. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gdi")] + internal class GdiGraphics : IChartRenderingEngine + { + #region Constructors + + /// + /// Default constructor + /// + public GdiGraphics() + { + } + + #endregion // Constructor + + #region Drawing Methods + + /// + /// Draws a line connecting two PointF structures. + /// + /// Pen object that determines the color, width, and style of the line. + /// PointF structure that represents the first point to connect. + /// PointF structure that represents the second point to connect. + public void DrawLine( + Pen pen, + PointF pt1, + PointF pt2 + ) + { + _graphics.DrawLine( pen, pt1, pt2 ); + } + + /// + /// Draws a line connecting the two points specified by coordinate pairs. + /// + /// Pen object that determines the color, width, and style of the line. + /// x-coordinate of the first point. + /// y-coordinate of the first point. + /// x-coordinate of the second point. + /// y-coordinate of the second point. + public void DrawLine( + Pen pen, + float x1, + float y1, + float x2, + float y2 + ) + { + _graphics.DrawLine( pen, x1, y1, x2, y2 ); + } + + /// + /// Draws the specified portion of the specified Image object at the specified location and with the specified size. + /// + /// Image object to draw. + /// Rectangle structure that specifies the location and size of the drawn image. The image is scaled to fit the rectangle. + /// x-coordinate of the upper-left corner of the portion of the source image to draw. + /// y-coordinate of the upper-left corner of the portion of the source image to draw. + /// Width of the portion of the source image to draw. + /// Height of the portion of the source image to draw. + /// Member of the GraphicsUnit enumeration that specifies the units of measure used to determine the source rectangle. + /// ImageAttributes object that specifies recoloring and gamma information for the image object. + public void DrawImage( + System.Drawing.Image image, + Rectangle destRect, + int srcX, + int srcY, + int srcWidth, + int srcHeight, + GraphicsUnit srcUnit, + ImageAttributes imageAttr + ) + { + _graphics.DrawImage( + image, + destRect, + srcX, + srcY, + srcWidth, + srcHeight, + srcUnit, + imageAttr + ); + } + + /// + /// Draws an ellipse defined by a bounding rectangle specified by + /// a pair of coordinates: a height, and a width. + /// + /// Pen object that determines the color, width, and style of the ellipse. + /// x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse. + /// y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse. + /// Width of the bounding rectangle that defines the ellipse. + /// Height of the bounding rectangle that defines the ellipse. + public void DrawEllipse( + Pen pen, + float x, + float y, + float width, + float height + ) + { + _graphics.DrawEllipse( pen, x, y, width, height ); + } + + /// + /// Draws a cardinal spline through a specified array of PointF structures + /// using a specified tension. The drawing begins offset from + /// the beginning of the array. + /// + /// Pen object that determines the color, width, and height of the curve. + /// Array of PointF structures that define the spline. + /// Offset from the first element in the array of the points parameter to the starting point in the curve. + /// Number of segments after the starting point to include in the curve. + /// Value greater than or equal to 0.0F that specifies the tension of the curve. + public void DrawCurve( + Pen pen, + PointF[] points, + int offset, + int numberOfSegments, + float tension + ) + { + _graphics.DrawCurve( pen, points, offset, numberOfSegments, tension ); + } + + /// + /// Draws a rectangle specified by a coordinate pair: a width, and a height. + /// + /// Pen object that determines the color, width, and style of the rectangle. + /// x-coordinate of the upper-left corner of the rectangle to draw. + /// y-coordinate of the upper-left corner of the rectangle to draw. + /// Width of the rectangle to draw. + /// Height of the rectangle to draw. + public void DrawRectangle( + Pen pen, + int x, + int y, + int width, + int height + ) + { + _graphics.DrawRectangle( pen, x, y, width, height ); + } + + /// + /// Draws a polygon defined by an array of PointF structures. + /// + /// Pen object that determines the color, width, and style of the polygon. + /// Array of PointF structures that represent the vertices of the polygon. + public void DrawPolygon( + Pen pen, + PointF[] points + ) + { + _graphics.DrawPolygon( pen, points ); + } + + /// + /// Draws the specified text string in the specified rectangle with the specified Brush and Font objects using the formatting properties of the specified StringFormat object. + /// + /// String to draw. + /// Font object that defines the text format of the string. + /// Brush object that determines the color and texture of the drawn text. + /// RectangleF structure that specifies the location of the drawn text. + /// StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text. + public void DrawString( + string s, + Font font, + Brush brush, + RectangleF layoutRectangle, + StringFormat format + ) + { + _graphics.DrawString( s, font, brush, layoutRectangle, format ); + } + + /// + /// Draws the specified text string at the specified location with the specified Brush and Font objects using the formatting properties of the specified StringFormat object. + /// + /// String to draw. + /// Font object that defines the text format of the string. + /// Brush object that determines the color and texture of the drawn text. + /// PointF structure that specifies the upper-left corner of the drawn text. + /// StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text. + public void DrawString( + string s, + Font font, + Brush brush, + PointF point, + StringFormat format + ) + { + _graphics.DrawString( s, font, brush, point, format ); + } + + /// + /// Draws the specified portion of the specified Image object at the specified location and with the specified size. + /// + /// Image object to draw. + /// Rectangle structure that specifies the location and size of the drawn image. The image is scaled to fit the rectangle. + /// x-coordinate of the upper-left corner of the portion of the source image to draw. + /// y-coordinate of the upper-left corner of the portion of the source image to draw. + /// Width of the portion of the source image to draw. + /// Height of the portion of the source image to draw. + /// Member of the GraphicsUnit enumeration that specifies the units of measure used to determine the source rectangle. + /// ImageAttributes object that specifies recoloring and gamma information for the image object. + public void DrawImage( + System.Drawing.Image image, + Rectangle destRect, + float srcX, + float srcY, + float srcWidth, + float srcHeight, + GraphicsUnit srcUnit, + ImageAttributes imageAttrs + ) + { + _graphics.DrawImage( image, destRect, srcX, srcY, srcWidth, srcHeight, srcUnit, imageAttrs ); + } + + /// + /// Draws a rectangle specified by a coordinate pair: a width, and a height. + /// + /// A Pen object that determines the color, width, and style of the rectangle. + /// The x-coordinate of the upper-left corner of the rectangle to draw. + /// The y-coordinate of the upper-left corner of the rectangle to draw. + /// The width of the rectangle to draw. + /// The height of the rectangle to draw. + public void DrawRectangle( + Pen pen, + float x, + float y, + float width, + float height + ) + { + _graphics.DrawRectangle( pen, x, y, width, height ); + } + + /// + /// Draws a GraphicsPath object. + /// + /// Pen object that determines the color, width, and style of the path. + /// GraphicsPath object to draw. + public void DrawPath( + Pen pen, + GraphicsPath path + ) + { + _graphics.DrawPath( pen, path ); + } + + /// + /// Draws a pie shape defined by an ellipse specified by a coordinate pair: a width, a height and two radial lines. + /// + /// Pen object that determines the color, width, and style of the pie shape. + /// x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// Width of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// Height of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// Angle measured in degrees clockwise from the x-axis to the first side of the pie shape. + /// Angle measured in degrees clockwise from the startAngle parameter to the second side of the pie shape. + public void DrawPie( + Pen pen, + float x, + float y, + float width, + float height, + float startAngle, + float sweepAngle + ) + { + _graphics.DrawPie( pen, x, y, width, height, startAngle, sweepAngle ); + } + + /// + /// Draws an arc representing a portion of an ellipse specified by a pair of coordinates: a width, and a height. + /// + /// Pen object that determines the color, width, and style of the arc. + /// x-coordinate of the upper-left corner of the rectangle that defines the ellipse. + /// y-coordinate of the upper-left corner of the rectangle that defines the ellipse. + /// Width of the rectangle that defines the ellipse. + /// Height of the rectangle that defines the ellipse. + /// Angle in degrees measured clockwise from the x-axis to the starting point of the arc. + /// Angle in degrees measured clockwise from the startAngle parameter to ending point of the arc. + public void DrawArc( + Pen pen, + float x, + float y, + float width, + float height, + float startAngle, + float sweepAngle + ) + { + _graphics.DrawArc( pen, x, y, width, height, startAngle, sweepAngle ); + } + + /// + /// Draws the specified Image object at the specified location and with the specified size. + /// + /// Image object to draw. + /// RectangleF structure that specifies the location and size of the drawn image. + public void DrawImage( + System.Drawing.Image image, + RectangleF rect + ) + { + _graphics.DrawImage( image, rect ); + } + + /// + /// Draws an ellipse defined by a bounding RectangleF. + /// + /// Pen object that determines the color, width, and style of the ellipse. + /// RectangleF structure that defines the boundaries of the ellipse. + public void DrawEllipse( + Pen pen, + RectangleF rect + ) + { + _graphics.DrawEllipse( pen, rect ); + } + + /// + /// Draws a series of line segments that connect an array of PointF structures. + /// + /// Pen object that determines the color, width, and style of the line segments. + /// Array of PointF structures that represent the points to connect. + public void DrawLines( + Pen pen, + PointF[] points + ) + { + _graphics.DrawLines( pen, points ); + } + + #endregion // Drawing Methods + + #region Filling Methods + + /// + /// Fills the interior of an ellipse defined by a bounding rectangle + /// specified by a RectangleF structure. + /// + /// Brush object that determines the characteristics of the fill. + /// RectangleF structure that represents the bounding rectangle that defines the ellipse. + public void FillEllipse( + Brush brush, + RectangleF rect + ) + { + _graphics.FillEllipse( brush, rect ); + } + + /// + /// Fills the interior of a GraphicsPath object. + /// + /// Brush object that determines the characteristics of the fill. + /// GraphicsPath object that represents the path to fill. + public void FillPath( + Brush brush, + GraphicsPath path + ) + { + _graphics.FillPath( brush, path ); + } + + /// + /// Fills the interior of a Region object. + /// + /// Brush object that determines the characteristics of the fill. + /// Region object that represents the area to fill. + public void FillRegion( + Brush brush, + Region region + ) + { + _graphics.FillRegion( brush, region ); + } + + /// + /// Fills the interior of a rectangle specified by a RectangleF structure. + /// + /// Brush object that determines the characteristics of the fill. + /// RectangleF structure that represents the rectangle to fill. + public void FillRectangle( + Brush brush, + RectangleF rect + ) + { + _graphics.FillRectangle( brush, rect ); + } + + /// + /// Fills the interior of a rectangle specified by a pair of coordinates, a width, and a height. + /// + /// Brush object that determines the characteristics of the fill. + /// x-coordinate of the upper-left corner of the rectangle to fill. + /// y-coordinate of the upper-left corner of the rectangle to fill. + /// Width of the rectangle to fill. + /// Height of the rectangle to fill. + public void FillRectangle( + Brush brush, + float x, + float y, + float width, + float height + ) + { + _graphics.FillRectangle( brush, x, y, width, height ); + } + + /// + /// Fills the interior of a polygon defined by an array of points specified by PointF structures . + /// + /// Brush object that determines the characteristics of the fill. + /// Array of PointF structures that represent the vertices of the polygon to fill. + public void FillPolygon( + Brush brush, + PointF[] points + ) + { + _graphics.FillPolygon( brush, points ); + } + + /// + /// Fills the interior of a pie section defined by an ellipse + /// specified by a pair of coordinates, a width, and a height + /// and two radial lines. + /// + /// Brush object that determines the characteristics of the fill. + /// x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie section comes. + /// y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie section comes. + /// Width of the bounding rectangle that defines the ellipse from which the pie section comes. + /// Height of the bounding rectangle that defines the ellipse from which the pie section comes. + /// Angle in degrees measured clockwise from the x-axis to the first side of the pie section. + /// Angle in degrees measured clockwise from the startAngle parameter to the second side of the pie section. + public void FillPie( + Brush brush, + float x, + float y, + float width, + float height, + float startAngle, + float sweepAngle + ) + { + _graphics.FillPie( brush, x, y, width, height, startAngle, sweepAngle ); + } + + #endregion // Filling Methods + + #region Other Methods + + /// + /// Measures the specified string when drawn with the specified + /// Font object and formatted with the specified StringFormat object. + /// + /// String to measure. + /// Font object defines the text format of the string. + /// SizeF structure that specifies the maximum layout area for the text. + /// StringFormat object that represents formatting information, such as line spacing, for the string. + /// This method returns a SizeF structure that represents the size, in pixels, of the string specified in the text parameter as drawn with the font parameter and the stringFormat parameter. + public SizeF MeasureString( + string text, + Font font, + SizeF layoutArea, + StringFormat stringFormat + ) + { + return _graphics.MeasureString( text, font, layoutArea, stringFormat ); + } + + /// + /// Measures the specified string when drawn with the specified + /// Font object and formatted with the specified StringFormat object. + /// + /// String to measure. + /// Font object defines the text format of the string. + /// This method returns a SizeF structure that represents the size, in pixels, of the string specified in the text parameter as drawn with the font parameter and the stringFormat parameter. + public SizeF MeasureString( + string text, + Font font + ) + { + return _graphics.MeasureString( text, font ); + } + + /// + /// Saves the current state of this Graphics object and identifies the saved state with a GraphicsState object. + /// + /// This method returns a GraphicsState object that represents the saved state of this Graphics object. + public GraphicsState Save() + { + return _graphics.Save(); + } + + /// + /// Restores the state of this Graphics object to the state represented by a GraphicsState object. + /// + /// GraphicsState object that represents the state to which to restore this Graphics object. + public void Restore( + GraphicsState gstate + ) + { + _graphics.Restore( gstate ); + } + + /// + /// Resets the clip region of this Graphics object to an infinite region. + /// + public void ResetClip() + { + _graphics.ResetClip(); + } + + /// + /// Sets the clipping region of this Graphics object to the rectangle specified by a RectangleF structure. + /// + /// RectangleF structure that represents the new clip region. + public void SetClip( + RectangleF rect + ) + { + _graphics.SetClip( rect ); + } + + /// + /// Sets the clipping region of this Graphics object to the result of the + /// specified operation combining the current clip region and the + /// specified GraphicsPath object. + /// + /// GraphicsPath object to combine. + /// Member of the CombineMode enumeration that specifies the combining operation to use. + public void SetClip( + GraphicsPath path, + CombineMode combineMode + ) + { + _graphics.SetClip( path, combineMode ); + } + + /// + /// Prepends the specified translation to the transformation matrix of this Graphics object. + /// + /// x component of the translation. + /// y component of the translation. + public void TranslateTransform( + float dx, + float dy + ) + { + _graphics.TranslateTransform( dx, dy ); + } + + /// + /// This method starts Selection mode + /// + /// The location of the referenced object, expressed as a URI reference. + /// Title which could be used for tooltips. + public void BeginSelection( string hRef, string title ) + { + // Not supported for GDI+ + } + + /// + /// This method stops Selection mode + /// + public void EndSelection( ) + { + // Not supported for GDI+ + } + + + #endregion // Other Methods + + #region Properties + + /// + /// Gets or sets the world transformation for this Graphics object. + /// + public Matrix Transform + { + get + { + return _graphics.Transform; + } + set + { + _graphics.Transform = value; + } + } + + /// + /// Gets or sets the rendering quality for this Graphics object. + /// + public SmoothingMode SmoothingMode + { + get + { + return _graphics.SmoothingMode; + } + set + { + _graphics.SmoothingMode = value; + } + } + + /// + /// Gets or sets the rendering mode for text associated with this Graphics object. + /// + public TextRenderingHint TextRenderingHint + { + get + { + return _graphics.TextRenderingHint; + } + set + { + _graphics.TextRenderingHint = value; + } + } + + /// + /// Gets or sets a Region object that limits the drawing region of this Graphics object. + /// + public Region Clip + { + get + { + return _graphics.Clip; + } + set + { + _graphics.Clip = value; + } + } + + /// + /// Gets a value indicating whether the clipping region of this Graphics object is empty. + /// + public bool IsClipEmpty + { + get + { + return _graphics.IsClipEmpty; + } + } + + /// + /// Reference to the Graphics object + /// + public Graphics Graphics + { + get + { + return _graphics; + } + set + { + _graphics = value; + } + } + + #endregion // Properties + + #region Fields + + /// + /// Graphics object + /// + Graphics _graphics = null; + + #endregion // Fields + } +} diff --git a/System.Web.DataVisualization/Common/General/GridTickMarks.cs b/System.Web.DataVisualization/Common/General/GridTickMarks.cs new file mode 100644 index 000000000..69b78cbea --- /dev/null +++ b/System.Web.DataVisualization/Common/General/GridTickMarks.cs @@ -0,0 +1,2046 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: GridTickMarks.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: TickMark, Grid +// +// Purpose: Axis tick marks and grid lines a very similar chart +// elements and most of the functionality is located +// in the Grid class. TickMark class is derived from +// the Grid class and provides tick mark specific +// functionality. +// +// Reviewed: AG - Jul 31, 2002 +// AG - Microsoft 14, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif + +{ + #region Tick marks style enumeration + + /// + /// An enumeration of tick mark styles. + /// + public enum TickMarkStyle + { + /// + /// Tickmarks are disabled. + /// + None, + /// + /// Tickmarks are located outside of the chart area. + /// + OutsideArea, + /// + /// Tickmarks are located inside of the chart area. + /// + InsideArea, + /// + /// Tickmarks are set across the axis line. + /// + AcrossAxis + }; + + #endregion + + /// + /// The TickMark class represents axis tick marks which are drawn next to + /// the axis line. TickMark shares many common properties with the Grid + /// class. This class also contains methods for tick marks drawing. + /// + [ + DefaultProperty("Enabled"), + SRDescription("DescriptionAttributeTickMark_TickMark"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class TickMark : Grid + { + #region Private fields and Constructors + + // Tick marks style + private TickMarkStyle _style = TickMarkStyle.OutsideArea; + + // Tick marks size + private float _size = 1; + + /// + /// Public default constructor + /// + public TickMark() : base(null, true) + { + } + + /// + /// Public constructor + /// + /// Axis which owns the grid or tick mark. + /// Major axis element. + internal TickMark(Axis axis, bool major) : base(axis, major) + { + } + + #endregion + + #region Tick marks painting method + + /// + /// Draws and hit test for TickMarks. + /// + /// Reference to the Chart Graphics object. + /// Back elements of the axis should be drawn in 3D scene. + internal void Paint( ChartGraphics graph, bool backElements ) + { + PointF first = PointF.Empty; // The First point of a tick mark + PointF second = PointF.Empty; // The Second point of a tick mark + float axisPosition; // Axis position. + + // Tick Marks are disabled + if( !this.enabled ) + { + return; + } + + // **************************************************************** + // This code creates auto interval for auto tick marks and + // gridlines. If type is not date there are always four tickmarks + // or gridlines between major gridlines and tickmarks. For date + // type interval is calculated using CalcInterval function. + // **************************************************************** + double oldInterval = this.interval; + DateTimeIntervalType oldIntervalType = this.intervalType; + double oldIntervalOffset = this.intervalOffset; + DateTimeIntervalType oldIntervalOffsetType = this.intervalOffsetType; + if( !this.majorGridTick && ( this.interval == 0 || double.IsNaN(this.interval) ) ) + { + // Number type + if (this.Axis.majorGrid.GetIntervalType() == DateTimeIntervalType.Auto) + { + this.interval = this.Axis.majorGrid.GetInterval() / Grid.NumberOfIntervals; + } + // Date type + else + { + DateTimeIntervalType localIntervalType = this.Axis.majorGrid.GetIntervalType(); + this.interval = Axis.CalcInterval( + this.Axis.ViewMinimum, + this.Axis.ViewMinimum + (this.Axis.ViewMaximum - this.Axis.ViewMinimum) / Grid.NumberOfDateTimeIntervals, + true, + out localIntervalType, + ChartValueType.DateTime ); + this.intervalType = localIntervalType; + this.intervalOffsetType = this.Axis.majorGrid.GetIntervalOffsetType(); + this.intervalOffset = this.Axis.majorGrid.GetIntervalOffset(); + } + } + + if( _style == TickMarkStyle.None ) + { + return; + } + + // Check if custom tick marks should be drawn from custom labels + if (Axis.IsCustomTickMarks()) + { + PaintCustom(graph, backElements); + return; + } + + // Get first series attached to this axis + Series axisSeries = null; + if (Axis.axisType == AxisName.X || Axis.axisType == AxisName.X2) + { + List seriesArray = Axis.ChartArea.GetXAxesSeries((Axis.axisType == AxisName.X) ? AxisType.Primary : AxisType.Secondary, Axis.SubAxisName); + if(seriesArray.Count > 0) + { + axisSeries = Axis.Common.DataManager.Series[seriesArray[0]]; + if(axisSeries != null && !axisSeries.IsXValueIndexed) + { + axisSeries = null; + } + } + } + + // Current position for tick mark is minimum + double current = Axis.ViewMinimum; + + // Get offse type + DateTimeIntervalType offsetType = (GetIntervalOffsetType() == DateTimeIntervalType.Auto) ? GetIntervalType() : GetIntervalOffsetType(); + + + // *********************************** + // Check if the AJAX zooming and scrolling mode is enabled. + // *********************************** + + // Adjust start position depending on the interval type + if (!Axis.ChartArea.chartAreaIsCurcular || + Axis.axisType == AxisName.Y || + Axis.axisType == AxisName.Y2) + { + current = ChartHelper.AlignIntervalStart(current, this.GetInterval(), this.GetIntervalType(), axisSeries, this.majorGridTick); + } + + // The Current position is start position, not minimum + if (GetIntervalOffset() != 0 && !double.IsNaN(GetIntervalOffset()) && axisSeries == null) + { + current += ChartHelper.GetIntervalSize(current, GetIntervalOffset(), + offsetType, axisSeries, 0, DateTimeIntervalType.Number, true, false); + } + + // Too many tick marks + if ((Axis.ViewMaximum - Axis.ViewMinimum) / ChartHelper.GetIntervalSize(current, this.GetInterval(), this.GetIntervalType(), axisSeries, 0, DateTimeIntervalType.Number, true) > ChartHelper.MaxNumOfGridlines) + { + return; + } + + // If Maximum, minimum and interval don’t have + // proper value do not draw tick marks. + if (Axis.ViewMaximum <= Axis.ViewMinimum) + { + return; + } + + // Axis scroll bar will increase size of the Outside and Cross style tick marks + float scrollBarSize = 0; + +#if Microsoft_CONTROL + + if (this.Axis.ScrollBar.IsVisible && + this.Axis.ScrollBar.IsPositionedInside && + (this.Axis.IsAxisOnAreaEdge || !this.Axis.IsMarksNextToAxis)) + { + scrollBarSize = (float)this.Axis.ScrollBar.GetScrollBarRelativeSize(); + } + +#endif // Microsoft_CONTROL + + // Left tickmarks + if (Axis.AxisPosition == AxisPosition.Left) + { + // The tick marks will follow axis or they will + // be always on the border of the chart area. + if (Axis.GetIsMarksNextToAxis()) + axisPosition = (float)Axis.GetAxisPosition(); + else + axisPosition = Axis.PlotAreaPosition.X; + + if( _style == TickMarkStyle.InsideArea ) + { + first.X = axisPosition; + second.X = axisPosition + _size; + } + else if( _style == TickMarkStyle.OutsideArea ) + { + first.X = axisPosition - _size - scrollBarSize; + second.X = axisPosition; + } + else if( _style == TickMarkStyle.AcrossAxis ) + { + first.X = axisPosition - _size/2 - scrollBarSize; + second.X = axisPosition + _size/2; + } + } + + // Right tickmarks + else if (Axis.AxisPosition == AxisPosition.Right) + { + // The tick marks will follow axis or they will + // be always on the border of the chart area. + if (Axis.GetIsMarksNextToAxis()) + axisPosition = (float)Axis.GetAxisPosition(); + else + axisPosition = Axis.PlotAreaPosition.Right; + + if( _style == TickMarkStyle.InsideArea ) + { + first.X = axisPosition - _size; + second.X = axisPosition; + } + else if( _style == TickMarkStyle.OutsideArea ) + { + first.X = axisPosition; + second.X = axisPosition + _size + scrollBarSize; + } + else if( _style == TickMarkStyle.AcrossAxis ) + { + first.X = axisPosition - _size/2; + second.X = axisPosition + _size/2 + scrollBarSize; + } + } + + // Top tickmarks + else if (Axis.AxisPosition == AxisPosition.Top) + { + // The tick marks will follow axis or they will + // be always on the border of the chart area. + if (Axis.GetIsMarksNextToAxis()) + axisPosition = (float)Axis.GetAxisPosition(); + else + axisPosition = Axis.PlotAreaPosition.Y; + + if( _style == TickMarkStyle.InsideArea ) + { + first.Y = axisPosition; + second.Y = axisPosition + _size; + } + else if( _style == TickMarkStyle.OutsideArea ) + { + first.Y = axisPosition - _size - scrollBarSize; + second.Y = axisPosition; + } + else if( _style == TickMarkStyle.AcrossAxis ) + { + first.Y = axisPosition - _size/2 - scrollBarSize; + second.Y = axisPosition + _size/2; + } + } + + // Bottom tickmarks + else if (Axis.AxisPosition == AxisPosition.Bottom) + { + // The tick marks will follow axis or they will + // be always on the border of the chart area. + if (Axis.GetIsMarksNextToAxis()) + axisPosition = (float)Axis.GetAxisPosition(); + else + axisPosition = Axis.PlotAreaPosition.Bottom; + + if( _style == TickMarkStyle.InsideArea ) + { + first.Y = axisPosition - _size; + second.Y = axisPosition; + } + else if( _style == TickMarkStyle.OutsideArea ) + { + first.Y = axisPosition; + second.Y = axisPosition + _size + scrollBarSize; + } + else if( _style == TickMarkStyle.AcrossAxis ) + { + first.Y = axisPosition - _size/2; + second.Y = axisPosition + _size/2 + scrollBarSize; + } + } + + + // Loop for drawing grid tick marks + int counter = 0; + int logStep = 1; + double oldCurrent = current; + double interval = 0; + while (current <= Axis.ViewMaximum) + { + double logInterval = 0; + + // Take an interval between gridlines. Interval + // depends on interval type. + if (this.majorGridTick || this.Axis.IsLogarithmic == false) + { + // Take an interval between tickmarks. Interval + // depends on interval type. + interval = ChartHelper.GetIntervalSize(current, this.GetInterval(), this.GetIntervalType(), axisSeries, this.GetIntervalOffset(), offsetType, true); + + } + // Code for linear minor gridlines and tickmarks + // if scale is logarithmic. + else + { + // This code is used only for logarithmic scale and minor tick marks or + // gridlines which have linear minor scale in logarithmic major scale. + // This code is used to find minimum value for the interval. For example + // if logarithmic base is 2 and interval is between 4 and 8; current value + // is 5.6; this method will return linearised value for 4. This code works + // like Math.Floor for logarithmic scale. + double logMinimum = this.GetLogMinimum( current, axisSeries ); + + if( oldCurrent != logMinimum ) + { + oldCurrent = logMinimum; + logStep = 1; + } + + // Find interval for logarithmic linearised scale + logInterval = Math.Log(1 + this.interval * logStep, Axis.logarithmBase); + + current = oldCurrent; + + interval = logInterval; + + logStep++; + + // Reset current position if major interval is passed. + if( this.GetLogMinimum( current + logInterval, axisSeries ) != logMinimum ) + { + current += logInterval; + continue; + } + } + + // For indexed series do not draw the last tickmark + if (current == Axis.ViewMaximum && axisSeries != null) + { + current += interval; + + continue; + } + + // Check interval size + if( interval == 0 ) + { + throw (new InvalidOperationException(SR.ExceptionTickMarksIntervalIsZero)); + } + + // Check if we do not exceed max number of elements + if (counter++ > ChartHelper.MaxNumOfGridlines) + { + break; + } + + // Do not draw the very first tick mark for circular chart area + if (this.Axis != null && this.Axis.ChartArea != null) + { + if (this.Axis.ChartArea.chartAreaIsCurcular && + ((this.Axis.IsReversed == false && current == Axis.ViewMinimum) || + (this.Axis.IsReversed == true && current == Axis.ViewMaximum))) + { + current += interval; + + continue; + } + } + + if (!this.majorGridTick && this.Axis.IsLogarithmic) + { + current += logInterval; + + if (current > Axis.ViewMaximum) + { + break; + } + } + + if ((decimal)current >= (decimal)Axis.ViewMinimum) + { + // Left tickmarks + if (Axis.AxisPosition == AxisPosition.Left) + { + first.Y = (float)Axis.GetLinearPosition(current); + second.Y = first.Y; + } + + // Right tickmarks + else if (Axis.AxisPosition == AxisPosition.Right) + { + first.Y = (float)Axis.GetLinearPosition(current); + second.Y = first.Y; + } + + // Top tickmarks + else if (Axis.AxisPosition == AxisPosition.Top) + { + first.X = (float)Axis.GetLinearPosition(current); + second.X = first.X; + } + + // Bottom tickmarks + else if (Axis.AxisPosition == AxisPosition.Bottom) + { + first.X = (float)Axis.GetLinearPosition(current); + second.X = first.X; + } + + if (Axis.Common.ProcessModeRegions) + { + if (this.Axis.ChartArea.chartAreaIsCurcular) + { + RectangleF rect = new RectangleF( first.X - 0.5f, first.Y - 0.5f, Math.Abs( second.X - first.X ) + 1, Math.Abs( second.Y - first.Y ) + 1 ); + using (GraphicsPath path = new GraphicsPath()) + { + path.AddRectangle(graph.GetAbsoluteRectangle(rect)); + path.Transform(graph.Transform); + this.Axis.Common.HotRegionsList.AddHotRegion( + path, + false, + ChartElementType.TickMarks, + this); + } + } + else if (!this.Axis.ChartArea.Area3DStyle.Enable3D || this.Axis.ChartArea.chartAreaIsCurcular) + { + RectangleF rect = new RectangleF( first.X - 0.5f, first.Y - 0.5f, Math.Abs( second.X - first.X ) + 1, Math.Abs( second.Y - first.Y ) + 1 ); + + Axis.Common.HotRegionsList.AddHotRegion(rect, this, ChartElementType.TickMarks, true); + } + else + { + if (!Axis.Common.ProcessModePaint) //if ProcessModePaint is true it will be called later + Draw3DTickLine(graph, first, second, backElements); + } + + } + + if (Axis.Common.ProcessModePaint) + { + // Draw grid line + if (!this.Axis.ChartArea.Area3DStyle.Enable3D || this.Axis.ChartArea.chartAreaIsCurcular) + { + graph.DrawLineRel( borderColor, borderWidth, borderDashStyle, first, second ); + } + else + { + Draw3DTickLine(graph, first, second, backElements); + } + } + } + + // Move position + if (this.majorGridTick || this.Axis.IsLogarithmic == false) + { + current += interval; + } + } + + // Used for auto interval for auto tick marks and + // gridlines + if( !this.majorGridTick ) + { + this.interval = oldInterval; + this.intervalType = oldIntervalType; + this.intervalOffset = oldIntervalOffset; + this.intervalOffsetType = oldIntervalOffsetType; + } + } + + /// + /// This method returns linearized logarithmic value + /// which is minimum for range with interval 1. + /// + /// Current value + /// First series attached to axis. + /// Returns Minimum for the range which contains current value + private double GetLogMinimum( double current, Series axisSeries ) + { + double viewMinimum = Axis.ViewMinimum; + DateTimeIntervalType offsetType = (GetIntervalOffsetType() == DateTimeIntervalType.Auto) ? GetIntervalType() : GetIntervalOffsetType(); + if( GetIntervalOffset() != 0 && axisSeries == null) + { + viewMinimum += ChartHelper.GetIntervalSize(viewMinimum, GetIntervalOffset(), + offsetType, axisSeries, 0, DateTimeIntervalType.Number, true, false); + } + + return viewMinimum + Math.Floor( ( current - viewMinimum )); + } + + /// + /// Draws and hit test for custom TickMarks from the custom labels collection. + /// + /// Reference to the Chart Graphics object. + /// Back elements of the axis should be drawn in 3D scene. + internal void PaintCustom( ChartGraphics graph, bool backElements ) + { + PointF first = PointF.Empty; // The First point of a tick mark + PointF second = PointF.Empty; // The Second point of a tick mark + float axisPosition; // Axis position. + + // Axis scroll bar will increase size of the Outside and Cross style tick marks + float scrollBarSize = 0; + +#if Microsoft_CONTROL + + if (this.Axis.ScrollBar.IsVisible && this.Axis.ScrollBar.IsPositionedInside && this.Axis.IsAxisOnAreaEdge) + { + scrollBarSize = (float)this.Axis.ScrollBar.GetScrollBarRelativeSize(); + } + +#endif // Microsoft_CONTROL + + // Left tickmarks + if (Axis.AxisPosition == AxisPosition.Left) + { + // The tick marks will follow axis or they will + // be always on the border of the chart area. + if (Axis.GetIsMarksNextToAxis()) + axisPosition = (float)Axis.GetAxisPosition(); + else + axisPosition = Axis.PlotAreaPosition.X; + + if( _style == TickMarkStyle.InsideArea ) + { + first.X = axisPosition; + second.X = axisPosition + _size; + } + else if( _style == TickMarkStyle.OutsideArea ) + { + first.X = axisPosition - _size - scrollBarSize; + second.X = axisPosition; + } + else if( _style == TickMarkStyle.AcrossAxis ) + { + first.X = axisPosition - _size/2 - scrollBarSize; + second.X = axisPosition + _size/2; + } + } + + // Right tickmarks + else if (Axis.AxisPosition == AxisPosition.Right) + { + // The tick marks will follow axis or they will + // be always on the border of the chart area. + if (Axis.GetIsMarksNextToAxis()) + axisPosition = (float)Axis.GetAxisPosition(); + else + axisPosition = Axis.PlotAreaPosition.Right; + + if( _style == TickMarkStyle.InsideArea ) + { + first.X = axisPosition - _size; + second.X = axisPosition; + } + else if( _style == TickMarkStyle.OutsideArea ) + { + first.X = axisPosition; + second.X = axisPosition + _size + scrollBarSize; + } + else if( _style == TickMarkStyle.AcrossAxis ) + { + first.X = axisPosition - _size/2; + second.X = axisPosition + _size/2 + scrollBarSize; + } + } + + // Top tickmarks + else if (Axis.AxisPosition == AxisPosition.Top) + { + // The tick marks will follow axis or they will + // be always on the border of the chart area. + if (Axis.GetIsMarksNextToAxis()) + axisPosition = (float)Axis.GetAxisPosition(); + else + axisPosition = Axis.PlotAreaPosition.Y; + + if( _style == TickMarkStyle.InsideArea ) + { + first.Y = axisPosition; + second.Y = axisPosition + _size; + } + else if( _style == TickMarkStyle.OutsideArea ) + { + first.Y = axisPosition - _size - scrollBarSize; + second.Y = axisPosition; + } + else if( _style == TickMarkStyle.AcrossAxis ) + { + first.Y = axisPosition - _size/2 - scrollBarSize; + second.Y = axisPosition + _size/2; + } + } + + // Bottom tickmarks + else if (Axis.AxisPosition == AxisPosition.Bottom) + { + // The tick marks will follow axis or they will + // be always on the border of the chart area. + if (Axis.GetIsMarksNextToAxis()) + axisPosition = (float)Axis.GetAxisPosition(); + else + axisPosition = Axis.PlotAreaPosition.Bottom; + + if( _style == TickMarkStyle.InsideArea ) + { + first.Y = axisPosition - _size; + second.Y = axisPosition; + } + else if( _style == TickMarkStyle.OutsideArea ) + { + first.Y = axisPosition; + second.Y = axisPosition + _size + scrollBarSize; + } + else if( _style == TickMarkStyle.AcrossAxis ) + { + first.Y = axisPosition - _size/2; + second.Y = axisPosition + _size/2 + scrollBarSize; + } + } + + // Loop through all custom labels + foreach (CustomLabel label in Axis.CustomLabels) + { + if((label.GridTicks & GridTickTypes.TickMark) == GridTickTypes.TickMark) + { + double position = (label.ToPosition + label.FromPosition) / 2.0; + if (position >= Axis.ViewMinimum && position <= Axis.ViewMaximum) + { + // Left tickmarks + if (Axis.AxisPosition == AxisPosition.Left) + { + first.Y = (float)Axis.GetLinearPosition(position); + second.Y = first.Y; + } + + // Right tickmarks + else if (Axis.AxisPosition == AxisPosition.Right) + { + first.Y = (float)Axis.GetLinearPosition(position); + second.Y = first.Y; + } + + // Top tickmarks + else if (Axis.AxisPosition == AxisPosition.Top) + { + first.X = (float)Axis.GetLinearPosition(position); + second.X = first.X; + } + + // Bottom tickmarks + else if (Axis.AxisPosition == AxisPosition.Bottom) + { + first.X = (float)Axis.GetLinearPosition(position); + second.X = first.X; + } + + if (Axis.Common.ProcessModeRegions) + { + if (!this.Axis.ChartArea.Area3DStyle.Enable3D || this.Axis.ChartArea.chartAreaIsCurcular) + { + RectangleF rect = new RectangleF( first.X - 0.5f, first.Y - 0.5f, Math.Abs( second.X - first.X ) + 1, Math.Abs( second.Y - first.Y ) + 1 ); + + Axis.Common.HotRegionsList.AddHotRegion(rect, this, ChartElementType.TickMarks, true); + } + else + { + Draw3DTickLine(graph, first, second, backElements); + } + } + + if (Axis.Common.ProcessModePaint) + { + // Draw grid line + if (!this.Axis.ChartArea.Area3DStyle.Enable3D || this.Axis.ChartArea.chartAreaIsCurcular) + { + graph.DrawLineRel( borderColor, borderWidth, borderDashStyle, first, second ); + } + else + { + Draw3DTickLine(graph, first, second, backElements); + } + } + } + } + } + } + + /// + /// Draws tick mark line in 3D space. + /// + /// Reference to the Chart Graphics object. + /// First line point. + /// Second line point. + /// Back elements of the axis should be drawn in 3D scene. + internal void Draw3DTickLine( + ChartGraphics graph, + PointF point1, + PointF point2, + bool backElements + ) + { + + ChartArea area = this.Axis.ChartArea; + + //***************************************************************** + //** Set the tick marks line depth + //***************************************************************** + bool axisOnEdge; + float wallZPosition = Axis.GetMarksZPosition(out axisOnEdge); + + //***************************************************************** + //** Check if tick mark should be drawn as back or front element + //***************************************************************** + + // Check if axis tick marks are drawn inside plotting area + bool tickMarksOnEdge = axisOnEdge; + if(tickMarksOnEdge && + this.Axis.MajorTickMark.TickMarkStyle == TickMarkStyle.AcrossAxis || + this.Axis.MajorTickMark.TickMarkStyle == TickMarkStyle.InsideArea || + this.Axis.MinorTickMark.TickMarkStyle == TickMarkStyle.AcrossAxis || + this.Axis.MinorTickMark.TickMarkStyle == TickMarkStyle.InsideArea) + { + tickMarksOnEdge = false; + } + + SurfaceNames surfaceName = (wallZPosition == 0f) ? SurfaceNames.Back : SurfaceNames.Front; + if( !area.ShouldDrawOnSurface(surfaceName, backElements, tickMarksOnEdge) ) + { + // Skip drawing + return; + } + + //***************************************************************** + //** Add area scene wall width to the length of the tick mark + //***************************************************************** + if (Axis.AxisPosition == AxisPosition.Bottom && + (!Axis.GetIsMarksNextToAxis() || axisOnEdge) && + area.IsBottomSceneWallVisible()) + { + point2.Y += area.areaSceneWallWidth.Height; + } + else if (Axis.AxisPosition == AxisPosition.Left && + (!Axis.GetIsMarksNextToAxis() || axisOnEdge) && + area.IsSideSceneWallOnLeft()) + { + point1.X -= area.areaSceneWallWidth.Width; + } + else if (Axis.AxisPosition == AxisPosition.Right && + (!Axis.GetIsMarksNextToAxis() || axisOnEdge) && + !area.IsSideSceneWallOnLeft()) + { + point2.X += area.areaSceneWallWidth.Width; + } + else if (Axis.AxisPosition == AxisPosition.Top && + (!Axis.GetIsMarksNextToAxis() || axisOnEdge)) + { + point1.Y -= area.areaSceneWallWidth.Height; + } + + //***************************************************************** + //** Adjust grid line direction for the Top axis + //***************************************************************** + Point3D point3 = null, point4 = null; + if(axisOnEdge && area.areaSceneWallWidth.Width != 0f) + { + if (Axis.AxisPosition == AxisPosition.Top) + { + // Always use plot area position to draw tick mark + float axisPosition = Axis.PlotAreaPosition.Y; + + if( _style == TickMarkStyle.InsideArea ) + { + point1.Y = axisPosition; + point2.Y = axisPosition + _size; + + point3 = new Point3D(point1.X, point1.Y, - area.areaSceneWallWidth.Width); + point4 = new Point3D(point1.X, point1.Y, 0f); + } + else if( _style == TickMarkStyle.OutsideArea ) + { + point1.Y = axisPosition; + point2.Y = axisPosition; + + point3 = new Point3D(point1.X, axisPosition, wallZPosition); + point4 = new Point3D(point1.X, point1.Y, - _size - area.areaSceneWallWidth.Width); + } + else if( _style == TickMarkStyle.AcrossAxis ) + { + point1.Y = axisPosition; + point2.Y = axisPosition + _size/2; + + point3 = new Point3D(point1.X, axisPosition, wallZPosition); + point4 = new Point3D(point1.X, point1.Y, - _size/2 - area.areaSceneWallWidth.Width); + } + + // Do not show "bent" tick marks on the top surface + if(area.ShouldDrawOnSurface(SurfaceNames.Top, backElements, false)) + { + point3 = null; + point4 = null; + } + } + + //***************************************************************** + //** Adjust grid line direction for the Left axis + //***************************************************************** + if (Axis.AxisPosition == AxisPosition.Left && !area.IsSideSceneWallOnLeft()) + { + // Always use plot area position to draw tick mark + float axisPosition = Axis.PlotAreaPosition.X; + + if( _style == TickMarkStyle.InsideArea ) + { + point1.X = axisPosition; + point2.X = axisPosition + _size; + + point3 = new Point3D(point1.X, point1.Y, - area.areaSceneWallWidth.Width); + point4 = new Point3D(point1.X, point1.Y, 0f); + } + else if( _style == TickMarkStyle.OutsideArea ) + { + point1.X = axisPosition; + point2.X = axisPosition; + + point3 = new Point3D(axisPosition, point1.Y, wallZPosition); + point4 = new Point3D(axisPosition, point1.Y, - _size - area.areaSceneWallWidth.Width); + } + else if( _style == TickMarkStyle.AcrossAxis ) + { + point1.X = axisPosition; + point2.X = axisPosition + _size/2; + + point3 = new Point3D(axisPosition, point1.Y, wallZPosition); + point4 = new Point3D(axisPosition, point1.Y, - _size/2 - area.areaSceneWallWidth.Width); + } + + // Do not show "bent" tick marks on the left surface + if(area.ShouldDrawOnSurface(SurfaceNames.Left, backElements, false)) + { + point3 = null; + point4 = null; + } + } + + //***************************************************************** + //** Adjust grid line direction for the Right axis + //***************************************************************** + else if (Axis.AxisPosition == AxisPosition.Right && area.IsSideSceneWallOnLeft()) + { + // Always use plot area position to draw tick mark + float axisPosition = Axis.PlotAreaPosition.Right; + + if( _style == TickMarkStyle.InsideArea ) + { + point1.X = axisPosition - _size; + point2.X = axisPosition; + + point3 = new Point3D(point2.X, point2.Y, - area.areaSceneWallWidth.Width); + point4 = new Point3D(point2.X, point2.Y, 0f); + } + else if( _style == TickMarkStyle.OutsideArea ) + { + point1.X = axisPosition; + point2.X = axisPosition; + + point3 = new Point3D(axisPosition, point1.Y, wallZPosition); + point4 = new Point3D(axisPosition, point1.Y, - _size - area.areaSceneWallWidth.Width); + + } + else if( _style == TickMarkStyle.AcrossAxis ) + { + point1.X = axisPosition - _size/2; + point2.X = axisPosition; + + point3 = new Point3D(axisPosition, point1.Y, wallZPosition); + point4 = new Point3D(axisPosition, point1.Y, - _size/2 - area.areaSceneWallWidth.Width); + } + + // Do not show "bent" tick marks on the right surface + if(area.ShouldDrawOnSurface(SurfaceNames.Right, backElements, false)) + { + point3 = null; + point4 = null; + } + } + } + + //***************************************************************** + //** Draw tick mark (first line) + //***************************************************************** + graph.Draw3DLine( + area.matrix3D, + borderColor, borderWidth, borderDashStyle, + new Point3D(point1.X, point1.Y, wallZPosition), + new Point3D(point2.X, point2.Y, wallZPosition), + Axis.Common, + this, + ChartElementType.TickMarks + ); + + + //***************************************************************** + //** Draw tick mark (second line) + //***************************************************************** + if(point3 != null && point4 != null) + { + graph.Draw3DLine( + area.matrix3D, + borderColor, borderWidth, borderDashStyle, + point3, + point4, + Axis.Common, + this, + ChartElementType.TickMarks + ); + } + } + + #endregion + + #region TickMark properties + + /// + /// Tick mark style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(TickMarkStyle.OutsideArea), + SRDescription("DescriptionAttributeTickMark_Style"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public TickMarkStyle TickMarkStyle + { + get + { + return _style; + } + set + { + _style = value; + this.Invalidate(); + } + } + + /// + /// Tick mark size. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1.0F), + SRDescription("DescriptionAttributeTickMark_Size"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public float Size + { + get + { + return _size; + } + set + { + _size = value; + this.Invalidate(); + } + } + + #endregion + } + + /// + /// The Grid class represents axis grid lines which are drawn in the + /// plotting area. It contains grid interval and visual appearance + /// properties. This class also contains methods for grid lines drawing. + /// + [ + DefaultProperty("Enabled"), + SRDescription("DescriptionAttributeGrid_Grid"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class Grid + { + #region Grid fields and Constructors + + // Reference to the Axis object + private Axis _axis = null; + + // Flags indicate that interval properties where changed + internal bool intervalOffsetChanged = false; + internal bool intervalChanged = false; + internal bool intervalTypeChanged = false; + internal bool intervalOffsetTypeChanged = false; + + internal bool enabledChanged = false; + + // Data members, which store properties values + internal double intervalOffset = 0; + internal double interval = 0; + internal DateTimeIntervalType intervalType = DateTimeIntervalType.Auto; + internal DateTimeIntervalType intervalOffsetType = DateTimeIntervalType.Auto; + internal Color borderColor = Color.Black; + internal int borderWidth = 1; + internal ChartDashStyle borderDashStyle = ChartDashStyle.Solid; + internal bool enabled = true; + + // Indicates that object describes Major Tick Mark or Grid Line + internal bool majorGridTick = false; + + // Common number of intervals on the numeric and date-time axis + internal const double NumberOfIntervals = 5.0; + internal const double NumberOfDateTimeIntervals = 4.0; + + /// + /// Public default constructor. + /// + public Grid() + { + } + + /// + /// Public constructor. + /// + /// Axis which owns the grid. + /// Major axis element. + internal Grid(Axis axis, bool major) + { + Initialize(axis, major); + } + + /// + /// Initializes the object. + /// + /// Axis which owns the grid. + /// Major axis element. + internal void Initialize(Axis axis, bool major) + { + // Minor elements are disabled by default + if(!this.enabledChanged && + this._axis == null && + !major) + { + enabled = false; + } + + // If object was first created and populated with data and then added into the axis + // we need to remember changed values. + // NOTE: Fixes issue #6237 + if(this._axis == null) + { + TickMark tickMark = this as TickMark; + + if(this.interval != 0) + { + if (tickMark != null) + { + if(major) + { + axis.tempMajorTickMarkInterval = this.interval; + } + else + { + axis.tempMinorTickMarkInterval = this.interval; + } + } + else + { + if(major) + { + axis.tempMajorGridInterval = this.interval; + } + else + { + axis.tempMinorGridInterval = this.interval; + } + } + } + if(this.intervalType != DateTimeIntervalType.Auto) + { + if(tickMark != null) + { + if(major) + { + axis.tempTickMarkIntervalType = this.intervalType; + } + } + else + { + if(major) + { + axis.tempGridIntervalType = this.intervalType; + } + } + } + } + + // Set axis object reference + this._axis = axis; + + // Set a flag if this object represent minor or major tick + this.majorGridTick = major; + +// internal double interval = 0; +// internal DateTimeIntervalType intervalType = DateTimeIntervalType.Auto; + + } + + #endregion + + #region Grid helper functions + /// + /// Gets axes to which this object attached to + /// + /// Axis object. + internal Axis GetAxis() + { + return _axis; + } + /// + /// Invalidate chart area the axis belong to. + /// + internal void Invalidate() + { +#if Microsoft_CONTROL + + if(this._axis != null) + { + this._axis.Invalidate(); + } +#endif + } + + #endregion + + #region Grid lines drawing functions + + /// + /// Draws grid lines. + /// + /// Reference to the Chart Graphics object. + internal void Paint( ChartGraphics graph ) + { + // Grids are disabled + if( !this.enabled ) + { + return; + } + + // Check if custom grid lines should be drawn from custom labels + if(_axis.IsCustomGridLines()) + { + PaintCustom( graph ); + return; + } + + double gridInterval; // Grid interval + double current; // Current position + + // Get first series attached to this axis + Series axisSeries = null; + if(_axis.axisType == AxisName.X || _axis.axisType == AxisName.X2) + { + List seriesArray = _axis.ChartArea.GetXAxesSeries((_axis.axisType == AxisName.X) ? AxisType.Primary : AxisType.Secondary, _axis.SubAxisName); + if(seriesArray.Count > 0) + { + axisSeries = _axis.Common.DataManager.Series[seriesArray[0]]; + if(axisSeries != null && !axisSeries.IsXValueIndexed) + { + axisSeries = null; + } + } + } + + // **************************************************************** + // This code creates auto interval for auto tick marks and + // gridlines. If type is not date there are always four tickmarks + // or gridlines between major gridlines and tickmarks. For date + // type interval is calculated using CalcInterval function. + // **************************************************************** + double oldInterval = this.interval; + DateTimeIntervalType oldIntervalType = this.intervalType; + double oldIntervalOffset = this.intervalOffset; + DateTimeIntervalType oldIntervalOffsetType = this.intervalOffsetType; + if( !this.majorGridTick && ( this.interval == 0 || double.IsNaN(this.interval) ) ) + { + // Number type + if( this._axis.majorGrid.GetIntervalType() == DateTimeIntervalType.Auto ) + { + this.interval = this._axis.majorGrid.GetInterval() / Grid.NumberOfIntervals; + } + // Date type + else + { + DateTimeIntervalType localIntervalType = this._axis.majorGrid.GetIntervalType(); + this.interval = _axis.CalcInterval( + this._axis.minimum, + this._axis.minimum + (this._axis.maximum - this._axis.minimum) / Grid.NumberOfDateTimeIntervals, + true, + out localIntervalType, + ChartValueType.DateTime); + this.intervalType = localIntervalType; + this.intervalOffsetType = this._axis.majorGrid.GetIntervalOffsetType(); + this.intervalOffset = this._axis.majorGrid.GetIntervalOffset(); + } + } + + // Current position for grid lines is minimum + current = _axis.ViewMinimum; + + + // *********************************** + // Check if the AJAX zooming and scrolling mode is enabled. + // *********************************** + + // Adjust start position depending on the interval type + if(!_axis.ChartArea.chartAreaIsCurcular || + _axis.axisType == AxisName.Y || + _axis.axisType == AxisName.Y2 ) + { + current = ChartHelper.AlignIntervalStart(current, this.GetInterval(), this.GetIntervalType(), axisSeries, this.majorGridTick); + } + + // The Current position is start position, not minimum + DateTimeIntervalType offsetType = (GetIntervalOffsetType() == DateTimeIntervalType.Auto) ? GetIntervalType() : GetIntervalOffsetType(); + if (GetIntervalOffset() != 0 && !double.IsNaN(GetIntervalOffset()) && axisSeries == null) + { + current += ChartHelper.GetIntervalSize(current, GetIntervalOffset(), offsetType, axisSeries, 0, DateTimeIntervalType.Number, true, false); + } + + // Too many gridlines + if( ( _axis.ViewMaximum - _axis.ViewMinimum ) / ChartHelper.GetIntervalSize( current, this.GetInterval(), this.GetIntervalType(), axisSeries, 0, DateTimeIntervalType.Number, true ) > ChartHelper.MaxNumOfGridlines ) + return; + + // If Maximum, minimum and interval don’t have + // proper value do not draw grid lines. + if( _axis.ViewMaximum <= _axis.ViewMinimum ) + return; + + if( this.GetInterval() <= 0 ) + return; + + // Loop for drawing grid lines + int counter = 0; + int logStep = 1; + double oldCurrent = current; + decimal viewMaximum = (decimal)_axis.ViewMaximum; + while( (decimal)current <= viewMaximum ) + { + // Take an interval between gridlines. Interval + // depends on interval type. + if( this.majorGridTick || this._axis.IsLogarithmic == false ) + { + double autoInterval = this.GetInterval(); + + gridInterval = ChartHelper.GetIntervalSize(current, autoInterval, this.GetIntervalType(), axisSeries, this.GetIntervalOffset(), offsetType, true); + + // Check interval size + if (gridInterval == 0) + { + throw (new InvalidOperationException(SR.ExceptionTickMarksIntervalIsZero)); + } + + // Draw between min & max values only + if((decimal)current >= (decimal)_axis.ViewMinimum) + { + DrawGrid( graph, current ); + } + + // Move position + current += gridInterval; + } + // Code for linear minor gridlines and tickmarks + // if scale is logarithmic. + else + { + // This code is used only for logarithmic scale and minor tick marks or + // gridlines which have linear minor scale in logarithmic major scale. + // This code is used to find minimum value for the interval. For example + // if logarithmic base is 2 and interval is between 4 and 8; current value + // is 5.6; this method will return linearised value for 4. This code works + // like Math.Floor for logarithmic scale. + double logMinimum = this.GetLogMinimum( current, axisSeries ); + + if( oldCurrent != logMinimum ) + { + oldCurrent = logMinimum; + logStep = 1; + } + + // Find interval for logarithmic linearised scale + double logInterval = Math.Log( 1 + this.interval * logStep, _axis.logarithmBase ); + + current = oldCurrent; + + // Move position + current += logInterval; + + logStep++; + + // Reset current position if major interval is passed. + if( this.GetLogMinimum( current, axisSeries ) != logMinimum ) + { + continue; + } + + // Check interval size + if (logInterval == 0) + { + throw (new InvalidOperationException(SR.ExceptionTickMarksIntervalIsZero)); + } + + // Draw between min & max values only + if( (decimal)current >= (decimal)_axis.ViewMinimum && (decimal)current <= (decimal)_axis.ViewMaximum ) + { + DrawGrid( graph, current ); + } + } + + // Check if we do not exceed max number of elements + if (counter++ > ChartHelper.MaxNumOfGridlines) + { + break; + } + } + + // Used for auto interval for auto tick marks and + // gridlines + if( !this.majorGridTick ) + { + this.interval = oldInterval; + this.intervalType = oldIntervalType; + this.intervalOffset = oldIntervalOffset; + this.intervalOffsetType = oldIntervalOffsetType; + } + } + + /// + /// This method returns linearized logarithmic value + /// which is minimum for range with interval 1. + /// + /// Current value + /// First series attached to axis. + /// Returns Minimum for the range which contains current value + private double GetLogMinimum( double current, Series axisSeries ) + { + double viewMinimum = _axis.ViewMinimum; + DateTimeIntervalType offsetType = (GetIntervalOffsetType() == DateTimeIntervalType.Auto) ? GetIntervalType() : GetIntervalOffsetType(); + if( GetIntervalOffset() != 0 && axisSeries == null) + { + viewMinimum += ChartHelper.GetIntervalSize(viewMinimum, GetIntervalOffset(), + offsetType, axisSeries, 0, DateTimeIntervalType.Number, true, false); + } + + return viewMinimum + Math.Floor( ( current - viewMinimum )); + } + + /// + /// Draw the grid line + /// + /// Chart Graphics object + /// Current position of the gridline + private void DrawGrid( ChartGraphics graph, double current ) + { + // Common elements + CommonElements common = this._axis.Common; + + PointF first = PointF.Empty; // The First point of a grid line + PointF second = PointF.Empty; // The Second point of a grid line + RectangleF plotArea; // Plot area position + + plotArea = _axis.PlotAreaPosition.ToRectangleF(); + + // Horizontal gridlines + if( _axis.AxisPosition == AxisPosition.Left || _axis.AxisPosition == AxisPosition.Right ) + { + first.X = plotArea.X; + second.X = plotArea.Right; + first.Y = (float)_axis.GetLinearPosition( current ); + second.Y = first.Y; + } + + // Vertical gridlines + if( _axis.AxisPosition == AxisPosition.Top || _axis.AxisPosition == AxisPosition.Bottom ) + { + first.Y = plotArea.Y; + second.Y = plotArea.Bottom; + first.X = (float)_axis.GetLinearPosition( current ); + second.X = first.X; + } + + if( common.ProcessModeRegions ) + { + if( this._axis.ChartArea.Area3DStyle.Enable3D && !this._axis.ChartArea.chartAreaIsCurcular) + { + if(!common.ProcessModePaint) //if ProcessModePaint is true it will be called later + graph.Draw3DGridLine(this._axis.ChartArea, borderColor, borderWidth, borderDashStyle, first, second, ( _axis.AxisPosition == AxisPosition.Left || _axis.AxisPosition == AxisPosition.Right ), common, this ); + } + else if(!this._axis.ChartArea.chartAreaIsCurcular) + { + using (GraphicsPath path = new GraphicsPath()) + { + if (Math.Abs(first.X - second.X) > Math.Abs(first.Y - second.Y)) + { + path.AddLine(first.X, first.Y - 1, second.X, second.Y - 1); + path.AddLine(second.X, second.Y + 1, first.X, first.Y + 1); + path.CloseAllFigures(); + } + else + { + path.AddLine(first.X - 1, first.Y, second.X - 1, second.Y); + path.AddLine(second.X + 1, second.Y, first.X + 1, first.Y); + path.CloseAllFigures(); + + } + common.HotRegionsList.AddHotRegion(path, true, ChartElementType.Gridlines, this); + } + } + } + + if( common.ProcessModePaint ) + { + // Check if grid lines should be drawn for circular chart area + if(_axis.ChartArea.chartAreaIsCurcular) + { + if(_axis.axisType == AxisName.Y) + { + _axis.DrawCircularLine( this, graph, borderColor, borderWidth, borderDashStyle, first.Y ); + } + if(_axis.axisType == AxisName.X) + { + ICircularChartType chartType = this._axis.ChartArea.GetCircularChartType(); + if(chartType != null && chartType.RadialGridLinesSupported()) + { + _axis.DrawRadialLine( this, graph, borderColor, borderWidth, borderDashStyle, current ); + } + } + } + else if(!this._axis.ChartArea.Area3DStyle.Enable3D || this._axis.ChartArea.chartAreaIsCurcular) + { + graph.DrawLineRel( borderColor, borderWidth, borderDashStyle, first, second ); + } + else + { + graph.Draw3DGridLine( this._axis.ChartArea, borderColor, borderWidth, borderDashStyle, first, second, ( _axis.AxisPosition == AxisPosition.Left || _axis.AxisPosition == AxisPosition.Right ), _axis.Common, this ); + } + } + } + + /// + /// Draws custom grid lines from custom labels. + /// + /// Reference to the Chart Graphics object. + internal void PaintCustom( ChartGraphics graph ) + { + // Common Elements + CommonElements common = this._axis.Common; + + PointF first = PointF.Empty; // The First point of a grid line + PointF second = PointF.Empty; // The Second point of a grid line + RectangleF plotArea = _axis.PlotAreaPosition.ToRectangleF(); // Plot area position + + + // Loop through all custom labels + foreach(CustomLabel label in _axis.CustomLabels) + { + if((label.GridTicks & GridTickTypes.Gridline) == GridTickTypes.Gridline) + { + double position = (label.ToPosition + label.FromPosition) / 2.0; + if(position >= _axis.ViewMinimum && position <= _axis.ViewMaximum) + { + // Horizontal gridlines + if( _axis.AxisPosition == AxisPosition.Left || _axis.AxisPosition == AxisPosition.Right ) + { + first.X = plotArea.X; + second.X = plotArea.Right; + first.Y = (float)_axis.GetLinearPosition( position ); + second.Y = first.Y; + + } + + // Vertical gridlines + if( _axis.AxisPosition == AxisPosition.Top || _axis.AxisPosition == AxisPosition.Bottom ) + { + first.Y = plotArea.Y; + second.Y = plotArea.Bottom; + first.X = (float)_axis.GetLinearPosition( position ); + second.X = first.X; + } + + if( common.ProcessModeRegions ) + { + if( !this._axis.ChartArea.Area3DStyle.Enable3D || this._axis.ChartArea.chartAreaIsCurcular ) + { + using (GraphicsPath path = new GraphicsPath()) + { + + if (Math.Abs(first.X - second.X) > Math.Abs(first.Y - second.Y)) + { + path.AddLine(first.X, first.Y - 1, second.X, second.Y - 1); + path.AddLine(second.X, second.Y + 1, first.X, first.Y + 1); + path.CloseAllFigures(); + } + else + { + path.AddLine(first.X - 1, first.Y, second.X - 1, second.Y); + path.AddLine(second.X + 1, second.Y, first.X + 1, first.Y); + path.CloseAllFigures(); + + } + common.HotRegionsList.AddHotRegion(path, true, ChartElementType.Gridlines, this); + } + } + else + { + graph.Draw3DGridLine(this._axis.ChartArea, borderColor, borderWidth, borderDashStyle, first, second, ( _axis.AxisPosition == AxisPosition.Left || _axis.AxisPosition == AxisPosition.Right ), common, this ); + } + } + + if( common.ProcessModePaint ) + { + if(!this._axis.ChartArea.Area3DStyle.Enable3D || this._axis.ChartArea.chartAreaIsCurcular) + { + graph.DrawLineRel( borderColor, borderWidth, borderDashStyle, first, second ); + } + else + { + graph.Draw3DGridLine(this._axis.ChartArea, borderColor, borderWidth, borderDashStyle, first, second, ( _axis.AxisPosition == AxisPosition.Left || _axis.AxisPosition == AxisPosition.Right ), _axis.Common, this ); + } + } + } + } + } + } + + #endregion + + #region Grid properties + + /// + /// Gets or sets grid or tick mark interval offset. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeIntervalOffset3"), + TypeConverter(typeof(AxisElementIntervalValueConverter)), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public double IntervalOffset + { + get + { + return intervalOffset; + } + set + { + intervalOffset = value; + intervalOffsetChanged = true; + this.Invalidate(); + } + } + + /// + /// Determines if Enabled property should be serialized. + /// + /// + internal bool ShouldSerializeIntervalOffset() + { + if (this.majorGridTick) + { + return !double.IsNaN(intervalOffset); + } + return intervalOffset != 0d; + } + + + /// + /// Gets the interval offset. + /// + /// + internal double GetIntervalOffset() + { + if(this.majorGridTick && double.IsNaN(intervalOffset) && this._axis != null) + { + + return this._axis.IntervalOffset; + } + return intervalOffset; + } + + + /// + /// Gets or sets the unit of measurement of grid or tick mark offset. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeIntervalOffsetType6"), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public DateTimeIntervalType IntervalOffsetType + { + get + { + return intervalOffsetType; + } + set + { + intervalOffsetType = value; + intervalOffsetTypeChanged = true; + this.Invalidate(); + } + } + + /// + /// Determines if IntervalOffsetType property should be serialized. + /// + /// + internal bool ShouldSerializeIntervalOffsetType() + { + if (this.majorGridTick) + { + return intervalOffsetType != DateTimeIntervalType.NotSet; + } + return intervalOffsetType != DateTimeIntervalType.Auto; + } + + /// + /// Gets the type of the interval offset. + /// + /// + internal DateTimeIntervalType GetIntervalOffsetType() + { + if(this.majorGridTick && intervalOffsetType == DateTimeIntervalType.NotSet && this._axis != null) + { + return this._axis.IntervalOffsetType; + } + return intervalOffsetType; + } + + /// + /// Gets or sets grid or tick mark interval size. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeInterval6"), + TypeConverter(typeof(AxisElementIntervalValueConverter)), + RefreshProperties(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public double Interval + { + get + { + return interval; + } + set + { + // Validation + if (value < 0.0) + throw (new ArgumentException(SR.ExceptionTickMarksIntervalIsNegative, "value")); + + interval = value; + intervalChanged = true; + + // Enable minor elements + if (!this.majorGridTick && value != 0.0 && !Double.IsNaN(value)) + { + // Prevent grids enabling during the serialization + if (this._axis != null) + { + if (this._axis.Chart != null && this._axis.Chart.serializing != false) + { + this.Enabled = true; + } + } + } + + // Reset original property value fields + if (this._axis != null) + { + if (this is TickMark) + { + if (this.majorGridTick) + { + this._axis.tempMajorTickMarkInterval = interval; + } + else + { + this._axis.tempMinorTickMarkInterval = interval; + } + } + else + { + if (this.majorGridTick) + { + this._axis.tempMajorGridInterval = interval; + } + else + { + this._axis.tempMinorGridInterval = interval; + } + } + } + + this.Invalidate(); + } + + } + + /// + /// Determines if IntervalOffsetType property should be serialized. + /// + /// + internal bool ShouldSerializeInterval() + { + if (this.majorGridTick) + { + return !double.IsNaN(interval); + } + return interval != 0d; + } + + /// + /// Gets the interval. + /// + /// + internal double GetInterval() + { + if(this.majorGridTick && double.IsNaN(interval) && this._axis != null) + { + return this._axis.Interval; + } + return interval; + } + + /// + /// Gets or sets the unit of measurement of grid or tick mark interval. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeIntervalType3"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public DateTimeIntervalType IntervalType + { + get + { + return intervalType; + } + set + { + intervalType = value; + intervalTypeChanged = true; + + // Reset original property value fields + if (this._axis != null) + { + if (this is TickMark) + { + this._axis.tempTickMarkIntervalType = intervalType; + } + else + { + this._axis.tempGridIntervalType = intervalType; + } + } + + this.Invalidate(); + } + } + + /// + /// Determines if IntervalOffsetType property should be serialized. + /// + /// + internal bool ShouldSerializeIntervalType() + { + if (this.majorGridTick) + { + return intervalType != DateTimeIntervalType.NotSet; + } + return intervalType != DateTimeIntervalType.Auto; + } + + + /// + /// Gets the type of the interval. + /// + /// + internal DateTimeIntervalType GetIntervalType() + { + if(this.majorGridTick && intervalType == DateTimeIntervalType.NotSet && this._axis != null) + { + // Return default value during serialization + return this._axis.IntervalType; + } + return intervalType; + } + + /// + /// Gets or sets grid or tick mark line color. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLineColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color LineColor + { + get + { + return borderColor; + } + set + { + borderColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets grid or tick mark line style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeLineDashStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartDashStyle LineDashStyle + { + get + { + return borderDashStyle; + } + set + { + borderDashStyle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets grid or tick mark line width. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeLineWidth"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int LineWidth + { + get + { + return borderWidth; + } + set + { + borderWidth = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a flag which indicates if the grid or tick mark is enabled. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeEnabled5"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool Enabled + { + get + { + //// Never serialize this property for minor elements + //// "Disabled" property should be serialized instead. + //if(this.axis != null && this.axis.IsSerializing()) + //{ + // if(!this.majorGridTick) + // { + // // Return default value to prevent serialization + // return true; + // } + //} + + return enabled; + } + set + { + enabled = value; + enabledChanged = true; + this.Invalidate(); + } + } + + /// + /// Determines if Enabled property should be serialized. + /// + /// + internal bool ShouldSerializeEnabled() + { + if (this.majorGridTick) + { + return !this.Enabled; + } + return this.Enabled; + } + + /// + /// Gets or sets the reference to the Axis object + /// + internal Axis Axis + { + get { return _axis; } + set { _axis = value; } + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/IChartRenderingEngine.cs b/System.Web.DataVisualization/Common/General/IChartRenderingEngine.cs new file mode 100644 index 000000000..967f18c23 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/IChartRenderingEngine.cs @@ -0,0 +1,536 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: IChartRenderingEngine.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: IChartRenderingEngine, IChartAnimationEngine +// +// Purpose: Defines interfaces which must be implemented by +// every rendering and animation engine class. These +// interfaces are used in GDI+, SVG and Flash rendering. +// Note that animation is only available in SVG and +// Flash rendering engines. +// +// Reviwed: AG - Jul 15, 2003 +// AG - MArch 14, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Drawing.Imaging; +using System.ComponentModel; +using System.Collections; + +#endregion + +#if WINFORMS_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// IChartRenderingEngine interface defines a set of methods and properties + /// which must be implemented by any chart rendering engine. It contains + /// methods for drawing basic shapes. + /// + internal interface IChartRenderingEngine + { + #region Drawing Methods + + /// + /// Draws a line connecting two PointF structures. + /// + /// Pen object that determines the color, width, and style of the line. + /// PointF structure that represents the first point to connect. + /// PointF structure that represents the second point to connect. + void DrawLine( + Pen pen, + PointF pt1, + PointF pt2 + ); + + /// + /// Draws a line connecting the two points specified by coordinate pairs. + /// + /// Pen object that determines the color, width, and style of the line. + /// x-coordinate of the first point. + /// y-coordinate of the first point. + /// x-coordinate of the second point. + /// y-coordinate of the second point. + void DrawLine( + Pen pen, + float x1, + float y1, + float x2, + float y2 + ); + + /// + /// Draws the specified portion of the specified Image object at the specified location and with the specified size. + /// + /// Image object to draw. + /// Rectangle structure that specifies the location and size of the drawn image. The image is scaled to fit the rectangle. + /// x-coordinate of the upper-left corner of the portion of the source image to draw. + /// y-coordinate of the upper-left corner of the portion of the source image to draw. + /// Width of the portion of the source image to draw. + /// Height of the portion of the source image to draw. + /// Member of the GraphicsUnit enumeration that specifies the units of measure used to determine the source rectangle. + /// ImageAttributes object that specifies recoloring and gamma information for the image object. + void DrawImage( + System.Drawing.Image image, + Rectangle destRect, + int srcX, + int srcY, + int srcWidth, + int srcHeight, + GraphicsUnit srcUnit, + ImageAttributes imageAttr + ); + + /// + /// Draws an ellipse defined by a bounding rectangle specified by + /// a pair of coordinates, a height, and a width. + /// + /// Pen object that determines the color, width, and style of the ellipse. + /// x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse. + /// y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse. + /// Width of the bounding rectangle that defines the ellipse. + /// Height of the bounding rectangle that defines the ellipse. + void DrawEllipse( + Pen pen, + float x, + float y, + float width, + float height + ); + + /// + /// Draws a cardinal spline through a specified array of PointF structures + /// using a specified tension. The drawing begins offset from + /// the beginning of the array. + /// + /// Pen object that determines the color, width, and height of the curve. + /// Array of PointF structures that define the spline. + /// Offset from the first element in the array of the points parameter to the starting point in the curve. + /// Number of segments after the starting point to include in the curve. + /// Value greater than or equal to 0.0F that specifies the tension of the curve. + void DrawCurve( + Pen pen, + PointF[] points, + int offset, + int numberOfSegments, + float tension + ); + + /// + /// Draws a rectangle specified by a coordinate pair, a width, and a height. + /// + /// Pen object that determines the color, width, and style of the rectangle. + /// x-coordinate of the upper-left corner of the rectangle to draw. + /// y-coordinate of the upper-left corner of the rectangle to draw. + /// Width of the rectangle to draw. + /// Height of the rectangle to draw. + void DrawRectangle( + Pen pen, + int x, + int y, + int width, + int height + ); + + /// + /// Draws a polygon defined by an array of PointF structures. + /// + /// Pen object that determines the color, width, and style of the polygon. + /// Array of PointF structures that represent the vertices of the polygon. + void DrawPolygon( + Pen pen, + PointF[] points + ); + + /// + /// Draws the specified text string in the specified rectangle with the specified Brush and Font objects using the formatting properties of the specified StringFormat object. + /// + /// String to draw. + /// Font object that defines the text format of the string. + /// Brush object that determines the color and texture of the drawn text. + /// RectangleF structure that specifies the location of the drawn text. + /// StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text. + void DrawString( + string s, + Font font, + Brush brush, + RectangleF layoutRectangle, + StringFormat format + ); + + /// + /// Draws the specified text string at the specified location with the specified Brush and Font objects using the formatting properties of the specified StringFormat object. + /// + /// String to draw. + /// Font object that defines the text format of the string. + /// Brush object that determines the color and texture of the drawn text. + /// PointF structure that specifies the upper-left corner of the drawn text. + /// StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text. + void DrawString( + string s, + Font font, + Brush brush, + PointF point, + StringFormat format + ); + + /// + /// Draws the specified portion of the specified Image object at the specified location and with the specified size. + /// + /// Image object to draw. + /// Rectangle structure that specifies the location and size of the drawn image. The image is scaled to fit the rectangle. + /// x-coordinate of the upper-left corner of the portion of the source image to draw. + /// y-coordinate of the upper-left corner of the portion of the source image to draw. + /// Width of the portion of the source image to draw. + /// Height of the portion of the source image to draw. + /// Member of the GraphicsUnit enumeration that specifies the units of measure used to determine the source rectangle. + /// ImageAttributes object that specifies recoloring and gamma information for the image object. + void DrawImage( + System.Drawing.Image image, + Rectangle destRect, + float srcX, + float srcY, + float srcWidth, + float srcHeight, + GraphicsUnit srcUnit, + ImageAttributes imageAttrs + ); + + /// + /// Draws a rectangle specified by a coordinate pair, a width, and a height. + /// + /// A Pen object that determines the color, width, and style of the rectangle. + /// The x-coordinate of the upper-left corner of the rectangle to draw. + /// The y-coordinate of the upper-left corner of the rectangle to draw. + /// The width of the rectangle to draw. + /// The height of the rectangle to draw. + void DrawRectangle( + Pen pen, + float x, + float y, + float width, + float height + ); + + /// + /// Draws a GraphicsPath object. + /// + /// Pen object that determines the color, width, and style of the path. + /// GraphicsPath object to draw. + void DrawPath( + Pen pen, + GraphicsPath path + ); + + /// + /// Draws a pie shape defined by an ellipse specified by a coordinate pair, a width, and a height and two radial lines. + /// + /// Pen object that determines the color, width, and style of the pie shape. + /// x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// Width of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// Height of the bounding rectangle that defines the ellipse from which the pie shape comes. + /// Angle measured in degrees clockwise from the x-axis to the first side of the pie shape. + /// Angle measured in degrees clockwise from the startAngle parameter to the second side of the pie shape. + void DrawPie( + Pen pen, + float x, + float y, + float width, + float height, + float startAngle, + float sweepAngle + ); + + /// + /// Draws an arc representing a portion of an ellipse specified by a pair of coordinates, a width, and a height. + /// + /// Pen object that determines the color, width, and style of the arc. + /// x-coordinate of the upper-left corner of the rectangle that defines the ellipse. + /// y-coordinate of the upper-left corner of the rectangle that defines the ellipse. + /// Width of the rectangle that defines the ellipse. + /// Height of the rectangle that defines the ellipse. + /// Angle in degrees measured clockwise from the x-axis to the starting point of the arc. + /// Angle in degrees measured clockwise from the startAngle parameter to ending point of the arc. + void DrawArc( + Pen pen, + float x, + float y, + float width, + float height, + float startAngle, + float sweepAngle + ); + + /// + /// Draws the specified Image object at the specified location and with the specified size. + /// + /// Image object to draw. + /// RectangleF structure that specifies the location and size of the drawn image. + void DrawImage( + System.Drawing.Image image, + RectangleF rect + ); + + /// + /// Draws an ellipse defined by a bounding RectangleF. + /// + /// Pen object that determines the color, width, and style of the ellipse. + /// RectangleF structure that defines the boundaries of the ellipse. + void DrawEllipse( + Pen pen, + RectangleF rect + ); + + /// + /// Draws a series of line segments that connect an array of PointF structures. + /// + /// Pen object that determines the color, width, and style of the line segments. + /// Array of PointF structures that represent the points to connect. + void DrawLines( + Pen pen, + PointF[] points + ); + + #endregion // Drawing Methods + + #region Filling Methods + + /// + /// Fills the interior of an ellipse defined by a bounding rectangle + /// specified by a RectangleF structure. + /// + /// Brush object that determines the characteristics of the fill. + /// RectangleF structure that represents the bounding rectangle that defines the ellipse. + void FillEllipse( + Brush brush, + RectangleF rect + ); + + /// + /// Fills the interior of a GraphicsPath object. + /// + /// Brush object that determines the characteristics of the fill. + /// GraphicsPath object that represents the path to fill. + void FillPath( + Brush brush, + GraphicsPath path + ); + + /// + /// Fills the interior of a Region object. + /// + /// Brush object that determines the characteristics of the fill. + /// Region object that represents the area to fill. + void FillRegion( + Brush brush, + Region region + ); + + /// + /// Fills the interior of a rectangle specified by a RectangleF structure. + /// + /// Brush object that determines the characteristics of the fill. + /// RectangleF structure that represents the rectangle to fill. + void FillRectangle( + Brush brush, + RectangleF rect + ); + + /// + /// Fills the interior of a rectangle specified by a pair of coordinates, a width, and a height. + /// + /// Brush object that determines the characteristics of the fill. + /// x-coordinate of the upper-left corner of the rectangle to fill. + /// y-coordinate of the upper-left corner of the rectangle to fill. + /// Width of the rectangle to fill. + /// Height of the rectangle to fill. + void FillRectangle( + Brush brush, + float x, + float y, + float width, + float height + ); + + /// + /// Fills the interior of a polygon defined by an array of points specified by PointF structures . + /// + /// Brush object that determines the characteristics of the fill. + /// Array of PointF structures that represent the vertices of the polygon to fill. + void FillPolygon( + Brush brush, + PointF[] points + ); + + /// + /// Fills the interior of a pie section defined by an ellipse + /// specified by a pair of coordinates, a width, and a height + /// and two radial lines. + /// + /// Brush object that determines the characteristics of the fill. + /// x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie section comes. + /// y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie section comes. + /// Width of the bounding rectangle that defines the ellipse from which the pie section comes. + /// Height of the bounding rectangle that defines the ellipse from which the pie section comes. + /// Angle in degrees measured clockwise from the x-axis to the first side of the pie section. + /// Angle in degrees measured clockwise from the startAngle parameter to the second side of the pie section. + void FillPie( + Brush brush, + float x, + float y, + float width, + float height, + float startAngle, + float sweepAngle + ); + + #endregion // Filling Methods + + #region Other Methods + + /// + /// Measures the specified string when drawn with the specified + /// Font object and formatted with the specified StringFormat object. + /// + /// String to measure. + /// Font object defines the text format of the string. + /// SizeF structure that specifies the maximum layout area for the text. + /// StringFormat object that represents formatting information, such as line spacing, for the string. + /// This method returns a SizeF structure that represents the size, in pixels, of the string specified in the text parameter as drawn with the font parameter and the stringFormat parameter. + SizeF MeasureString( + string text, + Font font, + SizeF layoutArea, + StringFormat stringFormat + ); + + /// + /// Measures the specified string when drawn with the specified + /// Font object and formatted with the specified StringFormat object. + /// + /// String to measure. + /// Font object defines the text format of the string. + /// This method returns a SizeF structure that represents the size, in pixels, of the string specified in the text parameter as drawn with the font parameter and the stringFormat parameter. + SizeF MeasureString( + string text, + Font font + ); + + /// + /// Saves the current state of this Graphics object and identifies the saved state with a GraphicsState object. + /// + /// This method returns a GraphicsState object that represents the saved state of this Graphics object. + GraphicsState Save(); + + /// + /// Restores the saved state of graphics object. + /// + /// State to restore. + void Restore( + GraphicsState gstate + ); + + /// + /// Resets the clip region of this Graphics object to an infinite region. + /// + void ResetClip(); + + /// + /// Sets the clipping region of this Graphics object to the rectangle specified by a RectangleF structure. + /// + /// RectangleF structure that represents the new clip region. + void SetClip( + RectangleF rect + ); + + /// + /// Sets the clipping region of this Graphics object to the result of the + /// specified operation combining the current clip region and the + /// specified GraphicsPath object. + /// + /// GraphicsPath object to combine. + /// Member of the CombineMode enumeration that specifies the combining operation to use. + void SetClip( + GraphicsPath path, + CombineMode combineMode + ); + + /// + /// Prepends the specified translation to the transformation matrix of this Graphics object. + /// + /// x component of the translation. + /// y component of the translation. + void TranslateTransform( + float dx, + float dy + ); + + /// + /// This method starts Selection mode + /// + /// The location of the referenced object, expressed as a URI reference. + /// Title which could be used for tooltips. + void BeginSelection( string hRef, string title ); + + /// + /// This method stops Selection mode + /// + void EndSelection( ); + + #endregion // Other Methods + + #region Properties + + /// + /// Gets or sets the world transformation for this Graphics object. + /// + Matrix Transform {get; set;} + + /// + /// Gets or sets the rendering quality for this Graphics object. + /// + SmoothingMode SmoothingMode {get; set;} + + /// + /// Gets or sets the rendering mode for text associated with this Graphics object. + /// + TextRenderingHint TextRenderingHint {get; set;} + + /// + /// Gets or sets a Region object that limits the drawing region of this Graphics object. + /// + Region Clip {get; set;} + + /// + /// Reference to the Graphics object + /// + Graphics Graphics {get; set;} + + /// + /// Gets a value indicating whether the clipping region of this Graphics object is empty. + /// + bool IsClipEmpty {get;} + + #endregion // Properties + } +} diff --git a/System.Web.DataVisualization/Common/General/ImageMap.cs b/System.Web.DataVisualization/Common/General/ImageMap.cs new file mode 100644 index 000000000..34847941a --- /dev/null +++ b/System.Web.DataVisualization/Common/General/ImageMap.cs @@ -0,0 +1,891 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ImageMap.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: MapArea, MapAreasCollection +// +// Purpose: Collection of MapArea classes is used to generate +// Chart image map, which provides functionality like +// tooltip, drilldown and client-side scripting. +// +// Reviewed: AG - Jul 31, 2002 +// AG - Microsoft 14, 2007 +// +//=================================================================== + + +#region Used namespaces + +using System; +using System.Text; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Design; +using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Utilities; +using System.Text.RegularExpressions; +using System.IO; + +#endif + +#endregion + +#if Microsoft_CONTROL + + namespace System.Windows.Forms.DataVisualization.Charting + +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + +#if ! Microsoft_CONTROL + + #region Map area shape enumeration + + /// + /// An enumeration of map areas shapes. + /// + public enum MapAreaShape + { + /// + /// The shape of the map area is rectangular. + /// + Rectangle, + + /// + /// The shape of the map area is circular. + /// + Circle, + + /// + /// The shape of the map area is polygonal. + /// + Polygon + } + + + #endregion + + #region IMapArea interface defenition + + /// + /// Interface which defines common properties for the map area + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public interface IChartMapArea + { + /// + /// Map area tooltip + /// + /// The tooltip. + string ToolTip + { + set; get; + } + /// + /// Map area Href + /// + /// The map area Href. + [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")] + string Url + { + set; get; + } + /// + /// Map area other custom attributes + /// + /// The map area attributes. + string MapAreaAttributes + { + set; get; + } + + /// + /// Map area custom data + /// + /// The tag. + object Tag + { + set; + get; + } + + /// + /// Map area post back value. + /// + /// The post back value. + string PostBackValue { get; set; } + } + + #endregion + + /// + /// The MapArea class represents an area of the chart with end-user + /// interactivity like tooltip, HREF or custom attributes. + /// + [ + DefaultProperty("ToolTip"), + SRDescription("DescriptionAttributeMapArea_MapArea") + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class MapArea : ChartNamedElement, IChartMapArea + { + + #region Member variables + + private string _toolTip = String.Empty; + private string _url = String.Empty; + private string _attributes = String.Empty; + private string _postBackValue = String.Empty; + private bool _isCustom = true; + private MapAreaShape _shape = MapAreaShape.Rectangle; + private float[] _coordinates = new float[4]; + private static Regex _mapAttributesRegex; + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public MapArea() + : base() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The destination URL or anchor point of the map area. + /// A GraphicsPath object that defines the shape of the map area. + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#")] + public MapArea(string url, GraphicsPath path) + : this(String.Empty, url, String.Empty, String.Empty, path, null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The destination URL or anchor point of the map area. + /// A RectangleF structure that defines shape of the rectangular map area. + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#")] + public MapArea(string url, RectangleF rect) + : this(String.Empty, url, String.Empty, String.Empty, rect, null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Area shape. + /// The destination URL or anchor point of the map area. + /// Coordinates array that determines the location of the circle, rectangle or polygon. + /// The type of shape that is being used determines the type of coordinates required. + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#")] + public MapArea(MapAreaShape shape, string url, float[] coordinates) + : this(shape, String.Empty, url, String.Empty, String.Empty, coordinates, null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Tool tip. + /// Jump URL. + /// Other area attributes. + /// The postback value. + /// Area coordinates as graphic path + /// The tag. + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#")] + public MapArea(string toolTip, string url, string attributes, string postBackValue, GraphicsPath path, object tag) + : base() + { + if(path.PointCount == 0) + { + throw new ArgumentException(SR.ExceptionImageMapPolygonShapeInvalid); + } + + // Flatten all curved lines + path.Flatten(); + + // Allocate array of floats + PointF[] pathPoints = path.PathPoints; + float[] coord = new float[pathPoints.Length * 2]; + + // Transfer path points + int index = 0; + foreach(PointF point in pathPoints) + { + coord[index++] = point.X; + coord[index++] = point.Y; + } + + // Initiazize area + Initialize(MapAreaShape.Polygon, toolTip, url, attributes, postBackValue, coord, tag); + } + + /// + /// Initializes a new instance of the class. + /// + /// Tool tip. + /// Jump URL. + /// Other area attributes. + /// The postback value. + /// Rect coordinates + /// The tag. + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#")] + public MapArea(string toolTip, string url, string attributes, string postBackValue, RectangleF rect, object tag) + : base() + { + float[] coord = new float[4]; + coord[0] = rect.X; + coord[1] = rect.Y; + coord[2] = rect.Right; + coord[3] = rect.Bottom; + + Initialize(MapAreaShape.Rectangle, toolTip, url, attributes, postBackValue, coord, tag); + } + + /// + /// Initializes a new instance of the class. + /// + /// The shape. + /// The tool tip. + /// The URL. + /// The attributes. + /// The postback value. + /// The coordinates. + /// The tag. + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#")] + public MapArea(MapAreaShape shape, string toolTip, string url, string attributes, string postBackValue, float[] coordinates, object tag) + : base() + { + Initialize(shape, toolTip, url, attributes, postBackValue, coordinates, tag); + } + + + private void Initialize(MapAreaShape shape, string toolTip, string url, string attributes, string postBackValue, float[] coordinates, object tag) + { + // Check number of coordinates depending on the area shape + if (shape == MapAreaShape.Circle && coordinates.Length != 3) + { + throw (new InvalidOperationException(SR.ExceptionImageMapCircleShapeInvalid)); + } + if (shape == MapAreaShape.Rectangle && coordinates.Length != 4) + { + throw (new InvalidOperationException(SR.ExceptionImageMapRectangleShapeInvalid)); + } + if (shape == MapAreaShape.Polygon && (coordinates.Length % 2f) != 0f) + { + throw (new InvalidOperationException(SR.ExceptionImageMapPolygonShapeInvalid)); + } + + // Create new area object + this._toolTip = toolTip; + this._url = url; + this._attributes = attributes; + this._shape = shape; + this._coordinates = new float[coordinates.Length]; + this._postBackValue = postBackValue; + this.Tag = tag; + coordinates.CopyTo(this._coordinates, 0); + } + #endregion + + #region Map area HTML tag generation methods + + /// + /// Gets the name of the shape. + /// + /// + private string GetShapeName() + { + //***************************************** + //** Set shape type + //***************************************** + if (_shape == MapAreaShape.Circle) + { + return "circle"; + } + else if (_shape == MapAreaShape.Rectangle) + { + return "rect"; + } + else if (_shape == MapAreaShape.Polygon) + { + return "poly"; + } + return String.Empty; + } + + + /// + /// Gets the coordinates. + /// + /// The graph. + /// + private string GetCoordinates(ChartGraphics graph) + { + // Transform coordinates from relative to pixels + float[] transformedCoord = new float[this.Coordinates.Length]; + if (this.Shape == MapAreaShape.Circle) + { + PointF p = graph.GetAbsolutePoint(new PointF(this.Coordinates[0], this.Coordinates[1])); + transformedCoord[0] = p.X; + transformedCoord[1] = p.Y; + p = graph.GetAbsolutePoint(new PointF(this.Coordinates[2], this.Coordinates[1])); + transformedCoord[2] = p.X; + } + else if (this.Shape == MapAreaShape.Rectangle) + { + PointF p = graph.GetAbsolutePoint(new PointF(this.Coordinates[0], this.Coordinates[1])); + transformedCoord[0] = p.X; + transformedCoord[1] = p.Y; + p = graph.GetAbsolutePoint(new PointF(this.Coordinates[2], this.Coordinates[3])); + transformedCoord[2] = p.X; + transformedCoord[3] = p.Y; + + // Check if rectangle has width and height + if ((int)Math.Round(transformedCoord[0]) == (int)Math.Round(transformedCoord[2])) + { + transformedCoord[2] = (float)Math.Round(transformedCoord[2]) + 1; + } + if ((int)Math.Round(transformedCoord[1]) == (int)Math.Round(transformedCoord[3])) + { + transformedCoord[3] = (float)Math.Round(transformedCoord[3]) + 1; + } + } + else + { + PointF pConverted = Point.Empty; + PointF pOriginal = Point.Empty; + for (int index = 0; index < this.Coordinates.Length - 1; index += 2) + { + pOriginal.X = this.Coordinates[index]; + pOriginal.Y = this.Coordinates[index + 1]; + pConverted = graph.GetAbsolutePoint(pOriginal); + transformedCoord[index] = pConverted.X; + transformedCoord[index + 1] = pConverted.Y; + } + } + + StringBuilder tagStringBuilder = new StringBuilder(); + // Store transformed coordinates in the string + bool firstElement = true; + foreach (float f in transformedCoord) + { + if (!firstElement) + { + tagStringBuilder.Append(","); + } + firstElement = false; + tagStringBuilder.Append((int)Math.Round(f)); + } + + return tagStringBuilder.ToString(); + } + + private static bool IsJavaScript(string value) + { + string checkValue = value.Trim().Replace("\r", String.Empty).Replace("\n", String.Empty); + if (checkValue.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + return false; + } + + + /// + /// Encodes the value. + /// + /// The chart. + /// The name. + /// The value. + /// + private static string EncodeValue(Chart chart, string name, string value) + { + if (chart.IsMapAreaAttributesEncoded) + { + if (IsJavaScript(value) || + name.Trim().StartsWith("on", StringComparison.OrdinalIgnoreCase)) + { + return HttpUtility.UrlEncode(value); + } + } + return value; + } + + /// + /// Renders the tag. + /// + /// The writer. + /// The chart. + [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification="We use lower case to generate html attributes.")] + internal void RenderTag(HtmlTextWriter writer, Chart chart) + { + StringBuilder excludedAttributes = new StringBuilder(); + + writer.WriteLine(); + + writer.AddAttribute(HtmlTextWriterAttribute.Shape, this.GetShapeName(), false); + writer.AddAttribute(HtmlTextWriterAttribute.Coords, this.GetCoordinates(chart.chartPicture.ChartGraph)); + + if (!String.IsNullOrEmpty(this.ToolTip)) + { + excludedAttributes.Append("title,"); + writer.AddAttribute(HtmlTextWriterAttribute.Title, EncodeValue(chart, "title", this.ToolTip)); + } + + bool postbackRendered = false; + if (!String.IsNullOrEmpty(this.Url)) + { + excludedAttributes.Append("href,"); + string resolvedUrl = chart.ResolveClientUrl(this.Url); + writer.AddAttribute(HtmlTextWriterAttribute.Href, EncodeValue(chart, "href", resolvedUrl)); + } + else if (!String.IsNullOrEmpty(this.PostBackValue) && chart.Page != null) + { + postbackRendered = true; + excludedAttributes.Append("href,"); + writer.AddAttribute(HtmlTextWriterAttribute.Href, chart.Page.ClientScript.GetPostBackClientHyperlink(chart, this.PostBackValue)); + } + + if (!postbackRendered && !String.IsNullOrEmpty(this.PostBackValue) && chart.Page != null) + { + excludedAttributes.Append("onclick,"); + writer.AddAttribute(HtmlTextWriterAttribute.Onclick, chart.Page.ClientScript.GetPostBackEventReference(chart, this.PostBackValue)); + } + + if (!String.IsNullOrEmpty(this._attributes)) + { + string excludedAttr = excludedAttributes.ToString(); + + // matches name1="value1" name2="value2", don't match name1="val"ue1" or name1="value1" /> + if (_mapAttributesRegex == null) + { + _mapAttributesRegex = new Regex(@"\s?(?(\w+))\s?=\s?""(?[^""]+)""\s?", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); + } + + foreach (Match match in _mapAttributesRegex.Matches(this._attributes)) + { + Group names = match.Groups["name"]; + Group values = match.Groups["value"]; + for (int i = 0; i < names.Captures.Count || i < values.Captures.Count; i++) + { + string name = names.Captures[i].Value.ToLowerInvariant(); + string value = values.Captures[i].Value; + + // skip already rendered attributes + if (!excludedAttr.Contains(name + ",")) + { + // is it url? + if ("src,href,longdesc,background,".Contains(name + ",") && !IsJavaScript(value)) + { + value = chart.ResolveClientUrl(value); + } + else + { + value = HttpUtility.HtmlAttributeEncode(value); + } + value = EncodeValue(chart, name, value); + writer.AddAttribute(name, value, false); + } + } + } + } + + if (this._attributes.IndexOf(" alt=", StringComparison.OrdinalIgnoreCase) == -1) + { + if (!String.IsNullOrEmpty(this.ToolTip)) + { + writer.AddAttribute(HtmlTextWriterAttribute.Alt, EncodeValue(chart, "title", this.ToolTip)); + } + else + { + writer.AddAttribute(HtmlTextWriterAttribute.Alt, ""); + } + } + + writer.RenderBeginTag(HtmlTextWriterTag.Area); + writer.RenderEndTag(); + } + + #endregion + + #region MapArea Properties + + /// + /// Gets or sets a flag which indicates whether the map area is custom. + /// + [ + Browsable(false), + SRDescription("DescriptionAttributeMapArea_Custom"), + DefaultValue(""), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public bool IsCustom + { + get + { + return _isCustom; + } + internal set + { + _isCustom = value; + } + } + + /// + /// Gets or sets the coordinates of of the map area. + /// + [ + SRCategory("CategoryAttributeShape"), + Bindable(true), + SRDescription("DescriptionAttributeMapArea_Coordinates"), + DefaultValue(""), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + TypeConverter(typeof(MapAreaCoordinatesConverter)) + ] + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public float[] Coordinates + { + get + { + return _coordinates; + } + set + { + _coordinates = value; + } + } + + /// + /// Gets or sets the shape of the map area. + /// + [ + SRCategory("CategoryAttributeShape"), + Bindable(true), + SRDescription("DescriptionAttributeMapArea_Shape"), + DefaultValue(typeof(MapAreaShape), "Rectangle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public MapAreaShape Shape + { + get + { + return _shape; + } + set + { + _shape = value; + } + } + + /// + /// Gets or sets the name of the map area. + /// + [ + SRCategory("CategoryAttributeData"), + SRDescription("DescriptionAttributeMapArea_Name"), + DefaultValue("Map Area"), + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public override string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + #endregion + + #region IMapAreaAttributesutes Properties implementation + + /// + /// Gets or sets the tooltip of the map area. + /// + [ + + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeToolTip"), + DefaultValue(""), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif + ] + public string ToolTip + { + set + { + _toolTip = value; + } + get + { + return _toolTip; + } + } + + /// + /// Gets or sets the URL of the map area. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeUrl"), + DefaultValue(""), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base) +#endif + ] + public string Url + { + set + { + _url = value; + } + get + { + return _url; + } + } + + /// + /// Gets or sets the attributes of the map area. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeMapAreaAttributes"), + DefaultValue(""), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif + ] + public string MapAreaAttributes + { + set + { + _attributes = value; + } + get + { + return _attributes; + } + } + + /// + /// Gets or sets the postback value which can be processed on click event. + /// + /// The value which is passed to click event as argument. + [DefaultValue("")] + [SRCategory(SR.Keys.CategoryAttributeMapArea)] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + public string PostBackValue + { + get + { + return this._postBackValue; + } + set + { + this._postBackValue = value; + } + } + + + #endregion + + } + + + /// + /// The MapAreasCollection class is a strongly typed collection of MapAreas. + /// + [ + SRDescription("DescriptionAttributeMapAreasCollection_MapAreasCollection") + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class MapAreasCollection : ChartElementCollection + { + + #region Constructors + + /// + /// Public constructor. + /// + public MapAreasCollection() + : base(null) + { + } + + #endregion + + #region Methods + + /// + /// Insert new map area items into the collection. + /// + /// Index to insert at. + /// Tool tip. + /// Jump URL. + /// Other area attributes. + /// The post back value associated with this item. + /// Area coordinates as graphics path. + /// Absolute coordinates in the graphics path. + /// Chart graphics object. + internal void InsertPath( + int index, + string toolTip, + string url, + string attributes, + string postBackValue, + GraphicsPath path, + bool absCoordinates, + ChartGraphics graph) + { + + // If there is more then one graphical path split them and create + // image maps for every graphical path separately. + GraphicsPathIterator iterator = new GraphicsPathIterator(path); + + // There is more then one path. + if( iterator.SubpathCount > 1 ) + { + GraphicsPath subPath = new GraphicsPath(); + while(iterator.NextMarker(subPath) > 0) + { + InsertSubpath(index, toolTip, url, attributes, postBackValue, subPath, absCoordinates, graph); + subPath.Reset(); + } + } + // There is only one path + else + { + InsertSubpath(index, toolTip, url, attributes, postBackValue, path, absCoordinates, graph); + } + } + + /// + /// Insert new map area item into the collection. + /// + /// Index to insert at. + /// Tool tip. + /// Jump URL. + /// Other area attributes. + /// The post back value associated with this item. + /// Area coordinates as graphics path. + /// Absolute coordinates in the graphics path. + /// Chart graphics object. + private void InsertSubpath( + int index, + string toolTip, + string url, + string attributes, + string postBackValue, + GraphicsPath path, + bool absCoordinates, + ChartGraphics graph) + { + if(path.PointCount > 0) + { + // Flatten all curved lines + path.Flatten(); + + // Allocate array of floats + PointF[] pathPoints = path.PathPoints; + float[] coord = new float[pathPoints.Length * 2]; + + // Convert absolute coordinates to relative + if(absCoordinates) + { + for(int pointIndex = 0; pointIndex < pathPoints.Length; pointIndex++) + { + pathPoints[pointIndex] = graph.GetRelativePoint( pathPoints[pointIndex] ); + } + } + + // Transfer path points + int i = 0; + foreach(PointF point in pathPoints) + { + coord[i++] = point.X; + coord[i++] = point.Y; + } + + // Add new area + MapArea area = new MapArea(MapAreaShape.Polygon, toolTip, url, attributes, postBackValue, coord, null); + area.IsCustom = false; + this.Insert(index, area); + } + } + + /// + /// Removes all non custom map areas items from the collection. + /// + internal void RemoveNonCustom() + { + for(int index = 0; index < this.Count; index++) + { + // Check the custom flag + if(!this[index].IsCustom) + { + this.RemoveAt(index); + --index; + } + } + } + + #endregion + } + +#endif +} diff --git a/System.Web.DataVisualization/Common/General/Label.cs b/System.Web.DataVisualization/Common/General/Label.cs new file mode 100644 index 000000000..005ded256 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/Label.cs @@ -0,0 +1,3002 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: LabelStyle.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: CustomLabelsCollection, CustomLabel, LabelStyle +// +// Purpose: LabelStyle and CustomLabel classes are used to determine +// chart axis labels. Labels can be automatically +// generated based on the series data or be “manually” +// set by the user. +// +// Reviewed: AG - Jul 31, 2002 +// AG - Microsoft 14, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Drawing.Text; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; + using System.Globalization; + using System.ComponentModel.Design.Serialization; + using System.Reflection; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif +{ + #region Labels enumerations + + /// + /// An enumeration that specifies a mark for custom labels. + /// + public enum LabelMarkStyle + { + /// + /// No label marks are used. + /// + None, + + /// + /// Labels use side marks. + /// + SideMark, + + /// + /// Labels use line and side marks. + /// + LineSideMark, + + + /// + /// Draws a box around the label. The box always starts at the axis position. + /// + Box + }; + + + /// + /// An enumeration of custom grid lines and tick marks flags used in the custom labels. + /// + [Flags] + public enum GridTickTypes + { + /// + /// No tick mark or grid line are shown. + /// + None = 0, + + /// + /// Tick mark is shown. + /// + TickMark = 1, + + /// + /// Grid line is shown. + /// + Gridline = 2, + + /// + /// Tick mark and grid line are shown. + /// + All = TickMark | Gridline + } + + + /// + /// An enumeration of label styles for circular chart area axis. + /// + internal enum CircularAxisLabelsStyle + { + /// + /// Style depends on number of labels. + /// + Auto, + + /// + /// Label text positions around the circular area. + /// + Circular, + + /// + /// Label text is always horizontal. + /// + Horizontal, + + /// + /// Label text has the same angle as circular axis. + /// + Radial + } + #endregion + + /// + /// The CustomLabelsCollection class is a strongly typed collection of + /// custom axis labels. + /// + [ + SRDescription("DescriptionAttributeCustomLabelsCollection_CustomLabelsCollection"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class CustomLabelsCollection : ChartElementCollection + { + #region Constructors + + /// + /// Custom labels collection object constructor + /// + /// Reference to the axis object. + internal CustomLabelsCollection(Axis axis) : base(axis) + { + } + + #endregion + + #region Properties + internal Axis Axis + { + get { return Parent as Axis; } + } + #endregion + + #region Labels adding methods + + /// + /// Adds a custom label into the collection. + /// + /// Label left position. + /// Label right position. + /// Label text. + /// Newly added item. + public CustomLabel Add(double fromPosition, double toPosition, string text) + { + CustomLabel label = new CustomLabel(fromPosition, toPosition, text, 0, LabelMarkStyle.None); + Add(label); + return label; + } + + /// + /// Adds one custom label into the collection. Custom label flag may be specified. + /// + /// Label left position. + /// Label right position. + /// Label text. + /// Indicates if label is custom (created by user). + /// Newly added item. + internal CustomLabel Add(double fromPosition, double toPosition, string text, bool customLabel) + { + CustomLabel label = new CustomLabel(fromPosition, toPosition, text, 0, LabelMarkStyle.None); + label.customLabel = customLabel; + Add(label); + return label; + } + + /// + /// Adds a custom label into the collection. + /// + /// Label left position. + /// Label right position. + /// Label text. + /// Label row index. + /// Label marking style. + /// Newly added item. + public CustomLabel Add(double fromPosition, double toPosition, string text, int rowIndex, LabelMarkStyle markStyle) + { + CustomLabel label = new CustomLabel(fromPosition, toPosition, text, rowIndex, markStyle); + Add(label); + return label; + } + + /// + /// Adds a custom label into the collection. + /// + /// Label left position. + /// Label right position. + /// Label text. + /// Label row index. + /// Label marking style. + /// Index of newly added item. + /// Custom grid line and tick mark flag. + public CustomLabel Add(double fromPosition, double toPosition, string text, int rowIndex, LabelMarkStyle markStyle, GridTickTypes gridTick) + { + CustomLabel label = new CustomLabel(fromPosition, toPosition, text, rowIndex, markStyle, gridTick); + Add(label); + return label; + } + + + /// + /// Adds multiple custom labels to the collection. + /// The labels will be DateTime labels with the specified interval type, + /// and will be generated for the axis range that is determined by the minimum and maximum arguments. + /// + /// The label step determines how often the custom labels will be drawn. + /// Unit of measurement of the label step. + /// Minimum value.. + /// Maximum value.. + /// Label text format. + /// Label row index. + /// Label marking style. + public void Add(double labelsStep, DateTimeIntervalType intervalType, double min, double max, string format, int rowIndex, LabelMarkStyle markStyle) + { + // Find labels range min/max values + if(min == 0.0 && + max == 0.0 && + this.Axis != null && + !double.IsNaN(this.Axis.Minimum) && + !double.IsNaN(this.Axis.Maximum)) + { + min = this.Axis.Minimum; + max = this.Axis.Maximum; + } + double fromX = Math.Min(min, max); + double toX = Math.Max(min, max); + + this.SuspendUpdates(); + try + { + + // Loop through all label points + double labelStart = fromX; + double labelEnd = 0; + while (labelStart < toX) + { + // Determine label end location + if (intervalType == DateTimeIntervalType.Number) + { + labelEnd = labelStart + labelsStep; + } + else if (intervalType == DateTimeIntervalType.Milliseconds) + { + labelEnd = DateTime.FromOADate(labelStart).AddMilliseconds(labelsStep).ToOADate(); + } + else if (intervalType == DateTimeIntervalType.Seconds) + { + labelEnd = DateTime.FromOADate(labelStart).AddSeconds(labelsStep).ToOADate(); + } + else if (intervalType == DateTimeIntervalType.Minutes) + { + labelEnd = DateTime.FromOADate(labelStart).AddMinutes(labelsStep).ToOADate(); + } + else if (intervalType == DateTimeIntervalType.Hours) + { + labelEnd = DateTime.FromOADate(labelStart).AddHours(labelsStep).ToOADate(); + } + else if (intervalType == DateTimeIntervalType.Days) + { + labelEnd = DateTime.FromOADate(labelStart).AddDays(labelsStep).ToOADate(); + } + else if (intervalType == DateTimeIntervalType.Weeks) + { + labelEnd = DateTime.FromOADate(labelStart).AddDays(7 * labelsStep).ToOADate(); + } + else if (intervalType == DateTimeIntervalType.Months) + { + labelEnd = DateTime.FromOADate(labelStart).AddMonths((int)labelsStep).ToOADate(); + } + else if (intervalType == DateTimeIntervalType.Years) + { + labelEnd = DateTime.FromOADate(labelStart).AddYears((int)labelsStep).ToOADate(); + } + else + { + // Unsupported step type + throw (new ArgumentException(SR.ExceptionAxisLabelsIntervalTypeUnsupported(intervalType.ToString()))); + } + if (labelEnd > toX) + { + labelEnd = toX; + } + + // Generate label text + ChartValueType valueType = ChartValueType.Double; + if (intervalType != DateTimeIntervalType.Number) + { + if (this.Axis.GetAxisValuesType() == ChartValueType.DateTimeOffset) + valueType = ChartValueType.DateTimeOffset; + else + valueType = ChartValueType.DateTime; + } + string text = ValueConverter.FormatValue( + this.Common.Chart, + this.Axis, + null, + labelStart + (labelEnd - labelStart) / 2, + format, + valueType, + ChartElementType.AxisLabels); + + // Add label + CustomLabel label = new CustomLabel(labelStart, labelEnd, text, rowIndex, markStyle); + this.Add(label); + + labelStart = labelEnd; + } + } + finally + { + this.ResumeUpdates(); + } + } + + /// + /// Adds multiple custom labels to the collection. + /// The labels will be DateTime labels with the specified interval type, + /// and will be generated for the axis range that is determined by the minimum and maximum arguments. + /// + /// The label step determines how often the custom labels will be drawn. + /// Unit of measurement of the label step. + public void Add(double labelsStep, DateTimeIntervalType intervalType) + { + Add(labelsStep, intervalType, 0, 0, "", 0, LabelMarkStyle.None); + } + + /// + /// Adds multiple custom labels to the collection. + /// The labels will be DateTime labels with the specified interval type, + /// and will be generated for the axis range that is determined by the minimum and maximum arguments. + /// + /// The label step determines how often the custom labels will be drawn. + /// Unit of measurement of the label step. + /// Label text format. + public void Add(double labelsStep, DateTimeIntervalType intervalType, string format) + { + Add(labelsStep, intervalType, 0, 0, format, 0, LabelMarkStyle.None); + } + + /// + /// Adds multiple custom labels to the collection. + /// The labels will be DateTime labels with the specified interval type, + /// and will be generated for the axis range that is determined by the minimum and maximum arguments. + /// + /// The label step determines how often the custom labels will be drawn. + /// Unit of measurement of the label step. + /// Label text format. + /// Label row index. + /// Label marking style. + public void Add(double labelsStep, DateTimeIntervalType intervalType, string format, int rowIndex, LabelMarkStyle markStyle) + { + Add(labelsStep, intervalType, 0, 0, format, rowIndex, markStyle); + } + + #endregion + + } + + + /// + /// The CustomLabel class represents a single custom axis label. Text and + /// position along the axis is provided by the caller. + /// + [ + SRDescription("DescriptionAttributeCustomLabel_CustomLabel"), + DefaultProperty("Text"), + ] +#if Microsoft_CONTROL + public class CustomLabel : ChartNamedElement +#else +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class CustomLabel : ChartNamedElement, IChartMapArea +#endif + { + #region Fields and Constructors + + // Private data members, which store properties values + private double _fromPosition = 0; + private double _toPosition = 0; + private string _text = ""; + private LabelMarkStyle _labelMark = LabelMarkStyle.None; + private Color _foreColor = Color.Empty; + private Color _markColor = Color.Empty; + private int _labelRowIndex = 0; + + // Custom grid lines and tick marks flags + private GridTickTypes _gridTick = GridTickTypes.None; + + // Indicates if label was automatically created or cpecified by user (custom) + internal bool customLabel = true; + + // Image associated with the label + private string _image = string.Empty; + + // Image transparent color + private Color _imageTransparentColor = Color.Empty; + + // Label tooltip + private string _tooltip = string.Empty; + + private Axis _axis = null; +#if !Microsoft_CONTROL + + // URL target of the label image. + private string _imageUrl = string.Empty; + + // Other attributes of the label image map area. + private string _imageMapAreaAttributes = string.Empty; + + private string _imagePostbackValue = String.Empty; + + // Label tooltip + private string _url = string.Empty; + + // Other attributes of the label image map area. + private string _mapAreaAttributes = string.Empty; + + private string _postbackValue = String.Empty; + + +#endif // !Microsoft_CONTROL + + + + #endregion + + #region Constructors + + /// + /// Default constructor + /// + public CustomLabel() + { + } + + /// + /// CustomLabel constructor + /// + /// From position. + /// To position. + /// Label text. + /// Label row index. + /// Label mark style. + public CustomLabel(double fromPosition, double toPosition, string text, int labelRow, LabelMarkStyle markStyle) + { + this._fromPosition = fromPosition; + this._toPosition = toPosition; + this._text = text; + this._labelRowIndex = labelRow; + this._labelMark = markStyle; + this._gridTick = GridTickTypes.None; + } + + /// + /// CustomLabel constructor + /// + /// From position. + /// To position. + /// Label text. + /// Label row index. + /// Label mark style. + /// Custom grid line and tick marks flag. + public CustomLabel(double fromPosition, double toPosition, string text, int labelRow, LabelMarkStyle markStyle, GridTickTypes gridTick) + { + this._fromPosition = fromPosition; + this._toPosition = toPosition; + this._text = text; + this._labelRowIndex = labelRow; + this._labelMark = markStyle; + this._gridTick = gridTick; + } + + #endregion + + #region Helper methods + + /// + /// Returns a cloned label object. + /// + /// Copy of current custom label. + public CustomLabel Clone() + { + CustomLabel newLabel = new CustomLabel(); + + newLabel.FromPosition = this.FromPosition; + newLabel.ToPosition = this.ToPosition; + newLabel.Text = this.Text; + newLabel.ForeColor = this.ForeColor; + newLabel.MarkColor = this.MarkColor; + newLabel.RowIndex = this.RowIndex; + newLabel.LabelMark = this.LabelMark; + newLabel.GridTicks = this.GridTicks; + + + + newLabel.ToolTip = this.ToolTip; + newLabel.Tag = this.Tag; + newLabel.Image = this.Image; + newLabel.ImageTransparentColor = this.ImageTransparentColor; + +#if !Microsoft_CONTROL + newLabel.Url = this.Url; + newLabel.MapAreaAttributes = this.MapAreaAttributes; + newLabel.ImageUrl = this.ImageUrl; + newLabel.ImageMapAreaAttributes = this.ImageMapAreaAttributes; +#endif // !Microsoft_CONTROL + + + + return newLabel; + } + + internal override IChartElement Parent + { + get + { + return base.Parent; + } + set + { + base.Parent = value; + if (value != null) + { + _axis = Parent.Parent as Axis; + } + } + } + + /// + /// Gets the axis to which this object is attached to. + /// + /// Axis. + [ + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + ] + public Axis Axis + { + get + { + return _axis; + } + } + + #endregion + + #region CustomLabel properties + + /// + /// Gets or sets the tooltip of the custom label. + /// + [ +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif //!Microsoft_CONTROL + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeToolTip"), + DefaultValue("") + ] + public string ToolTip + { + set + { + this._tooltip = value; + } + get + { + return this._tooltip; + } + } + + +#if !Microsoft_CONTROL + + /// + /// URL target of the custom label. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeUrl"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base) + ] + public string Url + { + set + { + this._url = value; + } + get + { + return this._url; + } + } + + /// + /// Gets or sets the other attributes of the custom label map area. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeMapAreaAttributes"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute) + ] + public string MapAreaAttributes + { + set + { + this._mapAreaAttributes = value; + } + get + { + return this._mapAreaAttributes; + } + } + + /// + /// Gets or sets the postback value which can be processed on a click event. + /// + /// The value which is passed to a click event as an argument. + [DefaultValue("")] + [SRCategory(SR.Keys.CategoryAttributeMapArea)] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + public string PostBackValue + { + get + { + return this._postbackValue; + } + set + { + this._postbackValue = value; + } + } + + /// + /// Gets or sets the URL target of the custom label image. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeCustomLabel_ImageUrl"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings") + ] + public string ImageUrl + { + set + { + this._imageUrl = value; + } + get + { + return this._imageUrl; + } + } + + /// + /// Gets or sets the other attributes of the map area of the custom label image. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeMapAreaAttributes"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute) + ] + public string ImageMapAreaAttributes + { + set + { + this._imageMapAreaAttributes = value; + } + get + { + return this._imageMapAreaAttributes; + } + } + + /// + /// Gets or sets the postback value which can be processed on a click event. + /// + /// The value which is passed to a click event as an argument. + [DefaultValue("")] + [SRCategory(SR.Keys.CategoryAttributeMapArea)] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + public string ImagePostBackValue + { + get + { + return this._imagePostbackValue; + } + set + { + this._imagePostbackValue = value; + } + } + + +#endif // !Microsoft_CONTROL + + /// + /// Gets or sets the label image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeCustomLabel_Image"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + NotifyParentPropertyAttribute(true) + ] + public string Image + { + get + { + return _image; + } + set + { + _image = value; + Invalidate(); + } + } + + /// + /// Gets or sets a color which will be replaced with a transparent color while drawing the image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color ImageTransparentColor + { + get + { + return _imageTransparentColor; + } + set + { + _imageTransparentColor = value; + this.Invalidate(); + } + } + + + + /// + /// Custom label name. This property is for internal use only. + /// + [ + SRCategory("CategoryAttributeAppearance"), + SRDescription("DescriptionAttributeCustomLabel_Name"), + DefaultValue("Custom LabelStyle"), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + DesignOnlyAttribute(true), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public override string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + + /// + /// Gets or sets a property which specifies whether + /// custom tick marks and grid lines will be drawn in the center of the label. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(GridTickTypes.None), + SRDescription("DescriptionAttributeCustomLabel_GridTicks"), + Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base) + ] + public GridTickTypes GridTicks + { + get + { + return _gridTick; + } + set + { + _gridTick = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the end position of the custom label in axis coordinates. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(0.0), + SRDescription("DescriptionAttributeCustomLabel_From"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + TypeConverter(typeof(AxisLabelDateValueConverter)) + ] + public double FromPosition + { + get + { + return _fromPosition; + } + set + { + _fromPosition = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the starting position of the custom label in axis coordinates. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(0.0), + SRDescription("DescriptionAttributeCustomLabel_To"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + TypeConverter(typeof(AxisLabelDateValueConverter)) + ] + public double ToPosition + { + get + { + return _toPosition; + } + set + { + _toPosition = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the text of the custom label. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeCustomLabel_Text"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public string Text + { + get + { + return _text; + } + set + { + _text = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the text color of the custom label. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeForeColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color ForeColor + { + get + { + return _foreColor; + } + set + { + _foreColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the color of the label mark line of the custom label. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeCustomLabel_MarkColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color MarkColor + { + get + { + return _markColor; + } + set + { + _markColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the row index of the custom label. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributeCustomLabel_RowIndex"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int RowIndex + { + get + { + return this._labelRowIndex; + } + set + { + if(value < 0) + { + throw (new InvalidOperationException(SR.ExceptionAxisLabelRowIndexIsNegative)); + } + + this._labelRowIndex = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a property which define the marks for the labels in the second row. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(LabelMarkStyle.None), + SRDescription("DescriptionAttributeCustomLabel_LabelMark"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public LabelMarkStyle LabelMark + { + get + { + return _labelMark; + } + set + { + _labelMark = value; + this.Invalidate(); + } + } + + #endregion + + } + + /// + /// The LabelStyle class contains properties which define the visual appearance of + /// the axis labels, their interval and position. This class is also + /// responsible for calculating the position of all the labels and + /// drawing them. + /// + [ + SRDescription("DescriptionAttributeLabel_Label"), + DefaultProperty("Enabled"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class LabelStyle : ChartElement + { + #region Fields + + // Reference to the Axis + private Axis _axis = null; + + // Private data members, which store properties values + private bool _enabled = true; + + internal double intervalOffset = double.NaN; + internal double interval = double.NaN; + internal DateTimeIntervalType intervalType = DateTimeIntervalType.NotSet; + internal DateTimeIntervalType intervalOffsetType = DateTimeIntervalType.NotSet; + + private FontCache _fontCache = new FontCache(); + private Font _font; + private Color _foreColor = Color.Black; + internal int angle = 0; + internal bool isStaggered = false; + private bool _isEndLabelVisible = true; + private bool _truncatedLabels = false; + private string _format = ""; + + #endregion + + #region Constructors + + /// + /// Public default constructor. + /// + public LabelStyle() + { + _font = _fontCache.DefaultFont; + } + + /// + /// Public constructor. + /// + /// Axis which owns the grid. + internal LabelStyle(Axis axis) + : this() + { + _axis = axis; + } + + #endregion + + #region Axis labels drawing methods + + /// + /// Draws axis labels on the circular chart area. + /// + /// Reference to the Chart Graphics object. + internal void PaintCircular( ChartGraphics graph ) + { + // Label string drawing format + using (StringFormat format = new StringFormat()) + { + format.FormatFlags |= StringFormatFlags.LineLimit; + format.Trimming = StringTrimming.EllipsisCharacter; + + // Labels are disabled for this axis + if (!_axis.LabelStyle.Enabled) + return; + + // Draw text with anti-aliasing + /* + if( (graph.AntiAliasing & AntiAliasing.Text) == AntiAliasing.Text ) + { + graph.TextRenderingHint = TextRenderingHint.AntiAlias; + } + else + { + graph.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; + } + */ + + // Gets axis labels style + CircularAxisLabelsStyle labelsStyle = this._axis.ChartArea.GetCircularAxisLabelsStyle(); + + // Get list of circular axes with labels + ArrayList circularAxes = this._axis.ChartArea.GetCircularAxisList(); + + // Draw each axis label + int index = 0; + foreach (CircularChartAreaAxis circAxis in circularAxes) + { + if (circAxis.Title.Length > 0) + { + //****************************************************************** + //** Calculate label position corner position + //****************************************************************** + PointF labelRelativePosition = new PointF( + this._axis.ChartArea.circularCenter.X, + this._axis.ChartArea.PlotAreaPosition.Y); + + // Adjust labels Y position + labelRelativePosition.Y -= _axis.markSize + Axis.elementSpacing; + + // Convert to absolute + PointF[] labelPosition = new PointF[] { graph.GetAbsolutePoint(labelRelativePosition) }; + + // Get label rotation angle + float labelAngle = circAxis.AxisPosition; + ICircularChartType chartType = this._axis.ChartArea.GetCircularChartType(); + if (chartType != null && chartType.XAxisCrossingSupported()) + { + if (!double.IsNaN(this._axis.ChartArea.AxisX.Crossing)) + { + labelAngle += (float)this._axis.ChartArea.AxisX.Crossing; + } + } + + // Make sure angle is presented as a positive number + while (labelAngle < 0) + { + labelAngle = 360f + labelAngle; + } + + // Set graphics rotation matrix + Matrix newMatrix = new Matrix(); + newMatrix.RotateAt(labelAngle, graph.GetAbsolutePoint(this._axis.ChartArea.circularCenter)); + newMatrix.TransformPoints(labelPosition); + + // Set text alignment + format.LineAlignment = StringAlignment.Center; + format.Alignment = StringAlignment.Near; + if (labelsStyle != CircularAxisLabelsStyle.Radial) + { + if (labelAngle < 5f || labelAngle > 355f) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Far; + } + if (labelAngle < 185f && labelAngle > 175f) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Near; + } + if (labelAngle > 185f && labelAngle < 355f) + { + format.Alignment = StringAlignment.Far; + } + } + else + { + if (labelAngle > 180f) + { + format.Alignment = StringAlignment.Far; + } + } + + + // Set text rotation angle + float textAngle = labelAngle; + if (labelsStyle == CircularAxisLabelsStyle.Radial) + { + if (labelAngle > 180) + { + textAngle += 90f; + } + else + { + textAngle -= 90f; + } + } + else if (labelsStyle == CircularAxisLabelsStyle.Circular) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Far; + } + + // Set text rotation matrix + Matrix oldMatrix = graph.Transform; + if (labelsStyle == CircularAxisLabelsStyle.Radial || labelsStyle == CircularAxisLabelsStyle.Circular) + { + Matrix textRotationMatrix = oldMatrix.Clone(); + textRotationMatrix.RotateAt(textAngle, labelPosition[0]); + graph.Transform = textRotationMatrix; + } + + // Get axis titl (label) color + Color labelColor = _foreColor; + if (!circAxis.TitleForeColor.IsEmpty) + { + labelColor = circAxis.TitleForeColor; + } + + // Draw label + using (Brush brush = new SolidBrush(labelColor)) + { + graph.DrawString( + circAxis.Title.Replace("\\n", "\n"), + (_axis.autoLabelFont == null) ? _font : _axis.autoLabelFont, + brush, + labelPosition[0], + format); + } + + // Process selection region + if (this._axis.Common.ProcessModeRegions) + { + SizeF size = graph.MeasureString(circAxis.Title.Replace("\\n", "\n"), (_axis.autoLabelFont == null) ? _font : _axis.autoLabelFont); + RectangleF labelRect = GetLabelPosition( + labelPosition[0], + size, + format); + PointF[] points = new PointF[] + { + labelRect.Location, + new PointF(labelRect.Right, labelRect.Y), + new PointF(labelRect.Right, labelRect.Bottom), + new PointF(labelRect.X, labelRect.Bottom) + }; + + using (GraphicsPath path = new GraphicsPath()) + { + path.AddPolygon(points); + path.CloseAllFigures(); + path.Transform(graph.Transform); + this._axis.Common.HotRegionsList.AddHotRegion( + path, + false, + ChartElementType.AxisLabels, + circAxis.Title); + } + } + + // Restore graphics + if(labelsStyle == CircularAxisLabelsStyle.Radial || labelsStyle == CircularAxisLabelsStyle.Circular) + { + graph.Transform = oldMatrix; + } + } + + ++index; + } + } + + } + + /// + /// Gets rectangle position of the label. + /// + /// Original label position. + /// Label text size. + /// Label string format. + /// Label rectangle position. + internal static RectangleF GetLabelPosition( + PointF position, + SizeF size, + StringFormat format) + { + // Calculate label position rectangle + RectangleF labelPosition = RectangleF.Empty; + labelPosition.Width = size.Width; + labelPosition.Height = size.Height; + + if(format.Alignment == StringAlignment.Far) + { + labelPosition.X = position.X - size.Width; + } + else if(format.Alignment == StringAlignment.Near) + { + labelPosition.X = position.X; + } + else if(format.Alignment == StringAlignment.Center) + { + labelPosition.X = position.X - size.Width/2F; + } + + if(format.LineAlignment == StringAlignment.Far) + { + labelPosition.Y = position.Y - size.Height; + } + else if(format.LineAlignment == StringAlignment.Near) + { + labelPosition.Y = position.Y; + } + else if(format.LineAlignment == StringAlignment.Center) + { + labelPosition.Y = position.Y - size.Height/2F; + } + + return labelPosition; + } + + /// + /// Draws axis labels. + /// + /// Reference to the Chart Graphics object. + /// Back elements of the axis should be drawn in 3D scene. + internal void Paint( ChartGraphics graph, bool backElements ) + { + // Label string drawing format + using (StringFormat format = new StringFormat()) + { + format.FormatFlags |= StringFormatFlags.LineLimit; + format.Trimming = StringTrimming.EllipsisCharacter; + + // Labels are disabled for this axis + if (!_axis.LabelStyle.Enabled) + return; + // deliant fix-> VSTS #157848, #143286 - drawing custom label in empty axis + if (Double.IsNaN(_axis.ViewMinimum) || Double.IsNaN(_axis.ViewMaximum)) + return; + + + // Draw labels in 3D space + if (this._axis.ChartArea.Area3DStyle.Enable3D && !this._axis.ChartArea.chartAreaIsCurcular) + { + this.Paint3D(graph, backElements); + return; + } + + // Initialize all labels position rectangle + RectangleF rectLabels = _axis.ChartArea.Position.ToRectangleF(); + float labelSize = _axis.labelSize; + + if (_axis.AxisPosition == AxisPosition.Left) + { + rectLabels.Width = labelSize; + if (_axis.GetIsMarksNextToAxis()) + rectLabels.X = (float)_axis.GetAxisPosition(); + else + rectLabels.X = _axis.PlotAreaPosition.X; + + rectLabels.X -= labelSize + _axis.markSize; + + // Set label text alignment + format.Alignment = StringAlignment.Far; + format.LineAlignment = StringAlignment.Center; + } + else if (_axis.AxisPosition == AxisPosition.Right) + { + rectLabels.Width = labelSize; + if (_axis.GetIsMarksNextToAxis()) + rectLabels.X = (float)_axis.GetAxisPosition(); + else + rectLabels.X = _axis.PlotAreaPosition.Right; + rectLabels.X += _axis.markSize; + + // Set label text alignment + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + } + else if (_axis.AxisPosition == AxisPosition.Top) + { + rectLabels.Height = labelSize; + if (_axis.GetIsMarksNextToAxis()) + rectLabels.Y = (float)_axis.GetAxisPosition(); + else + rectLabels.Y = _axis.PlotAreaPosition.Y; + rectLabels.Y -= labelSize + _axis.markSize; + + // Set label text alignment + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Far; + } + else if (_axis.AxisPosition == AxisPosition.Bottom) + { + rectLabels.Height = labelSize; + if (_axis.GetIsMarksNextToAxis()) + rectLabels.Y = (float)_axis.GetAxisPosition(); + else + rectLabels.Y = _axis.PlotAreaPosition.Bottom; + rectLabels.Y += _axis.markSize; + + // Set label text alignment + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Near; + } + + // Calculate bounding rectangle + RectangleF boundaryRect = rectLabels; + if (boundaryRect != RectangleF.Empty && _axis.totlaGroupingLabelsSize > 0) + { + if (_axis.AxisPosition == AxisPosition.Left) + { + boundaryRect.X += _axis.totlaGroupingLabelsSize; + boundaryRect.Width -= _axis.totlaGroupingLabelsSize; + } + else if (_axis.AxisPosition == AxisPosition.Right) + { + boundaryRect.Width -= _axis.totlaGroupingLabelsSize; + } + else if (_axis.AxisPosition == AxisPosition.Top) + { + boundaryRect.Y += _axis.totlaGroupingLabelsSize; + boundaryRect.Height -= _axis.totlaGroupingLabelsSize; + } + else if (_axis.AxisPosition == AxisPosition.Bottom) + { + boundaryRect.Height -= _axis.totlaGroupingLabelsSize; + } + } + + // Check if the AJAX zooming and scrolling mode is enabled. + // Labels are drawn slightly different in this case. + bool ajaxScrollingEnabled = false; + bool firstFrame = true; + bool lastFrame = true; + + // Draw all labels from the collection + int labelIndex = 0; + foreach (CustomLabel label in this._axis.CustomLabels) + { + bool truncatedLeft = false; + bool truncatedRight = false; + double labelFrom = label.FromPosition; + double labelTo = label.ToPosition; + bool useRelativeCoordiantes = false; + double labelFromRelative = double.NaN; + double labelToRelative = double.NaN; + + // Skip if label middle point is outside current scaleView + if (label.RowIndex == 0) + { + double middlePoint = (label.FromPosition + label.ToPosition) / 2.0; + decimal viewMin = (decimal)_axis.ViewMinimum; + decimal viewMax = (decimal)_axis.ViewMaximum; + + if (ajaxScrollingEnabled) + { + // Skip very first and last labels if they are partialy outside the scaleView + if (firstFrame) + { + if ((decimal)label.FromPosition < (decimal)_axis.Minimum) + { + continue; + } + } + if (lastFrame) + { + if ((decimal)label.ToPosition > (decimal)_axis.Maximum) + { + continue; + } + } + + // Skip label only if it is compleltly out of the scaleView + if ((decimal)label.ToPosition < viewMin || + (decimal)label.FromPosition > viewMax) + { + continue; + } + + // RecalculateAxesScale label index starting from the first frame. + // Index is used to determine position of the offset labels + if ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1)) + { + // Reset index + labelIndex = 0; + + // Get first series attached to this axis + Series axisSeries = null; + if (_axis.axisType == AxisName.X || _axis.axisType == AxisName.X2) + { + List seriesArray = _axis.ChartArea.GetXAxesSeries((_axis.axisType == AxisName.X) ? AxisType.Primary : AxisType.Secondary, _axis.SubAxisName); + if (seriesArray.Count > 0) + { + axisSeries = _axis.Common.DataManager.Series[seriesArray[0]]; + if (axisSeries != null && !axisSeries.IsXValueIndexed) + { + axisSeries = null; + } + } + } + + // Set start position and iterate through label positions + // NOTE: Labels offset should not be taken in the account + double currentPosition = _axis.Minimum; + while (currentPosition < _axis.Maximum) + { + if (currentPosition >= middlePoint) + { + break; + } + + currentPosition += ChartHelper.GetIntervalSize(currentPosition, _axis.LabelStyle.GetInterval(), _axis.LabelStyle.GetIntervalType(), + axisSeries, 0.0, DateTimeIntervalType.Number, true); + ++labelIndex; + } + + } + } + else + { + // Skip label if label middle point is not in the scaleView + if ((decimal)middlePoint < viewMin || + (decimal)middlePoint > viewMax) + { + continue; + } + } + + + + // Make sure label To and From coordinates are processed by one scale segment based + // on the label middle point position. + if (_axis.ScaleSegments.Count > 0) + { + AxisScaleSegment scaleSegment = _axis.ScaleSegments.FindScaleSegmentForAxisValue(middlePoint); + _axis.ScaleSegments.AllowOutOfScaleValues = true; + _axis.ScaleSegments.EnforceSegment(scaleSegment); + } + + + + // Use center point instead of the To/From if label takes all scaleView + // This is done to avoid issues with labels drawing with high + // zooming levels. + if ((decimal)label.FromPosition < viewMin && + (decimal)label.ToPosition > viewMax) + { + // Indicates that chart relative coordinates should be used instead of axis values + useRelativeCoordiantes = true; + + // Calculate label From/To in relative coordinates using + // label middle point and 100% width. + labelFromRelative = _axis.GetLinearPosition(middlePoint) - 50.0; + labelToRelative = labelFromRelative + 100.0; + } + } + else + { + // Skip labels completly outside the scaleView + if (label.ToPosition <= _axis.ViewMinimum || label.FromPosition >= _axis.ViewMaximum) + { + continue; + } + + // Check if label is partially visible. + if (!ajaxScrollingEnabled && + _axis.ScaleView.IsZoomed) + { + if (label.FromPosition < _axis.ViewMinimum) + { + truncatedLeft = true; + labelFrom = _axis.ViewMinimum; + } + if (label.ToPosition > _axis.ViewMaximum) + { + truncatedRight = true; + labelTo = _axis.ViewMaximum; + } + } + } + + // Calculate single label position + RectangleF rect = rectLabels; + + // Label is in the first row + if (label.RowIndex == 0) + { + if (_axis.AxisPosition == AxisPosition.Left) + { + rect.X = rectLabels.Right - _axis.unRotatedLabelSize; + rect.Width = _axis.unRotatedLabelSize; + + // Adjust label rectangle if offset labels are used + if ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1)) + { + rect.Width /= 2F; + if (labelIndex % 2 != 0F) + { + rect.X += rect.Width; + } + } + } + else if (_axis.AxisPosition == AxisPosition.Right) + { + rect.Width = _axis.unRotatedLabelSize; + + // Adjust label rectangle if offset labels are used + if ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1)) + { + rect.Width /= 2F; + if (labelIndex % 2 != 0F) + { + rect.X += rect.Width; + } + } + } + else if (_axis.AxisPosition == AxisPosition.Top) + { + rect.Y = rectLabels.Bottom - _axis.unRotatedLabelSize; + rect.Height = _axis.unRotatedLabelSize; + + // Adjust label rectangle if offset labels are used + if ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1)) + { + rect.Height /= 2F; + if (labelIndex % 2 != 0F) + { + rect.Y += rect.Height; + } + } + } + else if (_axis.AxisPosition == AxisPosition.Bottom) + { + rect.Height = _axis.unRotatedLabelSize; + + // Adjust label rectangle if offset labels are used + if ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1)) + { + rect.Height /= 2F; + if (labelIndex % 2 != 0F) + { + rect.Y += rect.Height; + } + } + } + + // Increase label index + ++labelIndex; + } + + // Label is in the second row + else if (label.RowIndex > 0) + { + if (_axis.AxisPosition == AxisPosition.Left) + { + rect.X += _axis.totlaGroupingLabelsSizeAdjustment; + for (int index = _axis.groupingLabelSizes.Length; index > label.RowIndex; index--) + { + rect.X += _axis.groupingLabelSizes[index - 1]; + } + rect.Width = _axis.groupingLabelSizes[label.RowIndex - 1]; + } + else if (_axis.AxisPosition == AxisPosition.Right) + { + rect.X = rect.Right - _axis.totlaGroupingLabelsSize - _axis.totlaGroupingLabelsSizeAdjustment;// + Axis.elementSpacing * 0.25f; + for (int index = 1; index < label.RowIndex; index++) + { + rect.X += _axis.groupingLabelSizes[index - 1]; + } + rect.Width = _axis.groupingLabelSizes[label.RowIndex - 1]; + } + else if (_axis.AxisPosition == AxisPosition.Top) + { + rect.Y += _axis.totlaGroupingLabelsSizeAdjustment; + for (int index = _axis.groupingLabelSizes.Length; index > label.RowIndex; index--) + { + rect.Y += _axis.groupingLabelSizes[index - 1]; + } + rect.Height = _axis.groupingLabelSizes[label.RowIndex - 1]; + } + if (_axis.AxisPosition == AxisPosition.Bottom) + { + rect.Y = rect.Bottom - _axis.totlaGroupingLabelsSize - _axis.totlaGroupingLabelsSizeAdjustment; + for (int index = 1; index < label.RowIndex; index++) + { + rect.Y += _axis.groupingLabelSizes[index - 1]; + } + rect.Height = _axis.groupingLabelSizes[label.RowIndex - 1]; + } + } + + // Unknown label row value + else + { + throw (new InvalidOperationException(SR.ExceptionAxisLabelIndexIsNegative)); + } + + // Set label From and To coordinates + double fromPosition = _axis.GetLinearPosition(labelFrom); + double toPosition = _axis.GetLinearPosition(labelTo); + if (useRelativeCoordiantes) + { + useRelativeCoordiantes = false; + fromPosition = labelFromRelative; + toPosition = labelToRelative; + } + + if (_axis.AxisPosition == AxisPosition.Top || _axis.AxisPosition == AxisPosition.Bottom) + { + rect.X = (float)Math.Min(fromPosition, toPosition); + rect.Width = (float)Math.Max(fromPosition, toPosition) - rect.X; + + // Adjust label To/From position if offset labels are used + if (label.RowIndex == 0 && + ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1))) + { + rect.X -= rect.Width / 2F; + rect.Width *= 2F; + } + } + else + { + rect.Y = (float)Math.Min(fromPosition, toPosition); + rect.Height = (float)Math.Max(fromPosition, toPosition) - rect.Y; + + // Adjust label To/From position if offset labels are used + if (label.RowIndex == 0 && + ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1))) + { + rect.Y -= rect.Height / 2F; + rect.Height *= 2F; + } + } + + // Draw label + using (Brush brush = new SolidBrush((label.ForeColor.IsEmpty) ? _foreColor : label.ForeColor)) + { + graph.DrawLabelStringRel(_axis, + label.RowIndex, + label.LabelMark, + label.MarkColor, + label.Text, + label.Image, + label.ImageTransparentColor, + (_axis.autoLabelFont == null) ? _font : _axis.autoLabelFont, + brush, + rect, + format, + (_axis.autoLabelAngle < -90) ? angle : _axis.autoLabelAngle, + (!this.TruncatedLabels || label.RowIndex > 0) ? RectangleF.Empty : boundaryRect, + label, + truncatedLeft, + truncatedRight); + } + + // Clear scale segment enforcement + _axis.ScaleSegments.EnforceSegment(null); + _axis.ScaleSegments.AllowOutOfScaleValues = false; + } + } + } + + #endregion + + #region 3D Axis labels drawing methods + + /// + /// Get a rectangle between chart area position and plotting area on specified side. + /// Also sets axis labels string formatting for the specified labels position. + /// + /// Chart area object. + /// Position in chart area. + /// Axis labels string format. + /// Axis labels rectangle. + private RectangleF GetAllLabelsRect(ChartArea area, AxisPosition position, StringFormat stringFormat) + { + // Find axis with same position + Axis labelsAxis = null; + foreach(Axis curAxis in area.Axes) + { + if(curAxis.AxisPosition == position) + { + labelsAxis = curAxis; + break; + } + } + + if(labelsAxis == null) + { + return RectangleF.Empty; + } + + // Calculate rect for different positions + RectangleF rectLabels = area.Position.ToRectangleF(); + if( position == AxisPosition.Left ) + { + rectLabels.Width = labelsAxis.labelSize; + if( labelsAxis.GetIsMarksNextToAxis() ) + { + rectLabels.X = (float)labelsAxis.GetAxisPosition(); + rectLabels.Width = (float)Math.Max(rectLabels.Width, rectLabels.X - labelsAxis.PlotAreaPosition.X); + } + else + { + rectLabels.X = labelsAxis.PlotAreaPosition.X; + } + + rectLabels.X -= rectLabels.Width; + + if(area.IsSideSceneWallOnLeft() || area.Area3DStyle.WallWidth == 0) + { + rectLabels.X -= labelsAxis.markSize; + } + + // Set label text alignment + stringFormat.Alignment = StringAlignment.Far; + stringFormat.LineAlignment = StringAlignment.Center; + } + else if( position == AxisPosition.Right ) + { + rectLabels.Width = labelsAxis.labelSize; + if( labelsAxis.GetIsMarksNextToAxis() ) + { + rectLabels.X = (float)labelsAxis.GetAxisPosition(); + rectLabels.Width = (float)Math.Max(rectLabels.Width, labelsAxis.PlotAreaPosition.Right - rectLabels.X); + } + else + { + rectLabels.X = labelsAxis.PlotAreaPosition.Right; + } + + if(!area.IsSideSceneWallOnLeft() || area.Area3DStyle.WallWidth == 0) + { + rectLabels.X += labelsAxis.markSize; + } + + // Set label text alignment + stringFormat.Alignment = StringAlignment.Near; + stringFormat.LineAlignment = StringAlignment.Center; + } + else if( position == AxisPosition.Top ) + { + rectLabels.Height = labelsAxis.labelSize; + if( labelsAxis.GetIsMarksNextToAxis() ) + { + rectLabels.Y = (float)labelsAxis.GetAxisPosition(); + rectLabels.Height = (float)Math.Max(rectLabels.Height, rectLabels.Y - labelsAxis.PlotAreaPosition.Y); + } + else + { + rectLabels.Y = labelsAxis.PlotAreaPosition.Y; + } + + rectLabels.Y -= rectLabels.Height; + + if(area.Area3DStyle.WallWidth == 0) + { + rectLabels.Y -= labelsAxis.markSize; + } + + // Set label text alignment + stringFormat.Alignment = StringAlignment.Center; + stringFormat.LineAlignment = StringAlignment.Far; + } + else if( position == AxisPosition.Bottom ) + { + rectLabels.Height = labelsAxis.labelSize; + if( labelsAxis.GetIsMarksNextToAxis() ) + { + rectLabels.Y = (float)labelsAxis.GetAxisPosition(); + rectLabels.Height = (float)Math.Max(rectLabels.Height, labelsAxis.PlotAreaPosition.Bottom - rectLabels.Y); + } + else + { + rectLabels.Y = labelsAxis.PlotAreaPosition.Bottom; + } + rectLabels.Y += labelsAxis.markSize; + + // Set label text alignment + stringFormat.Alignment = StringAlignment.Center; + stringFormat.LineAlignment = StringAlignment.Near; + } + + return rectLabels; + } + + /// + /// Gets position of axis labels. + /// Top and Bottom axis labels can be drawn on the sides (left or right) + /// of the plotting area. If angle between axis and it's projection is + /// between -25 and 25 degrees the axis are drawn at the bottom/top, + /// otherwise labels are moved on the left or right side. + /// + /// Axis object. + /// Position where axis labels should be drawn. + private AxisPosition GetLabelsPosition(Axis axis) + { + // Get angle between 2D axis and it's 3D projection. + double axisAngle = axis.GetAxisProjectionAngle(); + + // Pick the side to draw the labels on + if(axis.AxisPosition == AxisPosition.Bottom) + { + if(axisAngle <= -25 ) + return AxisPosition.Right; + else if(axisAngle >= 25 ) + return AxisPosition.Left; + } + else if(axis.AxisPosition == AxisPosition.Top) + { + if(axisAngle <= -25 ) + return AxisPosition.Left; + else if(axisAngle >= 25 ) + return AxisPosition.Right; + } + + // Labels are on the same side as the axis + return axis.AxisPosition; + } + + /// + /// Draws axis labels in 3D space. + /// + /// Reference to the Chart Graphics object. + /// Back elements of the axis should be drawn in 3D scene. + internal void Paint3D( ChartGraphics graph, bool backElements ) + { + // Label string drawing format + using (StringFormat format = new StringFormat()) + { + format.Trimming = StringTrimming.EllipsisCharacter; + + // Calculate single pixel size in relative coordinates + SizeF pixelSize = graph.GetRelativeSize(new SizeF(1f, 1f)); + + //******************************************************************** + //** Determine the side of the plotting area to draw the labels on. + //******************************************************************** + AxisPosition labelsPosition = GetLabelsPosition(_axis); + + //***************************************************************** + //** Set the labels Z position + //***************************************************************** + bool axisOnEdge; + float labelsZPosition = _axis.GetMarksZPosition(out axisOnEdge); + + // Adjust Z position for the "bent" tick marks + bool adjustForWallWidth = false; + if (this._axis.AxisPosition == AxisPosition.Top && + !this._axis.ChartArea.ShouldDrawOnSurface(SurfaceNames.Top, backElements, false)) + { + adjustForWallWidth = true; + } + if (this._axis.AxisPosition == AxisPosition.Left && + !this._axis.ChartArea.ShouldDrawOnSurface(SurfaceNames.Left, backElements, false)) + { + adjustForWallWidth = true; + } + if (this._axis.AxisPosition == AxisPosition.Right && + !this._axis.ChartArea.ShouldDrawOnSurface(SurfaceNames.Right, backElements, false)) + { + adjustForWallWidth = true; + } + + if (adjustForWallWidth && this._axis.ChartArea.Area3DStyle.WallWidth > 0) + { + if (this._axis.MajorTickMark.TickMarkStyle == TickMarkStyle.InsideArea) + { + labelsZPosition -= this._axis.ChartArea.areaSceneWallWidth.Width; + } + else if (this._axis.MajorTickMark.TickMarkStyle == TickMarkStyle.OutsideArea) + { + labelsZPosition -= this._axis.MajorTickMark.Size + this._axis.ChartArea.areaSceneWallWidth.Width; + } + else if (this._axis.MajorTickMark.TickMarkStyle == TickMarkStyle.AcrossAxis) + { + labelsZPosition -= this._axis.MajorTickMark.Size / 2f + this._axis.ChartArea.areaSceneWallWidth.Width; + } + } + + //***************************************************************** + //** Check if labels should be drawn as back or front element. + //***************************************************************** + bool labelsInsidePlotArea = (this._axis.GetIsMarksNextToAxis() && !axisOnEdge); + if (backElements == labelsInsidePlotArea) + { + // Skip drawing + return; + } + + //******************************************************************** + //** Initialize all labels position rectangle + //******************************************************************** + RectangleF rectLabels = this.GetAllLabelsRect(this._axis.ChartArea, this._axis.AxisPosition, format); + + //******************************************************************** + //** Calculate bounding rectangle used to truncate labels on the + //** chart area boundary if TruncatedLabels property is set to true. + //******************************************************************** + RectangleF boundaryRect = rectLabels; + if (boundaryRect != RectangleF.Empty && _axis.totlaGroupingLabelsSize > 0) + { + if (this._axis.AxisPosition == AxisPosition.Left) + { + boundaryRect.X += _axis.totlaGroupingLabelsSize; + boundaryRect.Width -= _axis.totlaGroupingLabelsSize; + } + else if (this._axis.AxisPosition == AxisPosition.Right) + { + boundaryRect.Width -= _axis.totlaGroupingLabelsSize; + } + else if (this._axis.AxisPosition == AxisPosition.Top) + { + boundaryRect.Y += _axis.totlaGroupingLabelsSize; + boundaryRect.Height -= _axis.totlaGroupingLabelsSize; + } + else if (this._axis.AxisPosition == AxisPosition.Bottom) + { + boundaryRect.Height -= _axis.totlaGroupingLabelsSize; + } + } + + // Pre-calculated height of the first labels row + float firstLabelsRowHeight = -1f; + + // For 3D axis labels the first row of labels + // has to be drawn after all other rows because + // of hot regions. + for (int selectionRow = 0; selectionRow <= this._axis.GetGroupLabelLevelCount(); selectionRow++) + { + //******************************************************************** + //** Draw all labels from the collection + //******************************************************************** + int labelIndex = 0; + foreach (CustomLabel label in this._axis.CustomLabels) + { + bool truncatedLeft = false; + bool truncatedRight = false; + double labelFrom = label.FromPosition; + double labelTo = label.ToPosition; + + if (label.RowIndex != selectionRow) + { + continue; + } + + // Skip if label middle point is outside current scaleView + if (label.RowIndex == 0) + { + double middlePoint = (label.FromPosition + label.ToPosition) / 2.0; + if ((decimal)middlePoint < (decimal)_axis.ViewMinimum || + (decimal)middlePoint > (decimal)_axis.ViewMaximum) + { + continue; + } + } + else + { + // Skip labels completly outside the scaleView + if (label.ToPosition <= _axis.ViewMinimum || label.FromPosition >= _axis.ViewMaximum) + { + continue; + } + + // Check if label is partially visible + if (_axis.ScaleView.IsZoomed) + { + if (label.FromPosition < _axis.ViewMinimum) + { + truncatedLeft = true; + labelFrom = _axis.ViewMinimum; + } + if (label.ToPosition > _axis.ViewMaximum) + { + truncatedRight = true; + labelTo = _axis.ViewMaximum; + } + } + } + + + // Calculate single label position + RectangleF rect = rectLabels; + + // Label is in the first row + if (label.RowIndex == 0) + { + if (this._axis.AxisPosition == AxisPosition.Left) + { + if (!this._axis.GetIsMarksNextToAxis()) + { + rect.X = rectLabels.Right - _axis.unRotatedLabelSize; + rect.Width = _axis.unRotatedLabelSize; + } + + // Adjust label rectangle if offset labels are used + if ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1)) + { + rect.Width /= 2F; + if (labelIndex % 2 != 0F) + { + rect.X += rect.Width; + } + } + } + else if (this._axis.AxisPosition == AxisPosition.Right) + { + if (!this._axis.GetIsMarksNextToAxis()) + { + rect.Width = _axis.unRotatedLabelSize; + } + + // Adjust label rectangle if offset labels are used + if ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1)) + { + rect.Width /= 2F; + if (labelIndex % 2 != 0F) + { + rect.X += rect.Width; + } + } + } + else if (this._axis.AxisPosition == AxisPosition.Top) + { + if (!this._axis.GetIsMarksNextToAxis()) + { + rect.Y = rectLabels.Bottom - _axis.unRotatedLabelSize; + rect.Height = _axis.unRotatedLabelSize; + } + + // Adjust label rectangle if offset labels are used + if ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1)) + { + rect.Height /= 2F; + if (labelIndex % 2 != 0F) + { + rect.Y += rect.Height; + } + } + } + else if (this._axis.AxisPosition == AxisPosition.Bottom) + { + if (!this._axis.GetIsMarksNextToAxis()) + { + rect.Height = _axis.unRotatedLabelSize; + } + + // Adjust label rectangle if offset labels are used + if ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1)) + { + rect.Height /= 2F; + if (labelIndex % 2 != 0F) + { + rect.Y += rect.Height; + } + } + } + + // Increase label index + ++labelIndex; + } + + // Label is in the second row + else if (label.RowIndex > 0) + { + // Hide grouping labels (where index of row > 0) when they are displayed + // not on the same side as their axis. Fixes MS issue #64. + if (labelsPosition != this._axis.AxisPosition) + { + continue; + } + + if (_axis.AxisPosition == AxisPosition.Left) + { + rect.X += _axis.totlaGroupingLabelsSizeAdjustment; + for (int index = _axis.groupingLabelSizes.Length; index > label.RowIndex; index--) + { + rect.X += _axis.groupingLabelSizes[index - 1]; + } + rect.Width = _axis.groupingLabelSizes[label.RowIndex - 1]; + } + else if (_axis.AxisPosition == AxisPosition.Right) + { + rect.X = rect.Right - _axis.totlaGroupingLabelsSize - _axis.totlaGroupingLabelsSizeAdjustment;// + Axis.elementSpacing * 0.25f; + for (int index = 1; index < label.RowIndex; index++) + { + rect.X += _axis.groupingLabelSizes[index - 1]; + } + rect.Width = _axis.groupingLabelSizes[label.RowIndex - 1]; + } + else if (_axis.AxisPosition == AxisPosition.Top) + { + rect.Y += _axis.totlaGroupingLabelsSizeAdjustment; + for (int index = _axis.groupingLabelSizes.Length; index > label.RowIndex; index--) + { + rect.Y += _axis.groupingLabelSizes[index - 1]; + } + rect.Height = _axis.groupingLabelSizes[label.RowIndex - 1]; + } + if (_axis.AxisPosition == AxisPosition.Bottom) + { + rect.Y = rect.Bottom - _axis.totlaGroupingLabelsSize - _axis.totlaGroupingLabelsSizeAdjustment; + for (int index = 1; index < label.RowIndex; index++) + { + rect.Y += _axis.groupingLabelSizes[index - 1]; + } + rect.Height = _axis.groupingLabelSizes[label.RowIndex - 1]; + } + } + + // Unknown label row value + else + { + throw (new InvalidOperationException(SR.ExceptionAxisLabelRowIndexMustBe1Or2)); + } + + //******************************************************************** + //** Set label From and To coordinates. + //******************************************************************** + double fromPosition = _axis.GetLinearPosition(labelFrom); + double toPosition = _axis.GetLinearPosition(labelTo); + if (this._axis.AxisPosition == AxisPosition.Top || this._axis.AxisPosition == AxisPosition.Bottom) + { + rect.X = (float)Math.Min(fromPosition, toPosition); + rect.Width = (float)Math.Max(fromPosition, toPosition) - rect.X; + if (rect.Width < pixelSize.Width) + { + rect.Width = pixelSize.Width; + } + + // Adjust label To/From position if offset labels are used + if (label.RowIndex == 0 && + ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1))) + { + rect.X -= rect.Width / 2F; + rect.Width *= 2F; + } + } + else + { + rect.Y = (float)Math.Min(fromPosition, toPosition); + rect.Height = (float)Math.Max(fromPosition, toPosition) - rect.Y; + if (rect.Height < pixelSize.Height) + { + rect.Height = pixelSize.Height; + } + + // Adjust label To/From position if offset labels are used + if (label.RowIndex == 0 && + ((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1))) + { + rect.Y -= rect.Height / 2F; + rect.Height *= 2F; + } + } + + // Save original rect + RectangleF initialRect = new RectangleF(rect.Location, rect.Size); + + //******************************************************************** + //** Transform and adjust label rectangle coordinates in 3D space. + //******************************************************************** + Point3D[] rectPoints = new Point3D[3]; + if (this._axis.AxisPosition == AxisPosition.Left) + { + rectPoints[0] = new Point3D(rect.Right, rect.Y, labelsZPosition); + rectPoints[1] = new Point3D(rect.Right, rect.Y + rect.Height / 2f, labelsZPosition); + rectPoints[2] = new Point3D(rect.Right, rect.Bottom, labelsZPosition); + this._axis.ChartArea.matrix3D.TransformPoints(rectPoints); + rect.Y = rectPoints[0].Y; + rect.Height = rectPoints[2].Y - rect.Y; + rect.Width = rectPoints[1].X - rect.X; + } + else if (this._axis.AxisPosition == AxisPosition.Right) + { + rectPoints[0] = new Point3D(rect.X, rect.Y, labelsZPosition); + rectPoints[1] = new Point3D(rect.X, rect.Y + rect.Height / 2f, labelsZPosition); + rectPoints[2] = new Point3D(rect.X, rect.Bottom, labelsZPosition); + this._axis.ChartArea.matrix3D.TransformPoints(rectPoints); + rect.Y = rectPoints[0].Y; + rect.Height = rectPoints[2].Y - rect.Y; + rect.Width = rect.Right - rectPoints[1].X; + rect.X = rectPoints[1].X; + } + else if (this._axis.AxisPosition == AxisPosition.Top) + { + // Transform 3 points of the rectangle + rectPoints[0] = new Point3D(rect.X, rect.Bottom, labelsZPosition); + rectPoints[1] = new Point3D(rect.X + rect.Width / 2f, rect.Bottom, labelsZPosition); + rectPoints[2] = new Point3D(rect.Right, rect.Bottom, labelsZPosition); + this._axis.ChartArea.matrix3D.TransformPoints(rectPoints); + + if (labelsPosition == AxisPosition.Top) + { + rect.X = rectPoints[0].X; + rect.Width = rectPoints[2].X - rect.X; + rect.Height = rectPoints[1].Y - rect.Y; + } + else if (labelsPosition == AxisPosition.Right) + { + RectangleF rightLabelsRect = this.GetAllLabelsRect(this._axis.ChartArea, labelsPosition, format); + rect.Y = rectPoints[0].Y; + rect.Height = rectPoints[2].Y - rect.Y; + rect.X = rectPoints[1].X; + rect.Width = rightLabelsRect.Right - rect.X; + } + else if (labelsPosition == AxisPosition.Left) + { + RectangleF rightLabelsRect = this.GetAllLabelsRect(this._axis.ChartArea, labelsPosition, format); + rect.Y = rectPoints[2].Y; + rect.Height = rectPoints[0].Y - rect.Y; + rect.X = rightLabelsRect.X; + rect.Width = rectPoints[1].X - rightLabelsRect.X; + } + } + else if (this._axis.AxisPosition == AxisPosition.Bottom) + { + // Transform 3 points of the rectangle + rectPoints[0] = new Point3D(rect.X, rect.Y, labelsZPosition); + rectPoints[1] = new Point3D(rect.X + rect.Width / 2f, rect.Y, labelsZPosition); + rectPoints[2] = new Point3D(rect.Right, rect.Y, labelsZPosition); + this._axis.ChartArea.matrix3D.TransformPoints(rectPoints); + + if (labelsPosition == AxisPosition.Bottom) + { + rect.X = rectPoints[0].X; + rect.Width = rectPoints[2].X - rect.X; + rect.Height = rect.Bottom - rectPoints[1].Y; + rect.Y = rectPoints[1].Y; + } + else if (labelsPosition == AxisPosition.Right) + { + RectangleF rightLabelsRect = this.GetAllLabelsRect(this._axis.ChartArea, labelsPosition, format); + rect.Y = rectPoints[2].Y; + rect.Height = rectPoints[0].Y - rect.Y; + rect.X = rectPoints[1].X; + rect.Width = rightLabelsRect.Right - rect.X; + + // Adjust label rect by shifting it down by quarter of the tick size + if (this._axis.autoLabelAngle == 0) + { + rect.Y += this._axis.markSize / 4f; + } + } + else if (labelsPosition == AxisPosition.Left) + { + RectangleF rightLabelsRect = this.GetAllLabelsRect(this._axis.ChartArea, labelsPosition, format); + rect.Y = rectPoints[0].Y; + rect.Height = rectPoints[2].Y - rect.Y; + rect.X = rightLabelsRect.X; + rect.Width = rectPoints[1].X - rightLabelsRect.X; + + // Adjust label rect by shifting it down by quarter of the tick size + if (this._axis.autoLabelAngle == 0) + { + rect.Y += this._axis.markSize / 4f; + } + } + } + + // Find axis with same position + Axis labelsAxis = null; + foreach (Axis curAxis in this._axis.ChartArea.Axes) + { + if (curAxis.AxisPosition == labelsPosition) + { + labelsAxis = curAxis; + break; + } + } + + //******************************************************************** + //** Adjust font angles for Top and Bottom axis + //******************************************************************** + int labelsFontAngle = (_axis.autoLabelAngle < -90) ? angle : _axis.autoLabelAngle; + if (labelsPosition != this._axis.AxisPosition) + { + if ((this._axis.AxisPosition == AxisPosition.Top || this._axis.AxisPosition == AxisPosition.Bottom) && + (labelsFontAngle == 90 || labelsFontAngle == -90)) + { + labelsFontAngle = 0; + } + else if (this._axis.AxisPosition == AxisPosition.Bottom) + { + if (labelsPosition == AxisPosition.Left && labelsFontAngle > 0) + { + labelsFontAngle = -labelsFontAngle; + } + else if (labelsPosition == AxisPosition.Right && labelsFontAngle < 0) + { + labelsFontAngle = -labelsFontAngle; + } + } + else if (this._axis.AxisPosition == AxisPosition.Top) + { + if (labelsPosition == AxisPosition.Left && labelsFontAngle < 0) + { + labelsFontAngle = -labelsFontAngle; + } + else if (labelsPosition == AxisPosition.Right && labelsFontAngle > 0) + { + labelsFontAngle = -labelsFontAngle; + } + } + } + + //******************************************************************** + //** NOTE: Code below improves chart labels readability in scenarios + //** described in MS issue #65. + //** + //** Prevent labels in the first row from overlapping the grouping + //** labels in the rows below. The solution only apply to the limited + //** use cases defined by the condition below. + //******************************************************************** + StringFormatFlags oldFormatFlags = format.FormatFlags; + + if (label.RowIndex == 0 && + labelsFontAngle == 0 && + _axis.groupingLabelSizes != null && + _axis.groupingLabelSizes.Length > 0 && + this._axis.AxisPosition == AxisPosition.Bottom && + labelsPosition == AxisPosition.Bottom && + !((this._axis.autoLabelOffset == -1) ? this.IsStaggered : (this._axis.autoLabelOffset == 1))) + { + if (firstLabelsRowHeight == -1f) + { + // Calculate first labels row max height + Point3D[] labelPositionPoints = new Point3D[1]; + labelPositionPoints[0] = new Point3D(initialRect.X, initialRect.Bottom - _axis.totlaGroupingLabelsSize - _axis.totlaGroupingLabelsSizeAdjustment, labelsZPosition); + this._axis.ChartArea.matrix3D.TransformPoints(labelPositionPoints); + + float height = labelPositionPoints[0].Y - rect.Y; + + firstLabelsRowHeight = (height > 0f) ? height : rect.Height; + } + + // Resuse pre-calculated first labels row height + rect.Height = firstLabelsRowHeight; + + // Change current string format to prevent strings to go out of the + // specified bounding rectangle + if ((format.FormatFlags & StringFormatFlags.LineLimit) == 0) + { + format.FormatFlags |= StringFormatFlags.LineLimit; + } + } + + + //******************************************************************** + //** Draw label text. + //******************************************************************** + + using (Brush brush = new SolidBrush((label.ForeColor.IsEmpty) ? _foreColor : label.ForeColor)) + { + graph.DrawLabelStringRel( + labelsAxis, + label.RowIndex, + label.LabelMark, + label.MarkColor, + label.Text, + label.Image, + label.ImageTransparentColor, + (_axis.autoLabelFont == null) ? _font : _axis.autoLabelFont, + brush, + rect, + format, + labelsFontAngle, + (!this.TruncatedLabels || label.RowIndex > 0) ? RectangleF.Empty : boundaryRect, + label, + truncatedLeft, + truncatedRight); + } + + // Restore old string format that was temporary modified + if (format.FormatFlags != oldFormatFlags) + { + format.FormatFlags = oldFormatFlags; + } + } + } + } + } + + #endregion + + #region Helper methods + + /// + /// Sets the axis to which this object attached to. + /// + /// Axis object. + internal Axis Axis + { + set { _axis = value; } + } + + + /// + /// Invalidate chart picture + /// + internal override void Invalidate() + { +#if Microsoft_CONTROL + + if(this._axis != null) + { + this._axis.Invalidate(); + } +#endif + base.Invalidate(); + } + + #endregion + + #region Label properties + + /// + /// Gets or sets the interval offset of the label. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeLabel_IntervalOffset"), + DefaultValue(Double.NaN), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshPropertiesAttribute(RefreshProperties.All), + TypeConverter(typeof(AxisElementIntervalValueConverter)) + ] + public double IntervalOffset + { + get + { + return intervalOffset; + } + set + { + intervalOffset = value; + this.Invalidate(); + } + } + + + + /// + /// Gets the interval offset. + /// + /// + internal double GetIntervalOffset() + { + if(double.IsNaN(intervalOffset) && this._axis != null) + { + return this._axis.IntervalOffset; + } + return intervalOffset; + } + + /// + /// Gets or sets the unit of measurement of the label offset. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + DefaultValue(DateTimeIntervalType.NotSet), + SRDescription("DescriptionAttributeLabel_IntervalOffsetType"), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public DateTimeIntervalType IntervalOffsetType + { + get + { + return intervalOffsetType; + } + set + { + intervalOffsetType = value; + this.Invalidate(); + } + } + + + /// + /// Gets the type of the interval offset. + /// + /// + internal DateTimeIntervalType GetIntervalOffsetType() + { + if(intervalOffsetType == DateTimeIntervalType.NotSet && this._axis != null) + { + return this._axis.IntervalOffsetType; + } + return intervalOffsetType; + } + + /// + /// Gets or sets the interval size of the label. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + DefaultValue(Double.NaN), + SRDescription("DescriptionAttributeLabel_Interval"), + TypeConverter(typeof(AxisElementIntervalValueConverter)), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public double Interval + { + get + { + return interval; + } + set + { + interval = value; + + // Reset original property value fields + if (this._axis != null) + { + this._axis.tempLabelInterval = interval; + } + + this.Invalidate(); + } + } + + + /// + /// Gets the interval. + /// + /// + internal double GetInterval() + { + if(double.IsNaN(interval) && this._axis != null) + { + return this._axis.Interval; + } + return interval; + } + + /// + /// Gets or sets the unit of measurement of the interval size of the label. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + DefaultValue(DateTimeIntervalType.NotSet), + SRDescription("DescriptionAttributeLabel_IntervalType"), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public DateTimeIntervalType IntervalType + { + get + { + return intervalType; + } + set + { + intervalType = value; + + // Reset original property value fields + if (this._axis != null) + { + this._axis.tempLabelIntervalType = intervalType; + } + + this.Invalidate(); + } + } + + + /// + /// Gets the type of the interval. + /// + /// + internal DateTimeIntervalType GetIntervalType() + { + if(intervalType == DateTimeIntervalType.NotSet && this._axis != null) + { + return this._axis.IntervalType; + } + return intervalType; + } + + /// + /// Gets or sets the font of the label. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"), + SRDescription("DescriptionAttributeLabel_Font"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Font Font + { + get + { + return _font; + } + set + { + // Turn off labels autofitting + if (this._axis != null && this._axis.Common!=null && this._axis.Common.Chart != null) + { + if(!this._axis.Common.Chart.serializing) + { + this._axis.IsLabelAutoFit = false; + } + } + + _font = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the fore color of the label. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeFontColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color ForeColor + { + get + { + return _foreColor; + } + set + { + _foreColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a value that represents the angle at which font is drawn. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributeLabel_FontAngle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public int Angle + { + get + { + return angle; + } + set + { + if(value < -90 || value > 90) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionAxisLabelFontAngleInvalid)); + } + + // Turn of label offset if angle is not 0, 90 or -90 + if(IsStaggered && value != 0 && value != -90 && value != 90) + { + IsStaggered = false; + } + + // Turn off labels autofitting + if(this._axis != null && this._axis.Common!=null && this._axis.Common.Chart != null) + { + if (!this._axis.Common.Chart.serializing) + { + this._axis.IsLabelAutoFit = false; + } + } + + angle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a property which specifies whether the labels are shown with offset. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(false), + SRDescription("DescriptionAttributeLabel_OffsetLabels"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshPropertiesAttribute(RefreshProperties.All) + ] + public bool IsStaggered + { + get + { + return isStaggered; + } + set + { + // Make sure that angle is 0, 90 or -90 + if(value && (this.Angle != 0 || this.Angle != -90 || this.Angle != 90)) + { + this.Angle = 0; + } + + // Turn off labels autofitting + if (this._axis != null && this._axis.Common != null && this._axis.Common.Chart != null) + { + if (!this._axis.Common.Chart.serializing) + { + this._axis.IsLabelAutoFit = false; + } + } + + isStaggered = value; + + this.Invalidate(); + } + } + + /// + /// Gets or sets a property which specifies whether the labels are shown at axis ends. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeLabel_ShowEndLabels"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsEndLabelVisible + { + get + { + return _isEndLabelVisible; + } + set + { + _isEndLabelVisible = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a property which specifies whether the label can be truncated. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(false), + SRDescription("DescriptionAttributeLabel_TruncatedLabels"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool TruncatedLabels + { + get + { + return _truncatedLabels; + } + set + { + _truncatedLabels = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the formatting string for the label text. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeLabel_Format"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public string Format + { + get + { + return _format; + } + set + { + _format = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a property which indicates whether the label is enabled. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeLabel_Enabled"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool Enabled + { + get + { + return _enabled; + } + set + { + _enabled = value; + this.Invalidate(); + } + } + #endregion + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + //Free managed resources + if (_fontCache!=null) + { + _fontCache.Dispose(); + _fontCache = null; + } + } + } + + #endregion + + } +} diff --git a/System.Web.DataVisualization/Common/General/Legend.cs b/System.Web.DataVisualization/Common/General/Legend.cs new file mode 100644 index 000000000..4b4a99955 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/Legend.cs @@ -0,0 +1,6284 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: Legend.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: Legend, LegendCollection, LegendItemsCollection, +// LegendItem +// +// Purpose: Chart Legend consist of default and custom legend +// items. Default items are automatically added based +// on the data series and custom items are added by +// the user. Each item usually consist of 2 cells; +// series color marker and series name. Legend item +// cells form vertical columns in the legend. +// +// Please refer to the Chart documentation which +// contains images and samples describing legend features. +// +// NOTE: In early versions of the Chart control only 1 legend was +// exposed through the Legend property of the root chart object. +// Due to the customer requests, support for unlimited number of +// legends was added through the LegendCollection exposed as a +// Legends property in the root chart object. Old propertys was +// deprecated and marked as non-browsable. +// +// Reviewed: AG - Jul 31, 2002; +// GS - Aug 7, 2002 +// AG - Microsoft 14, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; + using System.ComponentModel.Design.Serialization; + using System.Reflection; + using System.Windows.Forms.Design; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Legend enumerations + + /// + /// An enumeration of legend item orderings. + /// + public enum LegendItemOrder + { + /// + /// Items will be added into the legend in an order automatically determined by the chart. + /// + Auto, + + /// + /// Items will be added into the legend in the same order as the chart series. + /// + SameAsSeriesOrder, + + /// + /// Items will be added into the legend in the same order as the chart series. + /// + ReversedSeriesOrder + + }; + + /// + /// An enumeration of legend separator styles. + /// + public enum LegendSeparatorStyle + { + /// + /// No separator will be shown. + /// + None, + + /// + /// Single solid line separator. + /// + Line, + + /// + /// Single solid thick line separator. + /// + ThickLine, + + /// + /// Double solid line separator. + /// + DoubleLine, + + /// + /// Single dash line separator. + /// + DashLine, + + /// + /// Single dot line separator. + /// + DotLine, + + /// + /// Gradient solid line separator. + /// + GradientLine, + + /// + /// Thick gradient solid line separator. + /// + ThickGradientLine, + } + + + + /// + /// An enumeration that specifies a style for a legend item's symbol. + /// + public enum LegendImageStyle + { + /// + /// The symbol will be a rectangle. + /// + Rectangle, + + /// + /// The symbol will be a line. + /// + Line, + + /// + /// The symbol will be a marker. + /// + Marker + } + + /// + /// An enumeration of legend styles. + /// + public enum LegendStyle + { + /// + /// One column, many rows. + /// + Column, + + /// + /// One row, many columns. + /// + Row, + + /// + /// Many column, many rows. + /// + Table + }; + + /// + /// An enumeration of legend table styles. + /// + public enum LegendTableStyle + { + /// + /// The legend table style is automatically determined by the chart. + /// + Auto, + + /// + /// The legend items will be fit horizontally within the legend. + /// It is preferred to use this style when the docking is set to top or bottom. + /// + Wide, + + /// + /// The legend items will be fit vertically within the legend. + /// It is preferred to use this style when docking is set to left or right. + /// + Tall + }; + + #endregion + + /// + /// The legend class represents a single chart legend. It contains visual + /// appearance, position and content properties. This class is also + /// responsible for drawing and positioning of the legend. + /// + [ + SRDescription("DescriptionAttributeLegend_Legend"), + DefaultProperty("Enabled"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class Legend : ChartNamedElement + { + #region Fields + + //*********************************************************** + //** Private data members, which store properties values + //*********************************************************** + private ElementPosition _position = null; + private bool _enabled = true; + + private LegendStyle _legendStyle = LegendStyle.Table; + + private LegendTableStyle _legendTableStyle = LegendTableStyle.Auto; + private LegendItemsCollection _customLegends = null; + private ChartHatchStyle _backHatchStyle = ChartHatchStyle.None; + private string _backImage = ""; + private ChartImageWrapMode _backImageWrapMode = ChartImageWrapMode.Tile; + private Color _backImageTransparentColor = Color.Empty; + private ChartImageAlignmentStyle _backImageAlignment = ChartImageAlignmentStyle.TopLeft; + private GradientStyle _backGradientStyle = GradientStyle.None; + private Color _backSecondaryColor = Color.Empty; + private Color _borderColor = Color.Empty; + private Color _backColor = Color.Empty; + private int _borderWidth = 1; + private ChartDashStyle _borderDashStyle = ChartDashStyle.Solid; + private FontCache _fontCache = new FontCache(); + private Font _font = null; + private Color _foreColor = Color.Black; + private StringAlignment _legendAlignment = StringAlignment.Near; + private Docking _legendDocking = Docking.Right; + private int _shadowOffset = 0; + private Color _shadowColor = Color.FromArgb(128, 0, 0, 0); + private bool _isTextAutoFit = true; + private string _dockedToChartArea = Constants.NotSetValue; + private bool _isDockedInsideChartArea = true; + + //*********************************************************** + //** Private data members + //*********************************************************** + + // Collection of custom and series legend items + internal LegendItemsCollection legendItems = null; + + // Number of rows and columns + private int _itemColumns = 0; + + + // Font calculated by auto fitting + internal Font autofitFont = null; + + // Indicates that all items in the legend should be equally spaced + private bool _isEquallySpacedItems = false; + + + // Indicate that legend rows should be drawn with isInterlaced background color. + private bool _interlacedRows = false; + + // Legend isInterlaced rows color + private Color _interlacedRowsColor = Color.Empty; + + // Legend offsets + private Size _offset = Size.Empty; + + // Adjustment point used for legend animation + private float _maximumLegendAutoSize = 50f; + + // Text length after which the legend item text will be wrapped on the next whitespace. + private int _textWrapThreshold = 25; + + // Value used to calculate auto-fit font size from the legend Font. + private int _autoFitFontSizeAdjustment = 0; + + // Legend column collection + private LegendCellColumnCollection _cellColumns = null; + + // Indicates that legend items automatically added based on the exsisting + // series in reversed order. + private LegendItemOrder _legendItemOrder = LegendItemOrder.Auto; + + // Legend title text + private string _title = String.Empty; + + // Legend title color + private Color _titleForeColor = Color.Black; + + // Legend title back color + private Color _titleBackColor = Color.Empty; + + // Legend title font + private Font _titleFont = null; + + // Legend title alignment + private StringAlignment _titleAlignment = StringAlignment.Center; + + // Legend title visual separator + private LegendSeparatorStyle _titleSeparator = LegendSeparatorStyle.None; + + // Legend title visual separator color + private Color _titleSeparatorColor = Color.Black; + + // Legend header visual separator + private LegendSeparatorStyle _headerSeparator = LegendSeparatorStyle.None; + + // Legend header visual separator color + private Color _headerSeparatorColor = Color.Black; + + // Legend table columns visual separator + private LegendSeparatorStyle _itemColumnSeparator = LegendSeparatorStyle.None; + + // Legend table columns visual separator color + private Color _itemColumnSeparatorColor = Color.Black; + + // Legend table column spacing calculated as a percentage of the font + private int _itemColumnSpacing = 50; + + // Legend table column spacing calculated in relative coordinates + private int _itemColumnSpacingRel = 0; + + // Legend title position in pixelcoordinates. + // Note that legend title always docked to the top of the legend. + private Rectangle _titlePosition = Rectangle.Empty; + + // Legend header position in pixel coordinates. + private Rectangle _headerPosition = Rectangle.Empty; + + // Minimum font size that can be used by the legend auto-fitting algorithm + private int _autoFitMinFontSize = 7; + + // Horizontal space left after fitting legend items + private int _horizontalSpaceLeft = 0; + + // Vertical space left after fitting legend items + private int _verticalSpaceLeft = 0; + + // Sub-columns sizes calculated during the fitting process + private int[,] _subColumnSizes = null; + + // Legend item heigts + private int[,] _cellHeights = null; + + // Number of rows per each legend table column + private int[] _numberOfRowsPerColumn = null; + + // Number of items from the collection that should be processed + private int _numberOfLegendItemsToProcess = -1; + + // Legend items area position in pixels + private Rectangle _legendItemsAreaPosition = Rectangle.Empty; + + // Indicates that not all legend items were able to fit the legend + private bool _legendItemsTruncated = false; + + // Size of the dots (pixels) that will drawn on the bottom of the legend when it is truncated + private int _truncatedDotsSize = 3; + + // Maximum number of cells in the legend item + private int _numberOfCells = -1; + + // Pixel size of the 'W' character + internal Size singleWCharacterSize = Size.Empty; + + + #endregion + + #region Constructors + + /// + /// Legend constructor + /// + public Legend() + { + _position = new ElementPosition(this); + // Initialize custom items collection + _customLegends = new LegendItemsCollection(this); + legendItems = new LegendItemsCollection(this); + _cellColumns = new LegendCellColumnCollection(this); + _font = _fontCache.DefaultFont; + _titleFont = _fontCache.DefaultBoldFont; + } + + /// + /// Legend constructor + /// + /// The legend name. + public Legend(string name) : base (name) + { + _position = new ElementPosition(this); + // Initialize custom items collection + _customLegends = new LegendItemsCollection(this); + legendItems = new LegendItemsCollection(this); + _cellColumns = new LegendCellColumnCollection(this); + _font = _fontCache.DefaultFont; + _titleFont = _fontCache.DefaultBoldFont; + } + + #endregion + + #region Legend position & size methods + + /// + /// Recalculates legend information: + /// - legend items collection + /// - maximum text rectangle + /// + /// Reference to the chart graphics. + private void RecalcLegendInfo(ChartGraphics chartGraph) + { + // Reset some values + RectangleF legendPositionRel = _position.ToRectangleF(); + Rectangle legendPosition = Rectangle.Round(chartGraph.GetAbsoluteRectangle(legendPositionRel)); + + //*********************************************************** + //** Use size of the "W" characters in current font to + //** calculate legend spacing + //*********************************************************** + this.singleWCharacterSize = chartGraph.MeasureStringAbs("W", this.Font); + Size doubleCharacterSize = chartGraph.MeasureStringAbs("WW", this.Font); + this.singleWCharacterSize.Width = doubleCharacterSize.Width - this.singleWCharacterSize.Width; + + // Calculate left, top offset and column spacing + this._offset.Width = (int)Math.Ceiling(singleWCharacterSize.Width / 2f); + this._offset.Height = (int)Math.Ceiling(singleWCharacterSize.Width / 3f); + + // Calculate item column spacing and make sure it is dividable by 2 + this._itemColumnSpacingRel = (int)(singleWCharacterSize.Width * (this._itemColumnSpacing / 100f)); + if(this._itemColumnSpacingRel % 2 == 1) + { + this._itemColumnSpacingRel += 1; + } + + //*********************************************************** + //** Calculate how much space required for the title. + //*********************************************************** + this._titlePosition = Rectangle.Empty; + if(this.Title.Length > 0) + { + // Measure title text size + Size titleSize = this.GetTitleSize(chartGraph, legendPosition.Size); + + // Set legend title position + this._titlePosition = new Rectangle( + legendPosition.Location.X, + legendPosition.Location.Y, + legendPosition.Width, + Math.Min(legendPosition.Height, titleSize.Height)); + + // Adjust legend items position height + legendPosition.Height -= this._titlePosition.Height; + + // Increase title top location by border height + this._titlePosition.Y += this.GetBorderSize(); + } + + + //*********************************************************** + //** Calculate how much space required for the header. + //*********************************************************** + this._headerPosition = Rectangle.Empty; + + // Find the largest (height only) header + Size highestHeader = Size.Empty; + foreach(LegendCellColumn legendColumn in this.CellColumns) + { + if(legendColumn.HeaderText.Length > 0) + { + // Measure header text size + Size headerSize = this.GetHeaderSize(chartGraph, legendColumn); + + // Get header with maximum height + highestHeader.Height = Math.Max(highestHeader.Height, headerSize.Height); + } + } + + // Check if any headers where found + if(!highestHeader.IsEmpty) + { + // Set legend header position + this._headerPosition = new Rectangle( + legendPosition.Location.X + this.GetBorderSize() + this._offset.Width, + legendPosition.Location.Y + this._titlePosition.Height, + legendPosition.Width - (this.GetBorderSize() + this._offset.Width) * 2, + Math.Min(legendPosition.Height - this._titlePosition.Height, highestHeader.Height)); + this._headerPosition.Height = Math.Max(this._headerPosition.Height, 0); + + // Adjust legend items position height + legendPosition.Height -= this._headerPosition.Height; + + // Increase header top location by border height + this._headerPosition.Y += this.GetBorderSize(); + } + + + //*********************************************************** + //** Calculate size available for all legend items + //*********************************************************** + this._legendItemsAreaPosition = new Rectangle( + legendPosition.X + this._offset.Width + this.GetBorderSize(), + legendPosition.Y + this._offset.Height + this.GetBorderSize() + this._titlePosition.Height + this._headerPosition.Height, + legendPosition.Width - 2 * (this._offset.Width + this.GetBorderSize()), + legendPosition.Height - 2 * (this._offset.Height + this.GetBorderSize()) ); + + //*********************************************************** + //** Calculate number of rows and columns depending on + //** the legend style + //*********************************************************** + this.GetNumberOfRowsAndColumns( + chartGraph, + this._legendItemsAreaPosition.Size, + -1, + out this._numberOfRowsPerColumn, + out this._itemColumns, + out this._horizontalSpaceLeft, + out this._verticalSpaceLeft); + + //*********************************************************** + //** Try to fit all legend item cells reducing the font size + //*********************************************************** + + // Reset auto-fit font adjustment value and truncated legend flag + this._autoFitFontSizeAdjustment = 0; + this._legendItemsTruncated = false; + + // Check if legend items fit into the legend area + bool autoFitDone = (this._horizontalSpaceLeft >= 0 && this._verticalSpaceLeft >= 0); + + // Calculate total number of items fit and make sure we fit all of them + this._numberOfLegendItemsToProcess = this.legendItems.Count; + int itemsFit = 0; + for(int index = 0; index < this._itemColumns; index++) + { + itemsFit += this._numberOfRowsPerColumn[index]; + } + if(itemsFit < this._numberOfLegendItemsToProcess) + { + autoFitDone = false; + } + + // If items do not fit try reducing font or number of legend items + this.autofitFont = this.Font; + if(!autoFitDone) + { + do + { + // Check if legend item font size can be reduced + if(this.IsTextAutoFit && + (this.Font.Size - this._autoFitFontSizeAdjustment) > this._autoFitMinFontSize) + { + // Reduce font size by one + ++this._autoFitFontSizeAdjustment; + + // Calculate new font size + int newFontSize = (int)Math.Round(this.Font.Size - this._autoFitFontSizeAdjustment); + if(newFontSize < 1) + { + // Font can't be less than size 1 + newFontSize = 1; + } + + // Create new font + this.autofitFont = this.Common.ChartPicture.FontCache.GetFont( + this.Font.FontFamily, + newFontSize, + this.Font.Style, + this.Font.Unit); + + // Calculate number of rows and columns + this.GetNumberOfRowsAndColumns( + chartGraph, + this._legendItemsAreaPosition.Size, + -1, + out this._numberOfRowsPerColumn, + out this._itemColumns, + out this._horizontalSpaceLeft, + out this._verticalSpaceLeft); + + autoFitDone = (this._horizontalSpaceLeft >= 0 && this._verticalSpaceLeft >= 0); + + // Calculate total number of items fit and make sure we fit all of them + itemsFit = 0; + for(int index = 0; index < this._itemColumns; index++) + { + itemsFit += this._numberOfRowsPerColumn[index]; + } + if(itemsFit < this._numberOfLegendItemsToProcess) + { + autoFitDone = false; + } + + } + else + { + // If font size cannot be reduced start removing legend items + if(this._numberOfLegendItemsToProcess > 2) + { + // Handle case of 1 column that do not fit horizontally + if(this._itemColumns == 1 && (this._horizontalSpaceLeft < 0 && this._verticalSpaceLeft >= 0)) + { + autoFitDone = true; + this._numberOfLegendItemsToProcess = + Math.Min(this._numberOfLegendItemsToProcess, this._numberOfRowsPerColumn[0]); + } + // Handle case of 1 row that do not fit vertically + else if(this.GetMaximumNumberOfRows() == 1 && (this._verticalSpaceLeft < 0 && this._horizontalSpaceLeft >= 0)) + { + autoFitDone = true; + this._numberOfLegendItemsToProcess = + Math.Min(this._numberOfLegendItemsToProcess, this._itemColumns); + } + else + { + // Adjust legend items area height by size required to show + // visually (dots) that legend is truncated + if(!this._legendItemsTruncated) + { + this._legendItemsAreaPosition.Height -= this._truncatedDotsSize; + } + + // Remove last legend item + this._legendItemsTruncated = true; + --this._numberOfLegendItemsToProcess; + + // RecalculateAxesScale number of rows and columns + this.GetNumberOfRowsAndColumns( + chartGraph, + this._legendItemsAreaPosition.Size, + this._numberOfLegendItemsToProcess, + out this._numberOfRowsPerColumn, + out this._itemColumns); + } + + // Make sure we show truncated legend symbols when not all items shown + if(autoFitDone && + !this._legendItemsTruncated && + this._numberOfLegendItemsToProcess < this.legendItems.Count) + { + // Adjust legend items area height by size required to show + // visually (dots) that legend is truncated + this._legendItemsAreaPosition.Height -= this._truncatedDotsSize; + + // Legend is truncated + this._legendItemsTruncated = true; + } + } + else + { + autoFitDone = true; + } + + // Check if legend items fit into the legend area + if(!autoFitDone) + { + autoFitDone = this.CheckLegendItemsFit( + chartGraph, + this._legendItemsAreaPosition.Size, + this._numberOfLegendItemsToProcess, + this._autoFitFontSizeAdjustment, + this._itemColumns, + this._numberOfRowsPerColumn, + out this._subColumnSizes, + out this._cellHeights, + out this._horizontalSpaceLeft, + out this._verticalSpaceLeft); + + } + } + } while(!autoFitDone); + } + + + //*********************************************************** + //** Calculate position of all cells + //*********************************************************** + + // Calculate item vertical spacing in relative coordinates but rounded on pixel boundary + Size itemHalfSpacing = Size.Empty; + if(this._verticalSpaceLeft > 0) + { + itemHalfSpacing.Height = (int)(this._verticalSpaceLeft / this.GetMaximumNumberOfRows() / 2); + } + if(this._horizontalSpaceLeft > 0) + { + itemHalfSpacing.Width = (int)(_horizontalSpaceLeft / 2); + } + + // Iterate through all legend items + int currentColumn = 0; + int currentRow = 0; + if(this._numberOfLegendItemsToProcess < 0) + { + this._numberOfLegendItemsToProcess = this.legendItems.Count; + } + for(int legendItemIndex = 0; legendItemIndex < this._numberOfLegendItemsToProcess; legendItemIndex++) + { + LegendItem legendItem = this.legendItems[legendItemIndex]; + + // Iterate through legend item cells + for(int cellIndex = 0; cellIndex < legendItem.Cells.Count; cellIndex++) + { + // Get legend cell + LegendCell legendCell = legendItem.Cells[cellIndex]; + + // Calculate cell position + Rectangle cellPosition = this.GetCellPosition(currentColumn, currentRow, cellIndex, itemHalfSpacing); + + // Check if current cell spans through more than 1 cell + int overlappedCellsNumber = 0; + if(legendCell.CellSpan > 1) + { + for(int spanIndex = 1; spanIndex < legendCell.CellSpan && (cellIndex + spanIndex) < legendItem.Cells.Count; spanIndex++) + { + // Calculate overlapped cell position + Rectangle overlappedCellPosition = this.GetCellPosition(currentColumn, currentRow, cellIndex + spanIndex, itemHalfSpacing); + + // Adjust current cell right position + if(cellPosition.Right < overlappedCellPosition.Right) + { + cellPosition.Width += overlappedCellPosition.Right - cellPosition.Right; + } + + // Increase number of overlapped cells + ++overlappedCellsNumber; + + // Set empty size for the overlapped cells + LegendCell overlappedLegendCell = legendItem.Cells[cellIndex + spanIndex]; + overlappedLegendCell.SetCellPosition( + currentRow, + Rectangle.Empty, + this.singleWCharacterSize); + } + } + + // Make sure cell is drawn inside the legend + cellPosition.Intersect(this._legendItemsAreaPosition); + + // Set cell object position + legendCell.SetCellPosition( + currentRow, + cellPosition, + this.singleWCharacterSize); + + // Skip overlapped cells + cellIndex += overlappedCellsNumber; + } + + // Advance to the next row/column. Break if number of legend items exceed + // number of availabale rows/columns. + ++currentRow; + if(currentRow >= this._numberOfRowsPerColumn[currentColumn]) + { + ++currentColumn; + currentRow = 0; + if(currentColumn >= this._itemColumns) + { + break; + } + } + } + } + + /// + /// Gets single cell position in relative coordinates. + /// + /// Cell column index. + /// Cell row index. + /// Index of the cell in the legend item. + /// Half legend item spacing in relative coordinates. + /// + private Rectangle GetCellPosition( + int columnIndex, + int rowIndex, + int cellIndex, + Size itemHalfSpacing) + { + Rectangle cellPosition = this._legendItemsAreaPosition; + + //***************************************************************** + //** Get cell Top location + //***************************************************************** + for(int index = 0; index < rowIndex; index++) + { + cellPosition.Y += this._cellHeights[columnIndex, index]; + } + if(itemHalfSpacing.Height > 0) + { + cellPosition.Y += itemHalfSpacing.Height * rowIndex * 2 + itemHalfSpacing.Height; + } + + //***************************************************************** + //** Get cell Left location + //***************************************************************** + + // Add extar space left after auto fitting + if(this._horizontalSpaceLeft > 0) + { + cellPosition.X += itemHalfSpacing.Width; + } + + // Calculate how many sub-columns (cells) this legend has + int numberOfSubColumns = this.GetNumberOfCells(); + + // Iterate through all prev. columns + for(int index = 0; index < columnIndex; index++) + { + // Add width of previous columns + for(int subColumnIndex = 0; subColumnIndex < numberOfSubColumns; subColumnIndex++) + { + cellPosition.X += this._subColumnSizes[index, subColumnIndex]; + } + + // Add width of separator for the previous columns + cellPosition.X += this.GetSeparatorSize(this.ItemColumnSeparator).Width; + } + // Add width of current column cells + for(int subColumnIndex = 0; subColumnIndex < cellIndex; subColumnIndex++) + { + cellPosition.X += this._subColumnSizes[columnIndex, subColumnIndex]; + } + + //***************************************************************** + //** Get cell Height + //***************************************************************** + cellPosition.Height = this._cellHeights[columnIndex, rowIndex]; + + //***************************************************************** + //** Get cell Width + //***************************************************************** + cellPosition.Width = this._subColumnSizes[columnIndex, cellIndex]; + + return cellPosition; + } + + /// + /// Calculates the optimal size of the legend. + /// + /// Chart graphics object. + /// Max size for the legend. + /// Legend optimal size. + private SizeF GetOptimalSize(ChartGraphics chartGraph, SizeF maxSizeRel) + { + // Reset some values + this._offset = Size.Empty; + this._itemColumns = 0; + this._horizontalSpaceLeft = 0; + this._verticalSpaceLeft = 0; + this._subColumnSizes = null; + this._numberOfRowsPerColumn = null; + this._cellHeights = null; + this.autofitFont = null; + this._autoFitFontSizeAdjustment = 0; + this._numberOfCells = -1; + this._numberOfLegendItemsToProcess = -1; + Size optimalSize = Size.Empty; + + // Convert to pixels + SizeF maxSizeAbs = chartGraph.GetAbsoluteSize(maxSizeRel); + Size maxSize = new Size((int)maxSizeAbs.Width, (int)maxSizeAbs.Height); + + // Clear all legend item cells cached information + foreach(LegendItem legendItem in this.legendItems) + { + foreach(LegendCell cell in legendItem.Cells) + { + cell.ResetCache(); + } + } + + // Check if legend is enabled + if(this.IsEnabled()) + { + // Add all series legend into items collection and then add custom legend items + FillLegendItemsCollection(); + + // Call a notification event, so that legend items collection can be modified by user + this.Common.Chart.CallOnCustomizeLegend(legendItems, this.Name); + + // Check if there are any items in the legend + if(this.legendItems.Count > 0) + { + //*********************************************************** + //** Use size of the "W" character in current font to + //** calculate legend spacing + //*********************************************************** + this.singleWCharacterSize = chartGraph.MeasureStringAbs("W", this.Font); + Size doubleCharacterSize = chartGraph.MeasureStringAbs("WW", this.Font); + this.singleWCharacterSize.Width = doubleCharacterSize.Width - this.singleWCharacterSize.Width; + + // Calculate left, top offset and column spacing + this._offset.Width = (int)Math.Ceiling(singleWCharacterSize.Width / 2f); + this._offset.Height = (int)Math.Ceiling(singleWCharacterSize.Width / 3f); + this._itemColumnSpacingRel = (int)(singleWCharacterSize.Width * (this._itemColumnSpacing / 100f)); + if(this._itemColumnSpacingRel % 2 == 1) + { + this._itemColumnSpacingRel += 1; + } + + + //*********************************************************** + //** Add size required for the legend tile + //*********************************************************** + + Size titleSize = Size.Empty; + if(this.Title.Length > 0) + { + titleSize = this.GetTitleSize(chartGraph, maxSize); + } + + //*********************************************************** + //** Add size required for the legend header + //*********************************************************** + + Size highestHeader = Size.Empty; + foreach(LegendCellColumn legendColumn in this.CellColumns) + { + if(legendColumn.HeaderText.Length > 0) + { + // Measure header text size + Size headerSize = this.GetHeaderSize(chartGraph, legendColumn); + + // Get header with maximum height + highestHeader.Height = Math.Max(highestHeader.Height, headerSize.Height); + } + } + + //*********************************************************** + //** Calculate size available for legend items + //*********************************************************** + Size legenItemsMaxSize = maxSize; + legenItemsMaxSize.Width -= 2 * (this._offset.Width + this.GetBorderSize()); + legenItemsMaxSize.Height -= 2 * (this._offset.Height + this.GetBorderSize()); + legenItemsMaxSize.Height -= titleSize.Height; + legenItemsMaxSize.Height -= highestHeader.Height; + + //*********************************************************** + //** Calculate number of rows and columns depending on + //** the legend style + //*********************************************************** + this._autoFitFontSizeAdjustment = 0; + + this.autofitFont = this.Font; + int vertSpaceLeft = 0; + int horizSpaceLeft = 0; + bool reduceFont = this.IsTextAutoFit; + bool autoFit = false; + do + { + // Get number of columns and rows that we can fit in the legend + this.GetNumberOfRowsAndColumns( + chartGraph, + legenItemsMaxSize, + -1, + out this._numberOfRowsPerColumn, + out this._itemColumns, + out horizSpaceLeft, + out vertSpaceLeft); + + // Calculate total number of items fit and make sure we fit all of them + int itemsFit = 0; + for(int index = 0; index < this._itemColumns; index++) + { + itemsFit += this._numberOfRowsPerColumn[index]; + } + autoFit = (horizSpaceLeft >= 0 && vertSpaceLeft >= 0 && itemsFit >= this.legendItems.Count); + + // Check if items fit + if(reduceFont && !autoFit) + { + if((this.Font.Size - this._autoFitFontSizeAdjustment) > this._autoFitMinFontSize) + { + // Reduce font size by one + ++this._autoFitFontSizeAdjustment; + + // Calculate new font size + int newFontSize = (int)Math.Round(this.Font.Size - this._autoFitFontSizeAdjustment); + if(newFontSize < 1) + { + // Font can't be less than size 1 + newFontSize = 1; + } + + // Create new font + this.autofitFont = this.Common.ChartPicture.FontCache.GetFont( + this.Font.FontFamily, + newFontSize, + this.Font.Style, + this.Font.Unit); + } + else + { + reduceFont = false; + } + } + } while(reduceFont && !autoFit); + + // Slightly reduce used space + horizSpaceLeft -= Math.Min(4, horizSpaceLeft); + vertSpaceLeft -= Math.Min(2, vertSpaceLeft); + + + //*********************************************************** + //** Calculate legend size + //*********************************************************** + optimalSize.Width = (legenItemsMaxSize.Width - horizSpaceLeft); + optimalSize.Width = Math.Max(optimalSize.Width, titleSize.Width); + optimalSize.Width += 2 * (this._offset.Width + this.GetBorderSize()); + + optimalSize.Height = (legenItemsMaxSize.Height - vertSpaceLeft) + titleSize.Height + highestHeader.Height; + optimalSize.Height += 2 * (this._offset.Height + this.GetBorderSize()); + + // Adjust legend items area height by size required to show + // visually (dots) that legend is truncated + if(horizSpaceLeft < 0 || vertSpaceLeft < 0) + { + optimalSize.Height += this._truncatedDotsSize; + } + + //*********************************************************** + //** Make sure legend size do not exceed max. value + //*********************************************************** + if(optimalSize.Width > maxSize.Width) + { + optimalSize.Width = maxSize.Width; + } + if(optimalSize.Height > maxSize.Height) + { + optimalSize.Height = maxSize.Height; + } + if(optimalSize.Width < 0) + { + optimalSize.Width = 0; + } + if(optimalSize.Height < 0) + { + optimalSize.Height = 0; + } + } + } + + // Convert result size from pixel to relative coordinates + return chartGraph.GetRelativeSize(optimalSize); + } + + + + /// + /// Recalculates legend position. + /// + /// Chart graphics used. + /// Area where the legend should be positioned. + /// Spacing size as a percentage of the area. + internal void CalcLegendPosition( + ChartGraphics chartGraph, + ref RectangleF chartAreasRectangle, + float elementSpacing) + { + RectangleF legendPosition = new RectangleF(); + + // Get optimal legend size + SizeF maxSize = new SizeF(chartAreasRectangle.Width - 2*elementSpacing, chartAreasRectangle.Height - 2*elementSpacing); + if (this.DockedToChartArea == Constants.NotSetValue) + { + + // Note: 'maxLegendSize' parameter is ignored. New legend property + // 'maximumLegendAutoSize' is used instead. + if(this.Docking == Docking.Top || this.Docking == Docking.Bottom) + { + maxSize.Height = (maxSize.Height / 100F) * this._maximumLegendAutoSize; + } + else + { + maxSize.Width = (maxSize.Width / 100F) * this._maximumLegendAutoSize; + } + } + + if(maxSize.Width <= 0 || maxSize.Height <= 0) + { + return; + } + + SizeF legendSize = this.GetOptimalSize(chartGraph, maxSize); + legendPosition.Height = legendSize.Height; + legendPosition.Width = legendSize.Width; + if(float.IsNaN(legendSize.Height) || float.IsNaN(legendSize.Width)) + { + return; + } + + // Calculate legend position + if(this.Docking == Docking.Top) + { + legendPosition.Y = chartAreasRectangle.Y + elementSpacing; + if(this.Alignment == StringAlignment.Near) + { + legendPosition.X = chartAreasRectangle.X + elementSpacing; + } + else if(this.Alignment == StringAlignment.Far) + { + legendPosition.X = chartAreasRectangle.Right - legendSize.Width - elementSpacing; + } + else if(this.Alignment == StringAlignment.Center) + { + legendPosition.X = chartAreasRectangle.X + (chartAreasRectangle.Width - legendSize.Width) / 2F; + } + + // Adjust position of the chart area(s) + chartAreasRectangle.Height -= legendPosition.Height + elementSpacing; + chartAreasRectangle.Y = legendPosition.Bottom; + } + else if(this.Docking == Docking.Bottom) + { + legendPosition.Y = chartAreasRectangle.Bottom - legendSize.Height - elementSpacing; + if(this.Alignment == StringAlignment.Near) + { + legendPosition.X = chartAreasRectangle.X + elementSpacing; + } + else if(this.Alignment == StringAlignment.Far) + { + legendPosition.X = chartAreasRectangle.Right - legendSize.Width - elementSpacing; + } + else if(this.Alignment == StringAlignment.Center) + { + legendPosition.X = chartAreasRectangle.X + (chartAreasRectangle.Width - legendSize.Width) / 2F; + } + + // Adjust position of the chart area(s) + chartAreasRectangle.Height -= legendPosition.Height + elementSpacing; + } + if(this.Docking == Docking.Left) + { + legendPosition.X = chartAreasRectangle.X + elementSpacing; + if(this.Alignment == StringAlignment.Near) + { + legendPosition.Y = chartAreasRectangle.Y + elementSpacing; + } + else if(this.Alignment == StringAlignment.Far) + { + legendPosition.Y = chartAreasRectangle.Bottom - legendSize.Height - elementSpacing; + } + else if(this.Alignment == StringAlignment.Center) + { + legendPosition.Y = chartAreasRectangle.Y + (chartAreasRectangle.Height - legendSize.Height) / 2F; + } + + // Adjust position of the chart area(s) + chartAreasRectangle.Width -= legendPosition.Width + elementSpacing; + chartAreasRectangle.X = legendPosition.Right; + } + if(this.Docking == Docking.Right) + { + legendPosition.X = chartAreasRectangle.Right - legendSize.Width - elementSpacing; + if(this.Alignment == StringAlignment.Near) + { + legendPosition.Y = chartAreasRectangle.Y + elementSpacing; + } + else if(this.Alignment == StringAlignment.Far) + { + legendPosition.Y = chartAreasRectangle.Bottom - legendSize.Height - elementSpacing; + } + else if(this.Alignment == StringAlignment.Center) + { + legendPosition.Y = chartAreasRectangle.Y + (chartAreasRectangle.Height - legendSize.Height) / 2F; + } + + // Adjust position of the chart area(s) + chartAreasRectangle.Width -= legendPosition.Width + elementSpacing; + } + + this.Position.SetPositionNoAuto(legendPosition.X, legendPosition.Y, legendPosition.Width, legendPosition.Height); + } + + + + /// + /// Get number of columns and rows that can be fit in specified size. + /// + /// Chart graphics. + /// Legend size. + /// Number of legend items to check. + /// Array with number of rows per each column. + /// Returns number of columns. + private void GetNumberOfRowsAndColumns( + ChartGraphics chartGraph, + Size legendSize, + int numberOfItemsToCheck, + out int[] numberOfRowsPerColumn, + out int columnNumber) + { + int horSpaceLeft = 0; + int vertSpaceLeft = 0; + this.GetNumberOfRowsAndColumns( + chartGraph, + legendSize, + numberOfItemsToCheck, + out numberOfRowsPerColumn, + out columnNumber, + out horSpaceLeft, + out vertSpaceLeft); + } + + /// + /// Get number of columns and rows that can be fit in specified size. + /// + /// Chart graphics. + /// Legend size. + /// Legend items number to check. + /// Array with number of rows per each column. + /// Returns number of columns. + /// Returns horizontal spacing left. + /// Returns vertical spacing left. + private void GetNumberOfRowsAndColumns( + ChartGraphics chartGraph, + Size legendSize, + int numberOfItemsToCheck, + out int[] numberOfRowsPerColumn, + out int columnNumber, + out int horSpaceLeft, + out int vertSpaceLeft) + { + // Initialize output parameters + numberOfRowsPerColumn = null; + columnNumber = 1; + horSpaceLeft = 0; + vertSpaceLeft = 0; + + // If number of items to check is nor set use total number of items in the collection + if(numberOfItemsToCheck < 0) + { + numberOfItemsToCheck = legendItems.Count; + } + + // Check legend style + if(this.LegendStyle == LegendStyle.Column || numberOfItemsToCheck <= 1) + { + columnNumber = 1; + numberOfRowsPerColumn = new int[] { numberOfItemsToCheck }; + } + else if(this.LegendStyle == LegendStyle.Row) + { + columnNumber = numberOfItemsToCheck; + numberOfRowsPerColumn = new int[columnNumber]; + for(int index = 0; index < columnNumber; index++) + { + numberOfRowsPerColumn[index] = 1; + } + } + else if(this.LegendStyle == LegendStyle.Table) + { + // Start with 1 column and 1 row + columnNumber = 1; + numberOfRowsPerColumn = new int[] { 1 }; + + // Get legend table style and adjust number of columns and rows accordinly + LegendTableStyle tableStyle = this.GetLegendTableStyle(chartGraph); + + //********************************************************************************* + //** Tall table layout + //********************************************************************************* + if(tableStyle == LegendTableStyle.Tall) + { + // Iterate from second item trying to add them and check if their fit + bool exitLoop = false; + int legendItemIndex = 1; + for(legendItemIndex = 1; !exitLoop && legendItemIndex < numberOfItemsToCheck; legendItemIndex ++) + { + // Try to increase number of rows in the current column + ++numberOfRowsPerColumn[columnNumber - 1]; + + // Check if legend items fit into the legend area + bool autoFitDone = this.CheckLegendItemsFit( + chartGraph, + legendSize, + legendItemIndex + 1, + this._autoFitFontSizeAdjustment, + columnNumber, + numberOfRowsPerColumn, + out this._subColumnSizes, + out this._cellHeights, + out horSpaceLeft, + out vertSpaceLeft); + + // Check if we fit or if we have just one column that do not fit + // horizontally but still have vertical space. + if(autoFitDone || + ( (columnNumber == 1 || horSpaceLeft < 0) && vertSpaceLeft > 0) ) + { + // Continue adding rows to the current column + continue; + } + else + { + // Reduce number of rows in the current column + if(numberOfRowsPerColumn[columnNumber - 1] > 1) + { + --numberOfRowsPerColumn[columnNumber - 1]; + } + + // Get half of average column width + int averageColumnWidth = 0; + if(horSpaceLeft > 0) + { + averageColumnWidth = (int)Math.Round((double)(legendSize.Width - horSpaceLeft) / columnNumber) / 2; + } + + // Check if number of columns can be increased + if(columnNumber < 50 && horSpaceLeft >= averageColumnWidth) + { + // Add new column + ++columnNumber; + + // Resize array that stores number of rows per column + int[] tempArray = numberOfRowsPerColumn; + numberOfRowsPerColumn = new int[columnNumber]; + for(int index = 0; index < tempArray.Length; index++) + { + numberOfRowsPerColumn[index] = tempArray[index]; + } + numberOfRowsPerColumn[columnNumber - 1] = 1; + + // If last legend item is moved into a new column + // call the auto fitting method before leaving the loop + if(legendItemIndex == numberOfItemsToCheck - 1) + { + this.CheckLegendItemsFit( + chartGraph, + legendSize, + legendItemIndex + 1, + this._autoFitFontSizeAdjustment, + columnNumber, + numberOfRowsPerColumn, + out this._subColumnSizes, + out this._cellHeights, + out horSpaceLeft, + out vertSpaceLeft); + } + } + else + { + exitLoop = true; + } + } + } + + // Check if we end up with legend with multiple columns + // where last column has sinificantly lower height of all rows + if(columnNumber > 1) + { + // Try reducing number of rows in the "tall" calumns and move them + // into the last column. + bool done = false; + while(!done) + { + // By default no more iterations required + done = true; + + // Find maximum column height not taking the last row in consideration + int maxColumnHeight = -1; + for(int columnIndex = 0; columnIndex < columnNumber; columnIndex++) + { + // Calculate current column height not taking the last row in consideration + int columnHeight = 0; + for(int rowIndex = 0; rowIndex < this._numberOfRowsPerColumn[columnIndex] - 1; rowIndex++) + { + columnHeight += this._cellHeights[columnIndex, rowIndex]; + } + + // Find maximum height + maxColumnHeight = Math.Max(maxColumnHeight, columnHeight); + } + + // Calculate total height of items in the last row + int totalHieghtOfItemInLastRow = 0; + for(int columnIndex = 0; columnIndex < (columnNumber - 1); columnIndex++) + { + if(this._numberOfRowsPerColumn[columnIndex] > 1) + { + totalHieghtOfItemInLastRow += this._cellHeights[columnIndex, this._numberOfRowsPerColumn[columnIndex] - 1]; + } + } + + // Check if rows are available for removal + if(totalHieghtOfItemInLastRow > 0) + { + // Get last column height + int lastColumnHeight = this.GetColumnHeight(columnNumber - 1); + + // Check if all items in the last row can vertically fit in last column + if( (lastColumnHeight + totalHieghtOfItemInLastRow) <= maxColumnHeight ) + { + // Reduce number of rows in all columns except last + int itemsToAdd = 0; + for(int columnIndex = 0; columnIndex < (columnNumber - 1); columnIndex++) + { + if(this._numberOfRowsPerColumn[columnIndex] > 1) + { + --this._numberOfRowsPerColumn[columnIndex]; + ++itemsToAdd; + } + } + + // Add rows to last column + if(itemsToAdd > 0) + { + // Add roes into the last column + this._numberOfRowsPerColumn[columnNumber - 1] += itemsToAdd; + + // Check if legend items fit into the legend area + bool autoFitDone = this.CheckLegendItemsFit( + chartGraph, + legendSize, + legendItemIndex + 1, + this._autoFitFontSizeAdjustment, + columnNumber, + numberOfRowsPerColumn, + out this._subColumnSizes, + out this._cellHeights, + out horSpaceLeft, + out vertSpaceLeft); + + // Try doing one more time + done = false; + } + } + } + } + } + } + //********************************************************************************* + //** Wide table layout + //********************************************************************************* + else if(tableStyle == LegendTableStyle.Wide) + { + // Iterate from second item trying to add them and check if they fit + bool exitLoop = false; + int legendItemIndex = 1; + for(legendItemIndex = 1; !exitLoop && legendItemIndex < numberOfItemsToCheck; legendItemIndex ++) + { + // Try to increase number of columns + ++columnNumber; + + // Resize array that stores number of rows per column + int[] tempArray = numberOfRowsPerColumn; + numberOfRowsPerColumn = new int[columnNumber]; + for(int index = 0; index < tempArray.Length; index++) + { + numberOfRowsPerColumn[index] = tempArray[index]; + } + numberOfRowsPerColumn[columnNumber - 1] = 1; + + // Check if legend items fit into the legend area + bool autoFitDone = this.CheckLegendItemsFit( + chartGraph, + legendSize, + legendItemIndex + 1, + this._autoFitFontSizeAdjustment, + columnNumber, + numberOfRowsPerColumn, + out this._subColumnSizes, + out this._cellHeights, + out horSpaceLeft, + out vertSpaceLeft); + + // Check if we fit or if we have just one row that do not fit + // vertically but still have horizontal space. + if(autoFitDone || + ( (this.GetMaximumNumberOfRows(numberOfRowsPerColumn) == 1 || vertSpaceLeft < 0) && horSpaceLeft > 0) ) + { + // Continue adding columns + continue; + } + else + { + // Remove columns and increase number of rows + bool columnFitting = true; + while(columnFitting) + { + columnFitting = false; + + // If we can't fit current number of columns reduce current column number + int rowsToAdd = 0; + if(columnNumber > 1) + { + rowsToAdd = numberOfRowsPerColumn[columnNumber - 1]; + --columnNumber; + + // Resize array that stores number of rows per column + tempArray = numberOfRowsPerColumn; + numberOfRowsPerColumn = new int[columnNumber]; + for(int index = 0; index < columnNumber; index++) + { + numberOfRowsPerColumn[index] = tempArray[index]; + } + } + + // We may need to add more than 1 row + for(int indexRowToAdd = 0; indexRowToAdd < rowsToAdd; indexRowToAdd++) + { + // Find first column with smallest height + int smallestColumnIndex = -1; + int columnMinHeight = int.MaxValue; + for(int columnIndex = 0; columnIndex < columnNumber; columnIndex++) + { + int columnHeight = this.GetColumnHeight(columnIndex); + int nextColumnFirstItemHeight = 0; + if(columnIndex < columnNumber - 1) + { + nextColumnFirstItemHeight = this._cellHeights[columnIndex + 1, 0]; + } + if(columnHeight < columnMinHeight && + (columnHeight + nextColumnFirstItemHeight) < legendSize.Height) + { + // Remember column index and height + columnMinHeight = columnHeight; + smallestColumnIndex = columnIndex; + } + } + + // No more items can fit + if(smallestColumnIndex < 0) + { + // Check if legend items fit into the legend area + autoFitDone = this.CheckLegendItemsFit( + chartGraph, + legendSize, + legendItemIndex + 1, + this._autoFitFontSizeAdjustment, + columnNumber, + numberOfRowsPerColumn, + out this._subColumnSizes, + out this._cellHeights, + out horSpaceLeft, + out vertSpaceLeft); + + exitLoop = true; + break; + } + + // Add new row to the smallest column + ++numberOfRowsPerColumn[smallestColumnIndex]; + + // Check if next column will be removed if it contains only 1 row + if(smallestColumnIndex < (columnNumber - 1)) + { + if(numberOfRowsPerColumn[smallestColumnIndex + 1] == 1) + { + // Shift number of rows per column + tempArray = numberOfRowsPerColumn; + for(int index = smallestColumnIndex + 1; index < tempArray.Length - 1; index++) + { + numberOfRowsPerColumn[index] = tempArray[index + 1]; + } + numberOfRowsPerColumn[columnNumber - 1] = 1; + } + } + + // Check if legend items fit into the legend area + autoFitDone = this.CheckLegendItemsFit( + chartGraph, + legendSize, + legendItemIndex + 1, + this._autoFitFontSizeAdjustment, + columnNumber, + numberOfRowsPerColumn, + out this._subColumnSizes, + out this._cellHeights, + out horSpaceLeft, + out vertSpaceLeft); + + } + + // If there is more than 1 column and items do not fit + // horizontally - reduce number of columns. + if(!autoFitDone && + horSpaceLeft < 0f && + columnNumber > 1) + { + columnFitting = true; + } + } + } + } + } + } + + // Check if items fit and how much empty space left + this.CheckLegendItemsFit( + chartGraph, + legendSize, + -1, + this._autoFitFontSizeAdjustment, + columnNumber, + numberOfRowsPerColumn, + out this._subColumnSizes, + out this._cellHeights, + out horSpaceLeft, + out vertSpaceLeft); + } + + /// + /// Gets column height. + /// + /// Index of the column to get the height for. + /// Column height in relative coordinates. + private int GetColumnHeight(int columnIndex) + { + // Calculate current column height + int columnHeight = 0; + for(int rowIndex = 0; rowIndex < this._numberOfRowsPerColumn[columnIndex]; rowIndex++) + { + columnHeight += this._cellHeights[columnIndex, rowIndex]; + } + + return columnHeight; + } + + /// + /// Checks if legend background is selected. + /// + internal void SelectLegendBackground() + { + Common.HotRegionsList.AddHotRegion(this.Position.ToRectangleF(), this, ChartElementType.LegendArea, true); + } + + #endregion Legend position & size methods + + #region Legend Items Fitting Methods + + /// + /// Gets maximum number of rows in all columns. + /// + /// Maximum number of rows. + private int GetMaximumNumberOfRows() + { + return this.GetMaximumNumberOfRows(this._numberOfRowsPerColumn); + } + + /// + /// Gets maximum number of rows in all columns. + /// + /// Array that stores number of rows per column. + /// Maximum number of rows. + private int GetMaximumNumberOfRows(int[] rowsPerColumn) + { + // Find column with maximum number of rows + int maxNumberOfColumns = 0; + if(rowsPerColumn != null) + { + for(int columnIndex = 0; columnIndex < rowsPerColumn.Length; columnIndex++) + { + maxNumberOfColumns = Math.Max(maxNumberOfColumns, rowsPerColumn[columnIndex]); + } + } + return maxNumberOfColumns; + } + + /// + /// Checks if specified legend will fit the specified size. + /// + /// Chart graphics. + /// Area that legend items must fit. + /// Number of items that should be fitted. + /// Number of points the standard legend font is reduced by auto-fitting algorithm. + /// Legend column number. + /// Array of number of rows per column. + /// Returns array of sub-column size. + /// Returns array of cell heights. + /// Returns horizontal space left. + /// Returns vertical space left. + /// True if items fit. + private bool CheckLegendItemsFit( + ChartGraphics graph, + Size legendItemsAreaSize, + int numberOfItemsToCheck, + int fontSizeReducedBy, + int numberOfColumns, + int[] numberOfRowsPerColumn, + out int[,] subColumnSizes, + out int[,] cellHeights, + out int horizontalSpaceLeft, + out int verticalSpaceLeft) + { + bool fitFlag = true; + + // Initialize output values + horizontalSpaceLeft = 0; + verticalSpaceLeft = 0; + + // Use current legend item count if number of items to check is not specified + if(numberOfItemsToCheck < 0) + { + numberOfItemsToCheck = this.legendItems.Count; + } + + // Calculate how many sub-columns (cells) this legend has + int numberOfSubColumns = this.GetNumberOfCells(); + + // Each column may have its own number of rows. Calculate the maximum number of rows. + int maxNumberOfRows = this.GetMaximumNumberOfRows(numberOfRowsPerColumn); + + // Create multidimensional arrays that will be holding the widths and heightsof all + // individual cells. First dimension will be the legend column index, second dimension + // is row index and the third is sub-column (cell) index. + int[,,] cellWidths = new int[numberOfColumns, maxNumberOfRows, numberOfSubColumns]; + cellHeights = new int[numberOfColumns, maxNumberOfRows]; + + + //************************************************************************* + //** Measure legend font single character + //************************************************************************* + this.singleWCharacterSize = graph.MeasureStringAbs("W", (this.autofitFont == null) ? this.Font : this.autofitFont); + Size doubleCharacterSize = graph.MeasureStringAbs("WW", (this.autofitFont == null) ? this.Font : this.autofitFont); + this.singleWCharacterSize.Width = doubleCharacterSize.Width - this.singleWCharacterSize.Width; + + + //************************************************************************* + //** Iterate through all legend items and measure each individual cell + //************************************************************************* + int currentColumn = 0; + int currentRow = 0; + for(int legendItemIndex = 0; legendItemIndex < numberOfItemsToCheck; legendItemIndex++) + { + LegendItem legendItem = this.legendItems[legendItemIndex]; + + // Iterate through legend item cells + int numberOfCellsToSkip = 0; + for(int cellIndex = 0; cellIndex < legendItem.Cells.Count; cellIndex++) + { + // Get legend cell + LegendCell legendCell = legendItem.Cells[cellIndex]; + + // Get assocated legend column object (may be NULL) + LegendCellColumn legendColumn = null; + if(cellIndex < this.CellColumns.Count) + { + legendColumn = this.CellColumns[cellIndex]; + } + + // Check if current cell should be skipped becuse it's overlapped + // by the previous sell that uses CellSpan. + if(numberOfCellsToSkip > 0) + { + // Put size (-1) for the cells that follow a cell using ColumnSpan + cellWidths[currentColumn, currentRow, cellIndex] = -1; + --numberOfCellsToSkip; + continue; + } + + // Check if current cell uses CellSpan + if(legendCell.CellSpan > 1) + { + numberOfCellsToSkip = legendCell.CellSpan - 1; + } + + // Measure cell and store the value in the array + Size cellSize = legendCell.MeasureCell( + graph, + fontSizeReducedBy, + (this.autofitFont == null) ? this.Font : this.autofitFont, + this.singleWCharacterSize); + + // Check for column maximum/minimum cell width restrictions + if(legendColumn != null) + { + if(legendColumn.MinimumWidth >= 0) + { + cellSize.Width = (int)Math.Max(cellSize.Width, legendColumn.MinimumWidth * singleWCharacterSize.Width / 100f); + } + if(legendColumn.MaximumWidth >= 0) + { + cellSize.Width = (int)Math.Min(cellSize.Width, legendColumn.MaximumWidth * singleWCharacterSize.Width / 100f); + } + } + + // Store cell size in arrays + cellWidths[currentColumn, currentRow, cellIndex] = cellSize.Width; + if(cellIndex == 0) + { + cellHeights[currentColumn, currentRow] = cellSize.Height; + } + else + { + cellHeights[currentColumn, currentRow] = + Math.Max(cellHeights[currentColumn, currentRow], cellSize.Height); + } + } + + // Advance to the next row/column. Break if number of legend items exceed + // number of availabale rows/columns. + ++currentRow; + if(currentRow >= numberOfRowsPerColumn[currentColumn]) + { + ++currentColumn; + currentRow = 0; + if(currentColumn >= numberOfColumns) + { + // Check if we were able to fit all the items + if(legendItemIndex < numberOfItemsToCheck - 1) + { + fitFlag = false; + } + break; + } + } + } + + //************************************************************************* + //** For each sub-column get the maximum cell width + //************************************************************************* + subColumnSizes = new int[numberOfColumns, numberOfSubColumns]; + bool secondIterationRequired = false; + for(currentColumn = 0; currentColumn < numberOfColumns; currentColumn++) + { + for(int currentSubColumn = 0; currentSubColumn < numberOfSubColumns; currentSubColumn++) + { + int width = 0; + for(currentRow = 0; currentRow < numberOfRowsPerColumn[currentColumn]; currentRow++) + { + // Get current cell size + int cellWidth = cellWidths[currentColumn, currentRow, currentSubColumn]; + + // Skip overlapped cells and cells that use ColumnSpan during the + // first iteration. Their size will be determined during the + // second iteration. + if(cellWidth < 0) + { + secondIterationRequired = true; + continue; + } + if(currentSubColumn + 1 < numberOfSubColumns) + { + int nextCellWidth = cellWidths[currentColumn, currentRow, currentSubColumn + 1]; + if(nextCellWidth < 0) + { + continue; + } + } + + // Get maximum width + width = Math.Max(width, cellWidth ); + } + + // Store maximum width in the array + subColumnSizes[currentColumn, currentSubColumn] = width; + } + } + + //************************************************************************* + //** If leagend header text is used check if it fits into the currenly + //** calculated sub-column sizes. + //************************************************************************* + + for(currentColumn = 0; currentColumn < numberOfColumns; currentColumn++) + { + for(int currentSubColumn = 0; currentSubColumn < numberOfSubColumns; currentSubColumn++) + { + if(currentSubColumn < this.CellColumns.Count) + { + LegendCellColumn legendColumn = this.CellColumns[currentSubColumn]; + if(legendColumn.HeaderText.Length > 0) + { + // Note that extra "I" character added to add more horizontal spacing + Size headerTextSize = graph.MeasureStringAbs(legendColumn.HeaderText + "I", legendColumn.HeaderFont); + if(headerTextSize.Width > subColumnSizes[currentColumn, currentSubColumn]) + { + // Set new width + subColumnSizes[currentColumn, currentSubColumn] = headerTextSize.Width; + + // Check for column maximum/minimum cell width restrictions + if(legendColumn.MinimumWidth >= 0) + { + subColumnSizes[currentColumn, currentSubColumn] = + (int)Math.Max(subColumnSizes[currentColumn, currentSubColumn], legendColumn.MinimumWidth * singleWCharacterSize.Width / 100f); + } + if(legendColumn.MaximumWidth >= 0) + { + subColumnSizes[currentColumn, currentSubColumn] = + (int)Math.Min(subColumnSizes[currentColumn, currentSubColumn], legendColumn.MaximumWidth * singleWCharacterSize.Width / 100f); + } + } + } + } + } + } + + //************************************************************************* + //** Adjust width of the cells to fit cell content displayed across + //** several cells (CellSpanning). + //************************************************************************* + if(secondIterationRequired) + { + for(currentColumn = 0; currentColumn < numberOfColumns; currentColumn++) + { + for(int currentSubColumn = 0; currentSubColumn < numberOfSubColumns; currentSubColumn++) + { + for(currentRow = 0; currentRow < numberOfRowsPerColumn[currentColumn]; currentRow++) + { + // Get current cell size + int cellWidth = cellWidths[currentColumn, currentRow, currentSubColumn]; + + // Second iteration used to adjust width of the cells that are used to + // draw content across several horizontal cells (CellSpanning) + // Check if current cell will be spanned to the next ones + int cellSpan = 0; + while(currentSubColumn + cellSpan + 1 < numberOfSubColumns) + { + int nextCellWidth = cellWidths[currentColumn, currentRow, currentSubColumn + cellSpan + 1]; + if(nextCellWidth >= 0) + { + break; + } + ++cellSpan; + } + + + // Cell span was detected + if(cellSpan > 0) + { + // Calculate total width of current cell and all overlapped cells + int spanWidth = 0; + for(int index = 0; index <= cellSpan; index++) + { + spanWidth += subColumnSizes[currentColumn, currentSubColumn + index]; + } + + // Check if current cell fits into the cell span + if(cellWidth > spanWidth) + { + // Adjust last span cell width to fit all curent cell content + subColumnSizes[currentColumn, currentSubColumn + cellSpan] += cellWidth - spanWidth; + } + } + } + } + } + } + + + //************************************************************************* + //** Check if equally spaced legend columns are used + //************************************************************************* + if(this.IsEquallySpacedItems) + { + // Makre sure that same sub-colimn width are used in all columns + for(int currentSubColumn = 0; currentSubColumn < numberOfSubColumns; currentSubColumn++) + { + int width = 0; + for(currentColumn = 0; currentColumn < numberOfColumns; currentColumn++) + { + width = Math.Max(width, subColumnSizes[currentColumn, currentSubColumn]); + } + + // Set new sub-column width for each column + for(currentColumn = 0; currentColumn < numberOfColumns; currentColumn++) + { + subColumnSizes[currentColumn, currentSubColumn] = width; + } + } + } + + //************************************************************************* + //** Calculate total width and height occupied by all cells + //************************************************************************* + int totalWidth = 0; + int totalTableColumnSpacingWidth = 0; + for(currentColumn = 0; currentColumn < numberOfColumns; currentColumn++) + { + // Add up all sub-columns + for(int currentSubColumn = 0; currentSubColumn < numberOfSubColumns; currentSubColumn++) + { + totalWidth += subColumnSizes[currentColumn, currentSubColumn]; + } + + // Add spacer between columns + if(currentColumn < numberOfColumns - 1) + { + totalTableColumnSpacingWidth += this.GetSeparatorSize(this.ItemColumnSeparator).Width; + } + } + + int totalHeight = 0; + for(currentColumn = 0; currentColumn < numberOfColumns; currentColumn++) + { + int columnHeight = 0; + for(currentRow = 0; currentRow < numberOfRowsPerColumn[currentColumn]; currentRow++) + { + columnHeight += cellHeights[currentColumn, currentRow]; + } + + totalHeight = Math.Max(totalHeight, columnHeight); + } + + //************************************************************************* + //** Check if everything fits + //************************************************************************* + horizontalSpaceLeft = legendItemsAreaSize.Width - totalWidth - totalTableColumnSpacingWidth; + if(horizontalSpaceLeft < 0) + { + fitFlag = false; + } + + verticalSpaceLeft = legendItemsAreaSize.Height - totalHeight; + if(verticalSpaceLeft < 0) + { + fitFlag = false; + } + + return fitFlag; + } + + /// + /// Gets maximum number of legend cells defined as Column objects + /// or Cells in the custom legend items. + /// + /// Maximum number of cells. + private int GetNumberOfCells() + { + // Calculate cell number if it was not previously cached + if(this._numberOfCells < 0) + { + // Initialize with number of defined columns + this._numberOfCells = this.CellColumns.Count; + + // Check if number of cells in legend items exceed number of defined columns + foreach(LegendItem legendItem in this.legendItems) + { + this._numberOfCells = Math.Max(this._numberOfCells, legendItem.Cells.Count); + } + } + return this._numberOfCells; + } + + #endregion // Legend Items Fitting Methods + + #region Legend items collection filling methods + + /// + /// Add all series legend into items collection and then + /// add custom legend items. + /// + private void FillLegendItemsCollection() + { + // Clear all items + legendItems.Clear(); + + // Check that there is no invalid legend names in the series + foreach(Series series in this.Common.DataManager.Series) + { + if (this.Common.ChartPicture.Legends.IndexOf(series.Legend)<0) + { + throw (new InvalidOperationException(SR.ExceptionLegendReferencedInSeriesNotFound(series.Name, series.Legend))); + } + } + + // Flag which indicates that series requires legend items to be reversed + bool seriesWithReversedLegendItemsPresent = false; + + // Add legend items based on the exsisting chart series + foreach(Series series in this.Common.DataManager.Series) + { + // Check if series uses this legend + // VSTS issue #140694 fix: support of series.Legend = "Default"; + if (this.Common.ChartPicture.Legends[series.Legend] != this) + { + continue; + } + + // Make sure series is assigned to the chart area + if(series.ChartArea.Length > 0) + { + // Check if chart area name is valid + bool areaNameFound = false; + foreach(ChartArea area in this.Common.ChartPicture.ChartAreas) + { + if(area.Name == series.ChartArea) + { + areaNameFound = true; + break; + } + } + + // Check if series is visible and valid chart area name was used + if(series.IsVisible() && areaNameFound) + { + // Check if we should add all data points into the legend + IChartType chartType = this.Common.ChartTypeRegistry.GetChartType(series.ChartTypeName); + + + // Check if series legend items should be reversed + if (this.LegendItemOrder == LegendItemOrder.Auto) + { + if(series.ChartType == SeriesChartType.StackedArea || + series.ChartType == SeriesChartType.StackedArea100 || + series.ChartType == SeriesChartType.Pyramid || + series.ChartType == SeriesChartType.StackedColumn || + series.ChartType == SeriesChartType.StackedColumn100 ) + { + seriesWithReversedLegendItemsPresent = true; + } + } + // Add item(s) based on series points label and fore color + if(chartType.DataPointsInLegend) + { + // Check if data points have X values set + bool xValuesSet = false; + foreach(DataPoint point in series.Points) + { + if(point.XValue != 0.0) + { + xValuesSet = true; + break; + } + } + + // Add legend items for each point + int index = 0; + foreach(DataPoint point in series.Points) + { + // Do not show empty data points in the legend + if(point.IsEmpty) + { + ++index; + continue; + } + + // Point should not be shown in the legend + if(!point.IsVisibleInLegend) + { + ++index; + continue; + } + + // Create new legend item + LegendItem item = new LegendItem(point.Label, point.Color, ""); + + // Check if series is drawn in 3D chart area + bool area3D = this.Common.Chart.ChartAreas[series.ChartArea].Area3DStyle.Enable3D; + + // Set legend item appearance properties + item.SetAttributes(this.Common, series); + item.SetAttributes(point, area3D); + + // Set chart image map properties + item.ToolTip = point.ReplaceKeywords(point.LegendToolTip); +#if !Microsoft_CONTROL + item.MapAreaAttributes = point.ReplaceKeywords(point.LegendMapAreaAttributes); + item.PostBackValue = point.ReplaceKeywords(point.LegendPostBackValue); + item.Url = point.ReplaceKeywords(point.LegendUrl); +#endif + item.Name = point.ReplaceKeywords(point.LegendText); + + item.SeriesPointIndex = index++; + if(item.Name.Length == 0) + { + item.Name = point.ReplaceKeywords((point.Label.Length > 0) ? point.Label : point.AxisLabel); + } + + // If legend item name is not defined - try using the X value + if(item.Name.Length == 0 && xValuesSet) + { + item.Name = ValueConverter.FormatValue( + series.Chart, + this, + this.Tag, + point.XValue, + "", // Do not use point label format! For Y values only! point.LabelFormat, + point.series.XValueType, + ChartElementType.LegendItem); + } + + // If legend item name is not defined - use index + if(item.Name.Length == 0) + { + item.Name = "Point " + index; + } + + // Add legend item cells based on predefined columns + item.AddAutomaticCells(this); + foreach(LegendCell cell in item.Cells) + { + if(cell.Text.Length > 0) + { + // #LEGENDTEXT - series name + cell.Text = cell.Text.Replace(KeywordName.LegendText, item.Name); + + // Process rest of the keywords + cell.Text = point.ReplaceKeywords(cell.Text); + cell.ToolTip = point.ReplaceKeywords(cell.ToolTip); +#if !Microsoft_CONTROL + cell.Url = point.ReplaceKeywords(cell.Url); + cell.MapAreaAttributes = point.ReplaceKeywords(cell.MapAreaAttributes); + cell.PostBackValue = point.ReplaceKeywords(cell.PostBackValue); +#endif // !Microsoft_CONTROL + } + } + + legendItems.Add(item); + } + } + + // Add item based on series name and fore color + else + { + // Point should not be shown in the legend + if(!series.IsVisibleInLegend) + { + continue; + } + + // Create legend item + LegendItem item = new LegendItem(series.Name, series.Color, ""); + item.SetAttributes(this.Common, series); + + item.ToolTip = series.ReplaceKeywords(series.LegendToolTip); +#if !Microsoft_CONTROL + item.Url = series.ReplaceKeywords(series.LegendUrl); + item.MapAreaAttributes = series.ReplaceKeywords(series.LegendMapAreaAttributes); + item.PostBackValue = series.ReplaceKeywords(series.LegendPostBackValue); +#endif // !Microsoft_CONTROL + + if (series.LegendText.Length > 0) + { + item.Name = series.ReplaceKeywords(series.LegendText); + } + + // Add legend item cells based on predefined columns + item.AddAutomaticCells(this); + foreach(LegendCell cell in item.Cells) + { + if(cell.Text.Length > 0) + { + // #LEGENDTEXT - series name + cell.Text = cell.Text.Replace(KeywordName.LegendText, item.Name); + + // Process rest of the keywords + cell.Text = series.ReplaceKeywords(cell.Text); + cell.ToolTip = series.ReplaceKeywords(cell.ToolTip); +#if !Microsoft_CONTROL + cell.Url = series.ReplaceKeywords(cell.Url); + cell.MapAreaAttributes = series.ReplaceKeywords(cell.MapAreaAttributes); + cell.PostBackValue = series.ReplaceKeywords(cell.PostBackValue); +#endif // !Microsoft_CONTROL + } + } + + legendItems.Add(item); + } + } + } + } + + + // Check if series legend items should be reversed + if (this.LegendItemOrder == LegendItemOrder.SameAsSeriesOrder || + (this.LegendItemOrder == LegendItemOrder.Auto && seriesWithReversedLegendItemsPresent)) + { + // Reversed series generated legend items + legendItems.Reverse(); + } + + + // Add custom items + foreach(LegendItem item in this._customLegends) + { + if(item.Enabled) + { + legendItems.Add(item); + } + } + + // Legend can't be empty at design time + if(legendItems.Count == 0 && this.Common != null && this.Common.Chart != null) + { + if(this.Common.Chart.IsDesignMode()) + { + LegendItem item = new LegendItem(this.Name + " - " + SR.DescriptionTypeEmpty, Color.White, ""); + item.ImageStyle = LegendImageStyle.Line; + legendItems.Add(item); + } + } + + // Add legend item cells based on predefined columns + foreach(LegendItem item in this.legendItems) + { + item.AddAutomaticCells(this); + } + + } + + #endregion + + #region Legend painting methods + + /// + /// Paints legend using chart graphics object. + /// + /// The graph provides drawing object to the display device. A Graphics object is associated with a specific device context. + internal void Paint(ChartGraphics chartGraph ) + { + // Reset some values + this._offset = Size.Empty; + this._itemColumns = 0; + this._horizontalSpaceLeft = 0; + this._verticalSpaceLeft = 0; + this._subColumnSizes = null; + this._numberOfRowsPerColumn = null; + this._cellHeights = null; + this.autofitFont = null; + this._autoFitFontSizeAdjustment = 0; + this._numberOfCells = -1; + this._numberOfLegendItemsToProcess = -1; + + // Do nothing if legend disabled + if(!this.IsEnabled() || + (this.MaximumAutoSize == 0f && this.Position.Auto)) + { + return; + } + + // Add all series legend into items collection and then add custom legend items + FillLegendItemsCollection(); + + // Clear all legend item cells information + foreach(LegendItem legendItem in this.legendItems) + { + foreach(LegendCell cell in legendItem.Cells) + { + cell.ResetCache(); + } + } + + // Call a notification event, so that legend items collection can be modified by user + this.Common.Chart.CallOnCustomizeLegend(legendItems, this.Name); + + // Check if legend is empty + if(this.legendItems.Count == 0) + { + return; + } + + //*********************************************************** + //** RecalculateAxesScale legend information + //*********************************************************** + this.RecalcLegendInfo(chartGraph); + + + + //*********************************************************** + //** Paint legend + //*********************************************************** + + // Call BackPaint event + if( Common.ProcessModePaint ) + { + // Draw legend background, border and shadow + chartGraph.FillRectangleRel( + chartGraph.GetRelativeRectangle(Rectangle.Round(chartGraph.GetAbsoluteRectangle(this.Position.ToRectangleF()))), + BackColor, + BackHatchStyle, + BackImage, + BackImageWrapMode, + BackImageTransparentColor, + BackImageAlignment, + BackGradientStyle, + BackSecondaryColor, + BorderColor, + this.GetBorderSize(), + BorderDashStyle, + ShadowColor, + ShadowOffset, + PenAlignment.Inset); + + Common.Chart.CallOnPrePaint(new ChartPaintEventArgs(this, chartGraph, Common, Position)); + } + + if( Common.ProcessModeRegions ) + { + SelectLegendBackground(); + } + + //*********************************************************** + //** Draw legend header + //*********************************************************** + + this.DrawLegendHeader(chartGraph); + + //*********************************************************** + //** Draw legend title + //*********************************************************** + + this.DrawLegendTitle(chartGraph); + + // Add legend title hot region + if( Common.ProcessModeRegions && !this._titlePosition.IsEmpty) + { + Common.HotRegionsList.AddHotRegion(chartGraph.GetRelativeRectangle(this._titlePosition), this, ChartElementType.LegendTitle, true ); + } + + //*********************************************************** + //** Draw legend items + //*********************************************************** + if(this._numberOfLegendItemsToProcess < 0) + { + this._numberOfLegendItemsToProcess = this.legendItems.Count; + } + for(int itemIndex = 0; itemIndex < this._numberOfLegendItemsToProcess; itemIndex++) + { + LegendItem legendItem = this.legendItems[itemIndex]; + + // Iterate through legend item cells + for(int cellIndex = 0; cellIndex < legendItem.Cells.Count; cellIndex++) + { + // Get legend cell + LegendCell legendCell = legendItem.Cells[cellIndex]; + + // Paint cell + legendCell.Paint( + chartGraph, + this._autoFitFontSizeAdjustment, + this.autofitFont, + this.singleWCharacterSize); + } + + // Paint legend item separator + if(legendItem.SeparatorType != LegendSeparatorStyle.None && + legendItem.Cells.Count > 0) + { + // Calculate separator position + Rectangle separatorPosition = Rectangle.Empty; + separatorPosition.X = legendItem.Cells[0].cellPosition.Left; + + // Find right most cell position excluding ovelapped cells that have negative size + int right = 0; + for(int index = legendItem.Cells.Count - 1; index >= 0; index--) + { + right = legendItem.Cells[index].cellPosition.Right; + if(right > 0) + { + break; + } + } + separatorPosition.Width = right - separatorPosition.X; + separatorPosition.Y = legendItem.Cells[0].cellPosition.Bottom; + separatorPosition.Height = this.GetSeparatorSize(legendItem.SeparatorType).Height; + separatorPosition.Intersect(this._legendItemsAreaPosition); + + // Draw separator + this.DrawSeparator( + chartGraph, + legendItem.SeparatorType, + legendItem.SeparatorColor, + true, + separatorPosition); + } + } + + //*********************************************************** + //** If legend items are in multiple columns draw vertical + //** separator + //*********************************************************** + if(this.ItemColumnSeparator != LegendSeparatorStyle.None) + { + Rectangle separatorRect = Rectangle.Round(chartGraph.GetAbsoluteRectangle(this.Position.ToRectangleF())); + separatorRect.Y += this.GetBorderSize() + this._titlePosition.Height; + separatorRect.Height -= 2 * this.GetBorderSize() + this._titlePosition.Height; + separatorRect.X += this.GetBorderSize() + this._offset.Width; + separatorRect.Width = this.GetSeparatorSize(this.ItemColumnSeparator).Width; + if(this._horizontalSpaceLeft > 0) + { + separatorRect.X += this._horizontalSpaceLeft / 2; + } + + // Check position + if(separatorRect.Width > 0 && separatorRect.Height > 0) + { + // Iterate through all columns + for(int columnIndex = 0; columnIndex < this._itemColumns; columnIndex++ ) + { + // Iterate through all sub-columns + int cellCount = this.GetNumberOfCells(); + for(int subColumnIndex = 0; subColumnIndex < cellCount; subColumnIndex++ ) + { + separatorRect.X += this._subColumnSizes[columnIndex, subColumnIndex]; + } + + // Draw separator if not the last column + if(columnIndex < this._itemColumns - 1) + { + this.DrawSeparator(chartGraph, this.ItemColumnSeparator, this.ItemColumnSeparatorColor, false, separatorRect); + } + + // Add separator width + separatorRect.X += separatorRect.Width; + } + } + } + + //*********************************************************** + //** Draw special indicator on the bottom of the legend if + //** it was truncated. + //*********************************************************** + if(this._legendItemsTruncated && + this._legendItemsAreaPosition.Height > this._truncatedDotsSize / 2) + { + // Calculate dots step (no more than 10 pixel) + int markerCount = 3; + int step = (this._legendItemsAreaPosition.Width / 3) / markerCount; + step = (int)Math.Min(step, 10); + + // Calculate start point + PointF point = new PointF( + this._legendItemsAreaPosition.X + this._legendItemsAreaPosition.Width / 2 - step * (float)Math.Floor(markerCount/2f), + this._legendItemsAreaPosition.Bottom + (this._truncatedDotsSize + this._offset.Height) / 2); + + // Draw several dots at the bottom of the legend + for(int index = 0; index < markerCount; index++) + { + chartGraph.DrawMarkerRel( + chartGraph.GetRelativePoint(point), + MarkerStyle.Circle, + this._truncatedDotsSize, + this.ForeColor, + Color.Empty, + 0, + string.Empty, + Color.Empty, + 0, + Color.Empty, + RectangleF.Empty); + + // Shift to the right + point.X += step; + } + + } + + + // Call Paint event + if( Common.ProcessModePaint ) + { + Common.Chart.CallOnPostPaint(new ChartPaintEventArgs(this, chartGraph, Common, Position)); + } + + // Remove temporary cells from legend items + foreach(LegendItem legendItem in this.legendItems) + { + if(legendItem.clearTempCells) + { + legendItem.clearTempCells = false; + legendItem.Cells.Clear(); + } + } + + } + + #endregion + + #region Legend properties + + /// + /// Gets or sets the name of the legend. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + SRDescription("DescriptionAttributeLegend_Name"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public override string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + + /// + /// Gets or sets the name of the chart area where the legend + /// should be docked. + /// + [ + SRCategory("CategoryAttributeDocking"), + Bindable(true), + DefaultValue(Constants.NotSetValue), + SRDescription("DescriptionAttributeLegend_DockToChartArea"), + TypeConverter(typeof(LegendAreaNameConverter)), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public string DockedToChartArea + { + get + { + return _dockedToChartArea; + } + set + { + if(value != _dockedToChartArea) + { + if (String.IsNullOrEmpty(value)) + { + _dockedToChartArea = Constants.NotSetValue; + } + else + { + if (Chart != null && Chart.ChartAreas != null) + { + Chart.ChartAreas.VerifyNameReference(value); + } + _dockedToChartArea = value; + } + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets a property which indicates whether + /// the legend is docked inside the chart area. + /// This property is only available when DockedToChartArea is set. + /// + [ + SRCategory("CategoryAttributeDocking"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeLegend_DockInsideChartArea"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public bool IsDockedInsideChartArea + { + get + { + return _isDockedInsideChartArea; + } + set + { + if(value != _isDockedInsideChartArea) + { + _isDockedInsideChartArea = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the position of the legend. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeLegend_Position"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ElementPositionConverter)), + SerializationVisibilityAttribute(SerializationVisibility.Element) + ] + public ElementPosition Position + { + get + { + // Serialize only position values if Auto set to false + if (this.Common != null && this.Common.Chart != null && this.Common.Chart.serializationStatus == SerializationStatus.Saving) + { + if(_position.Auto) + { + return new ElementPosition(); + } + else + { + ElementPosition newPosition = new ElementPosition(); +#if Microsoft_CONTROL + newPosition.Auto = false; +#else + newPosition.Auto = true; +#endif + newPosition.SetPositionNoAuto(_position.X, _position.Y, _position.Width, _position.Height); + return newPosition; + } + } + return _position; + } + set + { + _position = value; + this.Invalidate(false); + } + } + + /// + /// Determoines if this position should be serialized. + /// + /// + internal bool ShouldSerializePosition() + { + return !this.Position.Auto; + } + + + /// + /// Gets or sets a property which indicates whether + /// all legend items are equally spaced. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(false), + SRDescription("DescriptionAttributeLegend_EquallySpacedItems"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsEquallySpacedItems + { + get + { + return _isEquallySpacedItems; + } + set + { + _isEquallySpacedItems = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets a flag which indicates whether the legend is enabled. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeLegend_Enabled"), + NotifyParentPropertyAttribute(true), + ParenthesizePropertyNameAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool Enabled + { + get + { + return _enabled; + } + set + { + _enabled = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets a value that indicates if legend text is automatically sized. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeLegend_AutoFitText"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool IsTextAutoFit + { + get + { + return _isTextAutoFit; + } + set + { + _isTextAutoFit = value; + + if(_isTextAutoFit) + { + // Reset the font size to "8" + // Use current font family name ans style if possible. + if(_font != null) + { + _font = _fontCache.GetFont(_font.FontFamily, 8, _font.Style); ; + } + else + { + _font = _fontCache.DefaultFont; + } + } + + this.Invalidate(false); + } + } + + /// + /// Gets or sets the legend style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(LegendStyle.Table), + SRDescription("DescriptionAttributeLegend_LegendStyle"), + NotifyParentPropertyAttribute(true), + ParenthesizePropertyNameAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public LegendStyle LegendStyle + { + get + { + return _legendStyle; + } + set + { + _legendStyle = value; + this.Invalidate(false); + } + } + + + /// + /// Gets or sets the minimum font size that can be used by the legend text's auto-fitting algorithm. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(7), + SRDescription("DescriptionAttributeLegend_AutoFitMinFontSize"), + ] + public int AutoFitMinFontSize + { + get + { + return this._autoFitMinFontSize; + } + set + { + // Font size cannot be less than 5 + if(value < 5) + { + throw (new InvalidOperationException(SR.ExceptionLegendAutoFitMinFontSizeInvalid)); + } + + this._autoFitMinFontSize = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the maximum size (in percentage) of the legend used in the automatic layout algorithm. + /// + /// + /// If the legend is docked to the left or right, this property determines the maximum width of the legend, measured as a percentage. + /// If the legend is docked to the top or bottom, this property determines the maximum height of the legend, measured as a percentage. + /// + [ + SRCategory("CategoryAttributeDocking"), + DefaultValue(50f), + SRDescription("DescriptionAttributeLegend_MaxAutoSize"), + ] + public float MaximumAutoSize + { + get + { + return this._maximumLegendAutoSize; + } + set + { + if(value < 0f || value > 100f) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionLegendMaximumAutoSizeInvalid)); + } + this._maximumLegendAutoSize = value; + this.Invalidate(false); + } + } + + /// + /// Gets a collection of legend columns. + /// + [ + SRCategory("CategoryAttributeCellColumns"), + SRDescription("DescriptionAttributeLegend_CellColumns"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + Editor(Editors.LegendCellColumnCollectionEditor.Editor, Editors.LegendCellColumnCollectionEditor.Base), + ] + public LegendCellColumnCollection CellColumns + { + get + { + return this._cellColumns; + } + } + + /// + /// Gets the legend table style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(LegendTableStyle.Auto), + SRDescription("DescriptionAttributeLegend_TableStyle"), + NotifyParentPropertyAttribute(true), + ParenthesizePropertyNameAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public LegendTableStyle TableStyle + { + get + { + return this._legendTableStyle; + } + set + { + this._legendTableStyle = value; + this.Invalidate(false); + } + } + + /// + /// Gets the legend header separator style. + /// + [ + SRCategory("CategoryAttributeCellColumns"), + DefaultValue(typeof(LegendSeparatorStyle), "None"), + SRDescription("DescriptionAttributeLegend_HeaderSeparator"), + ] + public LegendSeparatorStyle HeaderSeparator + { + get + { + return this._headerSeparator; + } + set + { + if(value != this._headerSeparator) + { + this._headerSeparator = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the color of the legend header separator. + /// + [ + SRCategory("CategoryAttributeCellColumns"), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLegend_HeaderSeparatorColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color HeaderSeparatorColor + { + get + { + return this._headerSeparatorColor; + } + set + { + if(value != this._headerSeparatorColor) + { + this._headerSeparatorColor = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the separator style of the legend table columns. + /// + [ + SRCategory("CategoryAttributeCellColumns"), + DefaultValue(typeof(LegendSeparatorStyle), "None"), + SRDescription("DescriptionAttributeLegend_ItemColumnSeparator"), + ] + public LegendSeparatorStyle ItemColumnSeparator + { + get + { + return this._itemColumnSeparator; + } + set + { + if(value != this._itemColumnSeparator) + { + this._itemColumnSeparator = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the color of the separator of the legend table columns. + /// + [ + SRCategory("CategoryAttributeCellColumns"), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLegend_ItemColumnSeparatorColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color ItemColumnSeparatorColor + { + get + { + return this._itemColumnSeparatorColor; + } + set + { + if(value != this._itemColumnSeparatorColor) + { + this._itemColumnSeparatorColor = value; + this.Invalidate(false); + } + } + } + + + /// + /// Gets or sets the legend table column spacing, as a percentage of the legend text font. + /// + [ + SRCategory("CategoryAttributeCellColumns"), + DefaultValue(50), + SRDescription("DescriptionAttributeLegend_ItemColumnSpacing"), + ] + public int ItemColumnSpacing + { + get + { + return this._itemColumnSpacing; + } + set + { + if(value != this._itemColumnSpacing) + { + if(value < 0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionLegendColumnSpacingInvalid)); + } + this._itemColumnSpacing = value; + this.Invalidate(false); + } + } + } + + + + /// + /// Gets or sets the legend background color. + /// + [ + DefaultValue(typeof(Color), ""), + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeBackColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackColor + { + get + { + return _backColor; + } + set + { + _backColor = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the legend border color. + /// + [ + DefaultValue(typeof(Color), ""), + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeBorderColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BorderColor + { + get + { + return _borderColor; + } + set + { + _borderColor = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the legend border style. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeBorderDashStyle"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartDashStyle BorderDashStyle + { + get + { + return _borderDashStyle; + } + set + { + _borderDashStyle = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the legend border width. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeBorderWidth"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int BorderWidth + { + get + { + return _borderWidth; + } + set + { + if(value < 0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionLegendBorderWidthIsNegative)); + } + _borderWidth = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the legend background image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeBackImage"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + NotifyParentPropertyAttribute(true), + ] + public string BackImage + { + get + { + return _backImage; + } + set + { + _backImage = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the legend background image drawing mode. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageWrapMode.Tile), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageWrapMode"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageWrapMode BackImageWrapMode + { + get + { + return _backImageWrapMode; + } + set + { + _backImageWrapMode = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets a color which will be replaced with a transparent color while drawing the background image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackImageTransparentColor + { + get + { + return _backImageTransparentColor; + } + set + { + _backImageTransparentColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the background image alignment used for the unscaled drawing mode. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageAlignmentStyle.TopLeft), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackImageAlign"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageAlignmentStyle BackImageAlignment + { + get + { + return _backImageAlignment; + } + set + { + _backImageAlignment = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets background gradient style of the legend. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackGradientStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + + ] + public GradientStyle BackGradientStyle + { + get + { + return _backGradientStyle; + } + set + { + _backGradientStyle = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the secondary background color. + /// + /// + /// + /// + /// + /// A value used for the secondary color of background with + /// hatching or gradient fill. + /// + /// + /// This color is used with when or + /// are used. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackSecondaryColor + { + get + { + return _backSecondaryColor; + } + set + { + _backSecondaryColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the background hatch style. + /// + /// + /// + /// + /// + /// A value used for the background. + /// + /// + /// Two colors are used to draw the hatching, and . + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackHatchStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + public ChartHatchStyle BackHatchStyle + { + get + { + return _backHatchStyle; + } + set + { + _backHatchStyle = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the font of the legend text. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"), + SRDescription("DescriptionAttributeLegend_Font"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Font Font + { + get + { + return _font; + } + set + { + this.IsTextAutoFit = false; + + _font = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the color of the legend text. + /// + [ + + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLegendFontColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color ForeColor + { + get + { + return _foreColor; + } + set + { + _foreColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the text alignment. + /// + [ + SRCategory("CategoryAttributeDocking"), + Bindable(true), + DefaultValue(StringAlignment.Near), + SRDescription("DescriptionAttributeLegend_Alignment"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public StringAlignment Alignment + { + get + { + return _legendAlignment; + } + set + { + _legendAlignment = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the property that specifies where the legend docks. + /// + [ + SRCategory("CategoryAttributeDocking"), + Bindable(true), + DefaultValue(Docking.Right), + SRDescription("DescriptionAttributeLegend_Docking"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Docking Docking + { + get + { + return _legendDocking; + } + set + { + _legendDocking = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the offset between the legend and its shadow. + /// + /// + /// + /// An integer value that represents the offset between the legend and its shadow. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributeShadowOffset"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int ShadowOffset + { + get + { + return _shadowOffset; + } + set + { + _shadowOffset = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the color of a legend's shadow. + /// + /// + /// + /// A value used to draw a legend's shadow. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "128, 0, 0, 0"), + SRDescription("DescriptionAttributeShadowColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color ShadowColor + { + get + { + return _shadowColor; + } + set + { + _shadowColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the name of the chart area name inside which the legend is drawn. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + Bindable(false), + DefaultValue(Constants.NotSetValue), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeLegend_InsideChartArea"), + EditorBrowsableAttribute(EditorBrowsableState.Never), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + TypeConverter(typeof(LegendAreaNameConverter)) + ] + public string InsideChartArea + { + get + { + if(this.Common != null && + this.Common.Chart != null && + this.Common.Chart.serializing) + { + return "NotSet"; + } + return this.DockedToChartArea; + } + set + { + if(value.Length == 0) + { + this.DockedToChartArea = Constants.NotSetValue; + } + else + { + this.DockedToChartArea = value; + } + this.Invalidate(false); + } + } + + + /// + /// Gets the custom legend items. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeLegend_CustomItems"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + Editor(Editors.LegendItemCollectionEditor.Editor, Editors.LegendItemCollectionEditor.Base), + ] + public LegendItemsCollection CustomItems + { + get + { + return _customLegends; + } + } + + + + /// + /// Gets or sets a property that defines the preferred number of characters in a line of the legend text. + /// + /// + /// When legend text exceeds the value defined in the TextWrapThreshold property, it will be + /// automatically wrapped on the next whitespace. Text will not be wrapped if there is no whitespace + /// characters in the text. Set this property to zero to disable the feature. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(25), + SRDescription("DescriptionAttributeLegend_TextWrapThreshold"), + ] + public int TextWrapThreshold + { + get + { + return this._textWrapThreshold; + } + set + { + if(value != this._textWrapThreshold) + { + if(value < 0) + { + throw (new ArgumentException(SR.ExceptionTextThresholdIsNegative, "value")); + } + this._textWrapThreshold = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets a property that specifies the order that legend items are shown. This property only affects + /// legend items automatically added for the chart series and has no effect on custom legend items. + /// + /// + /// When the LegendItemOrder property is set to Auto, the legend will automatically be reversed + /// if StackedColumn, StackedColumn100, StackedArea or StackedArea100 chart types are used. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(LegendItemOrder.Auto), + SRDescription("DescriptionAttributeLegend_Reversed"), + ] + public LegendItemOrder LegendItemOrder + { + get + { + return this._legendItemOrder; + } + set + { + if(value != this._legendItemOrder) + { + this._legendItemOrder = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets a flag which indicates whether + /// legend rows should be drawn with interlaced background color. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(false), + SRDescription("DescriptionAttributeLegend_InterlacedRows"), + ] + public bool InterlacedRows + { + get + { + return this._interlacedRows; + } + set + { + if(value != this._interlacedRows) + { + this._interlacedRows = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the legend interlaced row's background color. Only applicable if interlaced rows are used. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeLegend_InterlacedRowsColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color InterlacedRowsColor + { + get + { + return this._interlacedRowsColor; + } + set + { + if(value != this._interlacedRowsColor) + { + this._interlacedRowsColor = value; + this.Invalidate(false); + } + } + } + + #endregion + + #region Legend Title Properties + + /// + /// Gets or sets the title text of the legend. + /// + [ + SRCategory("CategoryAttributeTitle"), + DefaultValue(""), + SRDescription("DescriptionAttributeLegend_Title"), + ] + public string Title + { + get + { + return this._title; + } + set + { + if(value != this._title) + { + this._title = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the text color of the legend title. + /// + [ + SRCategory("CategoryAttributeTitle"), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLegend_TitleColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color TitleForeColor + { + get + { + return this._titleForeColor; + } + set + { + if(value != this._titleForeColor) + { + this._titleForeColor = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the background color of the legend title. + /// + [ + SRCategory("CategoryAttributeTitle"), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeTitleBackColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color TitleBackColor + { + get + { + return this._titleBackColor; + } + set + { + if(value != this._titleBackColor) + { + this._titleBackColor = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the font of the legend title. + /// + [ + SRCategory("CategoryAttributeTitle"), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt, style=Bold"), + SRDescription("DescriptionAttributeTitleFont"), + ] + public Font TitleFont + { + get + { + return this._titleFont; + } + set + { + if(value != this._titleFont) + { + this._titleFont = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the text alignment of the legend title. + /// + [ + SRCategory("CategoryAttributeTitle"), + DefaultValue(typeof(StringAlignment), "Center"), + SRDescription("DescriptionAttributeLegend_TitleAlignment"), + ] + public StringAlignment TitleAlignment + { + get + { + return this._titleAlignment; + } + set + { + if(value != this._titleAlignment) + { + this._titleAlignment = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the separator style of the legend title. + /// + [ + SRCategory("CategoryAttributeTitle"), + DefaultValue(typeof(LegendSeparatorStyle), "None"), + SRDescription("DescriptionAttributeLegend_TitleSeparator"), + ] + public LegendSeparatorStyle TitleSeparator + { + get + { + return this._titleSeparator; + } + set + { + if(value != this._titleSeparator) + { + this._titleSeparator = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the separator color of the legend title. + /// + [ + SRCategory("CategoryAttributeTitle"), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLegend_TitleSeparatorColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color TitleSeparatorColor + { + get + { + return this._titleSeparatorColor; + } + set + { + if(value != this._titleSeparatorColor) + { + this._titleSeparatorColor = value; + this.Invalidate(false); + } + } + } + + + + #endregion // Legend Title Properties + + #region Legent Title and Header Helper methods + + /// + /// Gets legend title size in relative coordinates. + /// + /// Chart graphics. + /// Maximum possible legend title size. + /// Legend yitle size. + private Size GetTitleSize(ChartGraphics chartGraph, Size titleMaxSize) + { + Size titleSize = Size.Empty; + if(this.Title.Length > 0) + { + // Adjust available space + titleMaxSize.Width -= this.GetBorderSize() * 2 + this._offset.Width; + + // Measure title text size + titleSize = chartGraph.MeasureStringAbs( + this.Title.Replace("\\n", "\n"), + this.TitleFont, + titleMaxSize, + StringFormat.GenericTypographic); + + // Add text spacing + titleSize.Height += this._offset.Height; + titleSize.Width += this._offset.Width; + + // Add space required for the title separator + titleSize.Height += this.GetSeparatorSize(this.TitleSeparator).Height; + } + + return titleSize; + } + + /// + /// Gets legend header size in relative coordinates. + /// + /// Chart graphics. + /// Legend column to get the header for. + /// Legend yitle size. + private Size GetHeaderSize(ChartGraphics chartGraph, LegendCellColumn legendColumn) + { + Size headerSize = Size.Empty; + if(legendColumn.HeaderText.Length > 0) + { + // Measure title text size + headerSize = chartGraph.MeasureStringAbs( + legendColumn.HeaderText.Replace("\\n", "\n") + "I", + legendColumn.HeaderFont); + + // Add text spacing + headerSize.Height += this._offset.Height; + headerSize.Width += this._offset.Width; + + // Add space required for the title separator + headerSize.Height += this.GetSeparatorSize(this.HeaderSeparator).Height; + } + + return headerSize; + } + + /// + /// Draw Legend header. + /// + /// Chart graphics to draw the header on. + private void DrawLegendHeader(ChartGraphics chartGraph) + { + // Check if header should be drawn + if(!this._headerPosition.IsEmpty && + this._headerPosition.Width > 0 && + this._headerPosition.Height > 0) + { + int prevRightLocation = -1; + bool redrawLegendBorder = false; + + // Get Legend position + Rectangle legendPosition = Rectangle.Round(chartGraph.GetAbsoluteRectangle(this.Position.ToRectangleF())); + legendPosition.Y += /*this.offset.Height + */this.GetBorderSize(); + legendPosition.Height -= 2 * (this._offset.Height + this.GetBorderSize()); + legendPosition.X += this.GetBorderSize(); + legendPosition.Width -= 2 * this.GetBorderSize(); + if(this.GetBorderSize() > 0) + { + ++legendPosition.Height; + ++legendPosition.Width; + } + + // Check if at least 1 column header has non-empty background color + bool headerBackFill = false; + for(int subColumnIndex = 0; subColumnIndex < this.CellColumns.Count; subColumnIndex++ ) + { + LegendCellColumn legendColumn = this.CellColumns[subColumnIndex]; + if(!legendColumn.HeaderBackColor.IsEmpty) + { + headerBackFill = true; + } + } + + // Iterate through all columns + for(int columnIndex = 0; columnIndex < this._itemColumns; columnIndex++ ) + { + int columnStart = 0; + int columnWidth = 0; + + // Iterate through all sub-columns + int numberOfSubColumns = this._subColumnSizes.GetLength(1); + for(int subColumnIndex = 0; subColumnIndex < numberOfSubColumns; subColumnIndex++ ) + { + // Calculate position of the header + Rectangle rect = this._headerPosition; + if(_horizontalSpaceLeft > 0) + { + rect.X += (int)(this._horizontalSpaceLeft / 2f); + } + if(prevRightLocation != -1) + { + rect.X = prevRightLocation; + } + rect.Width = this._subColumnSizes[columnIndex, subColumnIndex]; + prevRightLocation = rect.Right; + + // Remember column start position and update width + if(subColumnIndex == 0) + { + columnStart = rect.Left; + } + columnWidth += rect.Width; + + // Make sure header position do not go outside of the legend + rect.Intersect(legendPosition); + if(rect.Width > 0 && rect.Height > 0) + { + // Define fill rectangle + Rectangle fillRect = rect; + + // Make sure header fill riches legend top border + if(this._titlePosition.Height <= 0) + { + fillRect.Y -= this._offset.Height; + fillRect.Height += this._offset.Height; + } + + // Stretch header fill rectangle and separators when vertical + // separator are used or if there is 1 column with header background + if( (this._itemColumns == 1 && headerBackFill) || + this.ItemColumnSeparator != LegendSeparatorStyle.None) + { + // For the first cell in the first column stretch filling + // to the left side of the legend + if(columnIndex == 0 && subColumnIndex == 0) + { + int newX = legendPosition.X; + columnWidth += columnStart - newX; + columnStart = newX; + fillRect.Width += fillRect.X - legendPosition.X; + fillRect.X = newX; + } + + // For the last cell in the last column stretch filling + // to the right side of the legend + if(columnIndex == (this._itemColumns - 1) && + subColumnIndex == (numberOfSubColumns - 1) ) + { + columnWidth += legendPosition.Right - fillRect.Right + 1; + fillRect.Width += legendPosition.Right - fillRect.Right + 1; + } + + // For the first cell of any column except the first one + // make sure we also fill the item column spacing + if(columnIndex != 0 && subColumnIndex == 0) + { + columnWidth += this._itemColumnSpacingRel / 2; + columnStart -= this._itemColumnSpacingRel / 2; + fillRect.Width += this._itemColumnSpacingRel / 2; + fillRect.X -= this._itemColumnSpacingRel / 2; + } + + // For the last cell in all columns except the last one + // make sure we also fill the item column spacing + if(columnIndex != (this._itemColumns - 1) && + subColumnIndex == (numberOfSubColumns - 1) ) + { + columnWidth += this._itemColumnSpacingRel / 2; + fillRect.Width += this._itemColumnSpacingRel / 2; + } + } + + if(subColumnIndex < this.CellColumns.Count) + { + // Draw header background + LegendCellColumn legendColumn = this.CellColumns[subColumnIndex]; + if(!legendColumn.HeaderBackColor.IsEmpty) + { + redrawLegendBorder = true; + + // Fill title background + if(fillRect.Right > legendPosition.Right) + { + fillRect.Width -= (legendPosition.Right - fillRect.Right); + } + if(fillRect.X < legendPosition.X) + { + fillRect.X += legendPosition.X - fillRect.X; + fillRect.Width -= (legendPosition.X - fillRect.X); + } + fillRect.Intersect(legendPosition); + chartGraph.FillRectangleRel( + chartGraph.GetRelativeRectangle(fillRect), + legendColumn.HeaderBackColor, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + Color.Empty, + 0, + ChartDashStyle.NotSet, + Color.Empty, + 0, + PenAlignment.Inset); + + } + + // Draw header text + using(SolidBrush textBrush = new SolidBrush(legendColumn.HeaderForeColor)) + { + // Set text alignment + using (StringFormat format = new StringFormat()) + { + format.Alignment = legendColumn.HeaderAlignment; + format.LineAlignment = StringAlignment.Center; + format.FormatFlags = StringFormatFlags.LineLimit; + format.Trimming = StringTrimming.EllipsisCharacter; + + // Draw string using relative coordinates + chartGraph.DrawStringRel( + legendColumn.HeaderText, + legendColumn.HeaderFont, + textBrush, + chartGraph.GetRelativeRectangle(rect), + format); + } + } + } + } + } + + // Draw header separator for each column + Rectangle separatorRect = this._headerPosition; + separatorRect.X = columnStart; + separatorRect.Width = columnWidth; + if(this.HeaderSeparator == LegendSeparatorStyle.Line || this.HeaderSeparator == LegendSeparatorStyle.DoubleLine) + { + // NOTE: For some reason a line with a single pen width is drawn 1 pixel longer than + // any other line. Reduce width to solve the issue. + legendPosition.Width -= 1; + } + separatorRect.Intersect(legendPosition); + this.DrawSeparator(chartGraph, this.HeaderSeparator, this.HeaderSeparatorColor, true, separatorRect); + + // Add spacing between columns + prevRightLocation += this.GetSeparatorSize(this.ItemColumnSeparator).Width; + } + + // Draw legend border to solve any issues with header background overlapping + if(redrawLegendBorder) + { + chartGraph.FillRectangleRel( + chartGraph.GetRelativeRectangle(Rectangle.Round(chartGraph.GetAbsoluteRectangle(this.Position.ToRectangleF()))), + Color.Transparent, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + BorderColor, + this.GetBorderSize(), + BorderDashStyle, + Color.Empty, + 0, + PenAlignment.Inset); + + } + + // Add legend header hot region + if( Common.ProcessModeRegions && !this._headerPosition.IsEmpty) + { + Common.HotRegionsList.AddHotRegion(chartGraph.GetRelativeRectangle(this._headerPosition), this, ChartElementType.LegendHeader, true ); + } + + } + } + + /// + /// Draw Legend title. + /// + /// Chart graphics to draw the title on. + private void DrawLegendTitle(ChartGraphics chartGraph) + { + // Check if title text is specified and position recalculated + if(this.Title.Length > 0 && + !this._titlePosition.IsEmpty) + { + // Get Legend position + Rectangle legendPosition = Rectangle.Round(chartGraph.GetAbsoluteRectangle(this.Position.ToRectangleF())); + legendPosition.Y += this.GetBorderSize(); + legendPosition.Height -= 2 * this.GetBorderSize(); + legendPosition.X += this.GetBorderSize(); + legendPosition.Width -= 2 * this.GetBorderSize(); + if(this.GetBorderSize() > 0) + { + ++legendPosition.Height; + ++legendPosition.Width; + } + + // Draw title background + if(!this.TitleBackColor.IsEmpty) + { + // Fill title background + Rectangle fillRect = this._titlePosition; + fillRect.Intersect(legendPosition); + chartGraph.FillRectangleRel( + chartGraph.GetRelativeRectangle(fillRect), + this.TitleBackColor, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + Color.Empty, + 0, + ChartDashStyle.NotSet, + Color.Empty, + 0, + PenAlignment.Inset); + } + + // Draw title text + using(SolidBrush textBrush = new SolidBrush(this.TitleForeColor)) + { + // Set text alignment + StringFormat format = new StringFormat(); + format.Alignment = this.TitleAlignment; + //format.LineAlignment = StringAlignment.Center; + + // Shift text rectangle by the top offset amount + Rectangle rect = this._titlePosition; + rect.Y += this._offset.Height; + rect.X += this._offset.Width; + rect.X += this.GetBorderSize(); + rect.Width -= this.GetBorderSize() * 2 + this._offset.Width; + + // Draw string using relative coordinates + rect.Intersect(legendPosition); + chartGraph.DrawStringRel( + this.Title.Replace("\\n", "\n"), + this.TitleFont, + textBrush, + chartGraph.GetRelativeRectangle(rect), + format); + } + + // Draw title separator + Rectangle separatorPosition = this._titlePosition; + if(this.TitleSeparator == LegendSeparatorStyle.Line || this.TitleSeparator == LegendSeparatorStyle.DoubleLine) + { + // NOTE: For some reason a line with a single pen width is drawn 1 pixel longer than + // any other line. Reduce width to solve the issue. + legendPosition.Width -= 1; + } + separatorPosition.Intersect(legendPosition); + this.DrawSeparator(chartGraph, this.TitleSeparator, this.TitleSeparatorColor, true, separatorPosition); + + // Draw legend border to solve any issues with title background overlapping + if(!this.TitleBackColor.IsEmpty || + this.TitleSeparator != LegendSeparatorStyle.None) + { + chartGraph.FillRectangleRel( + chartGraph.GetRelativeRectangle(Rectangle.Round(chartGraph.GetAbsoluteRectangle(this.Position.ToRectangleF()))), + Color.Transparent, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + BorderColor, + this.GetBorderSize(), + BorderDashStyle, + Color.Empty, + 0, + PenAlignment.Inset); + + } + } + } + + /// + /// Gets legend separator size in pixels + /// + /// Separator type. + /// Separator size in relative coordinates. + internal Size GetSeparatorSize(LegendSeparatorStyle separatorType) + { + Size size = Size.Empty; + + if(separatorType == LegendSeparatorStyle.None) + { + size = Size.Empty; + } + else if(separatorType == LegendSeparatorStyle.Line) + { + size = new Size(1, 1); + } + else if(separatorType == LegendSeparatorStyle.DashLine) + { + size = new Size(1, 1); + } + else if(separatorType == LegendSeparatorStyle.DotLine) + { + size = new Size(1, 1); + } + else if(separatorType == LegendSeparatorStyle.ThickLine) + { + size = new Size(2, 2); + } + else if(separatorType == LegendSeparatorStyle.DoubleLine) + { + size = new Size(3, 3); + } + else if(separatorType == LegendSeparatorStyle.GradientLine) + { + size = new Size(1, 1); + } + else if(separatorType == LegendSeparatorStyle.ThickGradientLine) + { + size = new Size(2, 2); + } + else + { + throw (new InvalidOperationException(SR.ExceptionLegendSeparatorTypeUnknown(separatorType.ToString()))); + } + + // For the vertical part of the separator always add additiobal spacing + size.Width += this._itemColumnSpacingRel; + + return size; + } + + /// + /// Draws specified legend separator. + /// + /// Chart graphics. + /// Separator type. + /// Separator color. + /// Flag that determines if separator is vertical or horizontal. + /// Separator position. + private void DrawSeparator( + ChartGraphics chartGraph, + LegendSeparatorStyle separatorType, + Color color, + bool horizontal, + Rectangle position) + { + // Temporary disable antialiasing + SmoothingMode oldSmoothingMode = chartGraph.SmoothingMode; + chartGraph.SmoothingMode = SmoothingMode.None; + + // Get line position in absolute coordinates + RectangleF rect = position; + if(!horizontal) + { + rect.X += (int)(_itemColumnSpacingRel / 2f); + rect.Width -= _itemColumnSpacingRel; + } + if(separatorType == LegendSeparatorStyle.Line) + { + if(horizontal) + { + // Draw horizontal line separator + chartGraph.DrawLineAbs( + color, + 1, + ChartDashStyle.Solid, + new PointF(rect.Left, rect.Bottom - 1), + new PointF(rect.Right, rect.Bottom - 1) ); + + } + else + { + // Draw vertical line separator + chartGraph.DrawLineAbs( + color, + 1, + ChartDashStyle.Solid, + new PointF(rect.Right - 1, rect.Top), + new PointF(rect.Right - 1, rect.Bottom) ); + } + } + else if(separatorType == LegendSeparatorStyle.DashLine) + { + if(horizontal) + { + // Draw horizontal line separator + chartGraph.DrawLineAbs( + color, + 1, + ChartDashStyle.Dash, + new PointF(rect.Left, rect.Bottom - 1), + new PointF(rect.Right, rect.Bottom - 1) ); + + } + else + { + // Draw vertical line separator + chartGraph.DrawLineAbs( + color, + 1, + ChartDashStyle.Dash, + new PointF(rect.Right - 1, rect.Top), + new PointF(rect.Right - 1, rect.Bottom) ); + } + } + else if(separatorType == LegendSeparatorStyle.DotLine) + { + if(horizontal) + { + // Draw horizontal line separator + chartGraph.DrawLineAbs( + color, + 1, + ChartDashStyle.Dot, + new PointF(rect.Left, rect.Bottom - 1), + new PointF(rect.Right, rect.Bottom - 1) ); + + } + else + { + // Draw vertical line separator + chartGraph.DrawLineAbs( + color, + 1, + ChartDashStyle.Dot, + new PointF(rect.Right - 1, rect.Top), + new PointF(rect.Right - 1, rect.Bottom) ); + } + } + else if(separatorType == LegendSeparatorStyle.ThickLine) + { + if(horizontal) + { + // Draw horizontal line separator + chartGraph.DrawLineAbs( + color, + 2, + ChartDashStyle.Solid, + new PointF(rect.Left, rect.Bottom - 1f), + new PointF(rect.Right, rect.Bottom - 1f) ); + } + else + { + // Draw vertical line separator + chartGraph.DrawLineAbs( + color, + 2, + ChartDashStyle.Solid, + new PointF(rect.Right - 1f, rect.Top), + new PointF(rect.Right - 1f, rect.Bottom) ); + } + } + else if(separatorType == LegendSeparatorStyle.DoubleLine) + { + if(horizontal) + { + // Draw horizontal line separator + chartGraph.DrawLineAbs( + color, + 1, + ChartDashStyle.Solid, + new PointF(rect.Left, rect.Bottom - 3), + new PointF(rect.Right, rect.Bottom - 3) ); + chartGraph.DrawLineAbs( + color, + 1, + ChartDashStyle.Solid, + new PointF(rect.Left, rect.Bottom - 1), + new PointF(rect.Right, rect.Bottom - 1) ); + } + else + { + // Draw vertical line separator + chartGraph.DrawLineAbs( + color, + 1, + ChartDashStyle.Solid, + new PointF(rect.Right - 3, rect.Top), + new PointF(rect.Right - 3, rect.Bottom) ); + chartGraph.DrawLineAbs( + color, + 1, + ChartDashStyle.Solid, + new PointF(rect.Right - 1, rect.Top), + new PointF(rect.Right - 1, rect.Bottom) ); + } + } + else if(separatorType == LegendSeparatorStyle.GradientLine) + { + if(horizontal) + { + // Draw horizontal line separator + chartGraph.FillRectangleAbs( + new RectangleF(rect.Left, rect.Bottom - 1f, rect.Width, 0f), + Color.Transparent, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.VerticalCenter, + color, + Color.Empty, + 0, + ChartDashStyle.NotSet, + PenAlignment.Inset); + } + else + { + // Draw vertical line separator + chartGraph.FillRectangleAbs( + new RectangleF(rect.Right - 1f, rect.Top, 0f, rect.Height), + Color.Transparent, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.HorizontalCenter, + color, + Color.Empty, + 0, + ChartDashStyle.NotSet, + PenAlignment.Inset); + } + } + else if(separatorType == LegendSeparatorStyle.ThickGradientLine) + { + if(horizontal) + { + // Draw horizontal line separator + chartGraph.FillRectangleAbs( + new RectangleF(rect.Left, rect.Bottom - 2f, rect.Width, 1f), + Color.Transparent, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.VerticalCenter, + color, + Color.Empty, + 0, + ChartDashStyle.NotSet, + PenAlignment.Inset); + } + else + { + // Draw vertical line separator + chartGraph.FillRectangleAbs( + new RectangleF(rect.Right - 2f, rect.Top, 1f, rect.Height), + Color.Transparent, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.HorizontalCenter, + color, + Color.Empty, + 0, + ChartDashStyle.NotSet, + PenAlignment.Inset); + } + } + + // Restore smoothing + chartGraph.SmoothingMode = oldSmoothingMode; + } + + #endregion // Legent Title Helper methods + + #region Helper methods + + /// + /// Get visible legend border size. + /// + /// Visible legend border size. + private int GetBorderSize() + { + if(this.BorderWidth > 0 && + this.BorderDashStyle != ChartDashStyle.NotSet && + !this.BorderColor.IsEmpty && + this.BorderColor != Color.Transparent) + { + return this.BorderWidth; + } + return 0; + } + + /// + /// Helper method which returns current legend table style. + /// + /// Chart graphics. + /// Legend table style. + private LegendTableStyle GetLegendTableStyle(ChartGraphics chartGraph) + { + LegendTableStyle style = this.TableStyle; + if(this.TableStyle == LegendTableStyle.Auto) + { + if(this.Position.Auto) + { + // If legend is automatically positioned, use docking + // do determine preffered table style + if(this.Docking == Docking.Left || + this.Docking == Docking.Right) + { + return LegendTableStyle.Tall; + } + else + { + return LegendTableStyle.Wide; + } + } + else + { + // If legend is custom positioned, use legend width and heiht + // to determine the best table layout. + SizeF legendPixelSize = chartGraph.GetAbsoluteRectangle(this.Position.ToRectangleF()).Size; + if(legendPixelSize.Width < legendPixelSize.Height) + { + return LegendTableStyle.Tall; + } + else + { + return LegendTableStyle.Wide; + } + } + } + + return style; + } + + + + /// + /// Helper method that checks if legend is enabled. + /// + /// True if legend is enabled. + internal bool IsEnabled() + { + if(this.Enabled) + { + + // Check if legend is docked to the chart area + if(this.DockedToChartArea.Length > 0 && + this.Common != null && + this.Common.ChartPicture != null) + { + if(this.Common.ChartPicture.ChartAreas.IndexOf(this.DockedToChartArea) >= 0) + { + // Do not show legend when it is docked to invisible chart area + ChartArea area = this.Common.ChartPicture.ChartAreas[this.DockedToChartArea]; + if(!area.Visible) + { + return false; + } + } + } + + + return true; + } + return false; + } + + /// + /// Invalidate chart legend when one of the properties is changed + /// + /// Indicates that only legend area should be invalidated. + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This parameter is used when compiling for the Microsoft version of Chart")] + internal void Invalidate(bool invalidateLegendOnly) + { +#if Microsoft_CONTROL + + if(Chart != null && !Chart.disableInvalidates) + { + if(invalidateLegendOnly) + { + // Calculate the position of the legend + Rectangle invalRect = Chart.ClientRectangle; + if(this.Position.Width != 0 && this.Position.Height != 0 ) + { + // Convert relative coordinates to absolute coordinates + invalRect.X = (int)(this.Position.X * (this.Common.ChartPicture.Width - 1) / 100F); + invalRect.Y = (int)(this.Position.Y * (this.Common.ChartPicture.Height - 1) / 100F); + invalRect.Width = (int)(this.Position.Width * (this.Common.ChartPicture.Width - 1) / 100F); + invalRect.Height = (int)(this.Position.Height * (this.Common.ChartPicture.Height - 1) / 100F); + + // Inflate rectangle size using border size and shadow size + invalRect.Inflate(this.BorderWidth + this.ShadowOffset + 1, this.BorderWidth + this.ShadowOffset + 1); + } + + // Invalidate legend rectangle only + Chart.dirtyFlag = true; + Chart.Invalidate(invalRect); + } + else + { + Invalidate(); + } + } +#endif + } + + #endregion + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + //Free managed resources + if (_fontCache != null) + { + _fontCache.Dispose(); + _fontCache = null; + } + if (legendItems != null) + { + legendItems.Dispose(); + legendItems = null; + } + if (_cellColumns != null) + { + _cellColumns.Dispose(); + _cellColumns = null; + } + if (_customLegends != null) + { + _customLegends.Dispose(); + _customLegends = null; + } + if (_position != null) + { + _position.Dispose(); + _position = null; + } + } + } + + + #endregion + } + + /// + /// The LegendCollection class is a strongly typed collection of legends. + /// + [ + SRDescription("DescriptionAttributeLegendCollection_LegendCollection"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class LegendCollection : ChartNamedElementCollection + { + #region Constructors + /// + /// LegendCollection constructor. + /// + /// Chart picture object. + internal LegendCollection(ChartPicture chartPicture) + : base(chartPicture) + { + } + + #endregion + + #region Properties + /// + /// Gets the default legend name. + /// + internal string DefaultNameReference + { + get { return this.Count > 0 ? this[0].Name : String.Empty; } + } + #endregion + + #region Methods + + /// + /// Creates a new Legend with the specified name and adds it to the collection. + /// + /// The new chart area name. + /// New legend + public Legend Add(string name) + { + Legend legend = new Legend(name); + this.Add(legend); + return legend; + } + + /// + /// Recalculates legend position in the collection. + /// + /// Chart graphics used. + /// Area where the legend should be positioned. + /// Spacing size as a percentage of the area. + internal void CalcLegendPosition( + ChartGraphics chartGraph, + ref RectangleF chartAreasRectangle, + float elementSpacing) + { + // Loop through all legends + foreach(Legend legend in this) + { + // Calculate position of the legends docked to the chart picture + if(legend.IsEnabled() && + legend.DockedToChartArea == Constants.NotSetValue && + legend.Position.Auto) + { + legend.CalcLegendPosition(chartGraph, ref chartAreasRectangle, elementSpacing); + } + } + } + + /// + /// Recalculates legend position in the collection for legends docked outside of chart area. + /// + /// Chart graphics used. + /// Area the legend is docked to. + /// Area where the legend should be positioned. + /// Spacing size as a percentage of the area. + internal void CalcOutsideLegendPosition( + ChartGraphics chartGraph, + ChartArea area, + ref RectangleF chartAreasRectangle, + float elementSpacing) + { + if(Common != null && Common.ChartPicture != null) + { + // Get elemets spacing + float areaSpacing = Math.Min((chartAreasRectangle.Height/100F) * elementSpacing, (chartAreasRectangle.Width/100F) * elementSpacing); + + // Loop through all legends + foreach(Legend legend in this) + { + // Check if all chart area names are valid + if (legend.DockedToChartArea != Constants.NotSetValue && this.Chart.ChartAreas.IndexOf(legend.DockedToChartArea)<0) + { + throw (new ArgumentException(SR.ExceptionLegendDockedChartAreaIsMissing((string)legend.DockedToChartArea))); + } + + // Process only legends docked to specified area + if(legend.IsEnabled() && + legend.IsDockedInsideChartArea == false && + legend.DockedToChartArea == area.Name && + legend.Position.Auto) + { + // Calculate legend position + legend.CalcLegendPosition(chartGraph, + ref chartAreasRectangle, + areaSpacing); + + // Adjust legend position + RectangleF legendPosition = legend.Position.ToRectangleF(); + if(legend.Docking == Docking.Top) + { + legendPosition.Y -= areaSpacing; + if(!area.Position.Auto) + { + legendPosition.Y -= legendPosition.Height; + } + } + else if(legend.Docking == Docking.Bottom) + { + legendPosition.Y += areaSpacing; + if(!area.Position.Auto) + { + legendPosition.Y = area.Position.Bottom + areaSpacing; + } + } + if(legend.Docking == Docking.Left) + { + legendPosition.X -= areaSpacing; + if(!area.Position.Auto) + { + legendPosition.X -= legendPosition.Width; + } + } + if(legend.Docking == Docking.Right) + { + legendPosition.X += areaSpacing; + if(!area.Position.Auto) + { + legendPosition.X = area.Position.Right + areaSpacing; + } + } + + legend.Position.SetPositionNoAuto(legendPosition.X, legendPosition.Y, legendPosition.Width, legendPosition.Height); + } + } + } + } + + /// + /// Recalculates legend position inside chart area in the collection. + /// + /// Chart graphics used. + /// Spacing size as a percentage of the area. + internal void CalcInsideLegendPosition( + ChartGraphics chartGraph, + float elementSpacing) + { + if(Common != null && Common.ChartPicture != null) + { + // Check if all chart area names are valid + foreach(Legend legend in this) + { + if (legend.DockedToChartArea != Constants.NotSetValue) + { + try + { + ChartArea area = Common.ChartPicture.ChartAreas[legend.DockedToChartArea]; + } + catch + { + throw(new ArgumentException( SR.ExceptionLegendDockedChartAreaIsMissing( (string)legend.DockedToChartArea ) ) ); + } + } + } + + // Loop through all chart areas + foreach (ChartArea area in Common.ChartPicture.ChartAreas) + { + + // Check if chart area is visible + if(area.Visible) + + { + // Get area position + RectangleF legendPlottingRectangle = area.PlotAreaPosition.ToRectangleF(); + + // Get elemets spacing + float areaSpacing = Math.Min((legendPlottingRectangle.Height/100F) * elementSpacing, (legendPlottingRectangle.Width/100F) * elementSpacing); + + // Loop through all legends + foreach(Legend legend in this) + { + if(legend.IsEnabled() && + legend.IsDockedInsideChartArea == true && + legend.DockedToChartArea == area.Name && + legend.Position.Auto) + { + // Calculate legend position + legend.CalcLegendPosition(chartGraph, + ref legendPlottingRectangle, + areaSpacing); + } + } + } + } + } + } + + #endregion + + #region Event handlers + internal void ChartAreaNameReferenceChanged(object sender, NameReferenceChangedEventArgs e) + { + //If all the chart areas are removed and then the first one is added we don't want to dock the legends + if (e.OldElement == null) + return; + + foreach (Legend legend in this) + if (legend.DockedToChartArea == e.OldName) + legend.DockedToChartArea = e.NewName; + } + #endregion + + } + + /// + /// The LegendItemsCollection class is a strongly typed collection of legend items. + /// + [ + SRDescription("DescriptionAttributeCustomLabelsCollection_CustomLabelsCollection"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class LegendItemsCollection : ChartElementCollection + { + #region Constructors + + /// + /// LegendItemsCollection constructor + /// + internal LegendItemsCollection(Legend legend) + : base(legend) + { + } + + #endregion + + #region Methods + + /// + /// Adds a legend item into the collection. + /// + /// Legend item color. + /// Legend item text. + /// Index of newly added item. + public int Add(Color color, string text) + { + LegendItem item = new LegendItem(text, color, ""); + Add(item); + return Count - 1; + } + + /// + /// Insert a legend item into the collection. + /// + /// Index to insert at. + /// Legend item color. + /// Legend item text. + /// Index of newly added item. + public void Insert(int index, Color color, string text) + { + LegendItem item = new LegendItem(text, color, ""); + this.Insert(index, item); + } + + /// + /// Adds a legend item into the collection. + /// + /// Legend item image. + /// Legend item text. + /// Index of newly added item. + public int Add(string image, string text) + { + LegendItem item = new LegendItem(text, Color.Empty, image); + Add(item); + return Count-1; + } + + /// + /// Insert one legend item into the collection. + /// + /// Index to insert at. + /// Legend item image. + /// Legend item text. + /// Index of newly added item. + public void Insert(int index, string image, string text) + { + LegendItem item = new LegendItem(text, Color.Empty, image); + this.Insert(index, item); + } + + /// + /// Reverses the order of items in the collection. + /// + public void Reverse() + { + List list = this.Items as List; + list.Reverse(); + Invalidate(); + } + + #endregion + + } + + + /// + /// The LegendItem class represents a single item (row) in the legend. + /// It contains properties which describe visual appearance and + /// content of the legend item. + /// + [ + SRDescription("DescriptionAttributeLegendItem_LegendItem"), + DefaultProperty("Name"), + ] +#if Microsoft_CONTROL + public class LegendItem : ChartNamedElement +#else +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class LegendItem : ChartNamedElement, IChartMapArea +#endif + { + #region Fields + + // Private data members, which store properties values + private Color _color = Color.Empty; + private string _image = ""; + private string _seriesName = ""; + private int _seriesPointIndex = -1; + + // Chart image map properties + private string _toolTip = ""; + +#if !Microsoft_CONTROL + private string _url = ""; + private string _attributes = ""; + private string _postbackValue = String.Empty; +#endif + + // Additional appearance properties + internal LegendImageStyle style = LegendImageStyle.Rectangle; + internal GradientStyle backGradientStyle = GradientStyle.None; + internal Color backSecondaryColor = Color.Empty; + internal Color backImageTransparentColor = Color.Empty; + internal Color borderColor = Color.Black; + internal int borderWidth = 1; + internal ChartDashStyle borderDashStyle = ChartDashStyle.Solid; + internal ChartHatchStyle backHatchStyle = ChartHatchStyle.None; + internal int shadowOffset = 0; + internal Color shadowColor = Color.FromArgb(128, 0, 0, 0); + internal ChartImageWrapMode backImageWrapMode = ChartImageWrapMode.Tile; + internal ChartImageAlignmentStyle backImageAlign = ChartImageAlignmentStyle.TopLeft; + + // Marker properties + internal MarkerStyle markerStyle = MarkerStyle.None; + internal int markerSize = 5; + internal string markerImage = ""; + internal Color markerImageTransparentColor = Color.Empty; + internal Color markerColor = Color.Empty; + internal Color markerBorderColor = Color.Empty; + + // True if legend item is enabled. + private bool _enabled = true; + + // Series marker border width + private int _markerBorderWidth = 1; + + // Collection of legend item cells + private LegendCellCollection _cells = null; + + // Legend item visual separator + private LegendSeparatorStyle _separatorType = LegendSeparatorStyle.None; + + // Legend item visual separator color + private Color _separatorColor = Color.Black; + + // Indicates that temporary cells where added and thet have to be removed + internal bool clearTempCells = false; + + #endregion + + #region Constructors + + /// + /// LegendItem constructor + /// + public LegendItem() + { + + // Create collection of legend item cells + this._cells = new LegendCellCollection(this); +#if !Microsoft_CONTROL + this.PostBackValue = String.Empty; +#endif //!WIN_CONTROL + } + + /// + /// LegendItem constructor + /// + /// Item name. + /// Item color. + /// Item image. + public LegendItem(string name, Color color, string image) : base (name) + { + this._color = color; + this._image = image; + + // Create collection of legend item cells + this._cells = new LegendCellCollection(this); +#if !Microsoft_CONTROL + this.PostBackValue = String.Empty; +#endif //!WIN_CONTROL + } + + #endregion + + #region Legend item properties + + /// + /// Gets the Legend object which the item belongs to. + /// + [ + Bindable(false), + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + ] + public Legend Legend + { + get + { + if (Parent != null) + return Parent.Parent as Legend; + else + return null; + } + } + + /// + /// Gets or sets the name of the legend item. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeLegendItem_Name"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ParenthesizePropertyNameAttribute(true) + ] + public override string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + + /// + /// Gets or sets the color of the legend item. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeLegendItem_Color"), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color Color + { + get + { + return _color; + } + set + { + _color = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets a string value that represents a URL to an image file, which will be used for the legend item's symbol. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeLegendItem_Image"), + DefaultValue(""), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + NotifyParentPropertyAttribute(true) + ] + public string Image + { + get + { + return _image; + } + set + { + _image = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the picture style of the legend item image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(LegendImageStyle), "Rectangle"), + SRDescription("DescriptionAttributeLegendItem_Style"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ParenthesizePropertyNameAttribute(true) + ] + public LegendImageStyle ImageStyle + { + get + { + return style; + } + set + { + style = value; + this.Invalidate(true); + } + } + + + /// + /// Gets or sets the border color of the legend item. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeBorderColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BorderColor + { + get + { + return borderColor; + } + set + { + borderColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the background hatch style of the legend item. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartHatchStyle.None), + SRDescription("DescriptionAttributeBackHatchStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + public ChartHatchStyle BackHatchStyle + { + get + { + return backHatchStyle; + } + set + { + backHatchStyle = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets a color which will be replaced with a transparent color while drawing the background image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackImageTransparentColor + { + get + { + return backImageTransparentColor; + } + set + { + backImageTransparentColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets background gradient style of the legend item. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(GradientStyle.None), + SRDescription("DescriptionAttributeBackGradientStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + public GradientStyle BackGradientStyle + { + get + { + return backGradientStyle; + } + set + { + backGradientStyle = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the secondary background color. + /// + /// + /// + /// + /// + /// A value used for the secondary color of background with + /// hatching or gradient fill. + /// + /// + /// This color is used with when or + /// are used. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackSecondaryColor + { + get + { + return backSecondaryColor; + } + set + { + if(value != Color.Empty && (value.A != 255 || value == Color.Transparent)) + { + throw (new ArgumentException(SR.ExceptionBackSecondaryColorIsTransparent)); + } + + backSecondaryColor = value; + + this.Invalidate(true); + } + } + + /// + /// Gets or sets the border width of the legend item. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeBorderWidth"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int BorderWidth + { + get + { + return borderWidth; + } + set + { + if(value < 0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionBorderWidthIsZero)); + } + borderWidth = value; + this.Invalidate(false); + } + } + + + + /// + /// Gets or sets a flag which indicates whether the Legend item is enabled. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(true), + SRDescription("DescriptionAttributeLegendItem_Enabled"), + ParenthesizePropertyNameAttribute(true), + ] + public bool Enabled + { + get + { + return this._enabled; + } + set + { + this._enabled = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the marker border width of the legend item. + /// + [ + SRCategory("CategoryAttributeMarker"), + DefaultValue(1), + SRDescription("DescriptionAttributeMarkerBorderWidth"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int MarkerBorderWidth + { + get + { + return this._markerBorderWidth; + } + set + { + if(value < 0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionLegendMarkerBorderWidthIsNegative)); + } + this._markerBorderWidth = value; + this.Invalidate(false); + } + } + + + + /// + /// Gets or sets the legend item border style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeBorderDashStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartDashStyle BorderDashStyle + { + get + { + return borderDashStyle; + } + set + { + borderDashStyle = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the offset between the legend item and its shadow. + /// + /// + /// + /// An integer value that represents the offset between the legend item and its shadow. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeShadowOffset"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif + DefaultValue(0) + ] + public int ShadowOffset + { + get + { + return shadowOffset; + } + set + { + shadowOffset = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the color of a legend item's shadow. + /// + /// + /// + /// A value used to draw a legend item's shadow. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "128,0,0,0"), + SRDescription("DescriptionAttributeShadowColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color ShadowColor + { + get + { + return shadowColor; + } + set + { + shadowColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the marker style of the legend item. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + DefaultValue(MarkerStyle.None), + SRDescription("DescriptionAttributeLegendItem_MarkerStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.MarkerStyleEditor.Editor, Editors.MarkerStyleEditor.Base), + RefreshProperties(RefreshProperties.All) + ] + public MarkerStyle MarkerStyle + { + get + { + return markerStyle; + } + set + { + markerStyle = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the marker size of the legend item. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + DefaultValue(5), + SRDescription("DescriptionAttributeLegendItem_MarkerSize"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshProperties(RefreshProperties.All) + ] + public int MarkerSize + { + get + { + return markerSize; + } + set + { + markerSize = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the marker image of the legend item. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeMarkerImage"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshProperties(RefreshProperties.All) + ] + public string MarkerImage + { + get + { + return markerImage; + } + set + { + markerImage = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets a color which will be replaced with a transparent color while drawing the marker image. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshProperties(RefreshProperties.All) + ] + public Color MarkerImageTransparentColor + { + get + { + return markerImageTransparentColor; + } + set + { + markerImageTransparentColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the marker color of the legend item. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeLegendItem_MarkerColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshProperties(RefreshProperties.All) + ] + public Color MarkerColor + { + get + { + return markerColor; + } + set + { + markerColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the marker border color of the legend item. + /// + [ + SRCategory("CategoryAttributeMarker"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeMarkerBorderColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + RefreshProperties(RefreshProperties.All) + ] + public Color MarkerBorderColor + { + get + { + return markerBorderColor; + } + set + { + markerBorderColor = value; + this.Invalidate(true); + } + } + + + /// + /// Gets or sets the series name of the legend item.. + /// + [ + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeLegendItem_SeriesName"), + DefaultValue("") + ] + public string SeriesName + { + get + { + return _seriesName; + } + set + { + _seriesName = value; + } + } + + /// + /// Gets or sets the index of the legend item's associated DataPoint object. + /// + [ + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + SRDescription("DescriptionAttributeLegendItem_SeriesPointIndex"), + DefaultValue(-1) + ] + public int SeriesPointIndex + { + get + { + return _seriesPointIndex; + } + set + { + _seriesPointIndex = value; + } + } + + + + + /// + /// Gets or sets the separator style of the legend item. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(LegendSeparatorStyle), "None"), + SRDescription("DescriptionAttributeLegendItem_Separator"), + ] + public LegendSeparatorStyle SeparatorType + { + get + { + return this._separatorType; + } + set + { + if(value != this._separatorType) + { + this._separatorType = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the separator color of the legend item. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLegendItem_SeparatorColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color SeparatorColor + { + get + { + return this._separatorColor; + } + set + { + if(value != this._separatorColor) + { + this._separatorColor = value; + this.Invalidate(false); + } + } + } + + + /// + /// The LegendCellCollection class is a collection of legend item cells. + /// + [ + SRCategory("CategoryAttributeAppearance"), + SRDescription("DescriptionAttributeLegendItem_Cells"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + Editor(Editors.LegendCellCollectionEditor.Editor, Editors.LegendCellCollectionEditor.Base), + ] + public LegendCellCollection Cells + { + get + { + return this._cells; + } + } + + #endregion + + #region IMapAreaAttributesutes Properties implementation + + /// + /// Tooltip of the area. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeToolTip"), + DefaultValue(""), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public string ToolTip + { + set + { + _toolTip = value; +#if Microsoft_CONTROL + if(Chart != null && Chart.selection != null) + { + Chart.selection.enabledChecked = false; + } +#endif + + } + get + { + return _toolTip; + } + } + +#if !Microsoft_CONTROL + /// + /// URL target of the area. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeUrl"), + DefaultValue(""), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base) +#endif + ] + public string Url + { + set + { + _url = value; + } + get + { + return _url; + } + } + +#endif +#if !Microsoft_CONTROL + + /// + /// Other attributes of the area. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeMapAreaAttributes"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute) + ] + public string MapAreaAttributes + { + set + { + _attributes = value; + } + get + { + return _attributes; + } + } + /// + /// Gets or sets the postback value which can be processed on a click event. + /// + /// The value which is passed to a click event as an argument. + [DefaultValue("")] + [SRCategory(SR.Keys.CategoryAttributeMapArea)] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + public string PostBackValue + { + get + { + return this._postbackValue; + } + set + { + this._postbackValue = value; + } + } + + +#endif //!Microsoft_CONTROL + #endregion + + #region Helper methods + + /// + /// Helper method adds default legend item cells based on the columns + /// specified. If columns collection is empty we assume the presence of + /// two columns: series marker and legend item text. + /// + /// Legend this item belongs to. + internal void AddAutomaticCells(Legend legend) + { + // Check if cells defined + if(this.Cells.Count == 0) + { + // Check if legend item was generated for the series + if(this.SeriesName.Length > 0) + { + // If legend do not have any columns set add a series marker + // and legend text cells + if(legend.CellColumns.Count == 0) + { + // VSTS 96787 - Text Direction (RTL/LTR) + if (legend.Common != null && legend.Common.ChartPicture.RightToLeft == RightToLeft.Yes) + { + this.Cells.Add(LegendCellType.Text, KeywordName.LegendText, ContentAlignment.MiddleLeft); + this.Cells.Add(LegendCellType.SeriesSymbol, string.Empty, ContentAlignment.MiddleCenter); + } + else + { + this.Cells.Add(LegendCellType.SeriesSymbol, string.Empty, ContentAlignment.MiddleCenter); + this.Cells.Add(LegendCellType.Text, KeywordName.LegendText, ContentAlignment.MiddleLeft); + } + } + else + { + // Add cell for each of the columns + foreach(LegendCellColumn legendColumn in legend.CellColumns) + { + this.Cells.Add(legendColumn.CreateNewCell()); + } + } + } + else + { + // Add Marker plus text for everything else + this.clearTempCells = true; + this.Cells.Add(LegendCellType.SeriesSymbol, string.Empty, ContentAlignment.MiddleCenter); + this.Cells.Add(LegendCellType.Text, KeywordName.LegendText, ContentAlignment.MiddleLeft); + } + } + } + + + /// + /// Sets legend item properties from the series + /// + /// Series object. + /// Common elements object. + internal void SetAttributes(CommonElements common, Series series) + { + // Get legend item picture style + IChartType chartType = common.ChartTypeRegistry.GetChartType(series.ChartTypeName); + style = chartType.GetLegendImageStyle(series); + + // Set series name + _seriesName = series.Name; + + // Get shadow properties + shadowOffset = series.ShadowOffset; + shadowColor = series.ShadowColor; + + // Check if series is drawn in 3D chart area + bool area3D = common.Chart.ChartAreas[series.ChartArea].Area3DStyle.Enable3D; + + // Get other properties + SetAttributes((DataPointCustomProperties) series, area3D); + } + + /// + /// Sets legend item properties from the DataPointCustomProperties object. + /// + /// DataPointCustomProperties object. + /// Element belongs to the 3D area. + internal void SetAttributes(DataPointCustomProperties properties, bool area3D) + { + borderColor = properties.BorderColor; + borderWidth = properties.BorderWidth; + borderDashStyle = properties.BorderDashStyle; + markerStyle = properties.MarkerStyle; + markerSize = properties.MarkerSize; + markerImage = properties.MarkerImage; + markerImageTransparentColor = properties.MarkerImageTransparentColor; + markerColor = properties.MarkerColor; + markerBorderColor = properties.MarkerBorderColor; + + + this._markerBorderWidth = properties.MarkerBorderWidth; + + float dpi = 96; + + if(Common != null) + dpi = Common.graph.Graphics.DpiX; + + int maxBorderWidth = (int)Math.Round((2 * dpi) / 96); + + if (this._markerBorderWidth > maxBorderWidth) + { + this._markerBorderWidth = maxBorderWidth; + } + + if(properties.MarkerBorderWidth <= 0) + { + markerBorderColor = Color.Transparent; + } + + // Improve readability of the line series marker by using at least 2 pixel wide lines + if(this.style == LegendImageStyle.Line && + borderWidth <= (int)Math.Round(dpi / 96) ) + { + borderWidth = maxBorderWidth; + } + + if(!area3D) + { + backGradientStyle = properties.BackGradientStyle; + backSecondaryColor = properties.BackSecondaryColor; + backImageTransparentColor = properties.BackImageTransparentColor; + backImageWrapMode = properties.BackImageWrapMode; + backImageAlign = properties.BackImageAlignment; + backHatchStyle = properties.BackHatchStyle; + } + } + + /// + /// Invalidate chart (or just legend )when collection is changed + /// + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This parameter is used when compiling for the Microsoft version of Chart")] + private void Invalidate(bool invalidateLegendOnly) + { +#if Microsoft_CONTROL + if(Legend != null) + { + // Invalidate control + Legend.Invalidate(invalidateLegendOnly); + } +#endif + } + + #endregion + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_cells != null) + { + _cells.Dispose(); + _cells = null; + } + } + base.Dispose(disposing); + } + + + #endregion + + } +} diff --git a/System.Web.DataVisualization/Common/General/LegendColumns.cs b/System.Web.DataVisualization/Common/General/LegendColumns.cs new file mode 100644 index 000000000..04d52956a --- /dev/null +++ b/System.Web.DataVisualization/Common/General/LegendColumns.cs @@ -0,0 +1,2909 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: LegendColumns.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: LegendCellColumn, LegendCellColumnCollection, +// LegendCell, LegendCellCollection, Margins +// +// Purpose: LegendCell and LegendCellColumn classes allow to +// create highly customize legends. Please refer to +// Chart documentation which contains images and +// samples describing this functionality. +// +// Reviewed: AG - Microsoft 14, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Windows.Forms.DataVisualization.Charting; + using System.ComponentModel.Design.Serialization; + using System.Reflection; + using System.Windows.Forms.Design; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + #region Enumerations + + /// + /// An enumeration of legend cell types. + /// + public enum LegendCellType + { + /// + /// Legend cell contains text. + /// + Text, + + /// + /// Legend cell contains series symbol. + /// + SeriesSymbol, + + /// + /// Legend cell contains image. + /// + Image + } + + /// + /// An enumeration of legend cell column types. + /// + public enum LegendCellColumnType + { + /// + /// Legend column contains text. + /// + Text, + + /// + /// Legend column contains series symbol. + /// + SeriesSymbol + } + + #endregion // Enumerations + + /// + /// The LegendCellColumn class represents a cell column in a legend, + /// used to extend the functionality of the default legend. It contains + /// visual appearance properties, legend header settings and also determine + /// how and in which order cells are formed for each of the legend items. + /// + [ + SRDescription("DescriptionAttributeLegendCellColumn_LegendCellColumn"), + ] +#if Microsoft_CONTROL + public class LegendCellColumn : ChartNamedElement +#else +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class LegendCellColumn : ChartNamedElement, IChartMapArea +#endif //!Microsoft_CONTROL + { + #region Fields + + // Legend column type + private LegendCellColumnType _columnType = LegendCellColumnType.Text; + + // Legend column text + private string _text = KeywordName.LegendText; + + // Legend column text color + private Color _foreColor = Color.Empty; + + // Legend column back color + private Color _backColor = Color.Empty; + + // Font cache + private FontCache _fontCache = new FontCache(); + + // Legend column text font + private Font _font = null; + + // Legend column series symbol size + private Size _seriesSymbolSize = new Size(200, 70); + + // Legend column content allignment + private ContentAlignment _alignment = ContentAlignment.MiddleCenter; + + // Legend column tooltip + private string _toolTip = string.Empty; + + // Legend column margins + private Margins _margins = new Margins(0, 0, 15, 15); + +#if !Microsoft_CONTROL + + // Legend column Url + private string _url = string.Empty; + + // Legend column map area attribute + private string _mapAreaAttribute = string.Empty; + private string _postbackValue = String.Empty; +#endif // !Microsoft_CONTROL + + // Legend column header text + private string _headerText = string.Empty; + + // Legend column/cell content allignment + private StringAlignment _headerAlignment = StringAlignment.Center; + + // Legend column header text color + private Color _headerForeColor = Color.Black; + + // Legend column header text back color + private Color _headerBackColor = Color.Empty; + + // Legend column header text font + private Font _headerFont = null; + + // Minimum column width + private int _minimumCellWidth = -1; + + // Maximum column width + private int _maximumCellWidth = -1; + + #endregion // Fields + + #region Constructors + + /// + /// LegendCellColumn constructor. + /// + public LegendCellColumn() + : this(string.Empty, LegendCellColumnType.Text, KeywordName.LegendText, ContentAlignment.MiddleCenter) + { + _headerFont = _fontCache.DefaultBoldFont; + } + + + /// + /// LegendCellColumn constructor. + /// + /// Column header text. + /// Column type. + /// Column cell text. + public LegendCellColumn(string headerText, LegendCellColumnType columnType, string text) : this(headerText, columnType, text, ContentAlignment.MiddleCenter) + { + + } + + /// + /// Legend column object constructor. + /// + /// Column header text. + /// Column type. + /// Column cell text . + /// Column cell content alignment. + public LegendCellColumn(string headerText, LegendCellColumnType columnType, string text, ContentAlignment alignment) + { + this._headerText = headerText; + this._columnType = columnType; + this._text = text; + this._alignment = alignment; + } + + + #endregion // Constructors + + #region Properties + + /// + /// Gets or sets name of legend column. + /// + [ + SRCategory("CategoryAttributeMisc"), + SRDescription("DescriptionAttributeLegendCellColumn_Name"), + ] + public override string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + + + /// + /// Gets legend this column belongs too. + /// + [ + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + ] + public virtual Legend Legend + { + get + { + if (Parent != null) + return Parent.Parent as Legend; + else + return null; + } + } + + + /// + /// Gets or sets legend column type. This is only applicable to items that are automatically generated for the series. + /// + [ + SRCategory("CategoryAttributeSeriesItems"), + DefaultValue(LegendCellColumnType.Text), + SRDescription("DescriptionAttributeLegendCellColumn_ColumnType"), + ParenthesizePropertyNameAttribute(true) + ] + public virtual LegendCellColumnType ColumnType + { + get + { + return this._columnType; + } + set + { + this._columnType = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets legend column text. This is only applicable to items that are automatically generated for the series. + /// Set the ColumnType property to text to use this property. + /// + [ + SRCategory("CategoryAttributeSeriesItems"), + DefaultValue(KeywordName.LegendText), + SRDescription("DescriptionAttributeLegendCellColumn_Text"), + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base), + ] + public virtual string Text + { + get + { + return this._text; + } + set + { + this._text = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the text color of the legend column. + /// + [ + SRCategory("CategoryAttributeSeriesItems"), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeForeColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public virtual Color ForeColor + { + get + { + return this._foreColor; + } + set + { + this._foreColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background color of the legend column. + /// + [ + SRCategory("CategoryAttributeSeriesItems"), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public virtual Color BackColor + { + get + { + return this._backColor; + } + set + { + this._backColor = value; + this.Invalidate(); + } + } + + + /// + /// Gets or sets the font of the legend column text. + /// + [ + SRCategory("CategoryAttributeSeriesItems"), + DefaultValue(null), + SRDescription("DescriptionAttributeLegendCellColumn_Font"), + ] + public virtual Font Font + { + get + { + return this._font; + } + set + { + this._font = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the series symbol size of the legend column + /// for the items automatically generated for the series. + /// + [ + SRCategory("CategoryAttributeSeriesItems"), + DefaultValue(typeof(Size), "200, 70"), + SRDescription("DescriptionAttributeLegendCellColumn_SeriesSymbolSize"), + ] + public virtual Size SeriesSymbolSize + { + get + { + return this._seriesSymbolSize; + } + set + { + if(value.Width < 0 || value.Height < 0) + { + throw (new ArgumentException(SR.ExceptionSeriesSymbolSizeIsNegative, "value")); + } + this._seriesSymbolSize = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the content alignment of the legend column. + /// This is only applicable to items that are automatically generated for the series. + /// + [ + SRCategory("CategoryAttributeSeriesItems"), + DefaultValue(ContentAlignment.MiddleCenter), + SRDescription("DescriptionAttributeLegendCellColumn_Alignment"), + ] + public virtual ContentAlignment Alignment + { + get + { + return this._alignment; + } + set + { + this._alignment = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the margins of the legend column (as a percentage of legend font size). + /// This is only applicable to items that are automatically generated for the series. + /// + [ + SRCategory("CategoryAttributeSeriesItems"), + DefaultValue(typeof(Margins), "0,0,15,15"), + SRDescription("DescriptionAttributeLegendCellColumn_Margins"), + SerializationVisibilityAttribute(SerializationVisibility.Attribute), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif + ] + public virtual Margins Margins + { + get + { + return this._margins; + } + set + { + this._margins = value; + this.Invalidate(); + +#if Microsoft_CONTROL + // Set common elements of the new margins class + if(this.Legend != null) + { + this._margins.Common = this.Legend.Common; + } +#endif // Microsoft_CONTROL + } + } + + /// + /// Returns true if property should be serialized. This is for internal use only. + /// + [EditorBrowsableAttribute(EditorBrowsableState.Never)] + public bool ShouldSerializeMargins() + { + if(this._margins.Top == 0 && + this._margins.Bottom == 0 && + this._margins.Left == 15 && + this._margins.Right == 15 ) + { + return false; + } + return true; + } + + /// + /// Gets or sets the legend column tooltip. This is only applicable to items that are automatically generated for the series. + /// + [ + SRCategory("CategoryAttributeSeriesItems"), + SRDescription("DescriptionAttributeToolTip"), + DefaultValue(""), + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base), + ] + public virtual string ToolTip + { + set + { + this._toolTip = value; +#if Microsoft_CONTROL + if(Chart != null && + Chart.selection != null) + { + Chart.selection.enabledChecked = false; + } +#endif + } + get + { + return this._toolTip; + } + } + +#if !Microsoft_CONTROL + + /// + /// Gets or sets the URL target of the legend items automatically generated for the series. + /// + [ + SRCategory("CategoryAttributeSeriesItems"), + SRDescription("DescriptionAttributeUrl"), + DefaultValue(""), + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base), + ] + public virtual string Url + { + set + { + this._url = value; + } + get + { + return this._url; + } + } + + /// + /// Gets or sets the other attributes of the legend items automatically generated for the series. + /// + [ + SRCategory("CategoryAttributeSeriesItems"), + SRDescription("DescriptionAttributeMapAreaAttributes"), + Editor(Editors.KeywordsStringEditor.Editor, Editors.KeywordsStringEditor.Base), + DefaultValue(""), + ] + public virtual string MapAreaAttributes + { + set + { + this._mapAreaAttribute = value; + } + get + { + return this._mapAreaAttribute; + } + } + + /// + /// Gets or sets the postback value which can be processed on a click event. + /// + /// The value which is passed to a click event as an argument. + [DefaultValue("")] + [SRCategory(SR.Keys.CategoryAttributeSeriesItems)] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + public string PostBackValue + { + get + { + return this._postbackValue; + } + set + { + this._postbackValue = value; + } + } + + +#endif // !Microsoft_CONTROL + + /// + /// Gets or sets the legend column header text. + /// + [ + SRCategory("CategoryAttributeHeader"), + DefaultValue(""), + SRDescription("DescriptionAttributeLegendCellColumn_HeaderText"), + ] + public virtual string HeaderText + { + get + { + return this._headerText; + } + set + { + this._headerText = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the color of the legend column header text. + /// + [ + SRCategory("CategoryAttributeHeader"), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeLegendCellColumn_HeaderColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public virtual Color HeaderForeColor + { + get + { + return this._headerForeColor; + } + set + { + this._headerForeColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background color of the legend column header. + /// + [ + SRCategory("CategoryAttributeHeader"), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeHeaderBackColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public virtual Color HeaderBackColor + { + get + { + return this._headerBackColor; + } + set + { + this._headerBackColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the font of the legend column header. + /// + [ + SRCategory("CategoryAttributeHeader"), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt, style=Bold"), + SRDescription("DescriptionAttributeLegendCellColumn_HeaderFont"), + ] + public virtual Font HeaderFont + { + get + { + return this._headerFont; + } + set + { + this._headerFont = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the horizontal text alignment of the legend column header. + /// + [ + SRCategory("CategoryAttributeHeader"), + DefaultValue(typeof(StringAlignment), "Center"), + SRDescription("DescriptionAttributeLegendCellColumn_HeaderTextAlignment"), + ] + public StringAlignment HeaderAlignment + { + get + { + return this._headerAlignment; + } + set + { + if(value != this._headerAlignment) + { + this._headerAlignment = value; + this.Invalidate(); + } + } + } + + /// + /// Gets or sets the minimum width (as a percentage of legend font size) of legend column. Set this property to -1 for automatic calculation. + /// + [ + SRCategory("CategoryAttributeSize"), + DefaultValue(-1), + TypeConverter(typeof(IntNanValueConverter)), + SRDescription("DescriptionAttributeLegendCellColumn_MinimumWidth"), + ] + public virtual int MinimumWidth + { + get + { + return this._minimumCellWidth; + } + set + { + if(value < -1) + { + throw (new ArgumentException(SR.ExceptionMinimumCellWidthIsWrong, "value")); + } + + this._minimumCellWidth = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the maximum width (as a percentage of legend font size) of legend column. Set this property to -1 for automatic calculation. + /// + [ + SRCategory("CategoryAttributeSize"), + DefaultValue(-1), + TypeConverter(typeof(IntNanValueConverter)), + SRDescription("DescriptionAttributeLegendCellColumn_MaximumWidth"), + ] + public virtual int MaximumWidth + { + get + { + return this._maximumCellWidth; + } + set + { + if(value < -1) + { + throw (new ArgumentException(SR.ExceptionMaximumCellWidthIsWrong, "value")); + } + this._maximumCellWidth = value; + this.Invalidate(); + } + } + + #endregion // Properties + + #region Methods + + /// + /// Creates a new LegendCell object and copies all properties from the + /// current column into the newly created one. + /// + /// A new copy of the LegendCell + internal LegendCell CreateNewCell() + { + LegendCell newCell = new LegendCell(); + newCell.CellType = (this.ColumnType == LegendCellColumnType.SeriesSymbol) ? LegendCellType.SeriesSymbol : LegendCellType.Text; + newCell.Text = this.Text; + newCell.ToolTip = this.ToolTip; +#if !Microsoft_CONTROL + newCell.Url = this.Url; + newCell.MapAreaAttributes = this.MapAreaAttributes; + newCell.PostBackValue = this.PostBackValue; +#endif // !Microsoft_CONTROL + + newCell.SeriesSymbolSize = this.SeriesSymbolSize; + newCell.Alignment = this.Alignment; + newCell.Margins = new Margins(this.Margins.Top, this.Margins.Bottom, this.Margins.Left, this.Margins.Right); + return newCell; + } + + #endregion // Methods + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_fontCache != null) + { + _fontCache.Dispose(); + _fontCache = null; + } + } + } + + + #endregion + } + + /// + /// The LegendCell class represents a single cell in the chart legend. + /// Legend contains several legend items. Each item contains several + /// cells which form the vertical columns. This class provides properties + /// which determine content of the cell and its visual appearance. It + /// also contains method which determine the size of the cell and draw + /// cell in the chart. + /// + [ + SRDescription("DescriptionAttributeLegendCell_LegendCell"), + ] +#if Microsoft_CONTROL + public class LegendCell : ChartNamedElement +#else +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class LegendCell : ChartNamedElement, IChartMapArea +#endif + { + #region Fields + + // Legend cell type + private LegendCellType _cellType = LegendCellType.Text; + + // Legend cell text + private string _text = string.Empty; + + // Legend cell text color + private Color _foreColor = Color.Empty; + + // Legend cell back color + private Color _backColor = Color.Empty; + + // Font cache + private FontCache _fontCache = new FontCache(); + + // Legend cell text font + private Font _font = null; + + // Legend cell image name + private string _image = string.Empty; + + // Legend cell image transparent color + private Color _imageTransparentColor = Color.Empty; + + // Legend cell image size + private Size _imageSize = Size.Empty; + + // Legend cell series symbol size + private Size _seriesSymbolSize = new Size(200, 70); + + // Legend cell content allignment + private ContentAlignment _alignment = ContentAlignment.MiddleCenter; + + // Numer of cells this cell uses to show it's content + private int _cellSpan = 1; + + // Legend cell tooltip + private string _toolTip = string.Empty; + + // Legend cell margins + private Margins _margins = new Margins(0, 0, 15, 15); + + // Cell row index + private int _rowIndex = -1; + +#if !Microsoft_CONTROL + + // Legend cell Url + private string _url = string.Empty; + + // Legend cell map area attribute + private string _mapAreaAttribute = string.Empty; + private string _postbackValue = String.Empty; + +#endif // !Microsoft_CONTROL + + // Position where cell is drawn in pixel coordinates. + // Exncludes margins and space required for separators + internal Rectangle cellPosition = Rectangle.Empty; + + // Position where cell is drawn in pixel coordinates. + // Includes margins and space required for separators + internal Rectangle cellPositionWithMargins = Rectangle.Empty; + + // Last cached cell size. + private Size _cachedCellSize = Size.Empty; + + // Font reduced value used to calculate last cached cell size + private int _cachedCellSizeFontReducedBy = 0; + + #endregion // Fields + + #region Constructors + + /// + /// LegendCell constructor. + /// + public LegendCell() + { + this.Intitialize(LegendCellType.Text, string.Empty, ContentAlignment.MiddleCenter); + } + + /// + /// LegendCell constructor. + /// + /// Cell text or image name, depending on the type. + public LegendCell(string text) + { + this.Intitialize(LegendCellType.Text, text, ContentAlignment.MiddleCenter); + } + + /// + /// LegendCell constructor. + /// + /// Cell type. + /// Cell text or image name, depending on the type. + public LegendCell(LegendCellType cellType, string text) + { + this.Intitialize(cellType, text, ContentAlignment.MiddleCenter); + } + + /// + /// LegendCell constructor. + /// + /// Cell type. + /// Cell text or image name, depending on the type. + /// Cell content alignment. + public LegendCell(LegendCellType cellType, string text, ContentAlignment alignment) + { + this.Intitialize(cellType, text, alignment); + } + + /// + /// Initializes newly created object. + /// + /// Cell type. + /// Cell text or image name depending on the type. + /// Cell content alignment. + private void Intitialize(LegendCellType cellType, string text, ContentAlignment alignment) + { + this._cellType = cellType; + if(this._cellType == LegendCellType.Image) + { + this._image = text; + } + else + { + this._text = text; + } + this._alignment = alignment; +#if !Microsoft_CONTROL + this.PostBackValue = String.Empty; +#endif //!WIN_CONTROL + } + + #endregion // Constructors + + #region Properties + + /// + /// Gets or sets the name of the legend cell. + /// + [ + SRCategory("CategoryAttributeMisc"), + SRDescription("DescriptionAttributeLegendCell_Name"), + ] + public override string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + + /// + /// Gets or sets the type of the legend cell. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(LegendCellType.Text), + SRDescription("DescriptionAttributeLegendCell_CellType"), + ParenthesizePropertyNameAttribute(true) + ] + public virtual LegendCellType CellType + { + get + { + return this._cellType; + } + set + { + this._cellType = value; + this.Invalidate(); + } + } + + /// + /// Gets legend this column/cell belongs too. + /// + [ + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + ] + public virtual Legend Legend + { + get + { + LegendItem item = this.LegendItem; + if (item != null) + return item.Legend; + else + return null; + } + } + + /// + /// Gets legend item this cell belongs too. + /// + [ + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + ] + public virtual LegendItem LegendItem + { + get + { + if (Parent != null) + return Parent.Parent as LegendItem; + else + return null; + } + } + + + + /// + /// Gets or sets the text of the legend cell. Set CellType to text to use this property. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(""), + SRDescription("DescriptionAttributeLegendCell_Text"), + ] + public virtual string Text + { + get + { + return this._text; + } + set + { + this._text = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the text color of the legend cell. Set CellType to text to use this property. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeForeColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public virtual Color ForeColor + { + get + { + return this._foreColor; + } + set + { + this._foreColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background color of the legend cell. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public virtual Color BackColor + { + get + { + return this._backColor; + } + set + { + this._backColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the font of the legend cell. Set CellType to text to use this property. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(null), + SRDescription("DescriptionAttributeLegendCell_Font"), + ] + public virtual Font Font + { + get + { + return this._font; + } + set + { + this._font = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the URL of the image of the legend cell. Set CellType to image to use this property. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(""), + SRDescription("DescriptionAttributeLegendCell_Image"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + ] + public virtual string Image + { + get + { + return this._image; + } + set + { + this._image = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a color which will be replaced with a transparent color while drawing the image. Set CellType to image to use this property. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public virtual Color ImageTransparentColor + { + get + { + return this._imageTransparentColor; + } + set + { + this._imageTransparentColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the image size (as a percentage of legend font size) of the legend cell. + /// Set CellType to Image to use this property. + /// + /// + /// If property is set to Size.IsEmpty, the original image pixels size is used. + /// + [ + SRCategory("CategoryAttributeLayout"), + DefaultValue(typeof(Size), "0, 0"), + TypeConverter(typeof(SizeEmptyValueConverter)), + SRDescription("DescriptionAttributeLegendCell_ImageSize"), + ] + public virtual Size ImageSize + { + get + { + return this._imageSize; + } + set + { + if(value.Width < 0 || value.Height < 0) + { + throw (new ArgumentException(SR.ExceptionLegendCellImageSizeIsNegative, "value")); + } + this._imageSize = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the series symbol size (as a percentage of legend font size) of the legend cell. + /// Set CellType to SeriesSymbol to use this property. + /// + [ + SRCategory("CategoryAttributeLayout"), + DefaultValue(typeof(Size), "200, 70"), + SRDescription("DescriptionAttributeLegendCell_SeriesSymbolSize"), + ] + public virtual Size SeriesSymbolSize + { + get + { + return this._seriesSymbolSize; + } + set + { + if(value.Width < 0 || value.Height < 0) + { + throw (new ArgumentException(SR.ExceptionLegendCellSeriesSymbolSizeIsNegative, "value")); + } + this._seriesSymbolSize = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the content alignment of the legend cell. + /// + [ + SRCategory("CategoryAttributeLayout"), + DefaultValue(ContentAlignment.MiddleCenter), + SRDescription("DescriptionAttributeLegendCell_Alignment"), + ] + public virtual ContentAlignment Alignment + { + get + { + return this._alignment; + } + set + { + this._alignment = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the number of horizontal cells used to draw the content. + /// + [ + SRCategory("CategoryAttributeLayout"), + DefaultValue(1), + SRDescription("DescriptionAttributeLegendCell_CellSpan"), + ] + public virtual int CellSpan + { + get + { + return this._cellSpan; + } + set + { + if(value < 1) + { + throw (new ArgumentException(SR.ExceptionLegendCellSpanIsLessThenOne, "value")); + } + this._cellSpan = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the legend cell margins (as a percentage of legend font size). + /// + [ + SRCategory("CategoryAttributeLayout"), + DefaultValue(typeof(Margins), "0,0,15,15"), + SRDescription("DescriptionAttributeLegendCell_Margins"), + SerializationVisibilityAttribute(SerializationVisibility.Attribute), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.InnerProperty), +#endif + ] + public virtual Margins Margins + { + get + { + return this._margins; + } + set + { + this._margins = value; + this.Invalidate(); + +#if Microsoft_CONTROL + // Set common elements of the new margins class + if(this.Legend != null) + { + this._margins.Common = this.Common; + } +#endif // Microsoft_CONTROL + } + } + + /// + /// Returns true if property should be serialized. This method is for internal use only. + /// + [EditorBrowsableAttribute(EditorBrowsableState.Never)] + internal bool ShouldSerializeMargins() + { + if(this._margins.Top == 0 && + this._margins.Bottom == 0 && + this._margins.Left == 15 && + this._margins.Right == 15 ) + { + return false; + } + return true; + } + + /// + /// Gets or sets the tooltip of the legend cell. + /// + [ + SRCategory("CategoryAttributeMapArea"), + SRDescription("DescriptionAttributeToolTip"), + DefaultValue(""), + ] + public virtual string ToolTip + { + set + { + this._toolTip = value; +#if Microsoft_CONTROL + if(this.Chart != null && + this.Chart.selection != null) + { + this.Chart.selection.enabledChecked = false; + } +#endif + } + get + { + return this._toolTip; + } + } + +#if !Microsoft_CONTROL + + /// + /// Gets or sets the URL target of the legend cell. + /// + [ + SRCategory("CategoryAttributeMapArea"), + SRDescription("DescriptionAttributeUrl"), + DefaultValue(""), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base) + ] + public virtual string Url + { + set + { + this._url = value; + } + get + { + return this._url; + } + } + + /// + /// Gets or sets the other map area attributes of the legend cell. + /// + [ + SRCategory("CategoryAttributeMapArea"), + SRDescription("DescriptionAttributeMapAreaAttributes"), + DefaultValue(""), + ] + public virtual string MapAreaAttributes + { + set + { + this._mapAreaAttribute = value; + } + get + { + return this._mapAreaAttribute; + } + } + + /// + /// Gets or sets the postback value which can be processed on a click event. + /// + /// The value which is passed to a click event as an argument. + [DefaultValue("")] + [SRCategory(SR.Keys.CategoryAttributeMapArea)] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + public string PostBackValue + { + get + { + return this._postbackValue; + } + set + { + this._postbackValue = value; + } + } + + +#endif // !Microsoft_CONTROL + + #endregion // Properties + + #region Methods + + /// + /// Resets cached cell values. + /// + internal void ResetCache() + { + this._cachedCellSize = Size.Empty; + this._cachedCellSizeFontReducedBy = 0; + } + + /// + /// Sets cell position in relative coordinates. + /// + /// Cell row index. + /// Cell position. + /// Size of the 'W' character used to calculate elements. + internal void SetCellPosition( + int rowIndex, + Rectangle position, + Size singleWCharacterSize) + { + // Set cell position + this.cellPosition = position; + this.cellPositionWithMargins = position; + this._rowIndex = rowIndex; + + // Adjust cell position by specified margin + this.cellPosition.X += (int)(this.Margins.Left * singleWCharacterSize.Width / 100f); + this.cellPosition.Y += (int)(this.Margins.Top * singleWCharacterSize.Height / 100f); + this.cellPosition.Width -= (int)(this.Margins.Left * singleWCharacterSize.Width / 100f) + + (int)(this.Margins.Right * singleWCharacterSize.Width / 100f); + this.cellPosition.Height -= (int)(this.Margins.Top * singleWCharacterSize.Height / 100f) + + (int)(this.Margins.Bottom * singleWCharacterSize.Height / 100f); + + // Adjust cell position by space required for the separatorType + if( LegendItem != null && + LegendItem.SeparatorType != LegendSeparatorStyle.None) + { + this.cellPosition.Height -= this.Legend.GetSeparatorSize(LegendItem.SeparatorType).Height; + } + } + + /// + /// Measures legend cell size in chart relative coordinates. + /// + /// + /// Chart graphics. + /// + /// + /// A positive or negative integer value that determines the how standard cell font size + /// should be adjusted. As a result smaller or larger font can be used. + /// + /// + /// Auto fit font used in the legend. + /// + /// + /// Size of the 'W' character used to calculate elements. + /// + /// Legend cell size. + internal Size MeasureCell( + ChartGraphics graph, + int fontSizeReducedBy, + Font legendAutoFont, + Size singleWCharacterSize) + { + // Check if cached size may be reused + if(this._cachedCellSizeFontReducedBy == fontSizeReducedBy && + !this._cachedCellSize.IsEmpty) + { + return this._cachedCellSize; + } + + // Get cell font + Size cellSize = Size.Empty; + bool disposeFont = false; + Font cellFont = this.GetCellFont(legendAutoFont, fontSizeReducedBy, out disposeFont); + + // Measure cell content size based on the type + if(this.CellType == LegendCellType.SeriesSymbol) + { + cellSize.Width = (int)(Math.Abs(this.SeriesSymbolSize.Width) * singleWCharacterSize.Width / 100f); + cellSize.Height = (int)(Math.Abs(this.SeriesSymbolSize.Height) * singleWCharacterSize.Height / 100f); + } + else if(this.CellType == LegendCellType.Image) + { + if(this.ImageSize.IsEmpty && this.Image.Length > 0) + { + SizeF imageSize = new SizeF(); + + // Use original image size + if (this.Common.ImageLoader.GetAdjustedImageSize(this.Image, graph.Graphics, ref imageSize)) + { + cellSize.Width = (int)imageSize.Width; + cellSize.Height = (int)imageSize.Height; + } + } + else + { + cellSize.Width = (int)(Math.Abs(this.ImageSize.Width) * singleWCharacterSize.Width / 100f); + cellSize.Height = (int)(Math.Abs(this.ImageSize.Height) * singleWCharacterSize.Height / 100f); + } + } + else if(this.CellType == LegendCellType.Text) + { + // Get current cell text taking in consideration keywords + // and automatic text wrapping. + string cellText = this.GetCellText(); + + // Measure text size. + // Note that extra "I" character added to add more horizontal spacing + cellSize = graph.MeasureStringAbs(cellText + "I", cellFont); + } + else + { + throw (new InvalidOperationException(SR.ExceptionLegendCellTypeUnknown(this.CellType.ToString()))); + } + + // Add cell margins + cellSize.Width += (int)((this.Margins.Left + this.Margins.Right) * singleWCharacterSize.Width / 100f); + cellSize.Height += (int)((this.Margins.Top + this.Margins.Bottom) * singleWCharacterSize.Height / 100f); + + // Add space required for the separatorType + if( LegendItem != null && + LegendItem.SeparatorType != LegendSeparatorStyle.None) + { + cellSize.Height += this.Legend.GetSeparatorSize(LegendItem.SeparatorType).Height; + } + + // Dispose created font object + if(disposeFont) + { + cellFont.Dispose(); + cellFont = null; + } + + // Save calculated size + this._cachedCellSize = cellSize; + this._cachedCellSizeFontReducedBy = fontSizeReducedBy; + + return cellSize; + } + + /// + /// Gets cell background color. + /// + /// + private Color GetCellBackColor() + { + Color resultColor = this.BackColor; + if(this.BackColor.IsEmpty && this.Legend != null) + { + // Try getting back color from the associated column + if(this.LegendItem != null) + { + // Get index of this cell + int cellIndex = this.LegendItem.Cells.IndexOf(this); + if(cellIndex >= 0) + { + // Check if associated column exsists + if(cellIndex < this.Legend.CellColumns.Count && + !this.Legend.CellColumns[cellIndex].BackColor.IsEmpty) + { + resultColor = this.Legend.CellColumns[cellIndex].BackColor; + } + } + } + + // Get font from the legend isInterlaced + if(resultColor.IsEmpty && + this.Legend.InterlacedRows && + this._rowIndex % 2 != 0) + { + if(this.Legend.InterlacedRowsColor.IsEmpty) + { + // Automatically determine background color + // If isInterlaced strips color is not set - use darker color of the area + if(this.Legend.BackColor == Color.Empty) + { + resultColor = Color.LightGray; + } + else if(this.Legend.BackColor == Color.Transparent) + { + if(Chart.BackColor != Color.Transparent && + Chart.BackColor != Color.Black) + { + resultColor = ChartGraphics.GetGradientColor( Chart.BackColor, Color.Black, 0.2 ); + } + else + { + resultColor = Color.LightGray; + } + } + else + { + resultColor = ChartGraphics.GetGradientColor( this.Legend.BackColor, Color.Black, 0.2 ); + } + } + else + { + resultColor = this.Legend.InterlacedRowsColor; + } + } + } + return resultColor; + } + + /// + /// Gets default cell font. Font can be specified in the cell, column or in the legend. + /// + /// Auto fit font used in the legend. + /// Number of points legend auto-font reduced by. + /// Returns a flag if result font object should be disposed. + /// Default cell font. + private Font GetCellFont(Font legendAutoFont, int fontSizeReducedBy, out bool disposeFont) + { + Font cellFont = this.Font; + disposeFont = false; + + // Check if font is not set in the cell and legend object reference is valid + if(cellFont == null && + this.Legend != null) + { + // Try getting font from the associated column + if(this.LegendItem != null) + { + // Get index of this cell + int cellIndex = this.LegendItem.Cells.IndexOf(this); + if(cellIndex >= 0) + { + // Check if associated column exsists + if(cellIndex < this.Legend.CellColumns.Count && + this.Legend.CellColumns[cellIndex].Font != null) + { + cellFont = this.Legend.CellColumns[cellIndex].Font; + } + } + } + + // Get font from the legend + if(cellFont == null) + { + cellFont = legendAutoFont; + + // No further processing required. + // Font is already reduced. + return cellFont; + } + } + + // Check if font size should be adjusted + if(cellFont != null && fontSizeReducedBy != 0) + { + // New font is created anf it must be disposed + disposeFont = true; + + // Calculate new font size + int newFontSize = (int)Math.Round(cellFont.Size - fontSizeReducedBy); + if(newFontSize < 1) + { + // Font can't be less than size 1 + newFontSize = 1; + } + + // Create new font + cellFont = new Font( + cellFont.FontFamily, + newFontSize, + cellFont.Style, + cellFont.Unit); + } + + return cellFont; + } + + /// + /// Helper function that returns cell tooltip. + /// + /// + /// Tooltip can be set in the cell or in the legend item. Cell + /// tooltip always has a higher priority. + /// + /// Returns cell text. + private string GetCellToolTip() + { + // Check if tooltip is set in the cell (highest priority) + if(this.ToolTip.Length > 0) + { + return this.ToolTip; + } + + // Check if tooltip is set in associated legend item + if(this.LegendItem != null) + { + return this.LegendItem.ToolTip; + } + + return string.Empty; + } + + /// + /// Helper function that returns cell url. + /// + /// + /// Url can be set in the cell or in the legend item. Cell + /// tooltip always has a higher priority. + /// + /// Returns cell text. + private string GetCellUrl() + { +#if !Microsoft_CONTROL + // Check if tooltip is set in the cell (highest priority) + if(this._url.Length > 0) + { + return this._url; + } + + // Check if tooltip is set in associated legend item + if(this.LegendItem != null) + { + return this.LegendItem.Url; + } +#endif // !Microsoft_CONTROL + return string.Empty; + } + + /// + /// Helper function that returns cell url. + /// + /// + /// Url can be set in the cell or in the legend item. Cell + /// tooltip always has a higher priority. + /// + /// Returns cell text. + private string GetCellMapAreaAttributes() + { +#if !Microsoft_CONTROL + // Check if tooltip is set in the cell (highest priority) + if(this._mapAreaAttribute.Length > 0) + { + return this._mapAreaAttribute; + } + + // Check if tooltip is set in associated legend item + if(this.LegendItem != null) + { + return this.LegendItem.MapAreaAttributes; + } +#endif // !Microsoft_CONTROL + return string.Empty; + } + + /// + /// Helper function that returns cell url. + /// + /// + /// Url can be set in the cell or in the legend item. Cell + /// tooltip always has a higher priority. + /// + /// Returns cell text. + private string GetCellPostBackValue() + { +#if !Microsoft_CONTROL + // Check if tooltip is set in the cell (highest priority) + if (this._postbackValue.Length > 0) + { + return this._postbackValue; + } + + // Check if tooltip is set in associated legend item + if (this.LegendItem != null) + { + return this.LegendItem.PostBackValue; + } +#endif // !Microsoft_CONTROL + return string.Empty; + } + + /// + /// Helper function that returns the exact text presented in the cell. + /// + /// + /// This method replaces the "\n" substring with the new line character + /// and automatically wrap text if required. + /// + /// Returns cell text. + private string GetCellText() + { + // Replace all "\n" strings with the new line character + string resultString = this.Text.Replace("\\n", "\n"); + + // Replace the KeywordName.LegendText keyword with legend item Name property + if(this.LegendItem != null) + { + resultString = resultString.Replace(KeywordName.LegendText, this.LegendItem.Name); + } + else + { + resultString = resultString.Replace(KeywordName.LegendText, ""); + } + + // Check if text width exceeds recomended character length + if(this.Legend != null) + { + int recomendedTextLength = this.Legend.TextWrapThreshold; + + if(recomendedTextLength > 0 && + resultString.Length > recomendedTextLength) + { + // Iterate through all text characters + int lineLength = 0; + for(int charIndex = 0; charIndex < resultString.Length; charIndex++) + { + // Reset line length when new line character is found + if(resultString[charIndex] == '\n') + { + lineLength = 0; + continue; + } + + // Increase line length counter + ++lineLength; + + // Check if current character is a white space and + // current line length exceeds the recomended values. + if(char.IsWhiteSpace(resultString, charIndex) && + lineLength >= recomendedTextLength) + { + // Insert new line character in the string + lineLength = 0; + resultString = resultString.Substring(0, charIndex) + "\n" + + resultString.Substring(charIndex + 1).TrimStart(); + } + } + } + } + + return resultString; + } + + /// + /// Helper function that returns cell text color. + /// + /// Cell text color. + private Color GetCellForeColor() + { + // Check if cell text color defined in the cell + if(!this.ForeColor.IsEmpty) + { + return this.ForeColor; + } + + // Check if color from the Column or legend should be used + if(this.Legend != null) + { + // Try getting font from the associated column + if(this.LegendItem != null) + { + // Get index of this cell + int cellIndex = this.LegendItem.Cells.IndexOf(this); + if(cellIndex >= 0) + { + // Check if associated column exsists + if(cellIndex < this.Legend.CellColumns.Count && + !this.Legend.CellColumns[cellIndex].ForeColor.IsEmpty) + { + return this.Legend.CellColumns[cellIndex].ForeColor; + } + } + } + + // Use legend text color + return this.Legend.ForeColor; + } + + return Color.Black; + } + + #endregion // Methods + + #region Cell Painting Methods + + /// + /// Paints content of the legend cell. + /// + /// Chart graphics to draw content on. + /// Number that determines how much the cell font should be reduced by. + /// Auto-fit font used in the legend. + /// Size of the 'W' character in auto-fit font. + internal void Paint( + ChartGraphics chartGraph, + int fontSizeReducedBy, + Font legendAutoFont, + Size singleWCharacterSize) + { + // Check cell size before painting + if(this.cellPosition.Width <= 0 || this.cellPosition.Height <= 0) + { + return; + } + + // Chart elements painting mode + if( this.Common.ProcessModePaint ) + { + // Check if cell background should be painted + Color cellBackColor = this.GetCellBackColor(); + RectangleF rectRelative = chartGraph.GetRelativeRectangle(this.cellPositionWithMargins); + if(!cellBackColor.IsEmpty) + { + chartGraph.FillRectangleRel( + rectRelative, + cellBackColor, + ChartHatchStyle.None, + string.Empty, + ChartImageWrapMode.Tile, + Color.Empty, + ChartImageAlignmentStyle.Center, + GradientStyle.None, + Color.Empty, + Color.Empty, + 0, + ChartDashStyle.NotSet, + Color.Empty, + 0, + PenAlignment.Inset); + } + + // Fire an event for custom cell back drawing + this.Chart.CallOnPrePaint(new ChartPaintEventArgs(this, chartGraph, this.Common, new ElementPosition(rectRelative.X, rectRelative.Y, rectRelative.Width, rectRelative.Height))); + + // Check legend cell type + switch(this.CellType) + { + case(LegendCellType.Text): + this.PaintCellText(chartGraph, fontSizeReducedBy, legendAutoFont); + break; + case(LegendCellType.Image): + this.PaintCellImage(chartGraph, singleWCharacterSize); + break; + case(LegendCellType.SeriesSymbol): + this.PaintCellSeriesSymbol(chartGraph, singleWCharacterSize); + break; + default: + throw (new InvalidOperationException(SR.ExceptionLegendCellTypeUnknown(this.CellType.ToString()))); + } + + // Fire an event for custom cell drawing + this.Chart.CallOnPostPaint(new ChartPaintEventArgs(this, chartGraph, this.Common, new ElementPosition(rectRelative.X, rectRelative.Y, rectRelative.Width, rectRelative.Height))); + } +#if DEBUG + // Draw bounding rectangle for debug purpose +// RectangleF absRectangle = this.cellPosition; +// chartGraph.DrawRectangle(Pens.Red, absRectangle.X, absRectangle.Y, absRectangle.Width, absRectangle.Height); +#endif // DEBUG + + // Legend cell selection mode + if( this.Common.ProcessModeRegions ) + { + // Add hot region. + // Note that legend cell is passed as sub-object of legend item + this.Common.HotRegionsList.AddHotRegion( + chartGraph.GetRelativeRectangle(this.cellPositionWithMargins), + this.GetCellToolTip(), + this.GetCellUrl(), + this.GetCellMapAreaAttributes(), + this.GetCellPostBackValue(), + this.LegendItem, + this, + ChartElementType.LegendItem, + this.LegendItem.SeriesName); + } + } + + /// + /// Draw legend cell text. + /// + /// Chart graphics to draw the text on. + /// Number that determines how much the cell font should be reduced by. + /// Auto-fit font used in the legend. + private void PaintCellText( + ChartGraphics chartGraph, + int fontSizeReducedBy, + Font legendAutoFont) + { + // Get cell font + bool disposeFont = false; + Font cellFont = this.GetCellFont(legendAutoFont, fontSizeReducedBy, out disposeFont); + + // Start Svg Selection mode + chartGraph.StartHotRegion( this.GetCellUrl(), this.GetCellToolTip() ); + + // Create font brush + using(SolidBrush fontBrush = new SolidBrush(this.GetCellForeColor())) + { + // Create cell text format + using (StringFormat format = new StringFormat(StringFormat.GenericDefault)) + { + format.FormatFlags = StringFormatFlags.LineLimit; + format.Trimming = StringTrimming.EllipsisCharacter; + format.Alignment = StringAlignment.Center; + if (this.Alignment == ContentAlignment.BottomLeft || + this.Alignment == ContentAlignment.MiddleLeft || + this.Alignment == ContentAlignment.TopLeft) + { + format.Alignment = StringAlignment.Near; + } + else if (this.Alignment == ContentAlignment.BottomRight || + this.Alignment == ContentAlignment.MiddleRight || + this.Alignment == ContentAlignment.TopRight) + { + format.Alignment = StringAlignment.Far; + } + format.LineAlignment = StringAlignment.Center; + if (this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.BottomLeft || + this.Alignment == ContentAlignment.BottomRight) + { + format.LineAlignment = StringAlignment.Far; + } + else if (this.Alignment == ContentAlignment.TopCenter || + this.Alignment == ContentAlignment.TopLeft || + this.Alignment == ContentAlignment.TopRight) + { + format.LineAlignment = StringAlignment.Near; + } + + // Measure string height out of one character + SizeF charSize = chartGraph.MeasureStringAbs(this.GetCellText(), cellFont, new SizeF(10000f, 10000f), format); + + // If height of one characte is more than rectangle heigjt - remove LineLimit flag + if (charSize.Height > this.cellPosition.Height && (format.FormatFlags & StringFormatFlags.LineLimit) != 0) + { + format.FormatFlags ^= StringFormatFlags.LineLimit; + } + + else if (charSize.Height < this.cellPosition.Height && (format.FormatFlags & StringFormatFlags.LineLimit) == 0) + { + format.FormatFlags |= StringFormatFlags.LineLimit; + } + + // Draw text + chartGraph.DrawStringRel( + this.GetCellText(), + cellFont, + fontBrush, + chartGraph.GetRelativeRectangle(this.cellPosition), + format); + } + } + + // End Svg Selection mode + chartGraph.EndHotRegion( ); + + // Dispose created cell font object + if(disposeFont) + { + cellFont.Dispose(); + cellFont = null; + } + } + + /// + /// Paints cell image. + /// + /// Graphics used to draw cell image. + /// Size of the 'W' character in auto-fit font. + private void PaintCellImage( + ChartGraphics chartGraph, + Size singleWCharacterSize) + { + if(this.Image.Length > 0) + { + // Get image size in relative coordinates + Rectangle imagePosition = Rectangle.Empty; + System.Drawing.Image image = this.Common.ImageLoader.LoadImage(this.Image); + + SizeF imageSize = new SizeF(); + + ImageLoader.GetAdjustedImageSize(image, chartGraph.Graphics, ref imageSize); + + imagePosition.Width = (int)imageSize.Width; + imagePosition.Height = (int)imageSize.Height; + + // Calculate cell position + Rectangle imageCellPosition = this.cellPosition; + imageCellPosition.Width = imagePosition.Width; + imageCellPosition.Height = imagePosition.Height; + if(!this.ImageSize.IsEmpty) + { + // Adjust cell size using image symbol size specified + if(this.ImageSize.Width > 0) + { + int newWidth = (int)(this.ImageSize.Width * singleWCharacterSize.Width / 100f); + if(newWidth > this.cellPosition.Width) + { + newWidth = this.cellPosition.Width; + } + imageCellPosition.Width = newWidth; + } + if(this.ImageSize.Height > 0) + { + int newHeight = (int)(this.ImageSize.Height * singleWCharacterSize.Height / 100f); + if(newHeight > this.cellPosition.Height) + { + newHeight = this.cellPosition.Height; + } + imageCellPosition.Height = newHeight; + } + } + + // Make sure image size fits into the cell drawing rectangle + float scaleValue = 1f; + if(imagePosition.Height > imageCellPosition.Height) + { + scaleValue = (float)imagePosition.Height / (float)imageCellPosition.Height; + } + if(imagePosition.Width > imageCellPosition.Width) + { + scaleValue = Math.Max(scaleValue, (float)imagePosition.Width / (float)imageCellPosition.Width); + } + + // Scale image size + imagePosition.Height = (int)(imagePosition.Height / scaleValue); + imagePosition.Width = (int)(imagePosition.Width / scaleValue); + + // Get image location + imagePosition.X = (int)((this.cellPosition.X + this.cellPosition.Width/2f) - imagePosition.Width/2f); + imagePosition.Y = (int)((this.cellPosition.Y + this.cellPosition.Height/2f) - imagePosition.Height/2f); + + // Adjust image location based on the cell content alignment + if(this.Alignment == ContentAlignment.BottomLeft || + this.Alignment == ContentAlignment.MiddleLeft || + this.Alignment == ContentAlignment.TopLeft) + { + imagePosition.X = this.cellPosition.X; + } + else if(this.Alignment == ContentAlignment.BottomRight || + this.Alignment == ContentAlignment.MiddleRight || + this.Alignment == ContentAlignment.TopRight) + { + imagePosition.X = this.cellPosition.Right - imagePosition.Width; + } + + if(this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.BottomLeft || + this.Alignment == ContentAlignment.BottomRight) + { + imagePosition.Y = this.cellPosition.Bottom - imagePosition.Height; + } + else if(this.Alignment == ContentAlignment.TopCenter || + this.Alignment == ContentAlignment.TopLeft || + this.Alignment == ContentAlignment.TopRight) + { + imagePosition.Y = this.cellPosition.Y; + } + + // Set image transparent color + System.Drawing.Imaging.ImageAttributes imageAttributes = new System.Drawing.Imaging.ImageAttributes(); + if(this.ImageTransparentColor != Color.Empty) + { + imageAttributes.SetColorKey(this.ImageTransparentColor, this.ImageTransparentColor, System.Drawing.Imaging.ColorAdjustType.Default); + } + + // Increase quality of image scaling + SmoothingMode oldSmoothingMode = chartGraph.SmoothingMode; + CompositingQuality oldCompositingQuality = chartGraph.Graphics.CompositingQuality; + InterpolationMode oldInterpolationMode = chartGraph.Graphics.InterpolationMode; + chartGraph.SmoothingMode = SmoothingMode.AntiAlias; + chartGraph.Graphics.CompositingQuality = CompositingQuality.HighQuality; + chartGraph.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; + + // Draw image + chartGraph.DrawImage( + image, + imagePosition, + 0, + 0, + image.Width, + image.Height, + GraphicsUnit.Pixel, + imageAttributes); + + // Restore graphics settings + chartGraph.SmoothingMode = oldSmoothingMode; + chartGraph.Graphics.CompositingQuality = oldCompositingQuality; + chartGraph.Graphics.InterpolationMode = oldInterpolationMode; + } + } + + /// + /// Paint a series symbol in the cell. + /// + /// Chart graphics + /// Size of the 'W' character in auto-fit font. + private void PaintCellSeriesSymbol( + ChartGraphics chartGraph, + SizeF singleWCharacterSize) + { + //Cache legend item + LegendItem legendItem = this.LegendItem; + + // Calculate cell position + Rectangle seriesMarkerPosition = this.cellPosition; + + // Adjust cell size using image symbol size specified + if(this.SeriesSymbolSize.Width >= 0) + { + int newWidth = (int)(this.SeriesSymbolSize.Width * singleWCharacterSize.Width / 100f); + if(newWidth > this.cellPosition.Width) + { + newWidth = this.cellPosition.Width; + } + seriesMarkerPosition.Width = newWidth; + } + if(this.SeriesSymbolSize.Height >= 0) + { + int newHeight = (int)(this.SeriesSymbolSize.Height * singleWCharacterSize.Height / 100f); + if(newHeight > this.cellPosition.Height) + { + newHeight = this.cellPosition.Height; + } + seriesMarkerPosition.Height = newHeight; + } + + // Check for empty size + if(seriesMarkerPosition.Height <= 0 || seriesMarkerPosition.Width <= 0) + { + return; + } + + // Get symbol location + seriesMarkerPosition.X = (int)((this.cellPosition.X + this.cellPosition.Width/2f) - seriesMarkerPosition.Width/2f); + seriesMarkerPosition.Y = (int)((this.cellPosition.Y + this.cellPosition.Height/2f) - seriesMarkerPosition.Height/2f); + + // Adjust image location based on the cell content alignment + if(this.Alignment == ContentAlignment.BottomLeft || + this.Alignment == ContentAlignment.MiddleLeft || + this.Alignment == ContentAlignment.TopLeft) + { + seriesMarkerPosition.X = this.cellPosition.X; + } + else if(this.Alignment == ContentAlignment.BottomRight || + this.Alignment == ContentAlignment.MiddleRight || + this.Alignment == ContentAlignment.TopRight) + { + seriesMarkerPosition.X = this.cellPosition.Right - seriesMarkerPosition.Width; + } + + if(this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.BottomLeft || + this.Alignment == ContentAlignment.BottomRight) + { + seriesMarkerPosition.Y = this.cellPosition.Bottom - seriesMarkerPosition.Height; + } + else if(this.Alignment == ContentAlignment.TopCenter || + this.Alignment == ContentAlignment.TopLeft || + this.Alignment == ContentAlignment.TopRight) + { + seriesMarkerPosition.Y = this.cellPosition.Y; + } + + // Start Svg Selection mode + chartGraph.StartHotRegion( this.GetCellUrl(), this.GetCellToolTip() ); + + // Draw legend item image + if(legendItem.Image.Length > 0) + { + // Get image size + Rectangle imageScale = Rectangle.Empty; + System.Drawing.Image image = this.Common.ImageLoader.LoadImage(legendItem.Image); + + if (image != null) + { + SizeF imageSize = new SizeF(); + + ImageLoader.GetAdjustedImageSize(image, chartGraph.Graphics, ref imageSize); + + imageScale.Width = (int)imageSize.Width; + imageScale.Height = (int)imageSize.Height; + + // Make sure image size fits into the drawing rectangle + float scaleValue = 1f; + if (imageScale.Height > seriesMarkerPosition.Height) + { + scaleValue = (float)imageScale.Height / (float)seriesMarkerPosition.Height; + } + if (imageScale.Width > seriesMarkerPosition.Width) + { + scaleValue = Math.Max(scaleValue, (float)imageScale.Width / (float)seriesMarkerPosition.Width); + } + + // Scale image size + imageScale.Height = (int)(imageScale.Height / scaleValue); + imageScale.Width = (int)(imageScale.Width / scaleValue); + + imageScale.X = (int)((seriesMarkerPosition.X + seriesMarkerPosition.Width / 2f) - imageScale.Width / 2f); + imageScale.Y = (int)((seriesMarkerPosition.Y + seriesMarkerPosition.Height / 2f) - imageScale.Height / 2f); + + // Set image transparent color + System.Drawing.Imaging.ImageAttributes imageAttributes = new System.Drawing.Imaging.ImageAttributes(); + if (legendItem.BackImageTransparentColor != Color.Empty) + { + imageAttributes.SetColorKey(legendItem.BackImageTransparentColor, legendItem.BackImageTransparentColor, System.Drawing.Imaging.ColorAdjustType.Default); + } + + // Draw image + chartGraph.DrawImage( + image, + imageScale, + 0, + 0, + image.Width, + image.Height, + GraphicsUnit.Pixel, + imageAttributes); + } + } + + else + { + int maxShadowOffset = (int)Math.Round((3 * chartGraph.Graphics.DpiX) / 96); + int maxBorderWidth = (int)Math.Round((3 * chartGraph.Graphics.DpiX) / 96); + + if(legendItem.ImageStyle == LegendImageStyle.Rectangle) + { + int maxBorderWidthRect = (int)Math.Round((2 * chartGraph.Graphics.DpiX) / 96); + + // Draw series rectangle + chartGraph.FillRectangleRel( + chartGraph.GetRelativeRectangle(seriesMarkerPosition), + legendItem.Color, + legendItem.BackHatchStyle, + legendItem.Image, + legendItem.backImageWrapMode, + legendItem.BackImageTransparentColor, + legendItem.backImageAlign, + legendItem.backGradientStyle, + legendItem.backSecondaryColor, + legendItem.borderColor, + (legendItem.BorderWidth > maxBorderWidthRect) ? maxBorderWidthRect : legendItem.BorderWidth, + legendItem.BorderDashStyle, + legendItem.ShadowColor, + (legendItem.ShadowOffset > maxShadowOffset) ? maxShadowOffset : legendItem.ShadowOffset, + PenAlignment.Inset); + } + if(legendItem.ImageStyle == LegendImageStyle.Line) + { + // Prepare line coordinates + Point point1 = new Point(); + point1.X = seriesMarkerPosition.X; + point1.Y = (int)(seriesMarkerPosition.Y + seriesMarkerPosition.Height/2F); + Point point2 = new Point(); + point2.Y = point1.Y; + point2.X = seriesMarkerPosition.Right; + + // Disable antialiasing + SmoothingMode oldMode = chartGraph.SmoothingMode; + chartGraph.SmoothingMode = SmoothingMode.None; + + // Draw line + chartGraph.DrawLineRel( + legendItem.Color, + (legendItem.borderWidth > maxBorderWidth) ? maxBorderWidth : legendItem.borderWidth, + legendItem.borderDashStyle, + chartGraph.GetRelativePoint(point1), + chartGraph.GetRelativePoint(point2), + legendItem.shadowColor, + (legendItem.shadowOffset > maxShadowOffset) ? maxShadowOffset : legendItem.shadowOffset); + + // Restore antialiasing mode + chartGraph.SmoothingMode = oldMode; + } + + // Draw symbol (for line also) + if(legendItem.ImageStyle == LegendImageStyle.Marker || + legendItem.ImageStyle == LegendImageStyle.Line) + { + MarkerStyle markerStyle = legendItem.markerStyle; + if(legendItem.style == LegendImageStyle.Marker) + { + markerStyle = (legendItem.markerStyle == MarkerStyle.None) ? + MarkerStyle.Circle : legendItem.markerStyle; + } + + if(markerStyle != MarkerStyle.None || + legendItem.markerImage.Length > 0) + { + // Calculate marker size + int markerSize = (int)Math.Min(seriesMarkerPosition.Width, seriesMarkerPosition.Height); + markerSize = (int)Math.Min(legendItem.markerSize, (legendItem.style == LegendImageStyle.Line) ? 2f*(markerSize/3f) : markerSize); + + // Reduce marker size to fit border + int markerBorderWidth = (legendItem.MarkerBorderWidth > maxBorderWidth) ? maxBorderWidth : legendItem.MarkerBorderWidth; + if(markerBorderWidth > 0) + { + markerSize -= markerBorderWidth; + if(markerSize < 1) + { + markerSize = 1; + } + } + + // Draw marker + Point point = new Point(); + point.X = (int)(seriesMarkerPosition.X + seriesMarkerPosition.Width/2f); + point.Y = (int)(seriesMarkerPosition.Y + seriesMarkerPosition.Height/2f); + + // Calculate image scale + Rectangle imageScale = Rectangle.Empty; + if(legendItem.markerImage.Length > 0) + { + // Get image size + System.Drawing.Image image = this.Common.ImageLoader.LoadImage(legendItem.markerImage); + + SizeF imageSize = new SizeF(); + + ImageLoader.GetAdjustedImageSize(image, chartGraph.Graphics, ref imageSize); + + imageScale.Width = (int)imageSize.Width; + imageScale.Height = (int)imageSize.Height; + + // Make sure image size fits into the drawing rectangle + float scaleValue = 1f; + if(imageScale.Height > seriesMarkerPosition.Height) + { + scaleValue = (float)imageScale.Height / (float)seriesMarkerPosition.Height; + } + if(imageScale.Width > seriesMarkerPosition.Width) + { + scaleValue = Math.Max(scaleValue, (float)imageScale.Width / (float)seriesMarkerPosition.Width); + } + + // Scale image size + imageScale.Height = (int)(imageScale.Height / scaleValue); + imageScale.Width = (int)(imageScale.Width / scaleValue); + } + + // Adjust marker position so that it always drawn on pixel + // boundary. + PointF pointF = new PointF(point.X, point.Y); + if( (markerSize%2) != 0.0 ) + { + pointF.X -= 0.5f; + pointF.Y -= 0.5f; + } + + // Draw marker if it's not image + chartGraph.DrawMarkerRel( + chartGraph.GetRelativePoint(pointF), + markerStyle, + markerSize, + (legendItem.markerColor == Color.Empty) ? legendItem.Color : legendItem.markerColor, + (legendItem.markerBorderColor == Color.Empty) ? legendItem.borderColor : legendItem.markerBorderColor, + markerBorderWidth, + legendItem.markerImage, + legendItem.markerImageTransparentColor, + (legendItem.shadowOffset > maxShadowOffset) ? maxShadowOffset : legendItem.shadowOffset, + legendItem.shadowColor, + imageScale); + } + } + } + + // End Svg Selection mode + chartGraph.EndHotRegion( ); + } + + #endregion // Cell Painting Methods + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_fontCache != null) + { + _fontCache.Dispose(); + _fontCache = null; + } + } + base.Dispose(disposing); + } + + + #endregion + } + + /// + /// The Margins class represents the margins for various chart elements. + /// + [ + SRDescription("DescriptionAttributeMargins_Margins"), + TypeConverter(typeof(MarginExpandableObjectConverter)), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class Margins + { + #region Fields + + // Top margin + private int _top = 0; + + // Bottom margin + private int _bottom = 0; + + // Left margin + private int _left = 0; + + // Right margin + private int _right = 0; + +#if Microsoft_CONTROL + + // Reference to common chart elements which allows to invalidate + // chart when one of the properties is changed. + internal CommonElements Common = null; + +#endif // Microsoft_CONTROL + + #endregion // Fields + + #region Constructor + + /// + /// Margins constructor. + /// + public Margins() + { + } + + /// + /// Margins constructor. + /// + /// Top margin. + /// Bottom margin. + /// Left margin. + /// Right margin. + public Margins(int top, int bottom, int left, int right) + { + this._top = top; + this._bottom = bottom; + this._left = left; + this._right = right; + } + + #endregion // Constructor + + #region Properties + + /// + /// Gets or sets the top margin. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(0), + SRDescription("DescriptionAttributeMargins_Top"), + RefreshPropertiesAttribute(RefreshProperties.All), + NotifyParentPropertyAttribute(true), + ] + public int Top + { + get + { + return this._top; + } + set + { + if(value < 0) + { + throw (new ArgumentException(SR.ExceptionMarginTopIsNegative, "value")); + } + this._top = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the bottom margin. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(0), + SRDescription("DescriptionAttributeMargins_Bottom"), + RefreshPropertiesAttribute(RefreshProperties.All), + NotifyParentPropertyAttribute(true), + ] + public int Bottom + { + get + { + return this._bottom; + } + set + { + if(value < 0) + { + throw (new ArgumentException(SR.ExceptionMarginBottomIsNegative, "value")); + } + this._bottom = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the left margin. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(0), + RefreshPropertiesAttribute(RefreshProperties.All), + SRDescription("DescriptionAttributeMargins_Left"), + NotifyParentPropertyAttribute(true), + ] + public int Left + { + get + { + return this._left; + } + set + { + if(value < 0) + { + throw (new ArgumentException(SR.ExceptionMarginLeftIsNegative, "value")); + } + this._left = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the right margin. + /// + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(0), + SRDescription("DescriptionAttributeMargins_Right"), + RefreshPropertiesAttribute(RefreshProperties.All), + NotifyParentPropertyAttribute(true), + ] + public int Right + { + get + { + return this._right; + } + set + { + if(value < 0) + { + throw (new ArgumentException(SR.ExceptionMarginRightIsNegative, "value")); + } + this._right = value; + this.Invalidate(); + } + } + + #endregion // Properties + + #region Methods + + /// + /// Convert margins object to string. + /// + /// A string that represents the margins object. + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + public override string ToString() + { + return string.Format( + CultureInfo.InvariantCulture, + "{0:D}, {1:D}, {2:D}, {3:D}", + this.Top, + this.Bottom, + this.Left, + this.Right); + } + + /// + /// Determines whether the specified Object is equal to the current Object. + /// + /// + /// The Object to compare with the current Object. + /// + /// + /// True if the specified Object is equal to the current Object; otherwise, false. + /// + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + public override bool Equals(object obj) + { + Margins margins = obj as Margins; + if(margins != null) + { + if(this.Top == margins.Top && + this.Bottom == margins.Bottom && + this.Left == margins.Left && + this.Right == margins.Right) + { + return true; + } + } + return false; + } + + /// + /// Gets object hash code. + /// + /// Margins object hash value. + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + public override int GetHashCode() + { + return this.Top.GetHashCode() + this.Bottom.GetHashCode() + this.Left.GetHashCode() + this.Right.GetHashCode(); + } + + /// + /// Checks if there is no margin. + /// + /// + /// True if all margins values are zeros. + /// + public bool IsEmpty() + { + return (this.Top == 0 && this.Bottom == 0 && this.Left == 0 && this.Right ==0); + } + + /// + /// Converts Margins class to RectangleF class. + /// + /// A RectangleF class that contains the values of the margins. + public RectangleF ToRectangleF() + { + return new RectangleF(this.Left, this.Top, this.Right, this.Bottom); + } + + /// + /// Invalidates chart. + /// + private void Invalidate() + { +#if Microsoft_CONTROL + if(this.Common != null && this.Common.Chart != null) + { + this.Common.Chart.Invalidate(); + } +#endif // Microsoft_CONTROL + } + + #endregion // Methods + } + + /// + /// LegendCellCollection is a strongly typed collection of LegendCell objects. + /// + [ + SRDescription("DescriptionAttributeLegendCellCollection_LegendCellCollection"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class LegendCellCollection : ChartNamedElementCollection + { + + #region Constructors + + /// + /// LegendCellCollection constructor. + /// + /// + /// This constructor is for internal use and should not be part of documentation. + /// + /// Legend item this collection belongs to. + internal LegendCellCollection(LegendItem parent) : base (parent) + { + } + + #endregion + + #region Methods + /// + /// Adds a cell to the end of the collection. + /// + /// + /// A value representing the cell type. + /// + /// + /// A string value representing cell text or image name depending + /// on the cellType parameter. + /// + /// + /// A value representing cell content alignment. + /// + /// + /// Index of the newly added object. + /// + public int Add(LegendCellType cellType, string text, ContentAlignment alignment) + { + Add(new LegendCell(cellType, text, alignment)); + return Count - 1; + } + + /// + /// Inserts a cell into the collection. + /// + /// + /// Index to insert the object at. + /// + /// + /// A value representing the cell type. + /// + /// + /// A string value representing cell text or image name depending + /// on the cellType parameter. + /// + /// + /// A value representing cell content alignment. + /// + public void Insert(int index, LegendCellType cellType, string text, ContentAlignment alignment) + { + this.Insert(index, new LegendCell(cellType, text, alignment)); + } + + #endregion + + } + + /// + /// The LegendCellColumnCollection class is a strongly typed collection + /// of LegendCellColumn objects. + /// + [ + SRDescription("DescriptionAttributeLegendCellColumnCollection_LegendCellColumnCollection"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class LegendCellColumnCollection : ChartNamedElementCollection + { + + #region Construction and Initialization + + /// + /// LegendCellColumnCollection constructor. + /// + /// + /// This constructor is for internal use and should not be part of documentation. + /// + /// + /// Chart legend which this collection belongs to. + /// + internal LegendCellColumnCollection(Legend legend) + : base(legend) + { + } + + #endregion // Construction and Initialization + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + //Free managed resources + foreach (LegendCellColumn item in this) + { + item.Dispose(); + } + this.ClearItems(); + } + base.Dispose(disposing); + } + + + #endregion + } + +} + diff --git a/System.Web.DataVisualization/Common/General/Matrix3D.cs b/System.Web.DataVisualization/Common/General/Matrix3D.cs new file mode 100644 index 000000000..04caadda6 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/Matrix3D.cs @@ -0,0 +1,1222 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: Matrix3D.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: Matrix3D +// +// Purpose: Matrix3D class is used during the 3D drawings to +// transform plotting area 3D coordinates into the 2D +// projection coordinates based on rotation and +// perspective settings. +// +// Reviewed: AG - Dec 4, 2002 +// AG - Microsoft 14, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Drawing.Imaging; +using System.ComponentModel; +using System.Collections; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + +#else + //using System.Web.UI.DataVisualization.Charting.Utilities; + //using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// This class is responsible for all 3D coordinates transformations: Translation, + /// Rotation, Scale, Perspective and RightAngle Projection. Translation + /// and rotation are stored in composite matrix (mainMatrix), and scaling, + /// projection and non-composite translation are stored in private fields. + /// Matrix is initialized with Chart Area 3D cube, which is invisible boundary + /// cube of 3D Chart area. The matrix has to be initialized every time + /// when angles, position or perspective parameters are changed. Method + /// TransformPoints will apply 3D Transformation on points using + /// Initialization values: Main matrix and other initialization values. + /// + internal class Matrix3D + { + #region Enumerations + + /// + /// 3D Axis used for rotation + /// + private enum RotationAxis + { + /// + /// Rotation around X axis. + /// + X, + + /// + /// Rotation around Y axis. + /// + Y, + + /// + /// Rotation around Z axis. + /// + Z + } + + #endregion // Enumerations + + #region Fields + + /// + /// Composite matrix. + /// + private float [][] _mainMatrix; + + /// + /// Default translation for chart area cube ( without composition ). + /// + private float _translateX; + + /// + /// Default translation for chart area cube ( without composition ). + /// + private float _translateY; + + /// + /// Default translation for chart area cube ( without composition ). + /// + private float _translateZ; + + /// + /// The value, which is used to rescale chart area. + /// + private float _scale; + + /// + /// The value used for Isometric Shift. + /// + private float _shiftX; + + /// + /// The value used for Isometric Shift. + /// + private float _shiftY; + + /// + /// Perspective value. + /// + internal float _perspective; + + /// + /// Isometric projection. + /// + private bool _rightAngleAxis; + + /// + /// The value, which is used for perspective. + /// + private float _perspectiveFactor = float.NaN; + + /// + /// The value, which is used to set projection plane. + /// + private float _perspectiveZ; + + /// + /// X Angle. + /// + private float _angleX; + + /// + /// Y Angle. + /// + private float _angleY; + + /// + /// Private fields used for lighting + /// + Point3D [] _lightVectors = new Point3D[7]; + + /// + /// LightStyle Style + /// + LightStyle _lightStyle; + + #endregion // Fields + + #region Properties + + /// + /// Gets the X Angle. + /// + internal float AngleX + { + get { return _angleX; } + } + + /// + /// Gets the Y Angle. + /// + internal float AngleY + { + get { return _angleY; } + } + + /// + /// Get perspective value. + /// + internal float Perspective + { + get { return _perspective; } + } + + #endregion // Properties + + #region Internal and Public Methods + + /// + /// Constructor for Matrix 3D + /// + public Matrix3D() + { + } + + /// + /// Checks if 3D matrix was initialized. + /// + /// True if matrix was initialized. + public bool IsInitialized() + { + return (this._mainMatrix != null); + } + + /// + /// Initialize Matrix 3D. This method calculates how much a chart area + /// cube has to be resized to fit Inner Plotting Area rectangle. Order + /// of operation is following: Translation for X and Y axes, Rotation + /// by X-axis, Rotation by Y-axis and same scaling for all axes. All + /// other elements, which belongs to this chart area cube (Data points, + /// grid lines etc.) has to follow same order. Translation and rotation + /// form composite matrix mainMatrix. Scale has to be allied separately. + /// + /// Inner Plotting Area position. Chart area cube has to be inside this rectangle + /// Depth of chart area cube + /// Angle of rotation by X axis. + /// Angle of rotation by Y axis. + /// Perspective in percentages + /// Right angle flag. + internal void Initialize( + RectangleF innerPlotRectangle, + float depth, + float angleX, + float angleY, + float perspective, + bool rightAngleAxis ) + { + // Initialization for mainMatrix + Reset(); + + // Remember non-composite translation + _translateX = innerPlotRectangle.X+innerPlotRectangle.Width/2; + _translateY = innerPlotRectangle.Y+innerPlotRectangle.Height/2; + _translateZ = depth / 2F; + float width = innerPlotRectangle.Width; + float height = innerPlotRectangle.Height; + this._perspective = perspective; + this._rightAngleAxis = rightAngleAxis; + + // Remember Angles + this._angleX = angleX; + this._angleY = angleY; + + // Change Degrees to radians. + angleX = angleX / 180F * (float)Math.PI; + angleY = angleY / 180F * (float)Math.PI; + + // Set points for 3D Bar which represents 3D Chart Area Cube. + Point3D [] points = Set3DBarPoints( width, height, depth ); + + // Translate Chart Area Cube WITH CENTER OF ROTATION - COMPOSITE TRANSLATION. + Translate( _translateX, _translateY, 0 ); + + // Non Isometric projection + if( !rightAngleAxis ) + { + // Rotate Chart Area Cube by X axis. + Rotate( angleX, RotationAxis.X ); + + // Rotate Chart Area Cube by Y axis. + Rotate( angleY, RotationAxis.Y ); + } + else + { + if( this._angleY >= 45 ) + { + // Rotate Chart Area Cube by Y axis. + Rotate( Math.PI / 2, RotationAxis.Y ); + } + else if( this._angleY <= -45 ) + { + // Rotate Chart Area Cube by Y axis. + Rotate( -Math.PI / 2, RotationAxis.Y ); + } + } + + // Apply composed transformation ( Translation and rotation ). + GetValues( points ); + + float maxZ = float.MinValue; + + if( perspective != 0F || rightAngleAxis ) + { + // Find projection plane + foreach( Point3D point in points ) + { + if( point.Z > maxZ ) + maxZ = point.Z; + } + + // Set Projection plane + _perspectiveZ = maxZ; + } + + if( perspective != 0F ) + { + _perspectiveFactor = perspective / 2000F; + + // Apply perspective + ApplyPerspective( points ); + } + + // Isometric projection is active + if( rightAngleAxis ) + { + RightAngleProjection( points ); + + float minX = 0F; + float minY = 0F; + float maxX = 0F; + float maxY = 0F; + + // Point loop + foreach( Point3D point in points ) + { + if( point.X - _translateX < 0F && Math.Abs( point.X - _translateX ) > minX ) + minX = Math.Abs( point.X - _translateX ); + + if( point.X - _translateX >=0F && Math.Abs( point.X - _translateX ) > maxX ) + maxX = Math.Abs( point.X - _translateX ); + + if( point.Y - _translateY < 0F && Math.Abs( point.Y - _translateY ) > minY ) + minY = Math.Abs( point.Y - _translateY ); + + if( point.Y - _translateY >=0F && Math.Abs( point.Y - _translateY ) > maxY ) + maxY = Math.Abs( point.Y - _translateY ); + } + + _shiftX = (maxX - minX)/2F; + _shiftY = (maxY - minY)/2F; + RightAngleShift( points ); + } + + // This code searches for value, which will be used for scaling. + float maxXScale = float.MinValue; + float maxYScale = float.MinValue; + + foreach( Point3D point in points ) + { + // Find maximum relative distance for X axis. + // Relative distance is (distance from the center of plotting area + // position) / (distance from the edge of rectangle to + // the center of the rectangle). + if( maxXScale < Math.Abs(point.X - _translateX) / width * 2 ) + maxXScale = Math.Abs(point.X - _translateX) / width * 2; + + // Find maximum relative distance for Y axis. + if( maxYScale < Math.Abs(point.Y - _translateY) / height * 2 ) + maxYScale = Math.Abs(point.Y - _translateY) / height * 2; + } + + // Remember scale factor + _scale = (maxYScale > maxXScale ) ? maxYScale : maxXScale; + + // Apply scaling + Scale( points ); + + } + + /// + /// Apply transformations on array od 3D Points. Order of operation is + /// following: Translation ( Set coordinate system for 0:100 to -50:50 + /// Center of rotation is always 0), Composite Translation for X and Y + /// axes ( Moving center of rotation ), Rotation by X-axis, Rotation + /// by Y-axis, perspective and same scaling for all axes. + /// + /// 3D Points array. + public void TransformPoints( Point3D[] points ) + { + TransformPoints( points, true ); + } +#if RS_DEADCODE + /// + /// This Method returns scale factor + /// + /// + internal float GetScale() + { + return scale; + } +#endif //RS_DEADCODE + #endregion // Internal and Public Methods + + #region Private Methods + + /// + /// Apply transformations on array od 3D Points. Order of operation is + /// following: Translation ( Set coordinate system for 0:100 to -50:50 + /// Center of rotation is always 0), Composite Translation for X and Y + /// axes ( Moving center of rotation ), Rotation by X-axis, Rotation + /// by Y-axis, perspective and same scaling for all axes. + /// + /// 3D Points array. + /// Applay Perspective + private void TransformPoints( Point3D[] points, bool withPerspective ) + { + // Matrix is not initialized. + if( _mainMatrix == null ) + { + throw new InvalidOperationException(SR.ExceptionMatrix3DNotinitialized); + } + + // Translate point. CENTER OF ROTATION is 0 and that center is in + // the middle of chart area 3D CUBE. Translate method cannot + // be used because composite translation WILL MOVE + // CENTER OF ROTATION. + foreach( Point3D point in points ) + { + point.X -= _translateX; + point.Y -= _translateY; + point.Z -= _translateZ; + } + + // Transform points using composite mainMatrix. (Translation of points together with + // Center of rotation and rotations by X and Y axes). + GetValues( points ); + + // Apply perspective + if( _perspective != 0F && withPerspective ) + { + ApplyPerspective( points ); + } + + // RightAngle Projection + if( _rightAngleAxis ) + { + RightAngleProjection( points ); + RightAngleShift( points ); + } + + // Scales data points. Scaling has to be performed SEPARATELY from + // composite matrix. If scale is used with composite matrix after + // rotation, scaling will deform object. + Scale( points ); + } + + /// + /// This method adjusts a position of 3D Chart Area cube. This + /// method will translate chart for better use of the inner + /// plotting area. Center of rotation is shifted for + /// right Angle projection. + /// + /// 3D Points array. + private void RightAngleShift( Point3D [] points ) + { + foreach( Point3D point in points ) + { + point.X = point.X - _shiftX; + point.Y = point.Y - _shiftY; + } + } + + /// + /// Method used to calculate right Angle projection. + /// + /// 3D points array. + private void RightAngleProjection( Point3D [] points ) + { + float coorectionAngle = 45F; + + float xFactor = this._angleX / 45; + + float yFactor; + + if( this._angleY >= 45 ) + { + yFactor = (this._angleY - 90) / coorectionAngle; + } + else if ( this._angleY <= -45 ) + { + yFactor = ( this._angleY + 90 ) / coorectionAngle; + } + else + { + yFactor = this._angleY / coorectionAngle; + } + + // Projection formula + // perspectiveZ - Position of perspective plain. + // Perspective Factor - Intensity of projection. + foreach( Point3D point in points ) + { + point.X = point.X + ( _perspectiveZ - point.Z ) * yFactor; + point.Y = point.Y - ( _perspectiveZ - point.Z ) * xFactor; + } + } + + /// + /// Method is used for Planar Geometric projection. + /// + /// 3D Points array. + private void ApplyPerspective( Point3D [] points ) + { + // Projection formula + // perspectiveZ - Position of perspective plain. + // perspectiveFactor - Intensity of projection. + foreach( Point3D point in points ) + { + point.X = _translateX + (point.X - _translateX) / ( 1 + (_perspectiveZ - point.Z) * _perspectiveFactor); + point.Y = _translateY + (point.Y - _translateY) / ( 1 + (_perspectiveZ - point.Z) * _perspectiveFactor); + } + } + + /// + /// Scales data points. Scaling has to be performed SEPARATELY from + /// composite matrix. If scale is used with composite matrix after + /// rotation, scaling will deform object. + /// + /// 3D Points array. + private void Scale( Point3D [] points ) + { + foreach( Point3D point in points ) + { + point.X = _translateX + (point.X - _translateX) / _scale; + point.Y = _translateY + (point.Y - _translateY) / _scale; + } + } + + /// + /// Prepend to this Matrix object a translation. This method is used + /// only if CENTER OF ROTATION HAS TO BE MOVED. + /// + /// Translate in x axis direction. + /// Translate in y axis direction. + /// Translate in z axis direction. + private void Translate( float dx, float dy, float dz ) + { + float [][] translationMatrix = new float[4][]; + translationMatrix[0] = new float[4]; + translationMatrix[1] = new float[4]; + translationMatrix[2] = new float[4]; + translationMatrix[3] = new float[4]; + + // Matrix initialization + // Row loop + for( int row = 0; row < 4; row ++ ) + { + // Column loop + for( int column = 0; column < 4; column ++ ) + { + // For initialization: Diagonal matrix elements are equal to one + // and all other elements are equal to zero. + if( row == column ) + { + translationMatrix[row][column] = 1F; + } + else + { + translationMatrix[row][column] = 0F; + } + } + } + + // Set translation values to the matrix + translationMatrix[0][3] = dx; + translationMatrix[1][3] = dy; + translationMatrix[2][3] = dz; + + // Translate main Matrix + Multiply( translationMatrix, MatrixOrder.Prepend, true ); + + } + + /// + /// This method initialize and set default values for mainMatrix ( there is no rotation and translation ) + /// + private void Reset() + { + // First element is row and second element is column !!! + _mainMatrix = new float[4][]; + _mainMatrix[0] = new float[4]; + _mainMatrix[1] = new float[4]; + _mainMatrix[2] = new float[4]; + _mainMatrix[3] = new float[4]; + + // Matrix initialization + // Row loop + for( int row = 0; row < 4; row ++ ) + { + // Column loop + for( int column = 0; column < 4; column ++ ) + { + // For initialization: Diagonal matrix elements are equal to one + // and all other elements are equal to zero. + if( row == column ) + { + _mainMatrix[row][column] = 1F; + } + else + { + _mainMatrix[row][column] = 0F; + } + } + } + } + + + /// + /// Multiplies this Matrix object by the matrix specified in the + /// matrix parameter, and in the order specified in the order parameter. + /// + /// The Matrix object by which this Matrix object is to be multiplied. + /// The MatrixOrder enumeration that represents the order of the multiplication. If the specified order is MatrixOrder.Prepend, this Matrix object is multiplied by the specified matrix in a prepended order. If the specified order is MatrixOrder.Append, this Matrix object is multiplied by the specified matrix in an appended order. + /// Set main matrix to be result of multiplication + /// Matrix multiplication result. + private float[][] Multiply( float [][] mulMatrix, MatrixOrder order, bool setMainMatrix ) + { + // A matrix which is result of matrix multiplication + // of mulMatrix and mainMatrix + float [][] resultMatrix = new float[4][]; + resultMatrix[0] = new float[4]; + resultMatrix[1] = new float[4]; + resultMatrix[2] = new float[4]; + resultMatrix[3] = new float[4]; + + // Row loop + for( int row = 0; row < 4; row ++ ) + { + // Column loop + for( int column = 0; column < 4; column ++ ) + { + // Initialize element + resultMatrix[row][column ] = 0F; + for( int sumIndx = 0; sumIndx < 4; sumIndx ++ ) + { + // Find matrix element + if( order == MatrixOrder.Prepend ) + { + // Order of matrix multiplication + resultMatrix[row][column ] += _mainMatrix[row][sumIndx ] * mulMatrix[sumIndx][column]; + } + else + { + // Order of matrix multiplication + resultMatrix[row][column] += mulMatrix[row][sumIndx] * _mainMatrix[sumIndx][column]; + } + } + } + } + + // Set result matrix to be main matrix + if( setMainMatrix ) + { + _mainMatrix = resultMatrix; + } + + return resultMatrix; + } + + + /// + /// Multiplies this Matrix object by the Vector specified in the + /// vector parameter. + /// + /// The vector object by which this Matrix object is to be multiplied. + /// Vector which is result of matrix and vector multiplication. + private void MultiplyVector( float [] mulVector, ref float [] resultVector ) + { + // Row loop + for( int row = 0; row < 3; row ++ ) + { + // Initialize element + resultVector[ row ] = 0F; + + // Column loop + for( int column = 0; column < 4; column ++ ) + { + // Find matrix element + resultVector[ row ] += _mainMatrix[row][column] * mulVector[ column ]; + } + } + } + + /// + /// Prepend to this Matrix object a clockwise rotation, around the axis and by the specified angle. + /// + /// Angle to rotate + /// Axis used for rotation + private void Rotate( double angle, RotationAxis axis ) + { + float [][] rotationMatrix = new float[4][]; + rotationMatrix[0] = new float[4]; + rotationMatrix[1] = new float[4]; + rotationMatrix[2] = new float[4]; + rotationMatrix[3] = new float[4]; + + // Change angle direction + angle = -1F * angle; + + // Matrix initialization + // Row loop + for( int row = 0; row < 4; row ++ ) + { + // Column loop + for( int column = 0; column < 4; column ++ ) + { + // For initialization: Diagonal matrix elements are equal to one + // and all other elements are equal to zero. + if( row == column ) + { + rotationMatrix[row][column] = 1F; + } + else + { + rotationMatrix[row][column] = 0F; + } + } + } + + // Rotation about axis + switch( axis ) + { + // Rotation about X axis + case RotationAxis.X: + rotationMatrix[1][1] = (float)Math.Cos( angle ); + rotationMatrix[1][2] = (float)-Math.Sin( angle ); + rotationMatrix[2][1] = (float)Math.Sin( angle ); + rotationMatrix[2][2] = (float)Math.Cos( angle ); + break; + + // Rotation about Y axis + case RotationAxis.Y: + rotationMatrix[0][0] = (float)Math.Cos( angle ); + rotationMatrix[0][2] = (float)Math.Sin( angle ); + rotationMatrix[2][0] = (float)-Math.Sin( angle ); + rotationMatrix[2][2] = (float)Math.Cos( angle ); + break; + + // Rotation about Z axis + case RotationAxis.Z: + rotationMatrix[0][0] = (float)Math.Cos( angle ); + rotationMatrix[0][1] = (float)-Math.Sin( angle ); + rotationMatrix[1][0] = (float)Math.Sin( angle ); + rotationMatrix[1][1] = (float)Math.Cos( angle ); + break; + + } + + // Rotate Main matrix + Multiply( rotationMatrix, MatrixOrder.Prepend, true ); + + } + + /// + /// Returns transformed x and y values from x, y and z values + /// and composed main matrix values (All rotations, + /// translations and scaling). + /// + /// Array of 3D points. + private void GetValues( Point3D [] points ) + { + // Create one dimensional matrix (vector) + float [] inputVector = new float[4]; + + // A vector which is result of matrix and vector multiplication + float [] resultVector = new float[4]; + + foreach( Point3D point in points ) + { + // Fill input vector with x, y and z coordinates + inputVector[0] = point.X; + inputVector[1] = point.Y; + inputVector[2] = point.Z; + inputVector[3] = 1; + + // Apply 3D transformations. + MultiplyVector( inputVector, ref resultVector ); + + // Return x and y coordinates. + point.X = resultVector[0]; + point.Y = resultVector[1]; + point.Z = resultVector[2]; + } + } + + + /// + /// Set points for 3D Bar which represents 3D Chart Area. + /// + /// Width of the bar 3D. + /// Height of the bar 3D. + /// Depth of the bar 3D. + /// Collection of Points 3D. + private Point3D [] Set3DBarPoints( float dx, float dy, float dz ) + { + Point3D [] points = new Point3D[8]; + + // ******************************************** + // 3D Bar side: Front + // ******************************************** + points[0] = new Point3D(-dx/2, -dy/2, dz/2); + points[1] = new Point3D(dx/2, -dy/2, dz/2); + points[2] = new Point3D(dx/2, dy/2, dz/2); + points[3] = new Point3D(-dx/2, dy/2, dz/2); + + // ******************************************** + // 3D Bar side: Back + // ******************************************** + points[4] = new Point3D(-dx/2, -dy/2, -dz/2); + points[5] = new Point3D(dx/2, -dy/2, -dz/2); + points[6] = new Point3D(dx/2, dy/2, -dz/2); + points[7] = new Point3D(-dx/2, dy/2, -dz/2); + + return points; + } + + #endregion // Private Methods + + #region Lighting Methods + + /// + /// Initial Lighting. Use matrix transformation only once + /// for Normal vectors. + /// + /// LightStyle Style + internal void InitLight( LightStyle lightStyle ) + { + // Set LightStyle Style + this._lightStyle = lightStyle; + + // Center of rotation + _lightVectors[0] = new Point3D( 0F, 0F, 0F ); + + // Front side normal Vector. + _lightVectors[1] = new Point3D( 0F, 0F, 1F ); + + // Back side normal Vector. + _lightVectors[2] = new Point3D( 0F, 0F, -1F ); + + // Left side normal Vector. + _lightVectors[3] = new Point3D( -1F, 0F, 0F ); + + // Right side normal Vector. + _lightVectors[4] = new Point3D( 1F, 0F, 0F ); + + // Top side normal Vector. + _lightVectors[5] = new Point3D( 0F, -1F, 0F ); + + // Bottom side normal Vector. + _lightVectors[6] = new Point3D( 0F, 1F, 0F ); + + // Apply matrix transformations + TransformPoints( _lightVectors, false ); + + // ******************************************************** + // LightStyle Vector and normal vectors have to have same center. + // Shift Normal vectors. + // ******************************************************** + + // Front Side shift + _lightVectors[1].X -= _lightVectors[0].X; + _lightVectors[1].Y -= _lightVectors[0].Y; + _lightVectors[1].Z -= _lightVectors[0].Z; + + // Back Side shift + _lightVectors[2].X -= _lightVectors[0].X; + _lightVectors[2].Y -= _lightVectors[0].Y; + _lightVectors[2].Z -= _lightVectors[0].Z; + + // Left Side shift + _lightVectors[3].X -= _lightVectors[0].X; + _lightVectors[3].Y -= _lightVectors[0].Y; + _lightVectors[3].Z -= _lightVectors[0].Z; + + // Right Side shift + _lightVectors[4].X -= _lightVectors[0].X; + _lightVectors[4].Y -= _lightVectors[0].Y; + _lightVectors[4].Z -= _lightVectors[0].Z; + + // Top Side shift + _lightVectors[5].X -= _lightVectors[0].X; + _lightVectors[5].Y -= _lightVectors[0].Y; + _lightVectors[5].Z -= _lightVectors[0].Z; + + // Bottom Side shift + _lightVectors[6].X -= _lightVectors[0].X; + _lightVectors[6].Y -= _lightVectors[0].Y; + _lightVectors[6].Z -= _lightVectors[0].Z; + + } + + /// + /// Return intensity of lightStyle for 3D Cube. There are tree types of lights: None, + /// Simplistic and Realistic. None Style have same lightStyle intensity on + /// all polygons. Normal vector doesn’t have influence on this type + /// of lighting. Simplistic style have lightStyle source, which is + /// rotated together with scene. Realistic lighting have fixed lightStyle + /// source and intensity of lightStyle is change when scene is rotated. + /// + /// Color used for polygons without lighting + /// Color corrected with intensity of lightStyle for Front side of the 3D Rectangle + /// Color corrected with intensity of lightStyle for Back side of the 3D Rectangle + /// Color corrected with intensity of lightStyle for Left side of the 3D Rectangle + /// Color corrected with intensity of lightStyle for Right side of the 3D Rectangle + /// Color corrected with intensity of lightStyle for Top side of the 3D Rectangle + /// Color corrected with intensity of lightStyle for Bottom side of the 3D Rectangle + internal void GetLight( Color surfaceColor, out Color front, out Color back, out Color left, out Color right, out Color top, out Color bottom ) + { + switch( _lightStyle ) + { + // LightStyle style is None + case LightStyle.None: + { + front = surfaceColor; + left = surfaceColor; + top = surfaceColor; + back = surfaceColor; + right = surfaceColor; + bottom = surfaceColor; + break; + } + // LightStyle style is Simplistic + case LightStyle.Simplistic: + { + front = surfaceColor; + left = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0.25); + top = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0.15); + back = surfaceColor; + right = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0.25); + bottom = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0.15); + break; + } + // LightStyle style is Realistic + default: + { + + // For Right Axis angle Realistic lightStyle should be different + if( _rightAngleAxis ) + { + // LightStyle source Vector + Point3D lightSource = new Point3D( 0F, 0F, -1F ); + Point3D [] rightPRpoints = new Point3D[1]; + rightPRpoints[0] = lightSource; + RightAngleProjection(rightPRpoints); + + // ****************************************************************** + // Color correction. Angle between Normal vector of polygon and + // vector of lightStyle source is used. + // ****************************************************************** + if( this._angleY >= 45 || this._angleY <= -45 ) + { + front = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, GetAngle(lightSource,_lightVectors[1])/Math.PI ); + + back = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, GetAngle(lightSource,_lightVectors[2])/Math.PI ); + + left = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0 ); + + right = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0 ); + } + else + { + front = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0 ); + + back = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 1 ); + + left = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, GetAngle(lightSource,_lightVectors[3])/Math.PI ); + + right = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, GetAngle(lightSource,_lightVectors[4])/Math.PI ); + } + + top = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, GetAngle(lightSource,_lightVectors[5])/Math.PI ); + + bottom = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, GetAngle(lightSource,_lightVectors[6])/Math.PI ); + } + else + { + // LightStyle source Vector + Point3D lightSource = new Point3D( 0F, 0F, 1F ); + + // ****************************************************************** + // Color correction. Angle between Normal vector of polygon and + // vector of lightStyle source is used. + // ****************************************************************** + front = GetBrightGradientColor( surfaceColor, GetAngle(lightSource,_lightVectors[1])/Math.PI ); + + back = GetBrightGradientColor( surfaceColor, GetAngle(lightSource,_lightVectors[2])/Math.PI ); + + left = GetBrightGradientColor( surfaceColor, GetAngle(lightSource,_lightVectors[3])/Math.PI ); + + right = GetBrightGradientColor( surfaceColor, GetAngle(lightSource,_lightVectors[4])/Math.PI ); + + top = GetBrightGradientColor( surfaceColor, GetAngle(lightSource,_lightVectors[5])/Math.PI ); + + bottom = GetBrightGradientColor( surfaceColor, GetAngle(lightSource,_lightVectors[6])/Math.PI ); + } + + break; + } + } + } + + + /// + /// Return intensity of lightStyle for Polygons. There are tree types of lights: None, + /// Simplistic and Realistic. None Style have same lightStyle intensity on + /// all polygons. Normal vector doesn’t have influence on this type + /// of lighting. Simplistic style have lightStyle source, which is + /// rotated together with scene. Realistic lighting have fixed lightStyle + /// source and intensity of lightStyle is change when scene is rotated. + /// + /// Points of the polygon + /// Color used for polygons without lighting + /// This flag gets information if polygon is visible or not. + /// Y angle ( from -90 to 90 ) Should be used width switchSeriesOrder to get from -180 to 180 + /// Used for lighting of front - back and left - right sides + /// Used to calculate real y angle + /// Color corrected with intensity of lightStyle + internal Color GetPolygonLight(Point3D[] points, Color surfaceColor, bool visiblePolygon, float rotation, SurfaceNames surfaceName, bool switchSeriesOrder) + { + // Corrected color + Color color = surfaceColor; + + // Direction of lightStyle source + Point3D lightSource; + lightSource = new Point3D( 0F, 0F, 1F ); + + // There are tree different lightStyle styles: None, Simplistic and realistic. + switch( _lightStyle ) + { + // LightStyle style is None + case LightStyle.None: + { + // Use same color + break; + } + // LightStyle style is Simplistic + case LightStyle.Simplistic: + { + // Find two vectors of polygon + Point3D firstVector = new Point3D(); + firstVector.X = points[0].X - points[1].X; + firstVector.Y = points[0].Y - points[1].Y; + firstVector.Z = points[0].Z - points[1].Z; + + Point3D secondVector = new Point3D(); + secondVector.X = points[2].X - points[1].X; + secondVector.Y = points[2].Y - points[1].Y; + secondVector.Z = points[2].Z - points[1].Z; + + // Find Normal vector for Polygon + Point3D normalVector = new Point3D(); + normalVector.X = firstVector.Y * secondVector.Z - firstVector.Z * secondVector.Y; + normalVector.Y = firstVector.Z * secondVector.X - firstVector.X * secondVector.Z; + normalVector.Z = firstVector.X * secondVector.Y - firstVector.Y * secondVector.X; + + // Polygon is left side ( like side of area chart ) + if( surfaceName == SurfaceNames.Left ) + { + color = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0.15); + } + // Polygon is right side ( like side of area chart ) + else if( surfaceName == SurfaceNames.Right ) + { + color = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0.15); + } + // Polygon is front side ( like side of area chart ) + else if( surfaceName == SurfaceNames.Front ) + { + color = surfaceColor; + } + // Polygon is back side ( like side of area chart ) + else if( surfaceName == SurfaceNames.Back ) + { + color = surfaceColor; + } + // Polygon has angle with bottom side ( Line chart or top of area chart ) + else + { + float angleLeft; + float angleRight; + + // Find angles between lightStyle and polygon for different y-axis angles. + if( switchSeriesOrder ) + { + if (rotation > 0 && rotation <= 90) + { + angleLeft = GetAngle( normalVector, _lightVectors[3] ); + angleRight = GetAngle( normalVector, _lightVectors[4] ); + } + else + { + angleLeft = GetAngle( normalVector, _lightVectors[4] ); + angleRight = GetAngle( normalVector, _lightVectors[3] ); + } + } + else + { + if (rotation > 0 && rotation <= 90) + { + angleLeft = GetAngle( normalVector, _lightVectors[4] ); + angleRight = GetAngle( normalVector, _lightVectors[3] ); + } + else + { + angleLeft = GetAngle( normalVector, _lightVectors[3] ); + angleRight = GetAngle( normalVector, _lightVectors[4] ); + } + } + + if( Math.Abs( angleLeft - angleRight ) < 0.01 ) + { + color = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0.25); + } + else if( angleLeft < angleRight ) + { + color = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0.25); + } + else + { + color = ChartGraphics.GetGradientColor( surfaceColor, Color.Black, 0.15); + } + } + + break; + } + // LightStyle style is Realistic + default: + { + + // Find two vectors of polygon + Point3D firstVector = new Point3D(); + firstVector.X = points[0].X - points[1].X; + firstVector.Y = points[0].Y - points[1].Y; + firstVector.Z = points[0].Z - points[1].Z; + + Point3D secondVector = new Point3D(); + secondVector.X = points[2].X - points[1].X; + secondVector.Y = points[2].Y - points[1].Y; + secondVector.Z = points[2].Z - points[1].Z; + + // Find Normal vector for Polygon + Point3D normalVector = new Point3D(); + normalVector.X = firstVector.Y * secondVector.Z - firstVector.Z * secondVector.Y; + normalVector.Y = firstVector.Z * secondVector.X - firstVector.X * secondVector.Z; + normalVector.Z = firstVector.X * secondVector.Y - firstVector.Y * secondVector.X; + + // ****************************************************************** + // Color correction. Angle between Normal vector of polygon and + // vector of lightStyle source is used. + // ****************************************************************** + if( surfaceName == SurfaceNames.Front ) + { + lightSource.Z *= -1; + color = GetBrightGradientColor( surfaceColor, GetAngle(lightSource,_lightVectors[2])/Math.PI ); + } + else if( surfaceName == SurfaceNames.Back ) + { + lightSource.Z *= -1; + color = GetBrightGradientColor( surfaceColor, GetAngle(lightSource,_lightVectors[1])/Math.PI ); + } + else + { + if( visiblePolygon ) + { + lightSource.Z *= -1; + } + + color = GetBrightGradientColor( surfaceColor, GetAngle(lightSource,normalVector)/Math.PI ); + } + + break; + } + } + return color; + + } + + /// + /// This method creates gradien color with brightnes. + /// + /// Start color for gradient. + /// Position used between Start and end color. + /// Calculated Gradient color from gradient position + private Color GetBrightGradientColor( Color beginColor, double position ) + { + position = position * 2; + double brightness = 0.5; + if( position < brightness ) + { + return ChartGraphics.GetGradientColor( Color.FromArgb(beginColor.A,255,255,255), beginColor, 1 - brightness + position ); + } + else if( -brightness + position < 1 ) + { + return ChartGraphics.GetGradientColor( beginColor, Color.Black, -brightness + position ); + } + else + { + return Color.FromArgb( beginColor.A, 0, 0, 0 ); + } + } + + /// + /// Returns the angle between two 3D vectors (a and b); + /// + /// First vector + /// Second Vector + /// Angle between vectors + private float GetAngle(Point3D a,Point3D b) + { + double angle; + + angle = Math.Acos( ( a.X * b.X + a.Y * b.Y + a.Z * b.Z ) / ( Math.Sqrt( a.X * a.X + a.Y * a.Y + a.Z * a.Z ) * Math.Sqrt( b.X * b.X + b.Y * b.Y + b.Z * b.Z ) ) ); + + return (float)angle; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/NamedImageCollection.cs b/System.Web.DataVisualization/Common/General/NamedImageCollection.cs new file mode 100644 index 000000000..01af71e1d --- /dev/null +++ b/System.Web.DataVisualization/Common/General/NamedImageCollection.cs @@ -0,0 +1,175 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: NamedImagesCollection.cs +// +// Namespace: System.Windows.Forms.DataVisualization.Charting.ChartTypes +// +// Classes: NamedImagesCollection, NamedImage +// +// Purpose: Every property in the chart references images by names. +// This means that you can set MarkerImage property to a +// full image path or URL. In case when the user wants to +// dynamically generate an image or load it from other +// location (like database) you can use named image +// collection which is exposed as Images property of the +// chart. Any Image can be added to this collection with +// unique name and than this name can be used in all the +// chart properties which require image names. +// +// Reviewed: AG - Microsoft 14, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Drawing; +using System.ComponentModel; +using System.Globalization; +using System.Reflection; +using System.ComponentModel.Design.Serialization; + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif +{ + /// + /// The NamedImagesCollection class is a strongly typed collection of NamedImage + /// objects. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class NamedImagesCollection : ChartNamedElementCollection + { + #region Constructor + + /// + /// Constructor + /// + internal NamedImagesCollection() : base(null) + { + } + + #endregion + + } + + /// + /// The NamedImage class stores a single Image with its unique name. + /// + [ + SRDescription("DescriptionAttributeNamedImage_NamedImage"), + DefaultProperty("Name"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class NamedImage : ChartNamedElement + { + #region Fields + + private string _name = string.Empty; + private System.Drawing.Image _image = null; + + #endregion + + #region Constructor + + /// + /// NamedImage constructor. + /// + public NamedImage() + { + } + + /// + /// NamedImage constructor. + /// + /// Image name. + /// Image object. + public NamedImage(string name, System.Drawing.Image image) + { + this._name = name; + this._image = image; + } + + #endregion + + #region Properties + + /// + /// Gets or sets the image name. + /// + [ + Bindable(false), + SRDescription("DescriptionAttributeNamedImage_Name"), + ] + public override string Name + { + get + { + return _name; + } + set + { + _name = value; + } + } + + /// + /// Gets or sets the image object. + /// + [ + Bindable(false), + SRDescription("DescriptionAttributeNamedImage_Image"), + ] + public System.Drawing.Image Image + { + get + { + return _image; + } + set + { + _image = value; + } + } + + #endregion + + + #region IDisposable Members + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Dispose managed resources + if (_image != null) + { + _image.Dispose(); + _image = null; + } + } + base.Dispose(disposing); + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/Selection.cs b/System.Web.DataVisualization/Common/General/Selection.cs new file mode 100644 index 000000000..554003cc1 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/Selection.cs @@ -0,0 +1,3495 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: Selection.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: Selection, HitTestResult, ToolTipEventArgs, +// HotRegionElement, Hot Region +// +// Purpose: This file contains methods used for Win Form selection +// +// Reviewed: AG - Oct 21 +// +//=================================================================== + + +#region Used namespaces + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; +using System.ComponentModel.Design; +using System.ComponentModel; +using System.Text; +using System.Collections.ObjectModel; + +#if Microsoft_CONTROL + using System.Windows.Forms; +#endif + + +#endregion + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + #region Enumerations + + + // Plase keep the folowing enumaration in chart layering order - ex. ChartArea is under DataPoint + /// + /// An enumeration of types of Chart Element. + /// + public enum ChartElementType + { + /// + /// No chart element. + /// + Nothing, + + /// + /// The title of a chart. + /// + Title, + + /// + /// Plotting area (chart area excluding axes, labels, etc.). + /// Also excludes the regions that data points may occupy. + /// + PlottingArea, + + /// + /// An Axis object. + /// + Axis, + + /// + /// Any major or minor tick mark. + /// + TickMarks, + + /// + /// Any major or minor grid line (both vertical or horizontal). + /// + Gridlines, + + /// + /// A StripLine object. + /// + StripLines, + + /// + /// Axis label Image. + /// + AxisLabelImage, + + /// + /// Axis labels + /// + AxisLabels, + + /// + /// Axis title + /// + AxisTitle, + + +#if Microsoft_CONTROL + + /// + /// A scrollbar tracking thumb. + /// + ScrollBarThumbTracker, + + /// + /// A scrollbar small decrement button. A "down arrow" + /// button for a vertical scrollbar, or a "left arrow" + /// button for a horizontal scroll bar. + /// + ScrollBarSmallDecrement, + + /// + /// A scrollbar small increment button. An "up arrow" + /// button for a vertical scrollbar, or a "right arrow" + /// button for a horizontal scroll bar. + /// + ScrollBarSmallIncrement, + + /// + /// The background of a scrollbar that will result in + /// a large decrement in the scale view size when clicked. + /// This is the background below the thumb for + /// a vertical scrollbar, and to the left of + /// the thumb for a horizontal scrollbar. + /// + ScrollBarLargeDecrement, + + /// + /// The background of a scrollbar that will result in + /// a large increment in the scale view size when clicked. + /// This is the background above the thumb for + /// a vertical scrollbar, and to the right of + /// the thumb for a horizontal scrollbar. + /// + ScrollBarLargeIncrement, + + /// + /// The zoom reset button of a scrollbar. + /// + ScrollBarZoomReset, + +#endif // Microsoft_CONTROL + + /// + /// A DataPoint object. + /// + DataPoint, + + /// + /// Series data point label. + /// + DataPointLabel, + + /// + /// The area inside a Legend object. Does not include + /// the space occupied by legend items. + /// + LegendArea, + + /// + /// Legend title. + /// + LegendTitle, + + /// + /// Legend header. + /// + LegendHeader, + + /// + /// A LegendItem object. + /// + LegendItem, + + + /// + /// Chart annotation object. + /// + Annotation, + + + } + + /// + /// Enumeration (Flag) used for processing chart types. + /// + [Flags] + internal enum ProcessMode + { + /// + /// Paint mode + /// + Paint = 1, + + /// + /// Selection mode. Collection of hot regions has to be created. + /// + HotRegions = 2, + + /// + /// Used for image maps + /// + ImageMaps = 4 + } + + #endregion + + /// + /// This class presents item in + /// the collection of hot regions. + /// + internal class HotRegion : IDisposable + { + #region Fields + + // Private data members, which store properties values + private GraphicsPath _path = null; + private bool _relativeCoordinates = true; + private RectangleF _boundingRectangle = RectangleF.Empty; + private object _selectedObject = null; + private int _pointIndex = -1; + private string _seriesName = ""; + private ChartElementType _type = ChartElementType.Nothing; + + + private object _selectedSubObject = null; + + + #endregion // Fields + + #region Properties + + /// + /// Region is Graphics path + /// + internal GraphicsPath Path + { + get + { + return _path; + } + set + { + _path = value; + } + } + + /// + /// Relative coordinates are used + /// to define region + /// + internal bool RelativeCoordinates + { + get + { + return _relativeCoordinates; + } + set + { + _relativeCoordinates = value; + } + } + + /// + /// Bounding Rectangle of an shape + /// + internal RectangleF BoundingRectangle + { + get + { + return _boundingRectangle; + } + set + { + _boundingRectangle = value; + } + } + + /// + /// Object which is presented with this region + /// + internal object SelectedObject + { + get + { + return _selectedObject; + } + set + { + _selectedObject = value; + } + } + + + + /// + /// Sub-Object which is presented with this region + /// + internal object SelectedSubObject + { + get + { + return _selectedSubObject; + } + set + { + _selectedSubObject = value; + } + } + + + + /// + /// Index of the data point which is presented with this region + /// + internal int PointIndex + { + get + { + return _pointIndex; + } + set + { + _pointIndex = value; + } + } + + /// + /// Name of the series which is presented with the region + /// + internal string SeriesName + { + get + { + return _seriesName; + } + set + { + _seriesName = value; + } + } + + /// + /// Chart Element AxisName + /// + internal ChartElementType Type + { + get + { + return _type; + } + set + { + _type = value; + } + } + + #endregion // Properties + + #region IDisposable members + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (_path != null) + { + _path.Dispose(); + _path = null; + } + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + + #region Methods + + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + string objectType = this.SelectedObject != null ? this.SelectedObject.ToString() : "null"; + if (this.SelectedObject == null && !String.IsNullOrEmpty(this.SeriesName)) + { + objectType = this.SeriesName; + } + return String.Format(CultureInfo.CurrentCulture, "{0} of {1}", this.Type, objectType); + } + + #endregion //Methods + } + + /// + /// This class is used to fill and + /// manage collection with Hot Regions + /// + internal class HotRegionsList : IDisposable + { + #region Fields + + /// + /// Process chart mode Flag + /// + private ProcessMode _processChartMode = ProcessMode.Paint; + + /// + /// Collection with Hor Region Elements + /// + private System.Collections.ArrayList _regionList = new ArrayList(); + + /// + /// Reference to the common elements object + /// + private CommonElements _common = null; + +#if Microsoft_CONTROL + + /// + /// True if hit test function is called + /// + internal bool hitTestCalled = false; + +#endif // Microsoft_CONTROL + + #endregion // Fields + + #region Properties + + /// + /// Flag used for processing chart types. It could + /// be Paint, HotRegion or both mode. + /// + internal ProcessMode ProcessChartMode + { + get + { + return _processChartMode; + } + set + { + _processChartMode = value; + if(this._common != null) + { + this._common.processModePaint = + (_processChartMode & ProcessMode.Paint ) == ProcessMode.Paint; + this._common.processModeRegions = + ( _processChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions || + ( _processChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps; + } + } + } + + /// + /// Collection with Hor Region Elements + /// + internal ArrayList List + { + get + { + return _regionList; + } + } + + #endregion // Properties + + #region Methods + + /// + /// Constructor + /// + /// Reference to the CommonElements + internal HotRegionsList( CommonElements common ) + { + this._common = common; + } + + /// + /// Add hot region to the collection. + /// + /// Rectangle which presents an Hot Region + /// Data Point + /// Data Series + /// Index of an Data Point in the series + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void AddHotRegion( + RectangleF rectSize, + DataPoint point, + string seriesName, + int pointIndex + ) + { + +#if !Microsoft_CONTROL + if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps ) + { + if (_common.ChartPicture.IsMapEnabled == true) + { + if(point.ToolTip.Length > 0 || + point.Url.Length > 0 || + point.MapAreaAttributes.Length > 0 || + point.PostBackValue.Length > 0 + ) + { + MapArea area = new MapArea( + point.ReplaceKeywords(point.ToolTip), + point.ReplaceKeywords(point.Url), + point.ReplaceKeywords(point.MapAreaAttributes), + point.ReplaceKeywords(point.PostBackValue), + rectSize, + point.Tag); + area.IsCustom = false; + _common.ChartPicture.MapAreas.Insert(0, area); + } + } + } +#endif // !Microsoft_CONTROL + + if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions ) + { + HotRegion region = new HotRegion(); + + region.BoundingRectangle = rectSize; + region.SeriesName = seriesName; + region.PointIndex = pointIndex; + region.Type = ChartElementType.DataPoint; + region.RelativeCoordinates = true; + + + + // Use index of the original data point + if(point != null && point.IsCustomPropertySet("OriginalPointIndex")) + { + region.PointIndex = int.Parse(point["OriginalPointIndex"], CultureInfo.InvariantCulture); + } + + + + _regionList.Add( region ); + } + } + + + /// + /// Adds the hot region. + /// + /// Bounding GraphicsPath. + /// if set to true the is relative path. + /// Chart Graphics Object + /// Selected data point + /// Name of the series. + /// Index of the point. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "graph")] + internal void AddHotRegion( + GraphicsPath path, + bool relativePath, + ChartGraphics graph, + DataPoint point, + string seriesName, + int pointIndex + ) + { + if( path == null ) + { + return; + } +#if !Microsoft_CONTROL + if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps ) + { + if (_common.ChartPicture.IsMapEnabled == true) + { + if(point.ToolTip.Length > 0 || + point.Url.Length > 0 || + point.MapAreaAttributes.Length > 0 || + point.PostBackValue.Length > 0 + ) + { + int prevMapAreaCount = _common.ChartPicture.MapAreas.Count; + _common.ChartPicture.MapAreas.InsertPath( + 0, + point.ReplaceKeywords(point.ToolTip), + point.ReplaceKeywords(point.Url), + point.ReplaceKeywords(point.MapAreaAttributes), + point.ReplaceKeywords(point.PostBackValue), + path, + !relativePath, + graph + ); + + + // Set map area type + for (int i = 0; i < _common.ChartPicture.MapAreas.Count - prevMapAreaCount; i++) + ((IChartMapArea)_common.ChartPicture.MapAreas[i]).Tag = ((IChartMapArea)point).Tag; + } + } + } +#endif // !Microsoft_CONTROL + + if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions ) + { + + HotRegion region = new HotRegion(); + + region.SeriesName = seriesName; + region.PointIndex = pointIndex; + region.Type = ChartElementType.DataPoint; + region.Path = (GraphicsPath)path.Clone(); + region.BoundingRectangle = path.GetBounds(); + region.RelativeCoordinates = relativePath; + + + + // Use index of the original data point + if(point != null && point.IsCustomPropertySet("OriginalPointIndex")) + { + region.PointIndex = int.Parse(point["OriginalPointIndex"], CultureInfo.InvariantCulture); + } + + + + _regionList.Add( region ); + + } + } + + /// + /// Adds the hot region. + /// + /// Position where to insert element. Used for image maps only + /// Bounding GraphicsPath. + /// if set to true the is relative path. + /// Chart Graphics Object + /// Selected data point + /// Name of the series. + /// Index of the point. + [ + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "graph"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "insertIndex") + ] + internal void AddHotRegion( + int insertIndex, + GraphicsPath path, + bool relativePath, + ChartGraphics graph, + DataPoint point, + string seriesName, + int pointIndex + ) + { +#if !Microsoft_CONTROL + if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps ) + { + if (_common.ChartPicture.IsMapEnabled == true) + { + if(point.ToolTip.Length > 0 || + point.Url.Length > 0 || + point.MapAreaAttributes.Length > 0 || + point.PostBackValue.Length > 0) + + { + int prevMapAreaCount = _common.ChartPicture.MapAreas.Count; + + _common.ChartPicture.MapAreas.InsertPath( + insertIndex, + point.ReplaceKeywords(point.ToolTip), + point.ReplaceKeywords(point.Url), + point.ReplaceKeywords(point.MapAreaAttributes), + point.ReplaceKeywords(point.PostBackValue), + path, + !relativePath, + graph + ); + + // Set map area type + for (int i = insertIndex; i < _common.ChartPicture.MapAreas.Count - prevMapAreaCount; i++) + ((IChartMapArea)_common.ChartPicture.MapAreas[i]).Tag = ((IChartMapArea)point).Tag; + } + } + } +#endif // !Microsoft_CONTROL + + if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions ) + { + + HotRegion region = new HotRegion(); + + region.SeriesName = seriesName; + region.PointIndex = pointIndex; + region.Type = ChartElementType.DataPoint; + region.Path = (GraphicsPath)path.Clone(); + region.BoundingRectangle = path.GetBounds(); + region.RelativeCoordinates = relativePath; + + + + // Use index of the original data point + if(point != null && point.IsCustomPropertySet("OriginalPointIndex")) + { + region.PointIndex = int.Parse(point["OriginalPointIndex"], CultureInfo.InvariantCulture); + } + + + + _regionList.Add( region ); + + } + } + + /// + /// Add hot region to the collection. + /// + /// Graphics path which presents hot region + /// Graphics path uses relative or absolute coordinates + /// Coordinates which defines polygon (Graphics Path). Used for image maps + /// Selected data point + /// Data Series + /// Index of an Data Point in the series + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "coord")] + internal void AddHotRegion( GraphicsPath path, bool relativePath, float [] coord, DataPoint point, string seriesName, int pointIndex ) + { + +#if !Microsoft_CONTROL + if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps ) + { + if (_common.ChartPicture.IsMapEnabled == true) + { + if(point.ToolTip.Length > 0 || + point.Url.Length > 0 || + point.MapAreaAttributes.Length > 0 || + point.PostBackValue.Length > 0) + { + MapArea area = new MapArea( + MapAreaShape.Polygon, + point.ReplaceKeywords(point.ToolTip), + point.ReplaceKeywords(point.Url), + point.ReplaceKeywords(point.MapAreaAttributes), + point.ReplaceKeywords(point.PostBackValue), + coord, + point.Tag); + area.IsCustom = false; + _common.ChartPicture.MapAreas.Insert(0,area); + + } + } + } +#endif // !Microsoft_CONTROL + + if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions ) + { + + HotRegion region = new HotRegion(); + + region.SeriesName = seriesName; + region.PointIndex = pointIndex; + region.Type = ChartElementType.DataPoint; + region.Path = (GraphicsPath)path.Clone(); + region.BoundingRectangle = path.GetBounds(); + region.RelativeCoordinates = relativePath; + + + + // Use index of the original data point + if(point != null && point.IsCustomPropertySet("OriginalPointIndex")) + { + region.PointIndex = int.Parse(point["OriginalPointIndex"], CultureInfo.InvariantCulture); + } + + + + _regionList.Add( region ); + + } + + } + + /// + /// Add Hot region to the collection. + /// + /// Position where to insert element. Used for image maps only + /// Chart Graphics Object + /// x coordinate. + /// y coordinate. + /// The radius. + /// Selected data point + /// Data Series + /// Index of an Data Point in the series + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "insertIndex")] + internal void AddHotRegion( int insertIndex, ChartGraphics graph, float x, float y, float radius, DataPoint point, string seriesName, int pointIndex ) + { + +#if !Microsoft_CONTROL + if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps ) + { + if (_common.ChartPicture.IsMapEnabled == true) + { + if(point.ToolTip.Length > 0 || + point.Url.Length > 0 || + point.MapAreaAttributes.Length > 0 || + point.PostBackValue.Length > 0 ) + { + + float[] circCoord = new float[3]; + circCoord[0] = x; + circCoord[1] = y; + circCoord[2] = radius; + + MapArea area = new MapArea( + MapAreaShape.Circle, + point.ReplaceKeywords(point.ToolTip), + point.ReplaceKeywords(point.Url), + point.ReplaceKeywords(point.MapAreaAttributes), + point.ReplaceKeywords(point.PostBackValue), + circCoord, + point.Tag); + area.IsCustom = false; + // Insert area + _common.ChartPicture.MapAreas.Insert(insertIndex,area); + + } + } + } +#endif // !Microsoft_CONTROL + + if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions ) + { + HotRegion region = new HotRegion(); + + PointF circleCenter = graph.GetAbsolutePoint( new PointF( x, y ) ); + SizeF circleRadius = graph.GetAbsoluteSize( new SizeF( radius, radius ) ); + + GraphicsPath path = new GraphicsPath(); + path.AddEllipse( + circleCenter.X - circleRadius.Width, + circleCenter.Y - circleRadius.Width, + 2 * circleRadius.Width, + 2 * circleRadius.Width + ); + region.BoundingRectangle = path.GetBounds(); + region.SeriesName = seriesName; + region.Type = ChartElementType.DataPoint; + region.PointIndex = pointIndex; + region.Path = path; + region.RelativeCoordinates = false; + + + + // Use index of the original data point + if(point != null && point.IsCustomPropertySet("OriginalPointIndex")) + { + region.PointIndex = int.Parse(point["OriginalPointIndex"], CultureInfo.InvariantCulture); + } + + + + _regionList.Add( region ); + } + } + + + /// + /// Add Hot region to the collection. + /// + /// Hot Region rectangle + /// Tool Tip Text + /// HRef string + /// Map area Attribute string + /// The post back value associated with this item + /// Object which present hot region + /// AxisName of the object which present hot region + /// Selected series + [ + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "hRef"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "mapAreaAttributes"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "postBackValue"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "toolTip") + ] + internal void AddHotRegion( RectangleF rectArea, string toolTip, string hRef, string mapAreaAttributes, string postBackValue, object selectedObject, ChartElementType type, string series ) + { +#if !Microsoft_CONTROL + if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps ) + { + // Add items to the image map collection + if (_common.ChartPicture.IsMapEnabled == true) + { + if(toolTip.Length > 0 || + hRef.Length > 0 || + mapAreaAttributes.Length > 0 || + postBackValue.Length > 0) + { + MapArea area = new MapArea( + toolTip, + hRef, + mapAreaAttributes, + postBackValue, + rectArea, + ((IChartMapArea)selectedObject).Tag); + area.IsCustom = false; + _common.ChartPicture.MapAreas.Add( area); + } + } + } +#endif // !Microsoft_CONTROL + + if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions ) + { + HotRegion region = new HotRegion(); + + region.BoundingRectangle = rectArea; + region.RelativeCoordinates = true; + region.Type = type; + region.SelectedObject = selectedObject; + if(!String.IsNullOrEmpty(series)) + { + region.SeriesName = series; + } + _regionList.Add( region ); + } + } + + + + /// + /// Add Hot region to the collection. + /// + /// Hot Region rectangle + /// Tool Tip Text + /// HRef string + /// Map area Attribute string + /// The post back value associated with this item + /// Object which present hot region + /// Sub-Object which present hot region + /// AxisName of the object which present hot region + /// Selected series + [ + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "hRef"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "mapAreaAttributes"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "postBackValue"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "toolTip") + ] + internal void AddHotRegion( + RectangleF rectArea, + string toolTip, + string hRef, + string mapAreaAttributes, + string postBackValue, + object selectedObject, + object selectedSubObject, + ChartElementType type, + string series ) + { +#if !Microsoft_CONTROL + if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps ) + { + // Add items to the image map collection + if (_common.ChartPicture.IsMapEnabled == true) + { + if(toolTip.Length > 0 || + hRef.Length > 0 || + mapAreaAttributes.Length > 0 || + postBackValue.Length > 0) + { + MapArea area = new MapArea( + toolTip, + hRef, + mapAreaAttributes, + postBackValue, + rectArea, + ((IChartMapArea)selectedObject).Tag); + area.IsCustom = false; + _common.ChartPicture.MapAreas.Add( area); + } + } + } +#endif // !Microsoft_CONTROL + + if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions ) + { + HotRegion region = new HotRegion(); + + region.BoundingRectangle = rectArea; + region.RelativeCoordinates = true; + region.Type = type; + region.SelectedObject = selectedObject; + region.SelectedSubObject = selectedSubObject; + if(!String.IsNullOrEmpty(series)) + { + region.SeriesName = series; + } + _regionList.Add( region ); + } + } + + + + /// + /// Add Hot region to the collection. + /// + /// Chart Graphics Object + /// Graphics path + /// Used relative coordinates for graphics path. + /// Tool Tip Text + /// HRef string + /// Map area Attribute string + /// The post back value associated with this item + /// Object which present hot region + /// AxisName of the object which present hot region + [ + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "graph"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "hRef"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "mapAreaAttributes"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "postBackValue"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "toolTip") + ] + internal void AddHotRegion( ChartGraphics graph, GraphicsPath path, bool relativePath, string toolTip, string hRef, string mapAreaAttributes, string postBackValue, object selectedObject, ChartElementType type ) + { +#if !Microsoft_CONTROL + if( ( ProcessChartMode & ProcessMode.ImageMaps ) == ProcessMode.ImageMaps ) + { + if (_common.ChartPicture.IsMapEnabled == true) + { + + if(toolTip.Length > 0 || + hRef.Length > 0 || + mapAreaAttributes.Length > 0 || + postBackValue.Length > 0) + { + _common.ChartPicture.MapAreas.InsertPath( + 0, + toolTip, + hRef, + mapAreaAttributes, + postBackValue, + path, + !relativePath, + graph + ); + } + } + } +#endif // !Microsoft_CONTROL + + if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions ) + { + + HotRegion region = new HotRegion(); + + region.Type = type; + region.Path = (GraphicsPath)path.Clone(); + region.SelectedObject = selectedObject; + region.BoundingRectangle = path.GetBounds(); + region.RelativeCoordinates = relativePath; + + _regionList.Add( region ); + + } + } + + /// + /// Add Hot region to the collection. + /// + /// Hot Region rectangle + /// Object which present hot region + /// AxisName of the object which present hot region + /// Coordinates for rectangle are relative + internal void AddHotRegion( RectangleF rectArea, object selectedObject, ChartElementType type, bool relativeCoordinates ) + { + this.AddHotRegion( rectArea, selectedObject, type, relativeCoordinates, false ); + } + + /// + /// Add Hot region to the collection. + /// + /// Hot Region rectangle + /// Object which present hot region + /// AxisName of the object which present hot region + /// Coordinates for rectangle are relative + /// Insert the hot region at the beginning of the collection + internal void AddHotRegion( RectangleF rectArea, object selectedObject, ChartElementType type, bool relativeCoordinates, bool insertAtBeginning ) + { + if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions ) + { + HotRegion region = new HotRegion(); + + region.BoundingRectangle = rectArea; + region.RelativeCoordinates = relativeCoordinates; + region.Type = type; + region.SelectedObject = selectedObject; + + if( insertAtBeginning ) + { + _regionList.Insert( _regionList.Count - 1, region ); + } + else + { + _regionList.Add( region ); + } + } + } + + /// + /// Add Hot region to the collection. + /// + /// Graphics path + /// Used relative coordinates for graphics path. + /// Type of the object which present hot region + /// Object which present hot region + internal void AddHotRegion( + GraphicsPath path, + bool relativePath, + ChartElementType type, + object selectedObject + ) + { + if( ( ProcessChartMode & ProcessMode.HotRegions ) == ProcessMode.HotRegions ) + { + + HotRegion region = new HotRegion(); + + region.SelectedObject = selectedObject; + region.Type = type; + region.Path = (GraphicsPath)path.Clone(); + region.BoundingRectangle = path.GetBounds(); + region.RelativeCoordinates = relativePath; + + _regionList.Add( region ); + + } + } + + /// + /// This method search for position in Map Areas which is the first + /// position after Custom areas. + /// + /// Insert Index + internal int FindInsertIndex() + { + int insertIndex = 0; +#if !Microsoft_CONTROL + foreach (MapArea mapArea in _common.ChartPicture.MapAreas) + { + if(!mapArea.IsCustom) + { + break; + } + ++insertIndex; + } +#endif // !Microsoft_CONTROL + + return insertIndex; + } + + /// + /// Clears this instance. + /// + public void Clear() + { + foreach (HotRegion hotRegion in this._regionList) + hotRegion.Dispose(); + + this._regionList.Clear(); + } + + #endregion // Methods + + #region IDisposable members + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (this._regionList != null) + { + foreach (HotRegion hotRegion in this._regionList) + hotRegion.Dispose(); + + this._regionList.Clear(); + } + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + + } + + /// + /// The HitTestResult class contains the result of the hit test function. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class HitTestResult + { + #region Fields + + // Private members + private object _obj = null; + private Series _series = null; + private int _dataPoint = -1; + private ChartArea _chartArea = null; + private Axis _axis = null; + private ChartElementType _type = ChartElementType.Nothing; + private object _subObject = null; + + #endregion + + #region Properties + + /// + /// Gets or sets the data series object. + /// + public Series Series + { + get + { + return _series; + } + set + { + _series = value; + } + } + + /// + /// Gets or sets the data point index. + /// + public int PointIndex + { + get + { + return _dataPoint; + } + set + { + _dataPoint = value; + } + } + + /// + /// Gets or sets the chart area object. + /// + public ChartArea ChartArea + { + get + { + return _chartArea; + } + set + { + _chartArea = value; + } + } + + /// + /// Gets or sets the axis object. + /// + public Axis Axis + { + get + { + return _axis; + } + set + { + _axis = value; + } + } + + /// + /// Gets or sets the chart element type. + /// + public ChartElementType ChartElementType + { + get + { + return _type; + } + set + { + _type = value; + } + } + + /// + /// Gets or sets the selected object. + /// + public object Object + { + get + { + return _obj; + } + set + { + _obj = value; + } + } + + + + /// + /// Gets or sets the selected sub object. + /// + public object SubObject + { + get + { + return _subObject; + } + set + { + _subObject = value; + } + } + + #endregion + } + + + /// + /// This class represents an array of marker points and + /// the outline path used for visual object selection in the chart. + /// + /// + /// may be null for complex objects or objects with two points or fewer. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class ChartElementOutline : IDisposable + { + /// + /// Initializes a new instance of the class. + /// + internal ChartElementOutline() + { + this.Markers = new ReadOnlyCollection( new PointF[] {}); + } + + /// + /// Gets the markers. + /// + /// The markers. + public ReadOnlyCollection Markers { get; internal set; } + + /// + /// Gets or sets the outline path. The result could be null for complex objects and objects with two points or fewer. + /// + /// The outline path. + public GraphicsPath OutlinePath { get; internal set; } + + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (this.OutlinePath != null) + { + this.OutlinePath.Dispose(); + this.OutlinePath = null; + } + this.Markers = null; + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + } + + + /// + /// This class contains methods used for Windows Forms selection. + /// + internal class Selection : IServiceProvider +#if Microsoft_CONTROL + , IDisposable +#endif //Microsoft_CONTROL + { + #region Fields + + /// + /// The chart service container + /// + private IServiceContainer _service = null; + +#if Microsoft_CONTROL + + /// + /// Stores the tooltip of the control. + /// + private ToolTip _toolTip = new ToolTip(); + + /// + /// Used by the tooltip - stores the time when the tooltip is activated. + /// + private DateTime _toolTipActivationTime = DateTime.Now; + + /// + /// Stores the last mouse move X and Y coordinates, so we can ignore false calls to + /// OnMouseMove generated my the tooltip. + /// + private Point _lastMouseMove = new Point(int.MinValue, int.MinValue); + + + // ToolTips enabled or disabled from series or legend + private bool _toolTipsEnabled = false; + + // Tool tips enabled flag checked + internal bool enabledChecked = false; + +#endif //Microsoft_CONTROL + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The service. + internal Selection(IServiceContainer service) + { + this._service = service; + this._chartControl = this.ChartControl; +#if Microsoft_CONTROL + + // Set up the tooltip + this._toolTip.Active = true; + this._toolTip.AutoPopDelay = 30000; // maximum delay possible + this._toolTip.InitialDelay = 500; + this._toolTip.ReshowDelay = 50; + this._toolTip.ShowAlways = true; + this._toolTip.Active = false; +#endif //Microsoft_CONTROL + + } + +#if Microsoft_CONTROL + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + private void Dispose(bool disposing) + { + if (disposing) + { + if (_toolTip != null) + { + _toolTip.Dispose(); + _toolTip = null; + } + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + +#endif //Microsoft_CONTROL + + #endregion //Constructors + + #region Properties + + private Chart _chartControl = null; + /// + /// Returns the attached chart control + /// + internal Chart ChartControl + { + get + { + if (this._chartControl == null) + { + if (this.ChartPicture != null) + { + this._chartControl = this.ChartPicture.Chart; + } + } + return this._chartControl; + } + } + + private ChartPicture _chartPicture = null; + /// + /// Returns the attached ChartPicture + /// + internal ChartPicture ChartPicture + { + get + { + if (this._chartPicture == null) + { + this._chartPicture = ((IServiceProvider)this).GetService(typeof(ChartImage)) as ChartPicture; + if (this._chartPicture == null) + { + this._chartPicture = ((IServiceProvider)this).GetService(typeof(ChartPicture)) as ChartPicture; + } + } + return this._chartPicture; + } + } + + private Data.DataManager _dataManager = null; + /// + /// Gets the chart data manager ( for series access ) + /// + internal Data.DataManager DataManager + { + get + { + if (this._dataManager == null) + { + this._dataManager = ((IServiceProvider)this).GetService(typeof(Data.DataManager)) as Data.DataManager; + } + return this._dataManager; + } + } + + /// + /// Gets the chart ChartGraphics + /// + internal ChartGraphics Graph + { + get + { + if (this.ChartPicture != null) + { + return this.ChartPicture.Common.graph; + } + return null; + } + } + + #endregion //Private Properties + + #region Methods + + #region Tooltips +#if Microsoft_CONTROL + /// + /// Checks if tooltips are enabled + /// + /// true if tooltips enabled + private bool IsToolTipsEnabled() + { + // Enabled checked. Don’t check every time series + // and data points for tooltips. + if( enabledChecked ) + { + return _toolTipsEnabled; + } + + enabledChecked = true; + + + + + // Annotations loop + foreach( Annotation annotation in _chartControl.Annotations ) + { + // ToolTip empty + if( annotation.ToolTip.Length > 0 ) + { + // ToolTips enabled + _toolTipsEnabled = true; + return true; + } + } + + + // Data series loop + foreach( Series series in _chartControl.Series ) + { + // Check series tooltips + if( series.ToolTip.Length > 0 || + series.LegendToolTip.Length > 0 || + series.LabelToolTip.Length > 0) + { + // ToolTips enabled + _toolTipsEnabled = true; + return true; + } + + + // Check if custom properties (Pie collected slice) that create tooltips are used + if(series.IsCustomPropertySet(Utilities.CustomPropertyName.CollectedToolTip)) + { + // ToolTips enabled + _toolTipsEnabled = true; + return true; + } + + + // Check point tooltips only for "non-Fast" chart types + if( !series.IsFastChartType() ) + { + // Data point loop + foreach( DataPoint point in series.Points ) + { + // ToolTip empty + if( point.ToolTip.Length > 0 || + point.LegendToolTip.Length > 0 || + point.LabelToolTip.Length > 0) + { + // ToolTips enabled + _toolTipsEnabled = true; + return true; + } + } + } + } + + // Legend items loop + foreach( Legend legend in _chartControl.Legends ) + { + // Check custom legend items + foreach( LegendItem legendItem in legend.CustomItems ) + { + // ToolTip empty + if( legendItem.ToolTip.Length > 0 ) + { + _toolTipsEnabled = true; + return true; + } + + + // Check all custom cells in the legend item + foreach(LegendCell legendCell in legendItem.Cells) + { + if(legendCell.ToolTip.Length > 0) + { + _toolTipsEnabled = true; + return true; + } + } + + } + + + // Iterate through legend columns + foreach(LegendCellColumn legendColumn in legend.CellColumns) + { + if(legendColumn.ToolTip.Length > 0) + { + _toolTipsEnabled = true; + return true; + } + } + + } + + // Title items loop + foreach( Title title in _chartControl.Titles ) + { + // ToolTip empty + if( title.ToolTip.Length > 0 ) + { + _toolTipsEnabled = true; + return true; + } + } + + // Chart areas loop + foreach( ChartArea area in _chartControl.ChartAreas ) + { + + // Check if chart area is visible + if(area.Visible) + + { + // Axis loop + foreach(Axis axis in area.Axes) + { + + // Check ToolTip + if( axis.ToolTip.Length > 0 ) + { + _toolTipsEnabled = true; + return true; + } + + + // Strip lines loop + foreach(StripLine stripLine in axis.StripLines) + { + // Check ToolTip + if( stripLine.ToolTip.Length > 0 ) + { + _toolTipsEnabled = true; + return true; + } + } + // Check custom labels + foreach(CustomLabel customLabel in axis.CustomLabels) + { + if( customLabel.ToolTip.Length > 0 ) + { + _toolTipsEnabled = true; + return true; + } + } + } + } + } + + // ToolTips disabled + _toolTipsEnabled = false; + return false; + } + + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", + Justification = "Too large of a code change to justify making this change")] + internal string EvaluateToolTip(System.Windows.Forms.MouseEventArgs e) + { + object obj; + object subObj; + ChartElementType type; + int dataPointIndex; + string seriesName; + string toolTipText = " "; + + HitTestResult hitTest = this.HitTest(e.X, e.Y, true); + + type = hitTest.ChartElementType; + dataPointIndex = hitTest.PointIndex; + seriesName = hitTest.Series != null ? hitTest.Series.Name : String.Empty; + obj = hitTest.Object; + subObj = hitTest.SubObject; + + + // Get tooltips from data points + if (type == ChartElementType.DataPoint) + { + if (_chartControl.Series.IndexOf(seriesName) >= 0 && + dataPointIndex >= 0 && + dataPointIndex < _chartControl.Series[seriesName].Points.Count) + { + // Take tool tip from data point + toolTipText = _chartControl.Series[seriesName].Points[dataPointIndex].ReplaceKeywords(_chartControl.Series[seriesName].Points[dataPointIndex].ToolTip); + } + else + { + DataPoint dataPoint = obj as DataPoint; + if (dataPoint != null) + { + // Take tool tip from data point + toolTipText = dataPoint.ReplaceKeywords(dataPoint.ToolTip); + } + } + } + + + + // Get tooltips from data points + if (type == ChartElementType.DataPointLabel) + { + if (_chartControl.Series.IndexOf(seriesName) >= 0 && + dataPointIndex >= 0 && + dataPointIndex < _chartControl.Series[seriesName].Points.Count) + { + // Take tool tip from data point + toolTipText = _chartControl.Series[seriesName].Points[dataPointIndex].ReplaceKeywords(_chartControl.Series[seriesName].Points[dataPointIndex].LabelToolTip); + } + } + + + // Get tooltips from custom label + if (type == ChartElementType.AxisLabels && + obj is CustomLabel) + { + toolTipText = ((CustomLabel)obj).ToolTip; + } + + + + + // Get tooltips from data points + else if (type == ChartElementType.Annotation && obj != null && obj is Annotation) + { + // Take tool tip from data point + toolTipText = ((Annotation)obj).ReplaceKeywords(((Annotation)obj).ToolTip); + + } + // Get tooltips from axis + else if (type == ChartElementType.Axis && obj != null && obj is Axis) + { + // Take tool tip from strip line + toolTipText = ((Axis)obj).ToolTip; + } + + // Get tooltips from strip lines + else if (type == ChartElementType.StripLines && obj != null && obj is StripLine) + { + // Take tool tip from strip line + toolTipText = ((StripLine)obj).ToolTip; + + } + // Get tooltips from data points + else if (type == ChartElementType.Title && obj != null && obj is Title) + { + // Take tool tip from data point + toolTipText = ((Title)obj).ToolTip; + + } // Get tooltips for legend items + + // Get tooltips for legend items + else if (type == ChartElementType.LegendItem) + { + // Take tool tip from legend item + toolTipText = ((LegendItem)obj).ToolTip; + + + // Check if cell has it's own tooltip + LegendCell legendCell = subObj as LegendCell; + if (legendCell != null && legendCell.ToolTip.Length > 0) + { + toolTipText = legendCell.ToolTip; + } + + + // Check if series is associated with legend item + if (toolTipText.Length == 0 && + seriesName.Length > 0 && + _chartControl.Series.IndexOf(seriesName) >= 0) + { + // Take tool tip from data point + if (dataPointIndex == -1) + { + if (seriesName.Length > 0) + { + // Take tool tip from series + toolTipText = _chartControl.Series[seriesName].ReplaceKeywords(_chartControl.Series[seriesName].LegendToolTip); + } + } + else + { + if (dataPointIndex >= 0 && + dataPointIndex < _chartControl.Series[seriesName].Points.Count) + { + // Take tool tip from data point + toolTipText = _chartControl.Series[seriesName].Points[dataPointIndex].ReplaceKeywords(_chartControl.Series[seriesName].Points[dataPointIndex].LegendToolTip); + } + } + } + } + + // Set event arguments + ToolTipEventArgs args = new ToolTipEventArgs(e.X, e.Y, toolTipText, hitTest); + + // Event + _chartControl.OnGetToolTipText(args); + + return args.Text.Trim(); + + } + + + /// + /// Mouse move event handler. + /// + /// Sender + /// Arguments + internal void Selection_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) + { + + // Ignore false calls to OnMouseMove caused by the tootip control. + if (e.X == this._lastMouseMove.X && e.Y == this._lastMouseMove.Y) + { + return; + } + else + { + this._lastMouseMove.X = e.X; + this._lastMouseMove.Y = e.Y; + } + + // Event is not active and tooltip properties are nor set. + if (!IsToolTipsEnabled() && !_chartControl.IsToolTipEventUsed()) + { + return; + } + + string newToolTipText = this.EvaluateToolTip(e); + + if (!String.IsNullOrEmpty(newToolTipText)) + { + string oldToolTipText = this._toolTip.GetToolTip(this._chartControl); + TimeSpan timeSpan = DateTime.Now.Subtract(this._toolTipActivationTime); + if (oldToolTipText != newToolTipText || timeSpan.Milliseconds > 600) + { + // Activate the tooltip + this._toolTip.Active = false; + this._toolTip.SetToolTip(this._chartControl, newToolTipText); + this._toolTip.Active = true; + this._toolTipActivationTime = DateTime.Now; + } + } + else + { + // We do not have a tooltip, so deactivate it + this._toolTip.Active = false; + this._toolTip.SetToolTip(this._chartControl, string.Empty); + } + } + +#endif //Microsoft_CONTROL + + #endregion //Tooltips + + #region HitTest + + + /// + /// Call this method to determine the chart element, + /// if any, that is located at a point defined by the given X and Y + /// coordinates. + /// + /// The X coordinate for the point in question. + /// Often obtained from a parameter in an event + /// (e.g. the X parameter value in the MouseDown event). + /// The Y coordinate for the point in question. + /// Often obtained from a parameter in an event + /// (e.g. the Y parameter value in the MouseDown event). + /// + /// An array of type which specify the types + /// to test for, on order to filter the result. If omitted checking for + /// elementTypes will be ignored and all kind of elementTypes will be + /// valid. + /// + /// Indicates that transparent + /// elements should be ignored. + /// + /// A array of objects, + /// which provides information concerning the chart element + /// (if any) that is at the specified location. Result contains at least + /// one element, which could be ChartElementType.Nothing. + /// The objects in the result are sorted in from top to bottom of + /// different layers of control. + /// Call this method to determine the gauge element + /// (if any) that is located at a specified point. Often this method is used in + /// some mouse-related event (e.g. MouseDown) + /// to determine what gauge element the end-user clicked on. + /// The X and Y mouse coordinates obtained from the + /// event parameters are then used for the X and Y parameter + /// values of this method call. The returned + /// object's properties + /// can then be used to determine what chart element was clicked on, + /// and also provides a reference to the actual object selected (if + /// any). + internal HitTestResult[] HitTest(int x, int y, bool ignoreTransparent, params ChartElementType[] requestedElementTypes) + { + List result = new List(); + ArrayList regionList = this.ChartPicture.Common.HotRegionsList.List; + + if (regionList.Count == 0) + { + this.ChartPicture.PaintOffScreen(); + } + + string alowedElements = String.Empty; + if (requestedElementTypes.Length > 0) + { + StringBuilder builder = new StringBuilder(); + foreach (ChartElementType elementType in requestedElementTypes) + { + builder.Append(elementType.ToString() + ";"); + } + alowedElements = builder.ToString(); + } + + float newX; + float newY; + float relativeX; + float relativeY; + RectangleF newMouseRect; + + // Find mouse position in relative and absolute coordinates + RectangleF mouseRect = new RectangleF(x - 1, y - 1, 2, 2); + relativeX = this.Graph.GetRelativePoint(new PointF(x, y)).X; + relativeY = this.Graph.GetRelativePoint(new PointF(x, y)).Y; + RectangleF relativeMouseRect = this.Graph.GetRelativeRectangle(mouseRect); + + // Try to pass through series object in design time. + // The series ussualy contain autogenerated points with short lifetime - during painting; + // This hit test result will be used in VS2005 desing time click. + for (int index = regionList.Count - 1; index >= 0; index--) + { + HotRegion region = (HotRegion)regionList[index]; + + // Check if only looking for specific chart element type + if (!String.IsNullOrEmpty(alowedElements) && alowedElements.IndexOf(region.Type.ToString() + ";", StringComparison.Ordinal) == -1) + { + continue; + } + + + // Change coordinates if relative path is used + if (region.RelativeCoordinates) + { + newX = relativeX; + newY = relativeY; + newMouseRect = relativeMouseRect; + } + else + { + newX = (float)x; + newY = (float)y; + newMouseRect = mouseRect; + } + + + // Check if series name and point index are valid + if (region.SeriesName.Length > 0 && + (this.ChartControl.Series.IndexOf(region.SeriesName) < 0 || region.PointIndex >= this.ChartControl.Series[region.SeriesName].Points.Count) + ) + { + continue; + } + + // Check if transparent chart elements should be ignored + if (ignoreTransparent && IsElementTransparent(region)) + { + continue; + } + // Check intersection with bounding rectangle + if (region.BoundingRectangle.IntersectsWith(newMouseRect)) + { + bool pointVisible = false; + + if (region.Path != null) + { + // If there is more then one graphical path split them and create + // image maps for every graphical path separately. + GraphicsPathIterator iterator = new GraphicsPathIterator(region.Path); + + // There is more then one path. + if (iterator.SubpathCount > 1) + { + GraphicsPath subPath = new GraphicsPath(); + while (iterator.NextMarker(subPath) > 0 && pointVisible == false) + { + if (subPath.IsVisible(newX, newY)) + { + pointVisible = true; + } + subPath.Reset(); + } + } + + // There is only one path + else if (region.Path.IsVisible(newX, newY)) + { + pointVisible = true; + } + } + else + { + // Point is inside bounding rectangle and path is not specified + pointVisible = true; + } + + // Check if point is inside the hot region + if (pointVisible) + { + HitTestResult hitTestToAdd = this.GetHitTestResult( + region.SeriesName, + region.PointIndex, + region.Type, + region.SelectedObject, + region.SelectedSubObject + ); + + int elementIndex = result.FindIndex( + delegate(HitTestResult test) + { + if ( + (test.ChartElementType == hitTestToAdd.ChartElementType) && + (test.Object == hitTestToAdd.Object) && + (test.SubObject == hitTestToAdd.SubObject) && + (test.Series == hitTestToAdd.Series) && + (test.PointIndex == hitTestToAdd.PointIndex) + ) + { + return true; + } + return false; + } + ); + + if (elementIndex == -1) + { + result.Add(hitTestToAdd); + } + } + } + } + if (result.Count == 0) + { + result.Add(this.GetHitTestResult(String.Empty, 0, ChartElementType.Nothing, null, null)); + } + return result.ToArray(); + } + + /// + /// This method performs the hit test and returns a HitTestResult objects. + /// + /// X coordinate + /// Y coordinate + /// Hit test result object + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + internal HitTestResult HitTest(int x, int y) + { + return this.HitTest(x, y, false, new ChartElementType[] {})[0]; + } + + /// + /// This method performs the hit test and returns a HitTestResult object. + /// + /// X coordinate + /// Y coordinate + /// Indicates that transparent elements should be ignored. + /// Hit test result object + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public HitTestResult HitTest(int x, int y, bool ignoreTransparent) + { + return this.HitTest(x, y, ignoreTransparent, new ChartElementType[] { })[0]; + } + + /// + /// This method performs the hit test and returns a HitTestResult object. + /// + /// X coordinate + /// Y coordinate + /// Only this chart element will be hit tested. + /// Hit test result object + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public HitTestResult HitTest(int x, int y, ChartElementType requestedElement) + { + return this.HitTest(x, y, false, requestedElement)[0]; + } + + /// + /// Checks if chart element associated with hot region has transparent background. + /// + /// Element hot region. + /// True if chart element is transparent. + private bool IsElementTransparent(HotRegion region) + { + bool isTransparent = false; + + if (region.Type == ChartElementType.DataPoint) + { + if (this.ChartControl != null) + { + DataPoint dataPoint = region.SelectedObject as DataPoint; + if (region.SeriesName.Length > 0) + { + dataPoint = this.ChartControl.Series[region.SeriesName].Points[region.PointIndex]; + } + if (dataPoint != null && dataPoint.Color == Color.Transparent) + { + isTransparent = true; + } + } + } + else if (region.SelectedObject is Axis) + { + if (((Axis)region.SelectedObject).LineColor == Color.Transparent) + { + isTransparent = true; + } + } + else if (region.SelectedObject is ChartArea) + { + if (((ChartArea)region.SelectedObject).BackColor == Color.Transparent) + { + isTransparent = true; + } + } + else if (region.SelectedObject is Legend) + { + if (((Legend)region.SelectedObject).BackColor == Color.Transparent) + { + isTransparent = true; + } + } + else if (region.SelectedObject is Grid) + { + if (((Grid)region.SelectedObject).LineColor == Color.Transparent) + { + isTransparent = true; + } + } + else if (region.SelectedObject is StripLine) + { + if (((StripLine)region.SelectedObject).BackColor == Color.Transparent) + { + isTransparent = true; + } + } + else if (region.SelectedObject is TickMark) + { + if (((TickMark)region.SelectedObject).LineColor == Color.Transparent) + { + isTransparent = true; + } + } + else if (region.SelectedObject is Title) + { + Title title = (Title)region.SelectedObject; + if ((title.Text.Length == 0 || title.ForeColor == Color.Transparent) && + (title.BackColor == Color.Transparent || title.BackColor.IsEmpty)) + { + isTransparent = true; + } + } + + return isTransparent; + } + + /// + /// Returns Hit Test Result object + /// + /// Data series Name + /// Data point index + /// Selected Chart element type + /// Selected object + /// Selected sub object + /// Hit test result object + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", + Justification = "Too large of a code change to justify making this change")] + internal HitTestResult GetHitTestResult( + string seriesName, + int pointIndex, + ChartElementType type, + object obj, + object subObject) + { + HitTestResult result = new HitTestResult(); + Chart chart = this.ChartControl; + // If data point is selected convert series + // name to series object. + if (seriesName.Length > 0) + { + result.Series = chart.Series[seriesName]; + } + + // Selected Object + result.Object = obj; + + result.SubObject = subObject; + + result.PointIndex = pointIndex; + result.ChartElementType = type; + +#if Microsoft_CONTROL + AxisScrollBar scrollBar; +#endif // Microsoft_CONTROL + + switch (type) + { + case ChartElementType.Axis: + Axis axis = (Axis)obj; + result.Axis = axis; + if (axis != null) + { + result.ChartArea = axis.ChartArea; + } + break; + case ChartElementType.DataPoint: + { + if (chart.Series.IndexOf(seriesName) >= 0 && + pointIndex < chart.Series[seriesName].Points.Count) + { + DataPoint dataPoint = chart.Series[seriesName].Points[pointIndex]; + result.Axis = null; + result.ChartArea = chart.ChartAreas[dataPoint.series.ChartArea]; + result.Object = dataPoint; + } + break; + } + + case ChartElementType.DataPointLabel: + { + if (chart.Series.IndexOf(seriesName) >= 0 && + pointIndex < chart.Series[seriesName].Points.Count) + { + DataPoint dataPoint = chart.Series[seriesName].Points[pointIndex]; + result.Axis = null; + result.ChartArea = chart.ChartAreas[dataPoint.series.ChartArea]; + result.Object = dataPoint; + } + break; + } + + case ChartElementType.Gridlines: + Grid gridLines = (Grid)obj; + result.Axis = gridLines.Axis; + if (gridLines.Axis != null) + { + result.ChartArea = gridLines.Axis.ChartArea; + } + break; + case ChartElementType.LegendArea: + result.Axis = null; + result.ChartArea = null; + break; + case ChartElementType.LegendItem: + result.PointIndex = ((LegendItem)obj).SeriesPointIndex; + result.Axis = null; + result.ChartArea = null; + break; + case ChartElementType.PlottingArea: + ChartArea area = (ChartArea)obj; + result.Axis = null; + result.ChartArea = area; + break; + case ChartElementType.StripLines: + StripLine stripLines = (StripLine)obj; + result.Axis = stripLines.Axis; + if (stripLines.Axis != null) + { + result.ChartArea = stripLines.Axis.ChartArea; + } + break; + case ChartElementType.TickMarks: + TickMark tickMarks = (TickMark)obj; + result.Axis = tickMarks.Axis; + if (tickMarks.Axis != null) + { + result.ChartArea = tickMarks.Axis.ChartArea; + } + break; + case ChartElementType.Title: + result.Axis = null; + result.ChartArea = null; + break; + case ChartElementType.AxisLabels: + if (obj is CustomLabel) + { + CustomLabel label = (CustomLabel)obj; + result.Axis = label.Axis; + result.ChartArea = label.Axis!=null ? label.Axis.ChartArea : null; + } + break; + case ChartElementType.AxisLabelImage: + if (obj is CustomLabel) + { + CustomLabel label = (CustomLabel)obj; + result.Axis = label.Axis; + result.ChartArea = label.Axis!=null ? label.Axis.ChartArea : null; + } + break; + case ChartElementType.AxisTitle: + if (obj is Axis) + { + result.Axis = (Axis)obj; + result.ChartArea = result.Axis.ChartArea; + } + break; +#if Microsoft_CONTROL + case ChartElementType.ScrollBarLargeDecrement: + scrollBar = (AxisScrollBar)obj; + result.Axis = scrollBar.axis; + if (scrollBar.axis != null) + { + result.ChartArea = scrollBar.axis.ChartArea; + } + break; + case ChartElementType.ScrollBarLargeIncrement: + scrollBar = (AxisScrollBar)obj; + result.Axis = scrollBar.axis; + if (scrollBar.axis != null) + { + result.ChartArea = scrollBar.axis.ChartArea; + } + break; + case ChartElementType.ScrollBarSmallDecrement: + scrollBar = (AxisScrollBar)obj; + result.Axis = scrollBar.axis; + if (scrollBar.axis != null) + { + result.ChartArea = scrollBar.axis.ChartArea; + } + break; + case ChartElementType.ScrollBarSmallIncrement: + scrollBar = (AxisScrollBar)obj; + result.Axis = scrollBar.axis; + if (scrollBar.axis != null) + { + result.ChartArea = scrollBar.axis.ChartArea; + } + break; + case ChartElementType.ScrollBarThumbTracker: + scrollBar = (AxisScrollBar)obj; + result.Axis = scrollBar.axis; + if (scrollBar.axis != null) + { + result.ChartArea = scrollBar.axis.ChartArea; + } + break; +#endif // Microsoft_CONTROL + + case ChartElementType.Annotation: + result.Axis = null; + result.ChartArea = null; + break; + } + return result; + } + + #endregion //HitTest + + #region Outline + + /// + /// Gets the chart element outline. + /// + /// The chart object. + /// Type of the element. + /// + internal ChartElementOutline GetChartElementOutline(object chartObject, ChartElementType elementType) + { + // Check arguments + if (chartObject == null) + throw new ArgumentNullException("chartObject"); + + // Get outline + ChartElementOutline result = new ChartElementOutline(); + chartObject = this.GetAutoGeneratedObject(chartObject); + ArrayList list = this.GetMarkers(chartObject, elementType); + result.Markers = new ReadOnlyCollection((PointF[])list.ToArray(typeof(PointF))); + result.OutlinePath = GetGraphicsPath(list, chartObject, elementType); + return result; + } + + #endregion //Outline + + #region Selection + + /// + /// Gets the graphics path. + /// + /// The markers. + /// The chart object. + /// Type of the element. + /// + private GraphicsPath GetGraphicsPath(IList markers, object chartObject, ChartElementType elementType) + { + bool chartArea3D = false; + ChartArea chartArea = chartObject as ChartArea; + if (chartArea != null && elementType == ChartElementType.PlottingArea) + { + chartArea3D = IsArea3D(chartArea); + } + if (elementType != ChartElementType.DataPoint && + elementType != ChartElementType.Gridlines && + elementType != ChartElementType.StripLines && + elementType != ChartElementType.TickMarks && + !chartArea3D + ) + { + GraphicsPath path = new GraphicsPath(); + PointF[] points = new PointF[markers.Count]; + markers.CopyTo(points, 0); + if (points.Length > 3) + { + if (elementType == ChartElementType.DataPointLabel) + { + for (int i = 0; i < points.Length; i += 4) + { + RectangleF rect = RectangleF.FromLTRB(points[i].X, points[i].Y, points[i + 2].X, points[i + 2].Y); + path.Reset(); + path.AddRectangle(Rectangle.Round(rect)); + } + } + else + { + if (points.Length == 4) + { + Point[] pointsAlligned = new Point[points.Length]; + for (int i = 0; i < points.Length; i++) + { + pointsAlligned[i] = Point.Round(points[i]); + } + path.AddPolygon(pointsAlligned); + } + else + { + path.AddPolygon(points); + } + } + } + return path; + } + return null; + } + + private static Int32 GetDataPointIndex(DataPoint dataPoint) + { + int pointIndex = -1; + if (dataPoint != null && dataPoint.series != null) + { + pointIndex = dataPoint.series.Points.IndexOf(dataPoint); + if (pointIndex == -1 && dataPoint.IsCustomPropertySet("OriginalPointIndex")) + { + if (!Int32.TryParse(dataPoint.GetCustomProperty("OriginalPointIndex"), out pointIndex)) + return -1; + } + } + return pointIndex; + } + + /// + /// Gets the auto generated object. + /// + /// The chart object. + /// + private object GetAutoGeneratedObject(object chartObject) + { + DataPoint dataPoint = chartObject as DataPoint; + if (dataPoint != null) + { + if (dataPoint.series != null) + { + string seriesName = dataPoint.series.Name; + int pointIndex = dataPoint.series.Points.IndexOf(dataPoint); + if (this.ChartControl.Series.IndexOf(seriesName) != -1) + { + Series series = this.ChartControl.Series[seriesName]; + if (series.Points.Contains(dataPoint)) + { + return chartObject; + } + if (pointIndex >= 0) + { + if (series.Points.Count > pointIndex) + { + return series.Points[pointIndex]; + } + } + } + } + } + + Series asSeries = chartObject as Series; + if (asSeries != null) + { + if (this.ChartControl.Series.Contains(asSeries)) + { + return chartObject; + } + if (this.ChartControl.Series.IndexOf(asSeries.Name) != -1) + { + return this.ChartControl.Series[asSeries.Name]; + } + } + return chartObject; + } + + /// + /// Gets the hot regions. + /// + /// The CNTX obj. + /// Type of the element. + /// + private HotRegion[] GetHotRegions(object cntxObj, ChartElementType elementType) + { + ArrayList result = new ArrayList(); + HotRegionsList hrList = this.ChartPicture.Common.HotRegionsList; + string dataPointSeries = String.Empty; + int dataPointIndex = -1; + + for (int i = hrList.List.Count - 1; i >= 0; i--) + { + HotRegion rgn = (HotRegion)hrList.List[i]; + if (rgn.Type == elementType) + { + switch (rgn.Type) + { + case ChartElementType.LegendItem: + LegendItem legendItem = cntxObj as LegendItem; + if (legendItem != null) + { + if (((LegendItem)rgn.SelectedObject).Name == legendItem.Name) + { + result.Add(rgn); + } + } + break; + case ChartElementType.AxisLabelImage: + case ChartElementType.AxisLabels: + CustomLabel label1 = cntxObj as CustomLabel; + CustomLabel label2 = rgn.SelectedObject as CustomLabel; + if (label1 != null) + { + if (label1 != null && label2 != null) + { + if (label1.Axis == label2.Axis) + { + if (label1.FromPosition == label2.FromPosition && + label1.ToPosition == label2.ToPosition && + label1.RowIndex == label2.RowIndex) + { + if (rgn.Path == null) + { + result.Add(rgn); + } + } + } + } + } + else + { + Axis axis = cntxObj as Axis; + if (axis != null) + { + if (axis == label2.Axis) + { + if (rgn.Path == null) + { + result.Add(rgn); + } + } + } + } + break; + case ChartElementType.DataPointLabel: + case ChartElementType.DataPoint: + DataPoint dataPoint = cntxObj as DataPoint; + if (dataPoint != null) + { + if (String.IsNullOrEmpty(dataPointSeries) || dataPointIndex == -1) + { + dataPointSeries = dataPoint.series.Name; + dataPointIndex = GetDataPointIndex(dataPoint); + } + if (rgn.PointIndex == dataPointIndex && rgn.SeriesName == dataPointSeries) + { + result.Add(rgn); + } + } + else + { + DataPointCollection dataPointCollection = cntxObj as DataPointCollection; + if (dataPointCollection != null) + { + cntxObj = dataPointCollection.series; + } + Series series = cntxObj as Series; + if (series != null) + { + if (String.IsNullOrEmpty(dataPointSeries) || dataPointIndex == -1) + { + dataPointSeries = series.Name; + } + if (rgn.SeriesName == dataPointSeries) + { + result.Add(rgn); + } + } + } + break; + + default: + if (rgn.SelectedObject == cntxObj) + { + result.Add(rgn); + } + break; + } + } + } + return (HotRegion[])result.ToArray(typeof(HotRegion)); + } + + + + /// + /// Gets the markers from regions. + /// + /// The chart object. + /// Type of the element. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + private ArrayList GetMarkersFromRegions(object chartObject, ChartElementType elementType) + { + ArrayList list = new ArrayList(); + HotRegion[] regions = this.GetHotRegions(chartObject, elementType); + ChartGraphics graph = this.Graph; + RectangleF rect; + + Grid grid = chartObject as Grid; + if (grid != null) + { + foreach (HotRegion rgn in regions) + { + if (!IsArea3D(grid.Axis.ChartArea)) + { + if (IsChartAreaCircular(grid.Axis.ChartArea)) + { + GraphicsPathIterator iterator = new GraphicsPathIterator(rgn.Path); + + // There is more then one path. + if (iterator.SubpathCount > 1) + { + GraphicsPath subPath = new GraphicsPath(); + while (iterator.NextMarker(subPath) > 0) + { + rect = subPath.GetBounds(); + list.Add(new PointF(rect.Left + rect.Width / 2, rect.Top)); + list.Add(new PointF(rect.Right, rect.Top + rect.Height / 2)); + list.Add(new PointF(rect.Right - rect.Width / 2, rect.Bottom)); + list.Add(new PointF(rect.Left, rect.Bottom - rect.Height / 2)); + subPath.Reset(); + } + } + } + else + { + // 2D + rect = this.GetHotRegionRectangle(rgn, RectangleF.Empty, elementType); + if (grid != null) + { + if (grid.GetAxis().AxisPosition == AxisPosition.Bottom || + grid.GetAxis().AxisPosition == AxisPosition.Top) + { + rect.Offset(rect.Width / 2, 0); + rect.Width = 0; + } + else + { + rect.Offset(0, rect.Height / 2); + rect.Height = 0; + } + } + list.AddRange(this.GetMarkers(rect, false)); + } + } + else + { // 3D + PointF[] points = rgn.Path.PathPoints; + for (int i = 0; i < points.Length - 3; i = i + 4) + { //Each gridline has a corresponding set of 4 points in the path + //One of the ends of a gridline is in the middle the line between points #0 and #3 + //Another ends of a gridline is in the middle the line between points #1 and #2 + //So we find those middles and put a marks to the ends of the gridline. + PointF middleP0P3 = new PointF((points[i].X + points[i + 3].X) / 2f, (points[i].Y + points[i + 3].Y) / 2f); + PointF middleP1P2 = new PointF((points[i + 1].X + points[i + 2].X) / 2f, (points[i + 1].Y + points[i + 2].Y) / 2f); + list.Add(graph.GetAbsolutePoint(middleP0P3)); + list.Add(graph.GetAbsolutePoint(middleP1P2)); + } + } + } + return list; + } + + DataPoint dataPoint = chartObject as DataPoint; + if (dataPoint != null && elementType != ChartElementType.DataPointLabel) + { + rect = Rectangle.Empty; + Series series = dataPoint.series; + if (this.ChartControl.ChartAreas.IndexOf(series.ChartArea) == -1) + { + return list; + } + ChartArea area = this.ChartControl.ChartAreas[series.ChartArea]; + PointF pp = this.Transform3D(area, dataPoint); + if (!(float.IsNaN(pp.X) || float.IsNaN(pp.Y))) + { + list.Add(graph.GetAbsolutePoint(pp)); + } + return list; + } + + Axis axis = chartObject as Axis; + if (axis != null && elementType == ChartElementType.AxisTitle) + { + foreach (HotRegion rgn in regions) + { + if (!IsArea3D(axis.ChartArea)) + { // 2D + rect = this.GetHotRegionRectangle(rgn, RectangleF.Empty, elementType); + list.AddRange(this.GetMarkers(rect, elementType)); + } + else + { // 3D + PointF[] points = rgn.Path.PathPoints; + list.AddRange(points); + } + } + return list; + } + + LegendItem legendItem = chartObject as LegendItem; + if (legendItem != null) + { + rect = Rectangle.Empty; + foreach (HotRegion rgn in regions) + { + rect = this.GetHotRegionRectangle(rgn, rect, elementType); + } + if (!rect.IsEmpty) + { + list.AddRange(this.GetMarkers(rect, elementType)); + } + return list; + } + else if (chartObject is Annotation) + { + rect = Rectangle.Empty; + foreach (HotRegion rgn in regions) + { + rect = this.GetHotRegionRectangle(rgn, rect, elementType); + } + if (!rect.IsEmpty) + { + list.AddRange(this.GetMarkers(rect, elementType)); + } + return list; + } + foreach (HotRegion rgn in regions) + { + rect = this.GetHotRegionRectangle(rgn, RectangleF.Empty, elementType); + list.AddRange(this.GetMarkers(rect, elementType)); + } + return list; + + } + + + /// + /// Gets the markers. + /// + /// The chart object. + /// Type of the element. + /// + private ArrayList GetMarkers(object chartObject, ChartElementType elementType) + { + ChartArea chartArea = chartObject as ChartArea; + if (chartArea != null) + { + return this.GetAreaMarkers(this.Graph, chartArea); + } + + + Axis axis = chartObject as Axis; + if (axis != null) + { + if ( + elementType == ChartElementType.AxisLabelImage || + elementType == ChartElementType.AxisLabels || + elementType == ChartElementType.AxisTitle + ) + { + return this.GetMarkersFromRegions(chartObject, elementType); + } + return this.GetAxisMarkers(this.Graph, axis); + } + + DataPoint dataPoint = chartObject as DataPoint; + if (dataPoint != null) + { + return this.GetMarkersFromRegions(chartObject, elementType); + } + + Series series = chartObject as Series; + if (series != null) + { + if (elementType == ChartElementType.DataPointLabel) + { + return this.GetMarkersFromRegions(chartObject, elementType); + } + return this.GetSeriesMarkers(series); + } + + return this.GetMarkersFromRegions(chartObject, elementType); + } + + /// + /// Determines whether specified chart area is circular or not have axes. These chart areas contain pie, doughnut, polar, radar + /// + /// The area. + /// + /// true if specified chart area is circular; otherwise, false. + /// + private Boolean IsChartAreaCircular(ChartArea area) + { + foreach (object o in area.ChartTypes) + { + ChartTypes.IChartType chartType = area.Common.ChartTypeRegistry.GetChartType(o.ToString()); + if (chartType != null && (chartType.CircularChartArea || !chartType.RequireAxes)) + { + return true; + } + } + return false; + } + + /// + /// Determines whether the chart area is in 3D mode. + /// + /// The area. + /// + /// true if the chart area is in 3D mode; otherwise, false. + /// + private Boolean IsArea3D(ChartArea area) + { + return area.Area3DStyle.Enable3D && !this.IsChartAreaCircular(area) && area.matrix3D != null && area.matrix3D.IsInitialized(); + } + + /// + /// Gets the series markers. + /// + /// The series. + /// List of PointF. + private ArrayList GetSeriesMarkers(Series series) + { + ArrayList list = new ArrayList(); + if (series != null) + { + String areaName = series.ChartArea; + + if (String.IsNullOrEmpty(areaName)) + { + areaName = ChartPicture.ChartAreas.DefaultNameReference; + } + + if (ChartPicture.ChartAreas.IndexOf(areaName) != -1 && series.Enabled) + { + + ChartArea chartArea = ChartPicture.ChartAreas[areaName]; + + if (ChartControl.Series.IndexOf(series.Name) != -1) + { + series = ChartControl.Series[series.Name]; + } + + DataPointCollection points = series.Points; + // in design mode we have usually fake points + if (points.Count == 0) + { + points = series.fakeDataPoints; + } + // transform points in 3D + foreach (DataPoint point in points) + { + PointF pp = this.Transform3D(chartArea, point); + if (float.IsNaN(pp.X) || float.IsNaN(pp.Y)) + { + continue; + } + list.Add(this.Graph.GetAbsolutePoint(pp)); + } + } + } + return list; + } + + /// + /// Gets the axis markers - list of points where markers are drawn. + /// + /// The graph. + /// The axis. + /// List of PointF. + private ArrayList GetAxisMarkers(ChartGraphics graph, Axis axis) + { + ArrayList list = new ArrayList(); + if (axis == null) + { + return list; + } + PointF first = PointF.Empty; + PointF second = PointF.Empty; + + // Set the position of axis + switch (axis.AxisPosition) + { + + case AxisPosition.Left: + + first.X = (float)axis.GetAxisPosition(); + first.Y = axis.PlotAreaPosition.Y; + second.X = (float)axis.GetAxisPosition(); + second.Y = axis.PlotAreaPosition.Bottom; + first.X -= axis.labelSize + axis.markSize; + break; + + case AxisPosition.Right: + + first.X = (float)axis.GetAxisPosition(); + first.Y = axis.PlotAreaPosition.Y; + second.X = (float)axis.GetAxisPosition(); + second.Y = axis.PlotAreaPosition.Bottom; + second.X += axis.labelSize + axis.markSize; + break; + + case AxisPosition.Bottom: + + first.X = axis.PlotAreaPosition.X; + first.Y = (float)axis.GetAxisPosition(); + second.X = axis.PlotAreaPosition.Right; + second.Y = (float)axis.GetAxisPosition(); + second.Y += axis.labelSize + axis.markSize; + break; + + case AxisPosition.Top: + + first.X = axis.PlotAreaPosition.X; + first.Y = (float)axis.GetAxisPosition(); + second.X = axis.PlotAreaPosition.Right; + second.Y = (float)axis.GetAxisPosition(); + first.Y -= axis.labelSize + axis.markSize; + break; + } + + // Update axis line position for circular area + if (axis.ChartArea.chartAreaIsCurcular) + { + second.Y = axis.PlotAreaPosition.Y + axis.PlotAreaPosition.Height / 2f; + } + + RectangleF rect1 = new RectangleF(first.X, first.Y, second.X - first.X, second.Y - first.Y); + + SizeF size = graph.GetRelativeSize(new SizeF(3, 3)); + if (axis.AxisPosition == AxisPosition.Top || axis.AxisPosition == AxisPosition.Bottom) + { + rect1.Inflate(2, size.Height); + } + else + { + rect1.Inflate(size.Width, 2); + } + IList list1 = this.GetMarkers(rect1, ChartElementType.Axis); + ChartArea area = axis.ChartArea; + if (this.IsArea3D(area)) + { + + Boolean axisOnEdge = false; + float zPositon = axis.GetMarksZPosition(out axisOnEdge); + + // Transform coordinates + Point3D[] points = new Point3D[list1.Count]; + for (int i = 0; i < list1.Count; i++) + { + points[i] = new Point3D(((PointF)list1[i]).X, ((PointF)list1[i]).Y, zPositon); + } + axis.ChartArea.matrix3D.TransformPoints(points); + for (int i = 0; i < list1.Count; i++) + { + list1[i] = points[i].PointF; + } + } + foreach (PointF p in list1) + { + list.Add(graph.GetAbsolutePoint(p)); + } + return list; + } + + /// + /// Gets the area markers. + /// + /// The graph. + /// The area. + /// List of PointF. + private ArrayList GetAreaMarkers(ChartGraphics graph, ChartArea area) + { + ArrayList list = new ArrayList(); + if (area == null) + { + return list; + } + IList list1 = this.GetMarkers(area.PlotAreaPosition.ToRectangleF(), ChartElementType.PlottingArea); + if (this.IsChartAreaCircular(area)) + { + list1 = this.GetMarkers(area.lastAreaPosition, ChartElementType.PlottingArea); + } + if (IsArea3D(area)) + { + float zPositon = 0; // area.areaSceneDepth; + // Transform coordinates + Point3D[] points = new Point3D[list1.Count]; + for (int i = 0; i < list1.Count; i++) + { + points[i] = new Point3D(((PointF)list1[i]).X, ((PointF)list1[i]).Y, zPositon); + } + area.matrix3D.TransformPoints(points); + for (int i = 0; i < list1.Count; i++) + { + list1[i] = points[i].PointF; + } + } + foreach (PointF p in list1) + { + list.Add(graph.GetAbsolutePoint(p)); + } + return list; + } + + /// + /// Builds list of markers (PointF) based on rectangle + /// + /// The rectangle + /// The type of chart elements to retrieve. + /// List of PointF + private ArrayList GetMarkers(RectangleF rect, ChartElementType elementType) + { + if (elementType.ToString().StartsWith("Legend", StringComparison.Ordinal) || elementType.ToString().StartsWith("Title", StringComparison.Ordinal)) + { + rect.Inflate(4f, 4f); + } + if (elementType.ToString().StartsWith("PlottingArea", StringComparison.Ordinal)) + { + SizeF relSize = this.Graph.GetRelativeSize(new SizeF(4f, 4f)); + rect.Inflate(relSize.Width, relSize.Height); + } + + if ((elementType != ChartElementType.Nothing) && (elementType != ChartElementType.PlottingArea)) + { + return this.GetMarkers(rect, false); + } + return this.GetMarkers(rect, true); + } + + + /// + /// Builds list of markers (PointF) based on rectangle + /// + /// The rectangle + /// Add additional markers to the rectangle. + /// List of PointF + private ArrayList GetMarkers(RectangleF rect, Boolean addAdditionalMarkers) + { + ArrayList list = new ArrayList(); + if (!addAdditionalMarkers) + { + if (rect.Width > 0 && rect.Height > 0) + { + list.Add(new PointF(rect.Left, rect.Top)); + list.Add(new PointF(rect.Right, rect.Top)); + list.Add(new PointF(rect.Right, rect.Bottom)); + list.Add(new PointF(rect.Left, rect.Bottom)); + } + else if (rect.Width > 0) + { + list.Add(new PointF(rect.Left, rect.Top)); + list.Add(new PointF(rect.Right, rect.Top)); + } + else if (rect.Height > 0) + { + list.Add(new PointF(rect.Left, rect.Top)); + list.Add(new PointF(rect.Left, rect.Bottom)); + } + } + else + { + if (rect.Width > 0) + { + list.Add(new PointF(rect.Left, rect.Top)); + + if (rect.Width > 30) + { + list.Add(new PointF(rect.Left + rect.Width / 2, rect.Top)); + } + + list.Add(new PointF(rect.Right, rect.Top)); + + if (rect.Height > 30) + { + list.Add(new PointF(rect.Right, rect.Top + rect.Height / 2)); + } + + list.Add(new PointF(rect.Right, rect.Bottom)); + if (rect.Width > 30) + { + list.Add(new PointF(rect.Left + rect.Width / 2, rect.Bottom)); + } + + list.Add(new PointF(rect.Left, rect.Bottom)); + if (rect.Height > 30) + { + list.Add(new PointF(rect.Left, rect.Top + rect.Height / 2)); + } + } + + else if (rect.Width > 0) + { + list.Add(new PointF(rect.Left, rect.Top)); + + if (rect.Width > 30) + { + list.Add(new PointF(rect.Left + rect.Width / 2, rect.Top)); + } + + list.Add(new PointF(rect.Right, rect.Top)); + } + else if (rect.Height > 0) + { + list.Add(new PointF(rect.Left, rect.Bottom)); + if (rect.Height > 30) + { + list.Add(new PointF(rect.Left, rect.Top + rect.Height / 2)); + } + list.Add(new PointF(rect.Left, rect.Top)); + } + } + return list; + } + + /// + /// Gets the region markers from graphics path. + /// + /// The path. + /// List of PointF. + private ArrayList GetRegionMarkers(GraphicsPath path) + { + return new ArrayList(path.PathPoints); + } + + /// + /// Calculates a DataPoint of 3D area into PointF to draw. + /// + /// 3D chart area + /// The DataPoint + /// Calculated PointF + private PointF Transform3D(ChartArea chartArea, DataPoint point) + { + if (chartArea is ChartArea && IsArea3D(chartArea)) + { + // Get anotation Z coordinate (use scene depth or anchored point Z position) + float positionZ = chartArea.areaSceneDepth; + if (point != null && point.series != null) + { + float depth = 0f; + chartArea.GetSeriesZPositionAndDepth( + point.series, + out depth, + out positionZ); + positionZ += depth / 2f; + } + + PointF pf = point.positionRel; + + // Define 3D points of annotation object + Point3D[] annot3DPoints = new Point3D[1]; + annot3DPoints[0] = new Point3D(pf.X, pf.Y, positionZ); + + // Tranform cube coordinates + chartArea.matrix3D.TransformPoints(annot3DPoints); + + return annot3DPoints[0].PointF; + } + return point.positionRel; + } + + /// + /// Gets the hot region rectangle. + /// + /// The hot region. + /// The rectangle to union with. + /// The type of the element. + /// Returns the rectangle around the hot region. + private RectangleF GetHotRegionRectangle(HotRegion rgn, RectangleF unionWith, ChartElementType elementType) + { + RectangleF rect; + if (rgn.Path != null) + { + rect = rgn.Path.GetBounds(); + } + else + { + rect = rgn.BoundingRectangle; + } + if (rgn.RelativeCoordinates) + { + rect = this.Graph.GetAbsoluteRectangle(rect); + } + if (elementType == ChartElementType.AxisLabels) + { + if (rect.Width > rect.Height) + { + rect.Inflate(-5, -2); + } + else if (rect.Width < rect.Height) + { + rect.Inflate(-2, -5); + } + } + if (!unionWith.IsEmpty) + { + return RectangleF.Union(unionWith, rect); + } + return rect; + } + + #endregion //Selection + + #endregion //Tooltips + + #region IServiceProvider Members + + /// + /// Gets the service object of the specified type. + /// + /// An object that specifies the type of service object to get. + /// + /// A service object of type . It returns null + /// if there is no service object of type . + /// + object IServiceProvider.GetService(Type serviceType) + { + if (serviceType == typeof(Selection)) + { + return this; + } + if (_service != null) + { + return _service.GetService(serviceType); + } + return null; + } + + #endregion + + } + + +#if Microsoft_CONTROL + /// + /// The ToolTipEventArgs class stores the tool tips event arguments. + /// + public class ToolTipEventArgs : EventArgs + { + #region Private fields + + // Private fields for properties values storage + private int x = 0; + private int y = 0; + private string text = ""; + private HitTestResult result = new HitTestResult(); + + #endregion + + #region Constructors + + /// + /// ToolTipEventArgs constructor. Creates ToolTip event arguments. + /// + /// X-coordinate of mouse. + /// Y-coordinate of mouse. + /// Tooltip text. + /// Hit test result object. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public ToolTipEventArgs(int x, int y, string text, HitTestResult result) + { + this.x = x; + this.y = y; + this.text = text; + this.result = result; + } + + #endregion + + #region Properties + + /// + /// Gets the x-coordinate of the mouse. + /// + [ + SRDescription("DescriptionAttributeToolTipEventArgs_X"), + ] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "X")] + public int X + { + get + { + return x; + } + } + + /// + /// Gets the result of the hit test. + /// + [ + SRDescription("DescriptionAttributeToolTipEventArgs_HitTestResult"), + ] + public HitTestResult HitTestResult + { + get + { + return result; + } + } + + /// + /// Gets the y-coordinate of the mouse. + /// + [ + SRDescription("DescriptionAttributeToolTipEventArgs_Y"), + ] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Y")] + public int Y + { + get + { + return y; + } + } + + /// + /// Gets the text of the tooltip. + /// + [ + SRDescription("DescriptionAttributeToolTipEventArgs_Text"), + ] + public string Text + { + get + { + return text; + } + set + { + text = value; + } + } + + #endregion + } + +#endif // #if Microsoft_CONTROL +} diff --git a/System.Web.DataVisualization/Common/General/SmartLabels.cs b/System.Web.DataVisualization/Common/General/SmartLabels.cs new file mode 100644 index 000000000..1b4ac8190 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/SmartLabels.cs @@ -0,0 +1,1710 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: SmartLabelStyle.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: SmartLabelStyle, SmartLabelStyle +// +// Purpose: Smart Labels are used to avoid data point's labels +// overlapping. SmartLabelStyle class is exposed from +// the Series and Annotation classes and allows enabling +// and adjusting of SmartLabelStyle algorithm. SmartLabelStyle class +// exposes a set of helper utility methods and store +// information about labels in a chart area. +// +// Reviewed: AG - Microsoft 14, 2007 +// +//=================================================================== + +#region Used namespaces +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +#if Microsoft_CONTROL + +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; +using System.Windows.Forms.DataVisualization.Charting; + +using System.Globalization; +using System.ComponentModel.Design.Serialization; +using System.Reflection; +using System.Windows.Forms.Design; +#else + using System.Web; + using System.Web.UI; + using System.Globalization; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.ChartTypes; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.Borders3D; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Enumerations + + /// + /// Line anchor cap style. + /// + [ + SRDescription("DescriptionAttributeLineAnchorCapStyle_LineAnchorCapStyle") + ] + public enum LineAnchorCapStyle + { + /// + /// No line anchor cap. + /// + None, + /// + /// Arrow line anchor cap. + /// + Arrow, + /// + /// Diamond line anchor cap. + /// + Diamond, + /// + /// Square line anchor cap. + /// + Square, + /// + /// Round line anchor cap. + /// + Round + } + + /// + /// Data point label callout style. + /// + [ + SRDescription("DescriptionAttributeLabelCalloutStyle_LabelCalloutStyle") + ] + public enum LabelCalloutStyle + { + /// + /// Label connected with the marker using just a line. + /// + None, + /// + /// Label is undelined and connected with the marker using a line. + /// + Underlined, + /// + /// Box is drawn around the label and it's connected with the marker using a line. + /// + Box + } + + /// + /// Data point label outside of the plotting area style. + /// + [ + SRDescription("DescriptionAttributeLabelOutsidePlotAreaStyle_LabelOutsidePlotAreaStyle") + ] + public enum LabelOutsidePlotAreaStyle + { + /// + /// Labels can be positioned outside of the plotting area. + /// + Yes, + /// + /// Labels can not be positioned outside of the plotting area. + /// + No, + /// + /// Labels can be partially outside of the plotting area. + /// + Partial + } + + #endregion + + /// + /// SmartLabelStyle class is used to enable and configure the + /// SmartLabelStyle algorithm for data point labels and annotations. + /// In most of the cases it is enough just to enable the algorithm, + /// but this class also contains properties which allow controlling + /// how the labels are moved around to avoid collisions. Visual + /// appearance of callouts can also be set through this class. + /// + [ + DefaultProperty("Enabled"), + SRDescription("DescriptionAttributeSmartLabelsStyle_SmartLabelsStyle"), + TypeConverter(typeof(NoNameExpandableObjectConverter)) + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class SmartLabelStyle + { + #region Fields + + // Reference to the series this style belongs to + internal object chartElement = null; + + // Indicates if SmartLabelStyle algorithm is enabled. + private bool _enabled = true; + + // Indicates that marker overlapping by label is allowed. + private bool _isMarkerOverlappingAllowed = false; + + // Indicates that overlapped labels that can't be repositioned will be hidden. + private bool _isOverlappedHidden = true; + + // Possible moving directions for the overlapped SmartLabelStyle. + private LabelAlignmentStyles _movingDirection = LabelAlignmentStyles.Top | LabelAlignmentStyles.Bottom | LabelAlignmentStyles.Right | LabelAlignmentStyles.Left | LabelAlignmentStyles.TopLeft | LabelAlignmentStyles.TopRight | LabelAlignmentStyles.BottomLeft | LabelAlignmentStyles.BottomRight; + + // Minimum distance the overlapped SmartLabelStyle can be moved from the marker. Distance is measured in pixels. + private double _minMovingDistance = 0.0; + + // Maximum distance the overlapped SmartLabelStyle can be moved from the marker. Distance is measured in pixels. + private double _maxMovingDistance = 30.0; + + // Defines if SmartLabelStyle are allowed to be drawn outside of the plotting area. + private LabelOutsidePlotAreaStyle _allowOutsidePlotArea = LabelOutsidePlotAreaStyle.Partial; + + // Callout style of the repositioned SmartLabelStyle. + private LabelCalloutStyle _calloutStyle = LabelCalloutStyle.Underlined; + + // Label callout line color. + private Color _calloutLineColor = Color.Black; + + // Label callout line style. + private ChartDashStyle _calloutLineDashStyle = ChartDashStyle.Solid; + + // Label callout back color. Applies to the Box style only! + private Color _calloutBackColor = Color.Transparent; + + // Label callout line width. + private int _calloutLineWidth = 1; + + // Label callout line anchor cap. + private LineAnchorCapStyle _calloutLineAnchorCapStyle = LineAnchorCapStyle.Arrow; + + #endregion + + #region Constructors and initialization + + /// + /// Default public constructor. + /// + public SmartLabelStyle() + { + this.chartElement = null; + } + + /// + /// Constructor. + /// + /// Chart element this style belongs to. + internal SmartLabelStyle(Object chartElement) + { + this.chartElement = chartElement; + } + + #endregion + + #region Properties + + /// + /// SmartLabelStyle algorithm enabled flag. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeEnabled13"), + ParenthesizePropertyNameAttribute(true), + ] + virtual public bool Enabled + { + get + { + return _enabled; + } + set + { + _enabled = value; + Invalidate(); + } + } + + /// + /// Indicates that marker overlapping by label is allowed. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(false), + SRDescription("DescriptionAttributeMarkerOverlapping"), + ] + virtual public bool IsMarkerOverlappingAllowed + { + get + { + return _isMarkerOverlappingAllowed; + } + set + { + _isMarkerOverlappingAllowed = value; + Invalidate(); + } + } + + /// + /// Indicates that overlapped labels that can't be repositioned will be hidden. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeHideOverlapped"), + ] + virtual public bool IsOverlappedHidden + { + get + { + return _isOverlappedHidden; + } + set + { + _isOverlappedHidden = value; + Invalidate(); + } + } + + /// + /// Possible moving directions for the overlapped SmartLabelStyle. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(typeof(LabelAlignmentStyles), "Top, Bottom, Right, Left, TopLeft, TopRight, BottomLeft, BottomRight"), + SRDescription("DescriptionAttributeMovingDirection"), + Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base), + ] + virtual public LabelAlignmentStyles MovingDirection + { + get + { + return _movingDirection; + } + set + { + if(value == 0) + { + throw (new InvalidOperationException(SR.ExceptionSmartLabelsDirectionUndefined)); + } + + _movingDirection = value; + Invalidate(); + } + } + + /// + /// Minimum distance the overlapped SmartLabelStyle can be moved from the marker. Distance is measured in pixels. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(0.0), + SRDescription("DescriptionAttributeMinMovingDistance"), + ] + virtual public double MinMovingDistance + { + get + { + return _minMovingDistance; + } + set + { + if(value < 0) + { + throw (new InvalidOperationException(SR.ExceptionSmartLabelsMinMovingDistanceIsNegative)); + } + _minMovingDistance = value; + Invalidate(); + } + } + + /// + /// Maximum distance the overlapped SmartLabelStyle can be moved from the marker. Distance is measured in pixels. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(30.0), + SRDescription("DescriptionAttributeMaxMovingDistance"), + ] + virtual public double MaxMovingDistance + { + get + { + return _maxMovingDistance; + } + set + { + if(value < 0 ) + { + throw (new InvalidOperationException(SR.ExceptionSmartLabelsMaxMovingDistanceIsNegative)); + } + _maxMovingDistance = value; + Invalidate(); + } + } + + /// + /// Defines if SmartLabelStyle are allowed to be drawn outside of the plotting area. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(LabelOutsidePlotAreaStyle.Partial), + SRDescription("DescriptionAttributeAllowOutsidePlotArea"), + ] + virtual public LabelOutsidePlotAreaStyle AllowOutsidePlotArea + { + get + { + return _allowOutsidePlotArea; + } + set + { + _allowOutsidePlotArea = value; + Invalidate(); + } + } + + /// + /// Callout style of the repositioned SmartLabelStyle. + /// + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(LabelCalloutStyle.Underlined), + SRDescription("DescriptionAttributeCalloutStyle3"), + ] + virtual public LabelCalloutStyle CalloutStyle + { + get + { + return _calloutStyle; + } + set + { + _calloutStyle = value; + Invalidate(); + } + } + + /// + /// Label callout line color. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeCalloutLineColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + virtual public Color CalloutLineColor + { + get + { + return _calloutLineColor; + } + set + { + _calloutLineColor = value; + Invalidate(); + } + } + + /// + /// Label callout line style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeLineDashStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + virtual public ChartDashStyle CalloutLineDashStyle + { + get + { + return _calloutLineDashStyle; + } + set + { + _calloutLineDashStyle = value; + Invalidate(); + } + } + + /// + /// Label callout back color. Applies to the Box style only! + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "Transparent"), + SRDescription("DescriptionAttributeCalloutBackColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + virtual public Color CalloutBackColor + { + get + { + return _calloutBackColor; + } + set + { + _calloutBackColor = value; + Invalidate(); + } + } + + /// + /// Label callout line width. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeLineWidth"), + ] + virtual public int CalloutLineWidth + { + get + { + return _calloutLineWidth; + } + set + { + _calloutLineWidth = value; + Invalidate(); + } + } + + /// + /// Label callout line anchor cap. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(LineAnchorCapStyle.Arrow), + SRDescription(SR.Keys.DescriptionAttributeCalloutLineAnchorCap), + ] + virtual public LineAnchorCapStyle CalloutLineAnchorCapStyle + { + get + { + return _calloutLineAnchorCapStyle; + } + set + { + _calloutLineAnchorCapStyle = value; + Invalidate(); + } + } + + #endregion + + #region Methods + + /// + /// Invalidates ----osiated chart element. + /// + private void Invalidate() + { + if(chartElement != null) + { + if(chartElement is Series) + { + ((Series)chartElement).Invalidate(false, false); + } + + else if(chartElement is Annotation) + { + ((Annotation)chartElement).Invalidate(); + } + + } + } + + #endregion + } + + /// + /// SmartLabelStyle class implements the SmartLabelStyle algorithm for the + /// data series points. It keeps track of all labels drawn and + /// detects their collisions. When labels collision is detected + /// the algorithm tries to resolve it by repositioning the labels. + /// If label can not be repositioned it maybe hidden depending on + /// the current settings. + /// + [ + SRDescription("DescriptionAttributeSmartLabels_SmartLabels"), + ] + internal class SmartLabel + { + #region Fields + + // List of all SmartLabelStyle positions in the area + internal ArrayList smartLabelsPositions = null; + + // Indicates that not a single collision is allowed + internal bool checkAllCollisions = false; + + // Number of positions in array for the markers + internal int markersCount = 0; + + #endregion + + #region Constructors and initialization + + /// + /// Default public constructor. + /// + public SmartLabel() + { + } + + #endregion + + #region Methods + + /// + /// Reset SmartLabelStyle object. + /// + internal void Reset() + { + // Re-initialize list of labels position + smartLabelsPositions = new ArrayList(); + } + + /// + /// Process single SmartLabelStyle by adjusting it's position in case of collision. + /// + /// Reference to common elements. + /// Reference to chart graphics object. + /// Chart area. + /// Smart labels style. + /// Original label position. + /// Label text size. + /// Label string format. + /// Marker position. + /// Marker size. + /// Original label alignment. + /// Adjusted position of the label. + internal PointF AdjustSmartLabelPosition( + CommonElements common, + ChartGraphics graph, + ChartArea area, + SmartLabelStyle smartLabelStyle, + PointF labelPosition, + SizeF labelSize, + StringFormat format, + PointF markerPosition, + SizeF markerSize, + LabelAlignmentStyles labelAlignment) + { + return AdjustSmartLabelPosition( + common, + graph, + area, + smartLabelStyle, + labelPosition, + labelSize, + format, + markerPosition, + markerSize, + labelAlignment, + false); + } + + /// + /// Process single SmartLabelStyle by adjusting it's position in case of collision. + /// + /// Reference to common elements. + /// Reference to chart graphics object. + /// Chart area. + /// Smart labels style. + /// Original label position. + /// Label text size. + /// Label string format. + /// Marker position. + /// Marker size. + /// Original label alignment. + /// Indicates that labels overlapping by callout line must be checked. + /// Adjusted position of the label. + internal PointF AdjustSmartLabelPosition( + CommonElements common, + ChartGraphics graph, + ChartArea area, + SmartLabelStyle smartLabelStyle, + PointF labelPosition, + SizeF labelSize, + StringFormat format, + PointF markerPosition, + SizeF markerSize, + LabelAlignmentStyles labelAlignment, + bool checkCalloutLineOverlapping) + { + // Check if SmartLabelStyle are enabled + if(smartLabelStyle.Enabled) + { + bool labelMovedAway = false; + + // Add series markers positions to avoid their overlapping + bool rememberMarkersCount = (this.smartLabelsPositions.Count == 0); + AddMarkersPosition(common, area); + if(rememberMarkersCount) + { + this.markersCount = this.smartLabelsPositions.Count; + } + + // Check label collision + if(IsSmartLabelCollide( + common, + graph, + area, + smartLabelStyle, + labelPosition, + labelSize, + markerPosition, + format, + labelAlignment, + checkCalloutLineOverlapping)) + { + // Try to find a new position for the SmartLabelStyle + labelMovedAway = FindNewPosition( + common, + graph, + area, + smartLabelStyle, + ref labelPosition, + labelSize, + format, + markerPosition, + ref markerSize, + ref labelAlignment, + checkCalloutLineOverlapping); + + // Draw label callout if label was moved away or + // it's displayed in the corners of the marker + if(labelMovedAway || + (labelAlignment == LabelAlignmentStyles.BottomLeft || + labelAlignment == LabelAlignmentStyles.BottomRight || + labelAlignment == LabelAlignmentStyles.TopLeft || + labelAlignment == LabelAlignmentStyles.TopRight)) + { + if(!labelPosition.IsEmpty) + { + DrawCallout( + common, + graph, + area, + smartLabelStyle, + labelPosition, + labelSize, + format, + markerPosition, + markerSize, + labelAlignment); + } + } + } + + // Add label position into the list + AddSmartLabelPosition(graph, labelPosition, labelSize, format); + } + + // Return label position + return labelPosition; + } + + + /// + /// Process single SmartLabelStyle by adjusting it's position in case of collision. + /// + /// Reference to common elements. + /// Reference to chart graphics object. + /// Chart area. + /// Smart labels style. + /// Original label position. + /// Label text size. + /// Label string format. + /// Marker position. + /// Marker size. + /// Label alignment. + /// Indicates that labels overlapping by callout line must be checked. + /// True if label was moved away from the marker. + private bool FindNewPosition( + CommonElements common, + ChartGraphics graph, + ChartArea area, + SmartLabelStyle smartLabelStyle, + ref PointF labelPosition, + SizeF labelSize, + StringFormat format, + PointF markerPosition, + ref SizeF markerSize, + ref LabelAlignmentStyles labelAlignment, + bool checkCalloutLineOverlapping) + { + SizeF newMarkerSize = SizeF.Empty; + PointF newLabelPosition = PointF.Empty; + int positionIndex = 0; + float labelMovement = 0f; + bool labelMovedAway = false; + LabelAlignmentStyles[] positions = new LabelAlignmentStyles[] { + LabelAlignmentStyles.Top, + LabelAlignmentStyles.Bottom, + LabelAlignmentStyles.Left, + LabelAlignmentStyles.Right, + LabelAlignmentStyles.TopLeft, + LabelAlignmentStyles.TopRight, + LabelAlignmentStyles.BottomLeft, + LabelAlignmentStyles.BottomRight, + LabelAlignmentStyles.Center + }; + + // Get relative size of single pixel + SizeF pixelSize = graph.GetRelativeSize(new SizeF(1f, 1f)); + + // Try to find a new position for the label + bool positionFound = false; + float movingStep = 2f; + float minMove = (float)Math.Min(smartLabelStyle.MinMovingDistance, smartLabelStyle.MaxMovingDistance); + float maxMove = (float)Math.Max(smartLabelStyle.MinMovingDistance, smartLabelStyle.MaxMovingDistance); + for(labelMovement = minMove; !positionFound && labelMovement <= maxMove; labelMovement += movingStep) + { + // Move label by increasing marker size by 4 pixels + newMarkerSize = new SizeF( + markerSize.Width + labelMovement*(pixelSize.Width * 2f), + markerSize.Height + labelMovement*(pixelSize.Height * 2f)); + + // Loop through different alignment types + for(positionIndex = 0; positionIndex < positions.Length; positionIndex++) + { + // Center label alignment should only be tried once! + if(positions[positionIndex] == LabelAlignmentStyles.Center && labelMovement != minMove) + { + continue; + } + + // Check if this alignment is valid + if((smartLabelStyle.MovingDirection & positions[positionIndex]) == positions[positionIndex]) + { + // Calculate new position of the label + newLabelPosition = CalculatePosition( + positions[positionIndex], + markerPosition, + newMarkerSize, + labelSize, + ref format); + + // Check new position collision + if(!IsSmartLabelCollide( + common, + null, + area, + smartLabelStyle, + newLabelPosition, + labelSize, + markerPosition, + format, + positions[positionIndex], + checkCalloutLineOverlapping)) + { + positionFound = true; + labelMovedAway = (labelMovement == 0f) ? false : true; + break; + } + } + } + } + + // Set new data if new label position was found + if(positionFound) + { + markerSize = newMarkerSize; + labelPosition = newLabelPosition; + labelAlignment = positions[positionIndex]; + } + + // DEBUG code +#if DEBUG + if(common.Chart.ShowDebugMarkings) + { + RectangleF lp = GetLabelPosition(graph, labelPosition, labelSize, format, false); + if(positionFound) + { + graph.Graphics.DrawRectangle(Pens.Green, Rectangle.Round(graph.GetAbsoluteRectangle(lp))); + } + else + { + graph.Graphics.DrawRectangle(new Pen(Color.Magenta, 3), Rectangle.Round(graph.GetAbsoluteRectangle(lp))); + } + } +#endif + // Do not draw overlapped labels that can't be repositioned + if(!positionFound && smartLabelStyle.IsOverlappedHidden) + { + labelPosition = PointF.Empty; + } + + + return (labelMovedAway && positionFound) ? true : false; + } + + /// + /// Process single SmartLabelStyle by adjusting it's position in case of collision. + /// + /// Reference to common elements. + /// Reference to chart graphics object. + /// Chart area. + /// Smart labels style. + /// Original label position. + /// Label text size. + /// Label string format. + /// Marker position. + /// Marker size. + /// Label alignment. + /// Adjusted position of the label. + virtual internal void DrawCallout( + CommonElements common, + ChartGraphics graph, + ChartArea area, + SmartLabelStyle smartLabelStyle, + PointF labelPosition, + SizeF labelSize, + StringFormat format, + PointF markerPosition, + SizeF markerSize, + LabelAlignmentStyles labelAlignment) + { + // Calculate label position rectangle + RectangleF labelRectAbs = graph.GetAbsoluteRectangle( + GetLabelPosition(graph, labelPosition, labelSize, format, true)); + + // Create callout pen + Pen calloutPen = new Pen(smartLabelStyle.CalloutLineColor, smartLabelStyle.CalloutLineWidth); + calloutPen.DashStyle = graph.GetPenStyle(smartLabelStyle.CalloutLineDashStyle); + + // Draw callout frame + if(smartLabelStyle.CalloutStyle == LabelCalloutStyle.Box) + { + // Fill callout box around the label + if(smartLabelStyle.CalloutBackColor != Color.Transparent) + { + using (Brush calloutBrush = new SolidBrush(smartLabelStyle.CalloutBackColor)) + { + graph.FillRectangle(calloutBrush, labelRectAbs); + } + } + + // Draw box border + graph.DrawRectangle(calloutPen, labelRectAbs.X, labelRectAbs.Y, labelRectAbs.Width, labelRectAbs.Height); + } + + else if(smartLabelStyle.CalloutStyle == LabelCalloutStyle.Underlined) + { + if(labelAlignment == LabelAlignmentStyles.Right) + { + // Draw line to the left of label's text + graph.DrawLine(calloutPen, labelRectAbs.X, labelRectAbs.Top, labelRectAbs.X, labelRectAbs.Bottom); + } + else if(labelAlignment == LabelAlignmentStyles.Left) + { + // Draw line to the right of label's text + graph.DrawLine(calloutPen, labelRectAbs.Right, labelRectAbs.Top, labelRectAbs.Right, labelRectAbs.Bottom); + } + else if(labelAlignment == LabelAlignmentStyles.Bottom) + { + // Draw line on top of the label's text + graph.DrawLine(calloutPen, labelRectAbs.X, labelRectAbs.Top, labelRectAbs.Right, labelRectAbs.Top); + } + else + { + // Draw line under the label's text + graph.DrawLine(calloutPen, labelRectAbs.X, labelRectAbs.Bottom, labelRectAbs.Right, labelRectAbs.Bottom); + } + } + + // Calculate connector line point on the label + PointF connectorPosition = graph.GetAbsolutePoint(labelPosition); + if(labelAlignment == LabelAlignmentStyles.Top) + { + connectorPosition.Y = labelRectAbs.Bottom; + } + else if(labelAlignment == LabelAlignmentStyles.Bottom) + { + connectorPosition.Y = labelRectAbs.Top; + } + + if(smartLabelStyle.CalloutStyle == LabelCalloutStyle.Underlined) + { + if(labelAlignment == LabelAlignmentStyles.TopLeft || + labelAlignment == LabelAlignmentStyles.TopRight || + labelAlignment == LabelAlignmentStyles.BottomLeft || + labelAlignment == LabelAlignmentStyles.BottomRight) + { + connectorPosition.Y = labelRectAbs.Bottom; + } + } + + // Apply anchor cap settings + if(smartLabelStyle.CalloutLineAnchorCapStyle == LineAnchorCapStyle.Arrow) + { + //calloutPen.StartCap = LineCap.ArrowAnchor; + calloutPen.StartCap = LineCap.Custom; + calloutPen.CustomStartCap = new AdjustableArrowCap(calloutPen.Width + 2, calloutPen.Width + 3, true); + } + else if(smartLabelStyle.CalloutLineAnchorCapStyle == LineAnchorCapStyle.Diamond) + { + calloutPen.StartCap = LineCap.DiamondAnchor; + } + else if(smartLabelStyle.CalloutLineAnchorCapStyle == LineAnchorCapStyle.Round) + { + calloutPen.StartCap = LineCap.RoundAnchor; + } + else if(smartLabelStyle.CalloutLineAnchorCapStyle == LineAnchorCapStyle.Square) + { + calloutPen.StartCap = LineCap.SquareAnchor; + } + + // Draw connection line between marker position and label + PointF markerPositionAbs = graph.GetAbsolutePoint(markerPosition); + graph.DrawLine( + calloutPen, + markerPositionAbs.X, + markerPositionAbs.Y, + connectorPosition.X, + connectorPosition.Y); + } + + /// + /// Checks SmartLabelStyle collision. + /// + /// Reference to common elements. + /// Reference to chart graphics object. + /// Chart area. + /// Smart labels style. + /// Original label position. + /// Label text size. + /// Marker position. + /// Label string format. + /// Label alignment. + /// Indicates that labels overlapping by callout line must be checked. + /// True if label collides. + virtual internal bool IsSmartLabelCollide( + CommonElements common, + ChartGraphics graph, + ChartArea area, + SmartLabelStyle smartLabelStyle, + PointF position, + SizeF size, + PointF markerPosition, + StringFormat format, + LabelAlignmentStyles labelAlignment, + bool checkCalloutLineOverlapping) + { + bool collisionDetected = false; + + // Calculate label position rectangle + RectangleF labelPosition = GetLabelPosition(graph, position, size, format, false); + + // Check if label goes outside of the chart picture + if(labelPosition.X < 0f || labelPosition.Y < 0f || + labelPosition.Bottom > 100f || labelPosition.Right > 100f) + { +#if DEBUG + // DEBUG: Mark collided labels + if (graph != null && common!=null && common.Chart!=null && common.Chart.ShowDebugMarkings) + { + graph.Graphics.DrawRectangle(Pens.Cyan, Rectangle.Round(graph.GetAbsoluteRectangle(labelPosition))); + } +#endif + collisionDetected = true; + } + + + // Check if label is drawn outside of plotting area (collides with axis?). + if(!collisionDetected && area != null) + { + if(area.chartAreaIsCurcular) + { + using( GraphicsPath areaPath = new GraphicsPath() ) + { + // Add circular shape of the area into the graphics path + areaPath.AddEllipse(area.PlotAreaPosition.ToRectangleF()); + + if(smartLabelStyle.AllowOutsidePlotArea == LabelOutsidePlotAreaStyle.Partial) + { + PointF centerPos = new PointF( + labelPosition.X + labelPosition.Width/2f, + labelPosition.Y + labelPosition.Height/2f); + if(!areaPath.IsVisible(centerPos)) + { + // DEBUG: Mark collided labels +#if DEBUG + if(graph != null && common.Chart.ShowDebugMarkings) + { + graph.Graphics.DrawRectangle(Pens.Cyan, Rectangle.Round(graph.GetAbsoluteRectangle(labelPosition))); + } +#endif + collisionDetected = true; + } + } + else if(smartLabelStyle.AllowOutsidePlotArea == LabelOutsidePlotAreaStyle.No) + { + if(!areaPath.IsVisible(labelPosition.Location) || + !areaPath.IsVisible(new PointF(labelPosition.Right, labelPosition.Y)) || + !areaPath.IsVisible(new PointF(labelPosition.Right, labelPosition.Bottom)) || + !areaPath.IsVisible(new PointF(labelPosition.X, labelPosition.Bottom)) ) + { + // DEBUG: Mark collided labels +#if DEBUG + if(graph != null && common.Chart.ShowDebugMarkings) + { + graph.Graphics.DrawRectangle(Pens.Cyan, Rectangle.Round(graph.GetAbsoluteRectangle(labelPosition))); + } +#endif + collisionDetected = true; + } + } + } + } + else + { + if(smartLabelStyle.AllowOutsidePlotArea == LabelOutsidePlotAreaStyle.Partial) + { + PointF centerPos = new PointF( + labelPosition.X + labelPosition.Width/2f, + labelPosition.Y + labelPosition.Height/2f); + if(!area.PlotAreaPosition.ToRectangleF().Contains(centerPos)) + { + // DEBUG: Mark collided labels +#if DEBUG + if(graph != null && common.Chart.ShowDebugMarkings) + { + graph.Graphics.DrawRectangle(Pens.Cyan, Rectangle.Round(graph.GetAbsoluteRectangle(labelPosition))); + } +#endif + collisionDetected = true; + } + } + else if(smartLabelStyle.AllowOutsidePlotArea == LabelOutsidePlotAreaStyle.No) + { + if(!area.PlotAreaPosition.ToRectangleF().Contains(labelPosition)) + { + // DEBUG: Mark collided labels +#if DEBUG + if(graph != null && common.Chart.ShowDebugMarkings) + { + graph.Graphics.DrawRectangle(Pens.Cyan, Rectangle.Round(graph.GetAbsoluteRectangle(labelPosition))); + } +#endif + collisionDetected = true; + } + } + } + } + + // Check if 1 collisuion is aceptable in case of cennter alignment + bool allowOneCollision = + (labelAlignment == LabelAlignmentStyles.Center && !smartLabelStyle.IsMarkerOverlappingAllowed) ? true : false; + if(this.checkAllCollisions) + { + allowOneCollision = false; + } + + + // Loop through all smart label positions + if(!collisionDetected && this.smartLabelsPositions != null) + { + int index = -1; + foreach(RectangleF pos in this.smartLabelsPositions) + { + // Increase index + ++index; + + // Check if label collide with other labels or markers. + bool collision = pos.IntersectsWith(labelPosition); + + // Check if label callout line collide with other labels or markers. + // Line may overlap markers! + if(!collision && + checkCalloutLineOverlapping && + index >= markersCount) + { + PointF labelCenter = new PointF( + labelPosition.X + labelPosition.Width / 2f, + labelPosition.Y + labelPosition.Height / 2f); + if(LineIntersectRectangle(pos, markerPosition, labelCenter)) + { + collision = true; + } + } + + // Collision detected + if(collision) + { + // Check if 1 collision allowed + if(allowOneCollision) + { + allowOneCollision = false; + continue; + } + + // DEBUG: Mark collided labels +#if DEBUG + if(graph != null && + common.ChartPicture != null && + common.ChartPicture.ChartGraph != null && + common.Chart.ShowDebugMarkings) + { + common.ChartPicture.ChartGraph.Graphics.DrawRectangle(Pens.Blue, Rectangle.Round(common.ChartPicture.ChartGraph.GetAbsoluteRectangle(pos))); + common.ChartPicture.ChartGraph.Graphics.DrawRectangle(Pens.Red, Rectangle.Round(common.ChartPicture.ChartGraph.GetAbsoluteRectangle(labelPosition))); + } +#endif + collisionDetected = true; + break; + } + } + } + + return collisionDetected; + } + + /// + /// Checks if rectangle intersected by the line. + /// + /// Rectangle to be tested. + /// First line point. + /// Second line point. + /// True if line intersects rectangle. + private bool LineIntersectRectangle(RectangleF rect, PointF point1, PointF point2) + { + // Check for horizontal line + if(point1.X == point2.X) + { + if(point1.X >= rect.X && point1.X <= rect.Right) + { + if(point1.Y < rect.Y && point2.Y < rect.Y) + { + return false; + } + if(point1.Y > rect.Bottom && point2.Y > rect.Bottom) + { + return false; + } + return true; + } + return false; + } + + // Check for vertical line + if(point1.Y == point2.Y) + { + if(point1.Y >= rect.Y && point1.Y <= rect.Bottom) + { + if(point1.X < rect.X && point2.X < rect.X) + { + return false; + } + if(point1.X > rect.Right && point2.X > rect.Right) + { + return false; + } + return true; + } + return false; + + } + + // Check if line completly outside rectangle + if(point1.X < rect.X && point2.X < rect.X) + { + return false; + } + else if(point1.X > rect.Right && point2.X > rect.Right) + { + return false; + } + else if(point1.Y < rect.Y && point2.Y < rect.Y) + { + return false; + } + else if(point1.Y > rect.Bottom && point2.Y > rect.Bottom) + { + return false; + } + + // Check if one of the points inside rectangle + if( rect.Contains(point1) || + rect.Contains(point2) ) + { + return true; + } + + // Calculate intersection point of the line with each side of the rectangle + PointF intersection = CalloutAnnotation.GetIntersectionY(point1, point2, rect.Y); + if( rect.Contains(intersection)) + { + return true; + } + intersection = CalloutAnnotation.GetIntersectionY(point1, point2, rect.Bottom); + if( rect.Contains(intersection)) + { + return true; + } + intersection = CalloutAnnotation.GetIntersectionX(point1, point2, rect.X); + if( rect.Contains(intersection)) + { + return true; + } + intersection = CalloutAnnotation.GetIntersectionX(point1, point2, rect.Right); + if( rect.Contains(intersection)) + { + return true; + } + + return false; + } + + /// + /// Adds positions of the series markers into the list. + /// + /// Reference to common elements. + /// Chart area. + virtual internal void AddMarkersPosition( + CommonElements common, + ChartArea area) + { + // Proceed only if there is no items in the list yet + if(this.smartLabelsPositions.Count == 0 && area != null) + { + // Get chart types registry + ChartTypeRegistry registry = common.ChartTypeRegistry; + + // Loop through all the series from this chart area + foreach(Series series in common.DataManager.Series) + { + // Check if marker overapping is enabled for the series + if(series.ChartArea == area.Name && + series.SmartLabelStyle.Enabled && + !series.SmartLabelStyle.IsMarkerOverlappingAllowed) + { + // Get series chart type + IChartType chartType = registry.GetChartType(series.ChartTypeName); + + // Add series markers positions into the list + chartType.AddSmartLabelMarkerPositions(common, area, series, this.smartLabelsPositions); + } + } + + + + // Make sure labels do not intersect with scale breaks + foreach(Axis currentAxis in area.Axes) + { + // Check if scale breaks are defined and there are non zero spacing + if(currentAxis.ScaleBreakStyle.Spacing > 0.0 + && currentAxis.ScaleSegments.Count > 0) + { + for(int index = 0; index < (currentAxis.ScaleSegments.Count - 1); index++) + { + // Get break position in pixel coordinates + RectangleF breakPosition = currentAxis.ScaleSegments[index].GetBreakLinePosition(common.graph, currentAxis.ScaleSegments[index + 1]); + breakPosition = common.graph.GetRelativeRectangle(breakPosition); + + // Create array list if needed + if(this.smartLabelsPositions == null) + { + this.smartLabelsPositions = new ArrayList(); + } + + // Add label position into the list + this.smartLabelsPositions.Add(breakPosition); + + } + } + } + + + } + } + + /// + /// Adds single Smart Label position into the list. + /// + /// Chart graphics object. + /// Original label position. + /// Label text size. + /// Label string format. + internal void AddSmartLabelPosition( + ChartGraphics graph, + PointF position, + SizeF size, + StringFormat format) + { + // Calculate label position rectangle + RectangleF labelPosition = GetLabelPosition(graph, position, size, format, false); + + if(this.smartLabelsPositions == null) + { + this.smartLabelsPositions = new ArrayList(); + } + + // Add label position into the list + this.smartLabelsPositions.Add(labelPosition); + } + + /// + /// Gets rectangle position of the label. + /// + /// Chart graphics object. + /// Original label position. + /// Label text size. + /// Label string format. + /// Result position is adjusted for drawing. + /// Label rectangle position. + internal RectangleF GetLabelPosition( + ChartGraphics graph, + PointF position, + SizeF size, + StringFormat format, + bool adjustForDrawing) + { + // Calculate label position rectangle + RectangleF labelPosition = RectangleF.Empty; + labelPosition.Width = size.Width; + labelPosition.Height = size.Height; + + // Calculate pixel size in relative coordiantes + SizeF pixelSize = SizeF.Empty; + if(graph != null) + { + pixelSize = graph.GetRelativeSize(new SizeF(1f, 1f)); + } + + if(format.Alignment == StringAlignment.Far) + { + labelPosition.X = position.X - size.Width; + if(adjustForDrawing && !pixelSize.IsEmpty) + { + labelPosition.X -= 4f*pixelSize.Width; + labelPosition.Width += 4f*pixelSize.Width; + } + } + else if(format.Alignment == StringAlignment.Near) + { + labelPosition.X = position.X; + if(adjustForDrawing && !pixelSize.IsEmpty) + { + labelPosition.Width += 4f*pixelSize.Width; + } + } + else if(format.Alignment == StringAlignment.Center) + { + labelPosition.X = position.X - size.Width/2F; + if(adjustForDrawing && !pixelSize.IsEmpty) + { + labelPosition.X -= 2f*pixelSize.Width; + labelPosition.Width += 4f*pixelSize.Width; + } + } + + if(format.LineAlignment == StringAlignment.Far) + { + labelPosition.Y = position.Y - size.Height; + } + else if(format.LineAlignment == StringAlignment.Near) + { + labelPosition.Y = position.Y; + } + else if(format.LineAlignment == StringAlignment.Center) + { + labelPosition.Y = position.Y - size.Height/2F; + } + + return labelPosition; + } + + /// + /// Gets point position of the label. + /// + /// Label alignment. + /// Marker position. + /// Marker size. + /// Label size. + /// String format. + /// Label point position. + private PointF CalculatePosition( + LabelAlignmentStyles labelAlignment, + PointF markerPosition, + SizeF sizeMarker, + SizeF sizeFont, + ref StringFormat format) + { + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + + // Calculate label position + PointF position = new PointF(markerPosition.X, markerPosition.Y); + switch(labelAlignment) + { + case LabelAlignmentStyles.Center: + format.Alignment = StringAlignment.Center; + break; + case LabelAlignmentStyles.Bottom: + format.Alignment = StringAlignment.Center; + position.Y += sizeMarker.Height / 1.75F; + position.Y += sizeFont.Height/ 2F; + break; + case LabelAlignmentStyles.Top: + format.Alignment = StringAlignment.Center; + position.Y -= sizeMarker.Height / 1.75F; + position.Y -= sizeFont.Height/ 2F; + break; + case LabelAlignmentStyles.Left: + format.Alignment = StringAlignment.Far; + position.X -= sizeMarker.Height / 1.75F; + break; + case LabelAlignmentStyles.TopLeft: + format.Alignment = StringAlignment.Far; + position.X -= sizeMarker.Height / 1.75F; + position.Y -= sizeMarker.Height / 1.75F; + position.Y -= sizeFont.Height/ 2F; + break; + case LabelAlignmentStyles.BottomLeft: + format.Alignment = StringAlignment.Far; + position.X -= sizeMarker.Height / 1.75F; + position.Y += sizeMarker.Height / 1.75F; + position.Y += sizeFont.Height/ 2F; + break; + case LabelAlignmentStyles.Right: + position.X += sizeMarker.Height / 1.75F; + break; + case LabelAlignmentStyles.TopRight: + position.X += sizeMarker.Height / 1.75F; + position.Y -= sizeMarker.Height / 1.75F; + position.Y -= sizeFont.Height/ 2F; + break; + case LabelAlignmentStyles.BottomRight: + position.X += sizeMarker.Height / 1.75F; + position.Y += sizeMarker.Height / 1.75F; + position.Y += sizeFont.Height/ 2F; + break; + } + + return position; + } + + #endregion + } + + /// + /// AnnotationSmartLabel class provides SmartLabelStyle functionality + /// specific to the annotation objects. + /// + [ + SRDescription("DescriptionAttributeAnnotationSmartLabels_AnnotationSmartLabels"), + ] + internal class AnnotationSmartLabel : SmartLabel + { + #region Constructors and initialization + + /// + /// Default public constructor. + /// + public AnnotationSmartLabel() + { + } + + #endregion + + #region Methods + + /// + /// Checks SmartLabelStyle collision. + /// + /// Reference to common elements. + /// Reference to chart graphics object. + /// Chart area. + /// Smart labels style. + /// Original label position. + /// Label text size. + /// Marker position. + /// Label string format. + /// Label alignment. + /// Indicates that labels overlapping by callout line must be checked. + /// True if label collides. + override internal bool IsSmartLabelCollide( + CommonElements common, + ChartGraphics graph, + ChartArea area, + SmartLabelStyle smartLabelStyle, + PointF position, + SizeF size, + PointF markerPosition, + StringFormat format, + LabelAlignmentStyles labelAlignment, + bool checkCalloutLineOverlapping) + { + bool collisionDetected = false; + + //******************************************************************* + //** Check collision with smatl labels of series in chart area + //******************************************************************* + if (area != null && area.Visible) + { + area.smartLabels.checkAllCollisions = true; + if (area.smartLabels.IsSmartLabelCollide( + common, + graph, + area, + smartLabelStyle, + position, + size, + markerPosition, + format, + labelAlignment, + checkCalloutLineOverlapping) ) + { + area.smartLabels.checkAllCollisions = false; + return true; + } + area.smartLabels.checkAllCollisions = false; + } + + //******************************************************************* + //** Check collision with other annotations. + //******************************************************************* + + // Calculate label position rectangle + RectangleF labelPosition = GetLabelPosition(graph, position, size, format, false); + + // Check if 1 collisuion is aceptable in case of cennter alignment + bool allowOneCollision = + (labelAlignment == LabelAlignmentStyles.Center && !smartLabelStyle.IsMarkerOverlappingAllowed) ? true : false; + if(this.checkAllCollisions) + { + allowOneCollision = false; + } + + // Check if label collide with other labels or markers. + foreach(RectangleF pos in this.smartLabelsPositions) + { + if(pos.IntersectsWith(labelPosition)) + { + // Check if 1 collision allowed + if(allowOneCollision) + { + allowOneCollision = false; + continue; + } + + // DEBUG: Mark collided labels +#if DEBUG + if(graph != null && common.Chart.ShowDebugMarkings) + { + graph.Graphics.DrawRectangle(Pens.Blue, Rectangle.Round(graph.GetAbsoluteRectangle(pos))); + graph.Graphics.DrawRectangle(Pens.Red, Rectangle.Round(graph.GetAbsoluteRectangle(labelPosition))); + } +#endif + collisionDetected = true; + break; + } + } + + return collisionDetected; + } + + /// + /// Adds positions of the series markers into the list. + /// + /// Reference to common elements. + /// Chart area. + override internal void AddMarkersPosition( + CommonElements common, + ChartArea area) + { + // Proceed only if there is no items in the list yet + if(this.smartLabelsPositions.Count == 0 && + common != null && + common.Chart != null) + { + // Add annotations anchor points + foreach(Annotation annotation in common.Chart.Annotations) + { + annotation.AddSmartLabelMarkerPositions(this.smartLabelsPositions); + } + } + } + + /// + /// Process single SmartLabelStyle by adjusting it's position in case of collision. + /// + /// Reference to common elements. + /// Reference to chart graphics object. + /// Chart area. + /// Smart labels style. + /// Original label position. + /// Label text size. + /// Label string format. + /// Marker position. + /// Marker size. + /// Label alignment. + /// Adjusted position of the label. + override internal void DrawCallout( + CommonElements common, + ChartGraphics graph, + ChartArea area, + SmartLabelStyle smartLabelStyle, + PointF labelPosition, + SizeF labelSize, + StringFormat format, + PointF markerPosition, + SizeF markerSize, + LabelAlignmentStyles labelAlignment) + { + // No callout is drawn for the annotations + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/Statistics.cs b/System.Web.DataVisualization/Common/General/Statistics.cs new file mode 100644 index 000000000..2f5461831 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/Statistics.cs @@ -0,0 +1,1671 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: StatisticFormula.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: StatisticFormula, TTestResult, FTestResult, AnovaResult, +// ZTestResult +// +// Purpose: StatisticFormula class provides helper methods for statistical +// calculations like TTest, FTest, Anova, ZTest and others. +// Actual calculations are made in the DataFormula class and +// the StatisticFormula class mange formula parameters, input and +// output series. +// +// TTestResult, FTestResult, AnovaResult and ZTestResult +// classes are used to store the results of the calculatiions. +// +// StatisticFormula class is exposed to the user through +// DataManipulator.StatisticFormula property. Here is an example of +// using the Anova test: +// +// AnovaResult result = Chart1.DataManipulator.StatisticFormula.Anova(0.6, "Group1,Group2,Group3"); +// +// NOTE: First versions of the chart use single method to execute +// ALL formulas. Formula name and parameters were passed as +// strings. Input and outpat data was passed through data +// series. +// +// This approach was hard to use by the end-user and was +// changed to a specific method for each formula. StatisticFormula +// class provides that simplified interface for all statistics +// formulas. Internally it still uses the DataFormula.Formula +// method with string parameters. +// +// Reviewed: AG - April 1, 2003 +// AG - Microsoft 14, 2007 +// +//=================================================================== + +using System; +using System.Diagnostics.CodeAnalysis; + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// The StatisticFormula class provides helper methods for statistical calculations. + /// Actual calculations are made in the DataFormula class and the StatisticFormula + /// class provide a simplified API which automatically prepares parameters and + /// deals with input and output series. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class StatisticFormula + { + #region Fields + + // Name used for temporary data series + private string _tempOutputSeriesName = "Statistical Analyses Formula Temporary Output Series 2552003"; + + // Reference to the class which describes calculation settings and + // provides access to chart common elements. + private DataFormula _formulaData = null; + + #endregion // Fields + + #region Constructor + + /// + /// StatisticFormula Constructor + /// + /// Formula Data + internal StatisticFormula( DataFormula formulaData ) + { + this._formulaData = formulaData; + } + + #endregion // Constructor + + #region Tests + + /// + /// This formula performs a Z Test using Normal distribution. + /// + /// Hypothesized mean difference. + /// Variance first group. + /// Variance second group. + /// Probability. + /// First input series name. + /// Second input series name. + /// ZTestResult object. + public ZTestResult ZTest( + double hypothesizedMeanDifference, + double varianceFirstGroup, + double varianceSecondGroup, + double probability, + string firstInputSeriesName, + string secondInputSeriesName ) + { + // Check arguments + if (firstInputSeriesName == null) + throw new ArgumentNullException("firstInputSeriesName"); + if (secondInputSeriesName == null) + throw new ArgumentNullException("secondInputSeriesName"); + + // Create output class + ZTestResult zTestResult = new ZTestResult(); + + // Make string with parameters + string parameter = hypothesizedMeanDifference.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + varianceFirstGroup.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + varianceSecondGroup.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + probability.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Set input series string + string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Execute formula + try + { + _formulaData.Formula("ZTest", parameter, inputSeriesParameter, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + zTestResult.firstSeriesMean = points[0].YValues[0]; + zTestResult.secondSeriesMean = points[1].YValues[0]; + zTestResult.firstSeriesVariance = points[2].YValues[0]; + zTestResult.secondSeriesVariance = points[3].YValues[0]; + zTestResult.zValue = points[4].YValues[0]; + zTestResult.probabilityZOneTail = points[5].YValues[0]; + zTestResult.zCriticalValueOneTail = points[6].YValues[0]; + zTestResult.probabilityZTwoTail = points[7].YValues[0]; + zTestResult.zCriticalValueTwoTail = points[8].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return zTestResult; + + } + + /// + /// Perform a T Test using Students distribution (T distribution) with unequal variances. + /// + /// Hypothesized mean difference. + /// Probability. + /// First input series name. + /// Second input series name. + /// TTestResult object. + public TTestResult TTestUnequalVariances( + double hypothesizedMeanDifference, + double probability, + string firstInputSeriesName, + string secondInputSeriesName ) + { + // Check arguments + if (firstInputSeriesName == null) + throw new ArgumentNullException("firstInputSeriesName"); + if (secondInputSeriesName == null) + throw new ArgumentNullException("secondInputSeriesName"); + + // Create output class + TTestResult tTestResult = new TTestResult(); + + // Make string with parameters + string parameter = hypothesizedMeanDifference.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + probability.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Set input series string + try + { + string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Execute formula + _formulaData.Formula("TTestUnequalVariances", parameter, inputSeriesParameter, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + tTestResult.firstSeriesMean = points[0].YValues[0]; + tTestResult.secondSeriesMean = points[1].YValues[0]; + tTestResult.firstSeriesVariance = points[2].YValues[0]; + tTestResult.secondSeriesVariance = points[3].YValues[0]; + tTestResult.tValue = points[4].YValues[0]; + tTestResult.degreeOfFreedom = points[5].YValues[0]; + tTestResult.probabilityTOneTail = points[6].YValues[0]; + tTestResult.tCriticalValueOneTail = points[7].YValues[0]; + tTestResult.probabilityTTwoTail = points[8].YValues[0]; + tTestResult.tCriticalValueTwoTail = points[9].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return tTestResult; + + } + + /// + /// Perform a T Test using Students distribution (T distribution) with equal variances. + /// + /// Hypothesized mean difference. + /// Probability. + /// First input series name. + /// Second input series name. + /// TTestResult object. + public TTestResult TTestEqualVariances( + double hypothesizedMeanDifference, + double probability, + string firstInputSeriesName, + string secondInputSeriesName ) + { + // Check arguments + if (firstInputSeriesName == null) + throw new ArgumentNullException("firstInputSeriesName"); + if (secondInputSeriesName == null) + throw new ArgumentNullException("secondInputSeriesName"); + + // Create output class + TTestResult tTestResult = new TTestResult(); + + // Make string with parameters + string parameter = hypothesizedMeanDifference.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + probability.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Set input series string + string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Execute formula + try + { + _formulaData.Formula("TTestEqualVariances", parameter, inputSeriesParameter, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + tTestResult.firstSeriesMean = points[0].YValues[0]; + tTestResult.secondSeriesMean = points[1].YValues[0]; + tTestResult.firstSeriesVariance = points[2].YValues[0]; + tTestResult.secondSeriesVariance = points[3].YValues[0]; + tTestResult.tValue = points[4].YValues[0]; + tTestResult.degreeOfFreedom = points[5].YValues[0]; + tTestResult.probabilityTOneTail = points[6].YValues[0]; + tTestResult.tCriticalValueOneTail = points[7].YValues[0]; + tTestResult.probabilityTTwoTail = points[8].YValues[0]; + tTestResult.tCriticalValueTwoTail = points[9].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return tTestResult; + } + + /// + /// Performs a T Test using Students distribution (T distribution) with paired samples. + /// This is useful when there is a natural pairing of observations in samples. + /// + /// Hypothesized mean difference. + /// Probability. + /// First input series name. + /// Second input series name. + /// TTestResult object. + public TTestResult TTestPaired( + double hypothesizedMeanDifference, + double probability, + string firstInputSeriesName, + string secondInputSeriesName ) + { + // Check arguments + if (firstInputSeriesName == null) + throw new ArgumentNullException("firstInputSeriesName"); + if (secondInputSeriesName == null) + throw new ArgumentNullException("secondInputSeriesName"); + + // Create output class + TTestResult tTestResult = new TTestResult(); + + // Make string with parameters + string parameter = hypothesizedMeanDifference.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + probability.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Set input series string + string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Execute formula + try + { + _formulaData.Formula("TTestPaired", parameter, inputSeriesParameter, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + tTestResult.firstSeriesMean = points[0].YValues[0]; + tTestResult.secondSeriesMean = points[1].YValues[0]; + tTestResult.firstSeriesVariance = points[2].YValues[0]; + tTestResult.secondSeriesVariance = points[3].YValues[0]; + tTestResult.tValue = points[4].YValues[0]; + tTestResult.degreeOfFreedom = points[5].YValues[0]; + tTestResult.probabilityTOneTail = points[6].YValues[0]; + tTestResult.tCriticalValueOneTail = points[7].YValues[0]; + tTestResult.probabilityTTwoTail = points[8].YValues[0]; + tTestResult.tCriticalValueTwoTail = points[9].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return tTestResult; + + } + + /// + /// Removes empty points from series. + /// + /// series name + private void RemoveEmptyPoints(string seriesName) + { + Series series = _formulaData.Common.DataManager.Series[seriesName]; + for (int pointIndex = 0; pointIndex < series.Points.Count; pointIndex++) + { + if (series.Points[pointIndex].IsEmpty) + { + series.Points.RemoveAt(pointIndex--); + } + } + } + + /// + /// This formula performs a two-sample F Test using the F distribution, and is used to see if the samples have different variances. + /// + /// Probability. + /// First input series name. + /// Second input series name. + /// FTestResult object. + public FTestResult FTest( + double probability, + string firstInputSeriesName, + string secondInputSeriesName ) + { + // Check arguments + if (firstInputSeriesName == null) + throw new ArgumentNullException("firstInputSeriesName"); + if (secondInputSeriesName == null) + throw new ArgumentNullException("secondInputSeriesName"); + + // Create output class + FTestResult fTestResult = new FTestResult(); + + // Make string with parameters + string parameter = probability.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Set input series string + string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + + // remove empty points from the collection. + RemoveEmptyPoints(firstInputSeriesName); + RemoveEmptyPoints(secondInputSeriesName); + + // Execute formula + try + { + _formulaData.Formula("FTest", parameter, inputSeriesParameter, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + fTestResult.firstSeriesMean = points[0].YValues[0]; + fTestResult.secondSeriesMean = points[1].YValues[0]; + fTestResult.firstSeriesVariance = points[2].YValues[0]; + fTestResult.secondSeriesVariance = points[3].YValues[0]; + fTestResult.fValue = points[4].YValues[0]; + fTestResult.probabilityFOneTail = points[5].YValues[0]; + fTestResult.fCriticalValueOneTail = points[6].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return fTestResult; + + } + + + /// + /// An Anova test is used to determine the existence, or absence of a statistically + /// significant difference between the mean values of two or more groups of data. + /// + /// Probability. + /// Comma-delimited list of input series names. + /// AnovaResult object. + public AnovaResult Anova( + double probability, + string inputSeriesNames) + { + // Check arguments + if (inputSeriesNames == null) + throw new ArgumentNullException("inputSeriesNames"); + + // Create output class + AnovaResult anovaResult = new AnovaResult(); + + // Make string with parameters + string parameter = probability.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Execute formula + try + { + _formulaData.Formula("Anova", parameter, inputSeriesNames, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + anovaResult.sumOfSquaresBetweenGroups = points[0].YValues[0]; + anovaResult.sumOfSquaresWithinGroups = points[1].YValues[0]; + anovaResult.sumOfSquaresTotal = points[2].YValues[0]; + anovaResult.degreeOfFreedomBetweenGroups = points[3].YValues[0]; + anovaResult.degreeOfFreedomWithinGroups = points[4].YValues[0]; + anovaResult.degreeOfFreedomTotal = points[5].YValues[0]; + anovaResult.meanSquareVarianceBetweenGroups = points[6].YValues[0]; + anovaResult.meanSquareVarianceWithinGroups = points[7].YValues[0]; + anovaResult.fRatio = points[8].YValues[0]; + anovaResult.fCriticalValue = points[9].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return anovaResult; + } + + #endregion // Test + + #region Distributions + + /// + /// This method returns the probability for the standard normal cumulative distribution function. + /// + /// The Z value for which the probability is required. + /// Returns value from the standard normal cumulative distribution function. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "Z is a cartesian coordinate and well understood")] + public double NormalDistribution(double zValue) + { + // Make string with parameters + string parameter = zValue.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("NormalDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return result; + + } + + /// + /// This method returns the inverse of the standard normal cumulative distribution. + /// + /// Probability. + /// Returns value from the inverse standard normal cumulative distribution function. + public double InverseNormalDistribution( double probability ) + { + + // Make string with parameters + string parameter = probability.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("InverseNormalDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return result; + } + + /// + /// This method returns the cumulative F distribution function probability. + /// + /// F Value. + /// First degree of freedom. + /// Second degree of freedom. + /// Returns value from the cumulative F distribution function. + public double FDistribution( + double value, + int firstDegreeOfFreedom, + int secondDegreeOfFreedom ) + { + + // Make string with parameters + string parameter = value.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + firstDegreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + secondDegreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("FDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return result; + } + + /// + /// Returns the inverse of the F cumulative distribution. + /// + /// Probability. + /// First degree of freedom. + /// Second degree of freedom. + /// Returns value from the inverse F distribution function. + public double InverseFDistribution( + double probability, + int firstDegreeOfFreedom, + int secondDegreeOfFreedom ) + { + + // Make string with parameters + string parameter = probability.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + firstDegreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + secondDegreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("InverseFDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return result; + } + + /// + /// Returns the probability for the T distribution (student's distribution). + /// + /// T value + /// Degree of freedom + /// If true, one-tailed distribution is used; otherwise two-tailed distribution is used. + /// Returns T Distribution cumulative function + public double TDistribution( + double value, + int degreeOfFreedom, + bool oneTail ) + { + + // Make string with parameters + string parameter = value.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + degreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture); + if( oneTail ) + { + parameter += ",1"; + } + else + { + parameter += ",2"; + } + + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("TDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return result; + + } + + /// + /// Returns the T-value of the T distribution as a function of probability and degrees of freedom. + /// + /// Probability. + /// Degree of freedom. + /// Returns Inverse T distribution. + public double InverseTDistribution( + double probability, + int degreeOfFreedom ) + { + + // Make string with parameters + string parameter = probability.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + degreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("InverseTDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output class + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result class + return result; + + } + + #endregion // Distributions + + #region Correlation and Covariance + + /// + /// This method gets the covariance value for two series of data. + /// + /// First input series name. + /// Second input series name. + /// Covariance. + public double Covariance( + string firstInputSeriesName, + string secondInputSeriesName ) + { + // Check arguments + if (firstInputSeriesName == null) + throw new ArgumentNullException("firstInputSeriesName"); + if (secondInputSeriesName == null) + throw new ArgumentNullException("secondInputSeriesName"); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Set input series string + string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("Covariance", "", inputSeriesParameter, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output value + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result + return result; + + } + + /// + /// This method gets the correlation value for two series of data. + /// + /// First input series name. + /// Second input series name. + /// Returns Correlation + public double Correlation( + string firstInputSeriesName, + string secondInputSeriesName ) + { + // Check arguments + if (firstInputSeriesName == null) + throw new ArgumentNullException("firstInputSeriesName"); + if (secondInputSeriesName == null) + throw new ArgumentNullException("secondInputSeriesName"); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Set input series string + string inputSeriesParameter = firstInputSeriesName + "," + secondInputSeriesName; + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("Correlation", "", inputSeriesParameter, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output value + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result + return result; + + } + + /// + /// This method returns the average of all data points stored in the specified series. + /// + /// Input series name. + /// The average of all data points. + public double Mean( + string inputSeriesName ) + { + // Check arguments + if (inputSeriesName == null) + throw new ArgumentNullException("inputSeriesName"); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Set input series string + string inputSeriesParameter = inputSeriesName; + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("Mean", "", inputSeriesParameter, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output value + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result + return result; + + } + + /// + /// This method returns the median of all data points in the specified series. + /// + /// Input series name. + /// Median. + public double Median( + string inputSeriesName ) + { + // Check arguments + if (inputSeriesName == null) + throw new ArgumentNullException("inputSeriesName"); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Set input series string + string inputSeriesParameter = inputSeriesName; + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("Median", "", inputSeriesParameter, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output value + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result + return result; + + } + + /// + /// This method returns the variance for a series. + /// + /// Input series name. + /// If true, the data is a sample of the population. If false, it is the entire population. + /// Variance. + public double Variance( + string inputSeriesName, + bool sampleVariance ) + { + // Check arguments + if (inputSeriesName == null) + throw new ArgumentNullException("inputSeriesName"); + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Set input series string + string inputSeriesParameter = inputSeriesName; + + // Formula parameter + string parameter = sampleVariance.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("Variance", parameter, inputSeriesParameter, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output value + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result + return result; + + } + + /// + /// This method returns the beta function for two given values. + /// + /// First parameter for beta function + /// Second Parameter for beta function + /// Returns beta function for the two given values. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "The Beta Function is a mathematical function where arbitrary letters to indicate inputs are common")] + public double BetaFunction( + double m, + double n ) + { + // Fix for the VSTS 230829: The BetaFunction for the m=0,n=0 is double.NaN + if (m == 0 && n == 0) + return double.NaN; + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Formula parameter + string parameter = m.ToString(System.Globalization.CultureInfo.InvariantCulture); + parameter += "," + n.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("BetaFunction", parameter, _tempOutputSeriesName, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output value + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result + return result; + } + + /// + /// This method returns the gamma function value for the given variable. + /// + /// The value. + /// Returns gamma function + public double GammaFunction( + double value ) + { + + // Create temporary output series. + _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) ); + + // Formula parameter + string parameter = value.ToString(System.Globalization.CultureInfo.InvariantCulture); + + // Execute formula + double result = double.NaN; + try + { + _formulaData.Formula("GammaFunction", parameter, _tempOutputSeriesName, _tempOutputSeriesName); + + DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points; + + // Fill Output value + result = points[0].YValues[0]; + } + finally + { + // Remove Temporary output series + _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]); + } + + // Return result + return result; + + } + + #endregion + } + + #region Output classes used to store statistical calculations results + + /// + /// The TTestResult class stores the results of the TTest statistical calculations. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class TTestResult + { + #region Fields + + /// + /// First series' mean. + /// + internal double firstSeriesMean = 0.0; + + /// + /// Second series' mean. + /// + internal double secondSeriesMean = 0.0; + + /// + /// First series' variance. + /// + internal double firstSeriesVariance = 0.0; + + /// + /// Second series' variance. + /// + internal double secondSeriesVariance = 0.0; + + /// + /// T value. + /// + internal double tValue = 0.0; + + /// + /// Degree of freedom. + /// + internal double degreeOfFreedom = 0.0; + + /// + /// Probability T one tail. + /// + internal double probabilityTOneTail = 0.0; + + /// + /// Critical T one tail. + /// + internal double tCriticalValueOneTail = 0.0; + + /// + /// Probability T two tails. + /// + internal double probabilityTTwoTail = 0.0; + + /// + /// Critical T two tails. + /// + internal double tCriticalValueTwoTail = 0.0; + + #endregion + + #region Properties + + /// + /// Gets the mean of the first series. + /// + public double FirstSeriesMean + { + get + { + return firstSeriesMean; + } + } + + /// + /// Gets the mean of the second series. + /// + public double SecondSeriesMean + { + get + { + return secondSeriesMean; + } + } + + /// + /// Gets the variance of the first series. + /// + public double FirstSeriesVariance + { + get + { + return firstSeriesVariance; + } + } + + /// + /// Gets the variance of the second series. + /// + public double SecondSeriesVariance + { + get + { + return secondSeriesVariance; + } + } + + /// + /// Gets the T value. + /// + public double TValue + { + get + { + return tValue; + } + } + + /// + /// Gets the degree of freedom. + /// + public double DegreeOfFreedom + { + get + { + return degreeOfFreedom; + } + } + + /// + /// Gets the probability T one tail value. + /// + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", + Justification = "T One Tail is a statistics term. 'Tone' is not the intended word here.")] + public double ProbabilityTOneTail + { + get + { + return probabilityTOneTail; + } + } + + /// + /// Gets the critical T one tail value. + /// + public double TCriticalValueOneTail + { + get + { + return tCriticalValueOneTail; + } + } + + /// + /// Gets the probability T two tails value. + /// + public double ProbabilityTTwoTail + { + get + { + return probabilityTTwoTail; + } + } + + /// + /// Gets the critical T two tails value. + /// + public double TCriticalValueTwoTail + { + get + { + return tCriticalValueTwoTail; + } + } + + #endregion + } + + /// + /// The FTestResult class stores the results of the FTest statistical calculations. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class FTestResult + { + #region Fields + + /// + /// First series' mean. + /// + internal double firstSeriesMean = 0.0; + + /// + /// Second series' mean. + /// + internal double secondSeriesMean = 0.0; + + /// + /// First series' variance. + /// + internal double firstSeriesVariance = 0.0; + + /// + /// Second series' variance. + /// + internal double secondSeriesVariance = 0.0; + + /// + /// F value. + /// + internal double fValue = 0.0; + + /// + /// Probability F one tail. + /// + internal double probabilityFOneTail = 0.0; + + /// + /// Critical F one tail. + /// + internal double fCriticalValueOneTail = 0.0; + + #endregion + + #region Properties + + /// + /// Gets the mean of the first series. + /// + public double FirstSeriesMean + { + get + { + return firstSeriesMean; + } + } + + /// + /// Gets the mean of the second series. + /// + public double SecondSeriesMean + { + get + { + return secondSeriesMean; + } + } + + /// + /// Gets the variance of the first series. + /// + public double FirstSeriesVariance + { + get + { + return firstSeriesVariance; + } + } + + /// + /// Gets the variance of the second series. + /// + public double SecondSeriesVariance + { + get + { + return secondSeriesVariance; + } + } + + /// + /// Gets the F value. + /// + public double FValue + { + get + { + return fValue; + } + } + + /// + /// Gets the probability F one tail. + /// + public double ProbabilityFOneTail + { + get + { + return probabilityFOneTail; + } + } + + /// + /// Gets the critical F one tail. + /// + public double FCriticalValueOneTail + { + get + { + return fCriticalValueOneTail; + } + } + + #endregion + } + + /// + /// The AnovaResult class stores the results of the Anova statistical calculations. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class AnovaResult + { + #region Fields + + /// + /// Sum of squares between groups. + /// + internal double sumOfSquaresBetweenGroups = 0.0; + + /// + /// Sum of squares within groups. + /// + internal double sumOfSquaresWithinGroups = 0.0; + + /// + /// Total sum of squares. + /// + internal double sumOfSquaresTotal = 0.0; + + /// + /// Degree of freedom between groups. + /// + internal double degreeOfFreedomBetweenGroups = 0.0; + + /// + /// Degree of freedom within groups. + /// + internal double degreeOfFreedomWithinGroups = 0.0; + + /// + /// Total degree of freedom. + /// + internal double degreeOfFreedomTotal = 0.0; + + /// + /// Mean square variance between groups. + /// + internal double meanSquareVarianceBetweenGroups = 0.0; + + /// + /// Mean square variance between groups. + /// + internal double meanSquareVarianceWithinGroups = 0.0; + + /// + /// F ratio. + /// + internal double fRatio = 0.0; + + /// + /// F critical value. + /// + internal double fCriticalValue = 0.0; + + #endregion + + #region Properties + + /// + /// Gets the sum of squares between groups. + /// + public double SumOfSquaresBetweenGroups + { + get + { + return sumOfSquaresBetweenGroups; + } + } + + /// + /// Gets the sum of squares within groups. + /// + public double SumOfSquaresWithinGroups + { + get + { + return sumOfSquaresWithinGroups; + } + } + + + /// + /// Gets the total sum of squares. + /// + public double SumOfSquaresTotal + { + get + { + return sumOfSquaresTotal; + } + } + + /// + /// Gets the degree of freedom between groups. + /// + public double DegreeOfFreedomBetweenGroups + { + get + { + return degreeOfFreedomBetweenGroups; + } + } + + /// + /// Gets the degree of freedom within groups. + /// + public double DegreeOfFreedomWithinGroups + { + get + { + return degreeOfFreedomWithinGroups; + } + } + + /// + /// Gets the total degree of freedom. + /// + public double DegreeOfFreedomTotal + { + get + { + return degreeOfFreedomTotal; + } + } + + /// + /// Gets the mean square variance between groups. + /// + public double MeanSquareVarianceBetweenGroups + { + get + { + return meanSquareVarianceBetweenGroups; + } + } + + /// + /// Gets the mean square variance within groups. + /// + public double MeanSquareVarianceWithinGroups + { + get + { + return meanSquareVarianceWithinGroups; + } + } + + /// + /// Gets the F ratio. + /// + public double FRatio + { + get + { + return fRatio; + } + } + + /// + /// Gets the F critical value. + /// + public double FCriticalValue + { + get + { + return fCriticalValue; + } + } + + #endregion + } + + /// + /// The ZTestResult class stores the results of the ZTest statistical calculations. + /// +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class ZTestResult + { + #region Constructor + + /// + /// ZTestResult Constructor + /// + public ZTestResult() + { + } + + #endregion // Constructor + + #region Fields + + // Internal fields used for public properties + internal double firstSeriesMean; + internal double secondSeriesMean; + internal double firstSeriesVariance; + internal double secondSeriesVariance; + internal double zValue; + internal double probabilityZOneTail; + internal double zCriticalValueOneTail; + internal double probabilityZTwoTail; + internal double zCriticalValueTwoTail; + + + #endregion // Fields + + #region Properties + + /// + /// Gets the mean of the first series. + /// + public double FirstSeriesMean + { + get + { + return firstSeriesMean; + } + } + + /// + /// Gets the mean of the second series. + /// + public double SecondSeriesMean + { + get + { + return secondSeriesMean; + } + } + + /// + /// Gets the variance of the first series. + /// + public double FirstSeriesVariance + { + get + { + return firstSeriesVariance; + } + } + + /// + /// Gets the variance of the second series. + /// + public double SecondSeriesVariance + { + get + { + return secondSeriesVariance; + } + } + + /// + /// Gets the Z Value + /// + public double ZValue + { + get + { + return zValue; + } + } + + /// + /// Gets the probability Z one tail value. + /// + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", + Justification = "Z One Tail is a statistics term. 'Zone' is not the intended word here.")] + public double ProbabilityZOneTail + { + get + { + return probabilityZOneTail; + } + } + + /// + /// Gets the Z critical value one tail value. + /// + public double ZCriticalValueOneTail + { + get + { + return zCriticalValueOneTail; + } + } + + /// + /// Gets the probability Z two tail value. + /// + public double ProbabilityZTwoTail + { + get + { + return probabilityZTwoTail; + } + } + + /// + /// Gets the Z critical value two tail value. + /// + public double ZCriticalValueTwoTail + { + get + { + return zCriticalValueTwoTail; + } + } + + #endregion // Properties + } + + #endregion // Output Classes +} + + diff --git a/System.Web.DataVisualization/Common/General/StripLine.cs b/System.Web.DataVisualization/Common/General/StripLine.cs new file mode 100644 index 000000000..628760442 --- /dev/null +++ b/System.Web.DataVisualization/Common/General/StripLine.cs @@ -0,0 +1,1616 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: StripLine.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: StripLinesCollection, StripLine +// +// Purpose: StripLinesCollection class is used to expose stripes +// or lines on the plotting area and is exposed through +// StripLines property of each Axis. +// +// Each StripLine class presents one or series of +// repeated axis horizontal or vertical strips within +// the plotting are. +// +// When multiple strip lines are defined for an axis, +// there is a possibility of overlap. The z-order of +// StripLine objects is determined by their order of +// occurrence in the StripLinesCollection object. The +// z-order follows this convention, the first occurrence +// is drawn first, the second occurrence is drawn second, +// and so on. +// +// Highlighting weekends on date axis is a good example +// of using strip lines with interval. +// +// Reviewed: AG - Jul 31, 2002; +// GS - Aug 7, 2002 +// AG - Microsoft 13, 2007 +// +//=================================================================== + + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.Globalization; + using System.ComponentModel.Design.Serialization; + using System.Reflection; + using System.Windows.Forms.Design; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else + namespace System.Web.UI.DataVisualization.Charting +#endif + +{ + /// + /// The StripLinesCollection class is a strongly typed collection of + /// StripLine classes. + /// + [ + SRDescription("DescriptionAttributeStripLinesCollection_StripLinesCollection"), + + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class StripLinesCollection : ChartElementCollection + { + + #region Constructor + /// + /// Legend item collection object constructor + /// + /// Axis object reference. + internal StripLinesCollection(Axis axis) + : base(axis) + { + } + #endregion + + + } + + /// + /// The StripLine class contains properties which define visual appearance + /// of the stripe or line, its position according to the axis. It + /// may optionally contain the repeat interval. Text may associate + /// with a strip or a line. It also contains methods of drawing and hit + /// testing. + /// + [ + SRDescription("DescriptionAttributeStripLine_StripLine"), + DefaultProperty("IntervalOffset"), + ] +#if Microsoft_CONTROL + public class StripLine : ChartElement +#else +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class StripLine : ChartElement, IChartMapArea +#endif + { + + #region Fields + + // Private data members, which store properties values + private double _intervalOffset = 0; + private double _interval = 0; + private DateTimeIntervalType _intervalType = DateTimeIntervalType.Auto; + internal DateTimeIntervalType intervalOffsetType = DateTimeIntervalType.Auto; + internal bool interlaced = false; + private double _stripWidth = 0; + private DateTimeIntervalType _stripWidthType = DateTimeIntervalType.Auto; + private Color _backColor = Color.Empty; + private ChartHatchStyle _backHatchStyle = ChartHatchStyle.None; + private string _backImage = ""; + private ChartImageWrapMode _backImageWrapMode = ChartImageWrapMode.Tile; + private Color _backImageTransparentColor = Color.Empty; + private ChartImageAlignmentStyle _backImageAlignment = ChartImageAlignmentStyle.TopLeft; + private GradientStyle _backGradientStyle = GradientStyle.None; + private Color _backSecondaryColor = Color.Empty; + private Color _borderColor = Color.Empty; + private int _borderWidth = 1; + private ChartDashStyle _borderDashStyle = ChartDashStyle.Solid; + + // Strip/Line title properties + private string _text = ""; + private Color _foreColor = Color.Black; + private FontCache _fontCache = new FontCache(); + private Font _font = null; + private StringAlignment _textAlignment = StringAlignment.Far; + private StringAlignment _textLineAlignment = StringAlignment.Near; + + // Chart image map properties + private string _toolTip = ""; + +#if !Microsoft_CONTROL + private string _url = ""; + private string _attributes = ""; + private string _postbackValue = String.Empty; +#endif + + // Default text orientation + private TextOrientation _textOrientation = TextOrientation.Auto; + + #endregion + + #region Properties + /// + /// Gets axes to which this object attached to. + /// + /// Axis object reference. + internal Axis Axis + { + get + { + if (Parent != null) + return Parent.Parent as Axis; + else + return null; + } + } + #endregion + + #region Constructors + + /// + /// Strip line object constructor. + /// + public StripLine() + : base() + { + _font = _fontCache.DefaultFont; + } + + #endregion + + #region Painting methods + + /// + /// Checks if chart title is drawn vertically. + /// Note: From the drawing perspective stacked text orientation is not vertical. + /// + /// True if text is vertical. + private bool IsTextVertical + { + get + { + TextOrientation currentTextOrientation = this.GetTextOrientation(); + return currentTextOrientation == TextOrientation.Rotated90 || currentTextOrientation == TextOrientation.Rotated270; + } + } + + /// + /// Returns stripline text orientation. If set to Auto automatically determines the + /// orientation based on the orientation of the stripline. + /// + /// Current text orientation. + private TextOrientation GetTextOrientation() + { + if (this.TextOrientation == TextOrientation.Auto && this.Axis != null) + { + if (this.Axis.AxisPosition == AxisPosition.Bottom || this.Axis.AxisPosition == AxisPosition.Top) + { + return TextOrientation.Rotated270; + } + return TextOrientation.Horizontal; + } + return this.TextOrientation; + } + + /// + /// Draw strip(s) or line(s). + /// + /// Reference to the Chart Graphics object. + /// Common objects. + /// Indicates if Lines or Stripes should be drawn. + internal void Paint( + ChartGraphics graph, + CommonElements common, + bool drawLinesOnly) + { + // Strip lines are not supported in circular chart area + if(this.Axis.ChartArea.chartAreaIsCurcular) + { + return; + } + + // Get plot area position + RectangleF plotAreaPosition = this.Axis.ChartArea.PlotAreaPosition.ToRectangleF(); + + // Detect if strip/line is horizontal or vertical + bool horizontal = true; + if(this.Axis.AxisPosition == AxisPosition.Bottom || this.Axis.AxisPosition == AxisPosition.Top) + { + horizontal = false; + } + + // Get first series attached to this axis + Series axisSeries = null; + if(Axis.axisType == AxisName.X || Axis.axisType == AxisName.X2) + { + List seriesArray = Axis.ChartArea.GetXAxesSeries((Axis.axisType == AxisName.X) ? AxisType.Primary : AxisType.Secondary, Axis.SubAxisName); + if(seriesArray.Count > 0) + { + axisSeries = Axis.Common.DataManager.Series[seriesArray[0]]; + if(axisSeries != null && !axisSeries.IsXValueIndexed) + { + axisSeries = null; + } + } + } + + // Get starting position from axis + // NOTE: Starting position was changed from "this.Axis.minimum" to + // fix the minimum scaleView location to fix issue #5962 -- AG + double currentPosition = this.Axis.ViewMinimum; + + // Adjust start position depending on the interval type + if(!Axis.ChartArea.chartAreaIsCurcular || + Axis.axisType == AxisName.Y || + Axis.axisType == AxisName.Y2 ) + { + double intervalToUse = this.Interval; + + // NOTE: fix for issue #5962 + // Always use original grid interval for isInterlaced strip lines. + if (this.interlaced) + { + // Automaticly generated isInterlaced strips have interval twice as big as major grids + intervalToUse /= 2.0; + } + currentPosition = ChartHelper.AlignIntervalStart(currentPosition, intervalToUse, this.IntervalType, axisSeries); + } + + // Too many tick marks + if(this.Interval != 0) + { + if( ( Axis.ViewMaximum - Axis.ViewMinimum ) / ChartHelper.GetIntervalSize(currentPosition, this._interval, this._intervalType, axisSeries, 0, DateTimeIntervalType.Number, false) > ChartHelper.MaxNumOfGridlines) + return; + } + + DateTimeIntervalType offsetType = (IntervalOffsetType == DateTimeIntervalType.Auto) ? IntervalType : IntervalOffsetType; + if(this.Interval == 0) + { + currentPosition = this.IntervalOffset; + } + /****************************************************************** + * Removed by AG. Causing issues with interalced strip lines. + /****************************************************************** + else if(axisSeries != null && axisSeries.IsXValueIndexed) + { + // Align first position for indexed series + currentPosition += this.Axis.AlignIndexedIntervalStart( + currentPosition, + this.Interval, + this.IntervalType, + axisSeries, + this.IntervalOffset, + offsetType, + false); + } + */ + else + { + if(this.IntervalOffset > 0) + { + currentPosition += ChartHelper.GetIntervalSize(currentPosition, this.IntervalOffset, + offsetType, axisSeries, 0, DateTimeIntervalType.Number, false); + } + else if(this.IntervalOffset < 0) + { + currentPosition -= ChartHelper.GetIntervalSize(currentPosition, -this.IntervalOffset, + offsetType, axisSeries, 0, DateTimeIntervalType.Number, false); + } + } + + // Draw several lines or strips if Interval property is set + int counter = 0; + do + { + // Check if we do not exceed max number of elements + if(counter++ > ChartHelper.MaxNumOfGridlines) + { + break; + } + + // Draw strip + if(this.StripWidth > 0 && !drawLinesOnly) + { + double stripRightPosition = currentPosition + ChartHelper.GetIntervalSize(currentPosition, this.StripWidth, this.StripWidthType, axisSeries, this.IntervalOffset, offsetType, false); + if (stripRightPosition > this.Axis.ViewMinimum && currentPosition < this.Axis.ViewMaximum) + { + // Calculate strip rectangle + RectangleF rect = RectangleF.Empty; + double pos1 = (float)this.Axis.GetLinearPosition(currentPosition); + double pos2 = (float)this.Axis.GetLinearPosition(stripRightPosition); + if(horizontal) + { + rect.X = plotAreaPosition.X; + rect.Width = plotAreaPosition.Width; + rect.Y = (float)Math.Min(pos1, pos2); + rect.Height = (float)Math.Max(pos1, pos2) - rect.Y; + + // Check rectangle boundaries + rect.Intersect(plotAreaPosition); + } + else + { + rect.Y = plotAreaPosition.Y; + rect.Height = plotAreaPosition.Height; + rect.X = (float)Math.Min(pos1, pos2); + rect.Width = (float)Math.Max(pos1, pos2) - rect.X; + + // Check rectangle boundaries + rect.Intersect(plotAreaPosition); + } + + if(rect.Width > 0 && rect.Height > 0) + { + + #if Microsoft_CONTROL + // Start Svg Selection mode + graph.StartHotRegion( "", this._toolTip ); + #else + // Start Svg Selection mode + graph.StartHotRegion( this._url, this._toolTip ); + #endif + if(!this.Axis.ChartArea.Area3DStyle.Enable3D) + { + // Draw strip + graph.FillRectangleRel( rect, + this.BackColor, this.BackHatchStyle, this.BackImage, + this.BackImageWrapMode, this.BackImageTransparentColor, this.BackImageAlignment, + this.BackGradientStyle, this.BackSecondaryColor, this.BorderColor, + this.BorderWidth, this.BorderDashStyle, Color.Empty, + 0, PenAlignment.Inset ); + } + else + { + Draw3DStrip( graph, rect, horizontal ); + } + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Draw strip line title + PaintTitle(graph, rect); + + if( common.ProcessModeRegions ) + { + if(!this.Axis.ChartArea.Area3DStyle.Enable3D) + { +#if !Microsoft_CONTROL + common.HotRegionsList.AddHotRegion(rect, this.ToolTip, this.Url, this.MapAreaAttributes, this.PostBackValue, this, ChartElementType.StripLines, string.Empty); +#else + common.HotRegionsList.AddHotRegion(rect, this.ToolTip, string.Empty, string.Empty, string.Empty, this, ChartElementType.StripLines, null ); +#endif // !Microsoft_CONTROL + } + } + } + + } + } + // Draw line + else if(this.StripWidth == 0 && drawLinesOnly) + { + if(currentPosition > this.Axis.ViewMinimum && currentPosition < this.Axis.ViewMaximum) + { + // Calculate line position + PointF point1 = PointF.Empty; + PointF point2 = PointF.Empty; + if(horizontal) + { + point1.X = plotAreaPosition.X; + point1.Y = (float)this.Axis.GetLinearPosition(currentPosition); + point2.X = plotAreaPosition.Right; + point2.Y = point1.Y; + } + else + { + point1.X = (float)this.Axis.GetLinearPosition(currentPosition); + point1.Y = plotAreaPosition.Y; + point2.X = point1.X; + point2.Y = plotAreaPosition.Bottom; + } + +#if Microsoft_CONTROL + // Start Svg Selection mode + graph.StartHotRegion( "", this._toolTip ); +#else + // Start Svg Selection mode + graph.StartHotRegion( this._url, this._toolTip ); +#endif + // Draw Line + if(!this.Axis.ChartArea.Area3DStyle.Enable3D) + { + graph.DrawLineRel(this.BorderColor, this.BorderWidth, this.BorderDashStyle, point1, point2); + } + else + { + graph.Draw3DGridLine(this.Axis.ChartArea, _borderColor, _borderWidth, _borderDashStyle, point1, point2, horizontal, Axis.Common, this ); + } + + // End Svg Selection mode + graph.EndHotRegion( ); + + // Draw strip line title + PaintTitle(graph, point1, point2); + + if( common.ProcessModeRegions ) + { + SizeF relBorderWidth = new SizeF(this.BorderWidth + 1, this.BorderWidth + 1); + relBorderWidth = graph.GetRelativeSize(relBorderWidth); + RectangleF lineRect = RectangleF.Empty; + if(horizontal) + { + lineRect.X = point1.X; + lineRect.Y = point1.Y - relBorderWidth.Height / 2f; + lineRect.Width = point2.X - point1.X; + lineRect.Height = relBorderWidth.Height; + } + else + { + lineRect.X = point1.X - relBorderWidth.Width / 2f; + lineRect.Y = point1.Y; + lineRect.Width = relBorderWidth.Width; + lineRect.Height = point2.Y - point1.Y; + } + +#if !Microsoft_CONTROL + common.HotRegionsList.AddHotRegion( lineRect, this.ToolTip, this.Url, this.MapAreaAttributes, this.PostBackValue, this, ChartElementType.StripLines, string.Empty ); +#else + common.HotRegionsList.AddHotRegion( lineRect, this.ToolTip, null, null, null, this, ChartElementType.StripLines, null ); +#endif // !Microsoft_CONTROL + } + } + } + + // Go to the next line/strip + if(this.Interval > 0) + { + currentPosition += ChartHelper.GetIntervalSize(currentPosition, this.Interval, this.IntervalType, axisSeries, this.IntervalOffset, offsetType, false); + } + + } while(this.Interval > 0 && currentPosition <= this.Axis.ViewMaximum); + } + + /// + /// Draws strip line in 3d. + /// + /// Chart graphics. + /// Strip rectangle. + /// Indicates that strip is horizontal + private void Draw3DStrip(ChartGraphics graph, RectangleF rect, bool horizontal ) + { + ChartArea area = this.Axis.ChartArea; + GraphicsPath path = null; + DrawingOperationTypes operationType = DrawingOperationTypes.DrawElement; + + if( this.Axis.Common.ProcessModeRegions ) + { + operationType |= DrawingOperationTypes.CalcElementPath; + } + + // Draw strip on the back/front wall + path = graph.Fill3DRectangle( + rect, + area.IsMainSceneWallOnFront() ? area.areaSceneDepth : 0f, + 0, + area.matrix3D, + area.Area3DStyle.LightStyle, + this.BackColor, + this.BorderColor, + this.BorderWidth, + this.BorderDashStyle, + operationType ); + + if( this.Axis.Common.ProcessModeRegions ) + { + +#if !Microsoft_CONTROL + this.Axis.Common.HotRegionsList.AddHotRegion( graph, path, false, this.ToolTip, this.Url, this.MapAreaAttributes, this.PostBackValue, this, ChartElementType.StripLines ); +#else + this.Axis.Common.HotRegionsList.AddHotRegion( graph, path, false, this.ToolTip, null, null, null, this, ChartElementType.StripLines ); +#endif // !Microsoft_CONTROL + } + + if(horizontal) + { + // Draw strip on the side wall (left or right) + if(!area.IsSideSceneWallOnLeft()) + { + rect.X = rect.Right; + } + rect.Width = 0f; + + path = graph.Fill3DRectangle( + rect, + 0f, + area.areaSceneDepth, + area.matrix3D, + area.Area3DStyle.LightStyle, + this.BackColor, + this.BorderColor, + this.BorderWidth, + this.BorderDashStyle, + operationType ); + + } + else if(area.IsBottomSceneWallVisible()) + { + // Draw strip on the bottom wall (if visible) + rect.Y = rect.Bottom; + rect.Height = 0f; + + path = graph.Fill3DRectangle( + rect, + 0f, + area.areaSceneDepth, + area.matrix3D, + area.Area3DStyle.LightStyle, + this.BackColor, + this.BorderColor, + this.BorderWidth, + this.BorderDashStyle, + operationType ); + + } + if( this.Axis.Common.ProcessModeRegions ) + { +#if !Microsoft_CONTROL + this.Axis.Common.HotRegionsList.AddHotRegion( graph, path, false, this.ToolTip, this.Url, this.MapAreaAttributes, this.PostBackValue, this, ChartElementType.StripLines ); +#else + this.Axis.Common.HotRegionsList.AddHotRegion( graph, path, false, this.ToolTip, null, null, null, this, ChartElementType.StripLines ); +#endif // !Microsoft_CONTROL + } + if (path != null) + { + path.Dispose(); + } + } + + /// + /// Draw strip/line title text + /// + /// Chart graphics object. + /// First line point. + /// Second line point. + private void PaintTitle(ChartGraphics graph, PointF point1, PointF point2) + { + if(this.Text.Length > 0) + { + // Define a rectangle to draw the title + RectangleF rect = RectangleF.Empty; + rect.X = point1.X; + rect.Y = point1.Y; + rect.Height = point2.Y - rect.Y; + rect.Width = point2.X - rect.X; + + // Paint title using a rect + PaintTitle(graph, rect); + } + } + + /// + /// Draw strip/line title text + /// + /// Chart graphics object. + /// Rectangle to draw in. + private void PaintTitle(ChartGraphics graph, RectangleF rect) + { + if(this.Text.Length > 0) + { + // Get title text + string titleText = this.Text; + + // Prepare string format + using (StringFormat format = new StringFormat()) + { + format.Alignment = this.TextAlignment; + + if (graph.IsRightToLeft) + { + if (format.Alignment == StringAlignment.Far) + { + format.Alignment = StringAlignment.Near; + } + else if (format.Alignment == StringAlignment.Near) + { + format.Alignment = StringAlignment.Far; + } + } + + format.LineAlignment = this.TextLineAlignment; + + // Adjust default title angle for horizontal lines + int angle = 0; + switch (this.TextOrientation) + { + case (TextOrientation.Rotated90): + angle = 90; + break; + case (TextOrientation.Rotated270): + angle = 270; + break; + case (TextOrientation.Auto): + if (this.Axis.AxisPosition == AxisPosition.Bottom || this.Axis.AxisPosition == AxisPosition.Top) + { + angle = 270; + } + break; + } + + // Set vertical text for horizontal lines + if (angle == 90) + { + format.FormatFlags = StringFormatFlags.DirectionVertical; + angle = 0; + } + else if (angle == 270) + { + format.FormatFlags = StringFormatFlags.DirectionVertical; + angle = 180; + } + + // Measure string size + SizeF size = graph.MeasureStringRel(titleText.Replace("\\n", "\n"), this.Font, new SizeF(100, 100), format, this.GetTextOrientation()); + + // Adjust text size + float zPositon = 0f; + if (this.Axis.ChartArea.Area3DStyle.Enable3D) + { + // Get projection coordinates + Point3D[] textSizeProjection = new Point3D[3]; + zPositon = this.Axis.ChartArea.IsMainSceneWallOnFront() ? this.Axis.ChartArea.areaSceneDepth : 0f; + textSizeProjection[0] = new Point3D(0f, 0f, zPositon); + textSizeProjection[1] = new Point3D(size.Width, 0f, zPositon); + textSizeProjection[2] = new Point3D(0f, size.Height, zPositon); + + // Transform coordinates of text size + this.Axis.ChartArea.matrix3D.TransformPoints(textSizeProjection); + + // Adjust text size + int index = this.Axis.ChartArea.IsMainSceneWallOnFront() ? 0 : 1; + size.Width *= size.Width / (textSizeProjection[index].X - textSizeProjection[(index == 0) ? 1 : 0].X); + size.Height *= size.Height / (textSizeProjection[2].Y - textSizeProjection[0].Y); + } + + + // Get relative size of the border width + SizeF sizeBorder = graph.GetRelativeSize(new SizeF(this.BorderWidth, this.BorderWidth)); + + // Find the center of rotation + PointF rotationCenter = PointF.Empty; + if (format.Alignment == StringAlignment.Near) + { // Near + rotationCenter.X = rect.X + size.Width / 2 + sizeBorder.Width; + } + else if (format.Alignment == StringAlignment.Far) + { // Far + rotationCenter.X = rect.Right - size.Width / 2 - sizeBorder.Width; + } + else + { // Center + rotationCenter.X = (rect.Left + rect.Right) / 2; + } + + if (format.LineAlignment == StringAlignment.Near) + { // Near + rotationCenter.Y = rect.Top + size.Height / 2 + sizeBorder.Height; + } + else if (format.LineAlignment == StringAlignment.Far) + { // Far + rotationCenter.Y = rect.Bottom - size.Height / 2 - sizeBorder.Height; + } + else + { // Center + rotationCenter.Y = (rect.Bottom + rect.Top) / 2; + } + + // Reset string alignment to center point + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + if (this.Axis.ChartArea.Area3DStyle.Enable3D) + { + // Get projection coordinates + Point3D[] rotationCenterProjection = new Point3D[2]; + rotationCenterProjection[0] = new Point3D(rotationCenter.X, rotationCenter.Y, zPositon); + if (format.FormatFlags == StringFormatFlags.DirectionVertical) + { + rotationCenterProjection[1] = new Point3D(rotationCenter.X, rotationCenter.Y - 20f, zPositon); + } + else + { + rotationCenterProjection[1] = new Point3D(rotationCenter.X - 20f, rotationCenter.Y, zPositon); + } + + // Transform coordinates of text rotation point + this.Axis.ChartArea.matrix3D.TransformPoints(rotationCenterProjection); + + // Adjust rotation point + rotationCenter = rotationCenterProjection[0].PointF; + + // Adjust angle of the text + if (angle == 0 || angle == 180 || angle == 90 || angle == 270) + { + if (format.FormatFlags == StringFormatFlags.DirectionVertical) + { + angle += 90; + } + + // Convert coordinates to absolute + rotationCenterProjection[0].PointF = graph.GetAbsolutePoint(rotationCenterProjection[0].PointF); + rotationCenterProjection[1].PointF = graph.GetAbsolutePoint(rotationCenterProjection[1].PointF); + + // Calcuate axis angle + float angleXAxis = (float)Math.Atan( + (rotationCenterProjection[1].Y - rotationCenterProjection[0].Y) / + (rotationCenterProjection[1].X - rotationCenterProjection[0].X)); + angleXAxis = (float)Math.Round(angleXAxis * 180f / (float)Math.PI); + angle += (int)angleXAxis; + } + } + + // Draw string + using (Brush brush = new SolidBrush(this.ForeColor)) + { + graph.DrawStringRel( + titleText.Replace("\\n", "\n"), + this.Font, + brush, + rotationCenter, + format, + angle, + this.GetTextOrientation()); + } + + } + } + } + + #endregion + + #region Strip line properties + + /// + /// Gets or sets the text orientation. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(TextOrientation.Auto), + SRDescription("DescriptionAttribute_TextOrientation"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public TextOrientation TextOrientation + { + get + { + return this._textOrientation; + } + set + { + this._textOrientation = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the strip or line starting position offset. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + DefaultValue(0.0), + SRDescription("DescriptionAttributeStripLine_IntervalOffset"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + TypeConverter(typeof(AxisLabelDateValueConverter)) + ] + public double IntervalOffset + { + get + { + return _intervalOffset; + } + set + { + _intervalOffset = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the unit of measurement of the strip or line offset. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeStripLine_IntervalOffsetType"), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public DateTimeIntervalType IntervalOffsetType + { + get + { + return intervalOffsetType; + } + set + { + intervalOffsetType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto; + this.Invalidate(); + } + } + + /// + /// Gets or sets the strip or line step size. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + DefaultValue(0.0), + RefreshPropertiesAttribute(RefreshProperties.All), + SRDescription("DescriptionAttributeStripLine_Interval"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public double Interval + { + get + { + return _interval; + } + set + { + _interval = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the unit of measurement of the strip or line step. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeStripLine_IntervalType"), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public DateTimeIntervalType IntervalType + { + get + { + return _intervalType; + } + set + { + _intervalType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto; + this.Invalidate(); + } + } + + /// + /// Gets or sets the strip width. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + DefaultValue(0.0), + SRDescription("DescriptionAttributeStripLine_StripWidth"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public double StripWidth + { + get + { + return _stripWidth; + } + set + { + if(value < 0) + { + throw (new ArgumentException(SR.ExceptionStripLineWidthIsNegative, "value")); + } + _stripWidth = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the unit of measurement of the strip width. + /// + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + DefaultValue(DateTimeIntervalType.Auto), + SRDescription("DescriptionAttributeStripLine_StripWidthType"), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public DateTimeIntervalType StripWidthType + { + get + { + return _stripWidthType; + } + set + { + _stripWidthType = (value != DateTimeIntervalType.NotSet) ? value : DateTimeIntervalType.Auto; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background color. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackColor + { + get + { + return _backColor; + } + set + { + _backColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the border color. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBorderColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BorderColor + { + get + { + return _borderColor; + } + set + { + _borderColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the border style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeBorderDashStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartDashStyle BorderDashStyle + { + get + { + return _borderDashStyle; + } + set + { + _borderDashStyle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the border width. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeBorderWidth"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int BorderWidth + { + get + { + return _borderWidth; + } + set + { + _borderWidth = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeBackImage"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + NotifyParentPropertyAttribute(true) + ] + public string BackImage + { + get + { + return _backImage; + } + set + { + _backImage = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background image drawing mode. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageWrapMode.Tile), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageWrapMode"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageWrapMode BackImageWrapMode + { + get + { + return _backImageWrapMode; + } + set + { + _backImageWrapMode = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets a color which will be replaced with a transparent color while drawing the background image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackImageTransparentColor + { + get + { + return _backImageTransparentColor; + } + set + { + _backImageTransparentColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background image alignment used by unscale drawing mode. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageAlignmentStyle.TopLeft), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackImageAlign"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageAlignmentStyle BackImageAlignment + { + get + { + return _backImageAlignment; + } + set + { + _backImageAlignment = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background gradient style. + /// + /// + /// + /// + /// + /// A value used for the background. + /// + /// + /// Two colors are used to draw the gradient, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(GradientStyle.None), + SRDescription("DescriptionAttributeBackGradientStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + public GradientStyle BackGradientStyle + { + get + { + return _backGradientStyle; + } + set + { + _backGradientStyle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the secondary background color. + /// + /// + /// + /// + /// + /// A value used for the secondary color of a background with + /// hatching or gradient fill. + /// + /// + /// This color is used with when or + /// are used. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackSecondaryColor + { + get + { + return _backSecondaryColor; + } + set + { + _backSecondaryColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the background hatch style. + /// + /// + /// + /// + /// + /// A value used for the background. + /// + /// + /// Two colors are used to draw the hatching, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartHatchStyle.None), + SRDescription("DescriptionAttributeBackHatchStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + public ChartHatchStyle BackHatchStyle + { + get + { + return _backHatchStyle; + } + set + { + _backHatchStyle = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the name of the strip line. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(false), + Browsable(false), + DefaultValue("StripLine"), + SRDescription("DescriptionAttributeStripLine_Name"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public string Name + { + get + { + return "StripLine"; + } + } + + /// + /// Gets or sets the title text of the strip line. + /// + [ + SRCategory("CategoryAttributeTitle"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeStripLine_Title"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public string Text + { + get + { + return _text; + } + set + { + _text = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the fore color of the strip line. + /// + [ + SRCategory("CategoryAttributeTitle"), + Bindable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeStripLine_TitleColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color ForeColor + { + get + { + return _foreColor; + } + set + { + _foreColor = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the text alignment of the strip line. + /// + [ + SRCategory("CategoryAttributeTitle"), + Bindable(true), + DefaultValue(typeof(StringAlignment), "Far"), + SRDescription("DescriptionAttributeStripLine_TitleAlignment"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public StringAlignment TextAlignment + { + get + { + return _textAlignment; + } + set + { + _textAlignment = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the text line alignment of the strip line. + /// + [ + SRCategory("CategoryAttributeTitle"), + Bindable(true), + DefaultValue(typeof(StringAlignment), "Near"), + SRDescription("DescriptionAttributeStripLine_TitleLineAlignment"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public StringAlignment TextLineAlignment + { + get + { + return _textLineAlignment; + } + set + { + _textLineAlignment = value; + this.Invalidate(); + } + } + + /// + /// Gets or sets the title font. + /// + [ + SRCategory("CategoryAttributeTitle"), + Bindable(true), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"), + SRDescription("DescriptionAttributeTitleFont"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Font Font + { + get + { + return _font; + } + set + { + _font = value; + this.Invalidate(); + } + } + + + /// + /// Gets or sets the tooltip. + /// + [ + SRCategory("CategoryAttributeMapArea"), + + Bindable(true), + SRDescription("DescriptionAttributeToolTip"), + DefaultValue(""), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public string ToolTip + { + set + { + this.Invalidate(); + _toolTip = value; + } + get + { + return _toolTip; + } + } + +#if !Microsoft_CONTROL + + /// + /// Gets or sets the URL. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeUrl"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base) + + ] + public string Url + { + set + { + _url = value; + this.Invalidate(); + } + get + { + return _url; + } + } + + /// + /// Gets or sets the other map area attributes. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeMapAreaAttributes"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute) + ] + public string MapAreaAttributes + { + set + { + _attributes = value; + this.Invalidate(); + } + get + { + return _attributes; + } + } + + /// + /// Gets or sets the postback value which can be processed on a click event. + /// + /// The value which is passed to a click event as an argument. + [DefaultValue("")] + [SRCategory(SR.Keys.CategoryAttributeMapArea)] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + public string PostBackValue + { + get + { + return this._postbackValue; + } + set + { + this._postbackValue = value; + } + } + + +#endif //#if !Microsoft_CONTROL + + #endregion + + + #region Invalidation methods + + /// + /// Invalidate chart area + /// + private new void Invalidate() + { +#if Microsoft_CONTROL + + if(this.Axis != null) + { + Axis.Invalidate(); + } +#endif + } + + #endregion + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_fontCache != null) + { + _fontCache.Dispose(); + _fontCache = null; + } + } + base.Dispose(disposing); + } + + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/General/SubAxis.cs b/System.Web.DataVisualization/Common/General/SubAxis.cs new file mode 100644 index 000000000..58ddbccff --- /dev/null +++ b/System.Web.DataVisualization/Common/General/SubAxis.cs @@ -0,0 +1,823 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: SubAxis.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: SubAxis, SubAxisCollection +// +// Purpose: Each chart area contains four main axes PrimaryX, +// PrimaryY, SecondaryX and SecondaryY which are usually +// positioned on each side of the plotting area. Most of +// the charts use only two axes; X and Y, but for some +// charts even 4 axes is not sufficient. Sub-axes were +// introduced to provide unlimited number of axes in +// the chart. +// +// Each main axis has a collection of SubAxis which is +// empty by default. By adding SubAxis into this collection +// user can add unlimited number of sub-axis which will +// be positioned next to the main axis. +// +// Each of the SubAxis have a unique name. To associate +// data series with a sub axis YSubAxisName and XSubAxisName +// properties of the Series should be used. +// +// Reviewed: AG - March 13, 2007 +// +//=================================================================== + +#if SUBAXES + +#region Used namespace +using System; +using System.Globalization; +using System.Reflection; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.ComponentModel.Design.Serialization; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Text; +using System.Drawing.Drawing2D; +#if WINFORMS_CONTROL +using System.Windows.Forms.DataVisualization.Charting; +using System.Windows.Forms.DataVisualization.Charting.Data; +using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +using System.Windows.Forms.DataVisualization.Charting.Utilities; +using System.Windows.Forms.DataVisualization.Charting.Borders3D; +using System.Windows.Forms.DataVisualization.Charting; + +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; + using System.Web.UI.DataVisualization.Charting.Utilities; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + + +#endregion + +#if WINFORMS_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting + +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// + /// SubAxis class is derived from the main Axis class and provides + /// additional axis associated with one of the main chart axis. + /// + [ + SRDescription("DescriptionAttributeSubAxis_SubAxis"), + DefaultProperty("Enabled"), +#if WINFORMS_CONTROL + TypeConverter(typeof(SubAxis.SubAxisConverter)), +#endif + + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class SubAxis : Axis + { +#region Fields + + /// + /// Sub-Axis parent axis object. + /// + internal Axis parentAxis = null; + + /// + /// Sub axis offset from the parent axis + /// + internal double offsetFromParent = 0.0; + + /// + /// Margin between prev. axis + /// + internal double locationOffset = 0.0; + +#endregion // Fields + +#region Constructor + + /// + /// Default constructor + /// + public SubAxis() : base() + { + base.Name = string.Empty; + } + + /// + /// Object constructor. + /// + /// Unique name of the object. + public SubAxis(string name) : base() + { + base.Name = name; + } + +#endregion + +#region Properties + + /// + /// Axis automatic scale breaks style. + /// + [ + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never), + SRCategory("CategoryAttributeScale"), + SRDescription("DescriptionAttributeScaleBreakStyle"), + TypeConverter(typeof(NoNameExpandableObjectConverter)), + NotifyParentPropertyAttribute(true), +#if WINFORMS_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + ] + override public AxisScaleBreakStyle ScaleBreakStyle + { + get + { + return base.ScaleBreakStyle; + } + set + { + base.ScaleBreakStyle = value; + } + } + + /// + /// Sub axis parent axis. + /// + [ + SRCategory("CategoryAttributeAxis"), + Bindable(true), + Browsable(false), + DefaultValue(null), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeSubAxis_ParentAxis"), +#if !WINFORMS_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public Axis ParentAxis + { + get + { + return this.parentAxis; + } + } + + + /// + /// Sub axis location offset relative to the previous axis. + /// + [ + SRCategory("CategoryAttributeLocation"), + Bindable(true), + DefaultValue(0.0), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeSubAxis_LocationOffset"), +#if !WINFORMS_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + ] + public double LocationOffset + { + get + { + return this.locationOffset; + } + set + { + this.locationOffset = value; + this.Invalidate(); + } + } + + /// + /// Axis position + /// + [ + Bindable(true), + Browsable(false), + DefaultValue(AxisPosition.Left), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeReverse"), +#if !WINFORMS_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + override internal AxisPosition AxisPosition + { + get + { + if(this.parentAxis != null) + { + return this.parentAxis.AxisPosition; + } + return AxisPosition.Left; + } + set + { + } + } + + /// + /// SubAxis name. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + Browsable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeSubAxis_Name"), +#if !WINFORMS_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible), + SerializationVisibilityAttribute(SerializationVisibility.Attribute) + ] + override public string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + + /// + /// Tick marks and labels move with axis when + /// the crossing value is changed. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeMarksNextToAxis"), + NotifyParentPropertyAttribute(true), +#if !WINFORMS_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + override public bool IsMarksNextToAxis + { + get + { + return base.IsMarksNextToAxis; + } + set + { + base.IsMarksNextToAxis = value; + } + } + + /// + /// Point where axis is crossed by another axis. + /// + [ + SRCategory("CategoryAttributeScale"), + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never), + Bindable(true), + DefaultValue(Double.NaN), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeCrossing"), +#if !WINFORMS_CONTROL + PersistenceMode(PersistenceMode.Attribute), +#endif + TypeConverter(typeof(AxisCrossingValueConverter)), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + override public double Crossing + { + get + { + return base.Crossing; + } + set + { + base.Crossing = value; + } + } + + /// + /// Sub-axes collection. + /// + [ + SRCategory("CategoryAttributeSubAxes"), + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never), + Bindable(true), + SRDescription("DescriptionAttributeSubAxes"), + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + ] + override public SubAxisCollection SubAxes + { + get + { + return base.SubAxes; + } + } + + /// + /// Indicates if this axis object present the main or sub axis. + /// + override internal bool IsSubAxis + { + get + { + return true; + } + } + + /// + /// Returns sub-axis name. + /// + override internal string SubAxisName + { + get + { + return base.Name; + } + } + +#endregion // Properties + +#region Methods + + /// + /// Find axis position using crossing value. + /// + /// Axis crossing should be ignored. + /// Relative position + override internal double GetAxisPosition(bool ignoreCrossing) + { + // Parent axis must be set + if(this.parentAxis != null) + { + // Get position of the parent axis + double position = this.parentAxis.GetAxisPosition(ignoreCrossing); + + // Addjust parent position by the offset + if(this.parentAxis.AxisPosition == AxisPosition.Left) + { + position -= this.offsetFromParent; + } + else if(this.parentAxis.AxisPosition == AxisPosition.Right) + { + position += this.offsetFromParent; + } + else if(this.parentAxis.AxisPosition == AxisPosition.Top) + { + position -= this.offsetFromParent; + } + else if(this.parentAxis.AxisPosition == AxisPosition.Bottom) + { + position += this.offsetFromParent; + } + return position; + } + + return 0.0; + } + +#endregion // Methods + +#region Type converter + +#if WINFORMS_CONTROL + + internal class SubAxisConverter : TypeConverter + { + /// + /// This method overrides CanConvertTo from TypeConverter. This is called when someone + /// wants to convert an instance of object to another type. Here, + /// only conversion to an InstanceDescriptor is supported. + /// + /// Descriptor context. + /// Destination type. + /// True if object can be converted. + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof(InstanceDescriptor)) + { + return true; + } + + // Always call the base to see if it can perform the conversion. + return base.CanConvertTo(context, destinationType); + } + + /// + /// This code performs the actual conversion from an object to an InstanceDescriptor. + /// + /// Descriptor context. + /// Culture information. + /// Object value. + /// Destination type. + /// Converted object. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(InstanceDescriptor)) + { + ConstructorInfo ci = typeof(SubAxis).GetConstructor(System.Type.EmptyTypes); + return new InstanceDescriptor(ci, null, false); + } + + // Always call base, even if you can't convert. + return base.ConvertTo(context, culture, value, destinationType); + } + } + +#endif //#if WINFORMS_CONTROL + +#endregion + } + + /// + /// SubAxisCollection is a strongly typed collection of chart sub-axes objects. + /// Collection indexer can accept sub-axis index or it's unique name as a parameter. + /// + [ + SRDescription("DescriptionAttributeSubAxisCollection_SubAxisCollection"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class SubAxisCollection : CollectionBase + { +#region Fields + + /// + /// Sub-Axis parent axis object. + /// + internal Axis parentAxis = null; + +#endregion + +#region Construction and Initialization + + /// + /// Default public constructor. + /// + /// + /// This constructor is for internal use and should not be part of documentation. + /// + public SubAxisCollection() + { + this.parentAxis = null; + } + + /// + /// Public constructor. + /// + /// + /// Chart object. + /// + /// + /// This constructor is for the internal use and should not be part of documentation. + /// + internal SubAxisCollection(Axis parentAxis) + { + this.parentAxis = parentAxis; + } + +#endregion + +#region Indexer + + /// + /// SubAxis collection indexer. + /// + /// + /// The SubAxis object's name or index can be provided as a parameter. Returns the object. + /// Make sure to cast the SubAxis to it's type (e.g. LineSubAxis) to access type + /// specific properties. + /// + [ + SRDescription("DescriptionAttributeSubAxisCollection_Item"), + ] + public SubAxis this[object parameter] + { + get + { + // Get SubAxis by index + if(parameter is int) + { + return (SubAxis)this.List[(int)parameter]; + } + + // Get SubAxis by name + else if(parameter is string) + { + // Find SubAxis with specified name + foreach(SubAxis SubAxis in this.List) + { + if(SubAxis.Name == (string)parameter) + { + return SubAxis; + } + } + + // SubAxis with specified name was not found + throw(new ArgumentException( SR.ExceptionSubAxisNameNotFound( (string)parameter ) ) ); + } + + // Invalid type of the indexer argument + throw(new ArgumentException(SR.ExceptionInvalidIndexerArgumentType)); + } + + set + { + // Check new SubAxis name + int indexSubAxis = -1; + if(value.Name.Length != 0) + { + indexSubAxis = this.List.IndexOf(value); + } + else + { + AssignUniqueName(value); + } + + // Set using index in the collection + if(parameter is int) + { + // Check if SubAxis with this name already exists + if( indexSubAxis != -1 && indexSubAxis != (int)parameter) + { + throw( new ArgumentException( SR.ExceptionSubAxisNameAlreadyExistsInCollection( value.Name ) ) ); + } + + this.List[(int)parameter] = value; + } + + // Set using name in the collection + else if(parameter is string) + { + // Find legend with specified name + int index = 0; + foreach(SubAxis SubAxis in this.List) + { + if(SubAxis.Name == (string)parameter) + { + // Check if SubAxis with this name already exists + if( indexSubAxis != -1 && indexSubAxis != index) + { + throw( new ArgumentException( SR.ExceptionSubAxisNameAlreadyExistsInCollection( value.Name ) ) ); + } + + this.List[index] = value; + break; + } + ++index; + } + } + else + { + throw(new ArgumentException(SR.ExceptionInvalidIndexerArgumentType)); + } + + this.Invalidate(); + } + } + +#endregion + +#region Collection Add and Insert methods + + /// + /// Removes the SubAxis with the specified name from the collection. + /// + /// + /// Name of the SubAxis to be removed. + /// + public void Remove(string name) + { + SubAxis axis = FindByName(name); + if(axis != null) + { + this.List.Remove(axis); + } + } + + /// + /// Removes the given SubAxis from the collection. + /// + /// + /// object to be removed. + /// + public void Remove(SubAxis SubAxis) + { + if(SubAxis != null) + { + this.List.Remove(SubAxis); + } + } + + /// + /// Adds a SubAxis to the end of the collection. + /// + /// + /// object to add. + /// + /// + /// Index of the newly added object. + /// + public int Add(SubAxis SubAxis) + { + return this.List.Add(SubAxis); + } + + /// + /// Inserts a SubAxis into the collection. + /// + /// + /// Index to insert the object at. + /// + /// + /// object to insert. + /// + public void Insert(int index, SubAxis SubAxis) + { + this.List.Insert(index, SubAxis); + } + +#endregion + +#region Items Inserting and Removing Notification methods + + /// + /// Called before the new item is inserted. + /// + /// Item index. + /// Item object. + /// + /// This is an internal method and should not be part of the documentation. + /// + protected override void OnInsert(int index, object value) + { + // Check SubAxis object name + if( ((SubAxis)value).Name.Length == 0 ) + { + AssignUniqueName((SubAxis)value); + } + else + { + if(this.FindByName(((SubAxis)value).Name) != null) + { + throw(new InvalidOperationException(SR.ExceptionSubAxisNameIsNotUnique( ((SubAxis)value).Name ))); + } + } + } + + /// + /// After new item inserted. + /// + /// Item index. + /// Item object. + /// + /// This is an internal method and should not be part of the documentation. + /// + protected override void OnInsertComplete(int index, object value) + { + // Set SubAxis parent axis reference + SubAxis subAxis = (SubAxis)value; + subAxis.parentAxis = this.parentAxis; + if(this.parentAxis != null) + { + subAxis.chart = this.parentAxis.chart; + subAxis.Common = this.parentAxis.Common; + subAxis.chartArea = this.parentAxis.chartArea; + subAxis.axisType= this.parentAxis.axisType; + subAxis.AxisPosition= this.parentAxis.AxisPosition; + } + this.Invalidate(); + } + + /// + /// After item removed. + /// + /// Item index. + /// Item object. + /// + /// This is an internal method and should not be part of the documentation. + /// + protected override void OnRemoveComplete(int index, object value) + { + // Reset SubAxis parent axis reference + ((SubAxis)value).parentAxis = null; + + this.Invalidate(); + } + + /// + /// After all items removed. + /// + /// + /// This is an internal method and should not be part of the documentation. + /// + protected override void OnClearComplete() + { + this.Invalidate(); + } + +#endregion + +#region Helper Methods + + /// + /// Invalidates chart the collection belongs to. + /// + private void Invalidate() + { +#if WINFORMS_CONTROL + if(this.parentAxis != null && this.parentAxis.chart != null) + { + this.parentAxis.chart.dirtyFlag = true; + this.parentAxis.chart.Invalidate(); + } +#endif + } + + /// + /// Assigns a unique name to the SubAxis object based on it's type. + /// + /// SubAxis object to be named. + internal void AssignUniqueName(SubAxis SubAxis) + { + // Generate name using SubAxis type name and unique index + string name = string.Empty; + int index = 1; + do + { + name = "SubAxis" + index.ToString(); + ++index; + } while(this.FindByName(name) != null && index < 10000 ); + + // Asign unique name; + SubAxis.Name = name; + } + + /// + /// Finds SubAxis by name. + /// + /// Name of the chart SubAxis. + /// SubAxis or null if it does not exist. + internal SubAxis FindByName(string name) + { + SubAxis result = null; + for(int index = 0; index < this.List.Count; index ++) + { + // Compare SubAxis name + if(String.Compare(this[index].Name, name, true, System.Globalization.CultureInfo.CurrentCulture) == 0) + { + result = this[index]; + break; + } + } + + return result; + } + +#endregion + } +} + +#endif // SUBAXES + diff --git a/System.Web.DataVisualization/Common/General/Title.cs b/System.Web.DataVisualization/Common/General/Title.cs new file mode 100644 index 000000000..00090cfdc --- /dev/null +++ b/System.Web.DataVisualization/Common/General/Title.cs @@ -0,0 +1,2237 @@ +//------------------------------------------------------------- +// +// Copyright © Microsoft Corporation. All Rights Reserved. +// +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: Title.cs +// +// Namespace: DataVisualization.Charting +// +// Classes: TitleCollection, Title, Docking +// +// Purpose: Titles can be added to the chart by simply including +// those titles into the Titles collection, which is +// found in the root Chart object. The Title object +// incorporates several properties that can be used to +// position, dock, and control the appearance of any +// Title. Title positioning can be explicitly set, or +// you can specify that your title be docked. The +// charting control gives you full control over all of +// the appearance properties of your Titles, so you have +// the ability to set specific properties for such things +// as fonts, or colors, and even text effects. +// +// NOTE: In early versions of the Chart control only 1 title was +// exposed through the Title, TitleFont and TitleFontColor properties +// in the root chart object. Due to the customer requests, support for +// unlimited number of titles was added through the TitleCollection +// exposed as a Titles property of the root chart object. Old +// properties were deprecated and marked as non-browsable. +// +// Reviewed: AG - Microsoft 13, 2007 +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; + using System.ComponentModel.Design.Serialization; + using System.Reflection; + using System.Windows.Forms.Design; +#else +using System.Web; +using System.Web.UI; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Title enumerations + + /// + /// An enumeration of chart element docking styles. + /// + public enum Docking + { + /// + /// Docked to the top. + /// + Top, + + /// + /// Docked to the right. + /// + Right, + + /// + /// Docked to the bottom. + /// + Bottom, + + /// + /// Docked to the left. + /// + Left, + }; + + /// + /// Text drawing styles. + /// + public enum TextStyle + { + /// + /// Default text drawing style. + /// + Default, + + /// + /// Shadow text. + /// + Shadow, + + /// + /// Emboss text. + /// + Emboss, + + /// + /// Embed text. + /// + Embed, + + /// + /// Frame text. + /// + Frame + } + + + /// + /// An enumeration of chart text orientation. + /// + public enum TextOrientation + { + /// + /// Orientation is automatically determined based on the type of the + /// chart element it is used in. + /// + Auto, + + /// + /// Horizontal text. + /// + Horizontal, + + /// + /// Text rotated 90 degrees and oriented from top to bottom. + /// + Rotated90, + + /// + /// Text rotated 270 degrees and oriented from bottom to top. + /// + Rotated270, + + /// + /// Text characters are not rotated and position one below the other. + /// + Stacked + } + + #endregion + + /// + /// The Title class provides properties which define content, visual + /// appearance and position of the single chart title. It also + /// contains methods responsible for calculating title position, + /// drawing and hit testing. + /// + [ + SRDescription("DescriptionAttributeTitle5"), + ] +#if Microsoft_CONTROL + public class Title : ChartNamedElement, IDisposable +#else +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class Title : ChartNamedElement, IDisposable, IChartMapArea +#endif + { + #region Fields + + // Spacing between title text and the border in pixels + internal int titleBorderSpacing = 4; + + + //*********************************************************** + //** Private data members, which store properties values + //*********************************************************** + + // Title text + private string _text = String.Empty; + + // Title drawing style + private TextStyle _style = TextStyle.Default; + + // Title position + private ElementPosition _position = null; + + // Background properties + private bool _visible = true; + private Color _backColor = Color.Empty; + private ChartHatchStyle _backHatchStyle = ChartHatchStyle.None; + private string _backImage = ""; + private ChartImageWrapMode _backImageWrapMode = ChartImageWrapMode.Tile; + private Color _backImageTransparentColor = Color.Empty; + private ChartImageAlignmentStyle _backImageAlignment = ChartImageAlignmentStyle.TopLeft; + private GradientStyle _backGradientStyle = GradientStyle.None; + private Color _backSecondaryColor = Color.Empty; + private int _shadowOffset = 0; + private Color _shadowColor = Color.FromArgb(128, 0, 0, 0); + + // Border properties + private Color _borderColor = Color.Empty; + private int _borderWidth = 1; + private ChartDashStyle _borderDashStyle = ChartDashStyle.Solid; + + // Font properties + private FontCache _fontCache = new FontCache(); + private Font _font; + private Color _foreColor = Color.Black; + + // Docking and Alignment properties + private ContentAlignment _alignment = ContentAlignment.MiddleCenter; + private Docking _docking = Docking.Top; + private string _dockedToChartArea = Constants.NotSetValue; + private bool _isDockedInsideChartArea = true; + private int _dockingOffset = 0; + + // Interactive properties + private string _toolTip = String.Empty; + +#if !Microsoft_CONTROL + private string _url = String.Empty; + private string _mapAreaAttributes = String.Empty; + private string _postbackValue = String.Empty; +#endif + + // Default text orientation + private TextOrientation _textOrientation = TextOrientation.Auto; + + #endregion + + #region Constructors and Initialization + + /// + /// Title constructor. + /// + public Title() + { + Initialize(string.Empty, Docking.Top, null, Color.Black); + } + + /// + /// Public constructor. + /// + /// Title text. + public Title(string text) + { + Initialize(text, Docking.Top, null, Color.Black); + } + + /// + /// Title constructor. + /// + /// Title text. + /// Title docking. + public Title(string text, Docking docking) + { + Initialize(text, docking, null, Color.Black); + } + + /// + /// Title constructor. + /// + /// Title text. + /// Title docking. + /// Title font. + /// Title color. + public Title(string text, Docking docking, Font font, Color color) + { + Initialize(text, docking, font, color); + } + + /// + /// Initialize title object. + /// + /// Title text. + /// Title docking. + /// Title font. + /// Title color. + private void Initialize(string text, Docking docking, Font font, Color color) + { + // Initialize fields + this._position = new ElementPosition(this); + this._font = _fontCache.DefaultFont; + this._text = text; + this._docking = docking; + this._foreColor = color; + if(font != null) + { + this._font = font; + } + } + + #endregion + + #region Properties + + /// + /// Gets or sets the unique name of a ChartArea object. + /// + [ + + SRCategory("CategoryAttributeMisc"), + Bindable(true), + SRDescription("DescriptionAttributeTitle_Name"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public override string Name + { + get + { + return base.Name; + } + set + { + base.Name = value; + } + } + + /// + /// Gets or sets the text orientation. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(TextOrientation.Auto), + SRDescription("DescriptionAttribute_TextOrientation"), + NotifyParentPropertyAttribute(true), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif +] + public TextOrientation TextOrientation + { + get + { + return this._textOrientation; + } + set + { + this._textOrientation = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets a flag that specifies whether the title is visible. + /// + /// + /// True if the title is visible; false otherwise. + /// + [ + SRCategory("CategoryAttributeAppearance"), + DefaultValue(true), + SRDescription("DescriptionAttributeTitle_Visible"), + ParenthesizePropertyNameAttribute(true), + ] + virtual public bool Visible + { + get + { + return _visible; + } + set + { + _visible = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the chart area name which the title is docked to inside or outside. + /// + [ + SRCategory("CategoryAttributeDocking"), + Bindable(true), + DefaultValue(Constants.NotSetValue), + SRDescription("DescriptionAttributeTitle_DockToChartArea"), + TypeConverter(typeof(LegendAreaNameConverter)), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public string DockedToChartArea + { + get + { + return _dockedToChartArea; + } + set + { + if(value != _dockedToChartArea) + { + if(value.Length == 0) + { + _dockedToChartArea = Constants.NotSetValue; + } + else + { + if (Chart != null && Chart.ChartAreas != null) + { + Chart.ChartAreas.VerifyNameReference(value); + } + _dockedToChartArea = value; + } + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets a property which indicates whether the title is docked inside chart area. + /// DockedToChartArea property must be set first. + /// + [ + SRCategory("CategoryAttributeDocking"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeTitle_DockInsideChartArea"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public bool IsDockedInsideChartArea + { + get + { + return _isDockedInsideChartArea; + } + set + { + if(value != _isDockedInsideChartArea) + { + _isDockedInsideChartArea = value; + this.Invalidate(false); + } + } + } + + /// + /// Gets or sets the positive or negative offset of the docked title position. + /// + [ + SRCategory("CategoryAttributeDocking"), + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributeTitle_DockOffset"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + ] + public int DockingOffset + { + get + { + return _dockingOffset; + } + set + { + if(value != _dockingOffset) + { + if (value < -100 || value > 100) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionValueMustBeInRange("DockingOffset", (-100).ToString(CultureInfo.CurrentCulture), (100).ToString(CultureInfo.CurrentCulture)))); + } + _dockingOffset = value; + this.Invalidate(false); + } + } + } + + + /// + /// Gets or sets the position of the title. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributeTitle_Position"), +#if Microsoft_CONTROL + DesignerSerializationVisibility(DesignerSerializationVisibility.Content), +#else + PersistenceMode(PersistenceMode.InnerProperty), +#endif + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ElementPositionConverter)), + SerializationVisibilityAttribute(SerializationVisibility.Element) + ] + public ElementPosition Position + { + get + { + // Serialize only position values if Auto set to false + if (Chart != null && Chart.serializationStatus == SerializationStatus.Saving) + { + if(_position.Auto) + { + return new ElementPosition(); + } + else + { + ElementPosition newPosition = new ElementPosition(); +#if Microsoft_CONTROL + newPosition.Auto = false; +#else + newPosition.Auto = true; +#endif + newPosition.SetPositionNoAuto(_position.X, _position.Y, _position.Width, _position.Height); + return newPosition; + } + } + return _position; + } + set + { + _position = value; + _position.Parent = this; + this.Invalidate(false); + } + } + + /// + /// Determoines if this position should be serialized. + /// + /// + internal bool ShouldSerializePosition() + { + return !this.Position.Auto; + } + + + /// + /// Gets or sets the text of the title. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeTitle_Text"), + NotifyParentPropertyAttribute(true), + ParenthesizePropertyNameAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public string Text + { + get + { + return _text; + } + set + { + _text = (value == null) ? string.Empty : value; + this.Invalidate(false); + } + } + + + /// + /// Title drawing style. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(TextStyle.Default), + SRDescription("DescriptionAttributeTextStyle"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public TextStyle TextStyle + { + get + { + return _style; + } + set + { + _style = value; + this.Invalidate(true); + } + } + + + /// + /// Gets or sets the background color of the title. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackColor + { + get + { + return _backColor; + } + set + { + _backColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the border color of the title. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBorderColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BorderColor + { + get + { + return _borderColor; + } + set + { + _borderColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the border style of the title. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartDashStyle.Solid), + SRDescription("DescriptionAttributeBorderDashStyle"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartDashStyle BorderDashStyle + { + get + { + return _borderDashStyle; + } + set + { + _borderDashStyle = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the border width of the title. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeBorderWidth"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int BorderWidth + { + get + { + return _borderWidth; + } + set + { + if(value < 0) + { + throw (new ArgumentOutOfRangeException("value", SR.ExceptionTitleBorderWidthIsNegative)); + } + _borderWidth = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the background image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeBackImage"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + NotifyParentPropertyAttribute(true), + ] + public string BackImage + { + get + { + return _backImage; + } + set + { + _backImage = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the background image drawing mode. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageWrapMode.Tile), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageWrapMode"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageWrapMode BackImageWrapMode + { + get + { + return _backImageWrapMode; + } + set + { + _backImageWrapMode = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets a color which will be replaced with a transparent color while drawing the background image. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageTransparentColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackImageTransparentColor + { + get + { + return _backImageTransparentColor; + } + set + { + _backImageTransparentColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the background image alignment used by unscale drawing mode. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageAlignmentStyle.TopLeft), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackImageAlign"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ChartImageAlignmentStyle BackImageAlignment + { + get + { + return _backImageAlignment; + } + set + { + _backImageAlignment = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the background gradient style. + /// + /// + /// + /// + /// + /// A value used for the background. + /// + /// + /// Two colors are used to draw the gradient, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(GradientStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackGradientStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + public GradientStyle BackGradientStyle + { + get + { + return _backGradientStyle; + } + set + { + _backGradientStyle = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the secondary background color. + /// + /// + /// + /// + /// + /// A value used for the secondary color of a background with + /// hatching or gradient fill. + /// + /// + /// This color is used with when or + /// are used. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackSecondaryColor"), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color BackSecondaryColor + { + get + { + return _backSecondaryColor; + } + set + { + _backSecondaryColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the background hatch style. + /// + /// + /// + /// + /// + /// A value used for the background. + /// + /// + /// Two colors are used to draw the hatching, and . + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartHatchStyle.None), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackHatchStyle"), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + #endif + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + public ChartHatchStyle BackHatchStyle + { + get + { + return _backHatchStyle; + } + set + { + _backHatchStyle = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets the title font. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"), + SRDescription("DescriptionAttributeTitle_Font"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Font Font + { + get + { + return _font; + } + set + { + _font = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the title fore color. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "Black"), + SRDescription("DescriptionAttributeTitle_Color"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color ForeColor + { + get + { + return _foreColor; + } + set + { + _foreColor = value; + this.Invalidate(true); + } + } + + /// + /// Gets or sets title alignment. + /// + [ + SRCategory("CategoryAttributeDocking"), + Bindable(true), + DefaultValue(ContentAlignment.MiddleCenter), + SRDescription("DescriptionAttributeTitle_Alignment"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public ContentAlignment Alignment + { + get + { + return _alignment; + } + set + { + _alignment = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the title docking style. + /// + [ + SRCategory("CategoryAttributeDocking"), + Bindable(true), + DefaultValue(Docking.Top), + SRDescription("DescriptionAttributeTitle_Docking"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Docking Docking + { + get + { + return _docking; + } + set + { + _docking = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the title shadow offset. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributeShadowOffset"), + NotifyParentPropertyAttribute(true), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public int ShadowOffset + { + get + { + return _shadowOffset; + } + set + { + _shadowOffset = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the title shadow color. + /// + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "128, 0, 0, 0"), + SRDescription("DescriptionAttributeShadowColor"), + NotifyParentPropertyAttribute(true), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public Color ShadowColor + { + get + { + return _shadowColor; + } + set + { + _shadowColor = value; + this.Invalidate(false); + } + } + + /// + /// Gets or sets the tooltip. + /// + [ +#if !Microsoft_CONTROL + SRCategory("CategoryAttributeMapArea"), +#else + SRCategory("CategoryAttributeToolTip"), +#endif + Bindable(true), + SRDescription("DescriptionAttributeToolTip"), + DefaultValue(""), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public string ToolTip + { + set + { + _toolTip = value; + } + get + { + return _toolTip; + } + } + + +#if !Microsoft_CONTROL + + /// + /// Gets or sets the URL target of the title. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeUrl"), + DefaultValue(""), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base) +#endif + ] + public string Url + { + set + { + _url = value; + } + get + { + return _url; + } + } + /// + /// Gets or sets the other attributes of the title map area. + /// + [ + SRCategory("CategoryAttributeMapArea"), + Bindable(true), + SRDescription("DescriptionAttributeMapAreaAttributes"), + DefaultValue(""), + PersistenceMode(PersistenceMode.Attribute) + ] + public string MapAreaAttributes + { + set + { + _mapAreaAttributes = value; + } + get + { + return _mapAreaAttributes; + } + } + + /// + /// Gets or sets the postback value which can be processed on a click event. + /// + /// The value which is passed to a click event as an argument. + [DefaultValue("")] + [SRCategory(SR.Keys.CategoryAttributeMapArea)] + [SRDescription(SR.Keys.DescriptionAttributePostBackValue)] + public string PostBackValue + { + get + { + return this._postbackValue; + } + set + { + this._postbackValue = value; + } + } + + +#endif + + /// + /// True if title background or border is visible + /// + internal bool BackGroundIsVisible + { + get + { + if(!this.BackColor.IsEmpty || + this.BackImage.Length > 0 || + (!this.BorderColor.IsEmpty && this.BorderDashStyle != ChartDashStyle.NotSet) ) + { + return true; + } + + return false; + } + } + + #endregion + + #region Helper Methods + + /// + /// Checks if chart title is drawn vertically. + /// Note: From the drawing perspective stacked text orientation is not vertical. + /// + /// True if text is vertical. + private bool IsTextVertical + { + get + { + TextOrientation currentTextOrientation = this.GetTextOrientation(); + return currentTextOrientation == TextOrientation.Rotated90 || currentTextOrientation == TextOrientation.Rotated270; + } + } + + /// + /// Returns title text orientation. If set to Auto automatically determines the + /// orientation based on title docking. + /// + /// Current text orientation. + private TextOrientation GetTextOrientation() + { + if (this.TextOrientation == TextOrientation.Auto) + { + // When chart title is docked to the left or right we automatically + // set vertical text with different rotation angles. + if (this.Position.Auto) + { + if (this.Docking == Docking.Left) + { + return TextOrientation.Rotated270; + } + else if (this.Docking == Docking.Right) + { + return TextOrientation.Rotated90; + } + } + return TextOrientation.Horizontal; + } + return this.TextOrientation; + } + + /// + /// Helper method that checks if title is visible. + /// + /// True if title is visible. + internal bool IsVisible() + { + if(this.Visible) + { + + // Check if title is docked to the chart area + if(this.DockedToChartArea.Length > 0 && + this.Chart != null) + { + if(this.Chart.ChartAreas.IndexOf(this.DockedToChartArea) >= 0) + { + // Do not show title when it is docked to invisible chart area + ChartArea area = this.Chart.ChartAreas[this.DockedToChartArea]; + if(!area.Visible) + { + return false; + } + } + } + + + return true; + } + return false; + } + + /// + /// Invalidate chart title when one of the properties is changed. + /// + /// Indicates that only title area should be invalidated. + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This parameter is used when compiling for the Microsoft version of Chart")] + internal void Invalidate(bool invalidateTitleOnly) + { +#if Microsoft_CONTROL + if(Chart != null) + { + // Set dirty flag + Chart.dirtyFlag = true; + + // Invalidate chart + if(invalidateTitleOnly) + { + // Calculate the position of the title + Rectangle invalRect = Chart.ClientRectangle; + if(this.Position.Width != 0 && this.Position.Height != 0 ) + { + // Convert relative coordinates to absolute coordinates + invalRect.X = (int)(this.Position.X * (Common.ChartPicture.Width - 1) / 100F); + invalRect.Y = (int)(this.Position.Y * (Common.ChartPicture.Height - 1) / 100F); + invalRect.Width = (int)(this.Position.Width * (Common.ChartPicture.Width - 1) / 100F); + invalRect.Height = (int)(this.Position.Height * (Common.ChartPicture.Height - 1) / 100F); + + // Inflate rectangle size using border size and shadow size + invalRect.Inflate(this.BorderWidth + this.ShadowOffset + 1, this.BorderWidth + this.ShadowOffset + 1); + } + + // Invalidate title rectangle only + Chart.Invalidate(invalRect); + } + else + { + Invalidate(); + } + } +#endif // #if Microsoft_CONTROL + } + + #endregion + + #region Painting and Selection Methods + + /// + /// Paints title using chart graphics object. + /// + /// The graph provides drawing object to the display device. A Graphics object is associated with a specific device context. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")] + internal void Paint(ChartGraphics chartGraph ) + { + // check if title is visible + if(!this.IsVisible()) + { + return; + } + + // Title text + string titleText = this.Text; + + //*************************************************************** + //** Calculate title relative position + //*************************************************************** + RectangleF titlePosition = this.Position.ToRectangleF(); + + // Auto set the title position if width or height is not set for custom position + if(!this.Position.Auto && Common != null && Common.ChartPicture != null) + { + if(titlePosition.Width == 0 || titlePosition.Height == 0) + { + // Calculate text layout area + SizeF layoutArea = new SizeF( + (titlePosition.Width == 0) ? Common.ChartPicture.Width : titlePosition.Width, + (titlePosition.Height == 0) ? Common.ChartPicture.Height : titlePosition.Height); + if (this.IsTextVertical) + { + float tempValue = layoutArea.Width; + layoutArea.Width = layoutArea.Height; + layoutArea.Height = tempValue; + } + + // Measure text size + layoutArea = chartGraph.GetAbsoluteSize(layoutArea); + SizeF titleSize = chartGraph.MeasureString( + "W" + titleText.Replace("\\n", "\n"), + this.Font, + layoutArea, + StringFormat.GenericDefault, + this.GetTextOrientation()); + + // Increase text size by 4 pixels + if(this.BackGroundIsVisible) + { + titleSize.Width += titleBorderSpacing; + titleSize.Height += titleBorderSpacing; + } + + // Switch width and height for vertical text + if (this.IsTextVertical) + { + float tempValue = titleSize.Width; + titleSize.Width = titleSize.Height; + titleSize.Height = tempValue; + } + + // Convert text size to relative coordinates + titleSize = chartGraph.GetRelativeSize(titleSize); + + // Update custom position + if(titlePosition.Width == 0) + { + titlePosition.Width = titleSize.Width; + if(this.Alignment == ContentAlignment.BottomRight || + this.Alignment == ContentAlignment.MiddleRight || + this.Alignment == ContentAlignment.TopRight) + { + titlePosition.X = titlePosition.X - titlePosition.Width; + } + else if(this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.MiddleCenter || + this.Alignment == ContentAlignment.TopCenter) + { + titlePosition.X = titlePosition.X - titlePosition.Width/2f; + } + } + if(titlePosition.Height == 0) + { + titlePosition.Height = titleSize.Height; + if(this.Alignment == ContentAlignment.BottomRight || + this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.BottomLeft) + { + titlePosition.Y = titlePosition.Y - titlePosition.Height; + } + else if(this.Alignment == ContentAlignment.MiddleCenter || + this.Alignment == ContentAlignment.MiddleLeft || + this.Alignment == ContentAlignment.MiddleRight) + { + titlePosition.Y = titlePosition.Y - titlePosition.Height/2f; + } + } + + } + } + + //*************************************************************** + //** Convert title position to absolute coordinates + //*************************************************************** + RectangleF absPosition = new RectangleF(titlePosition.Location, titlePosition.Size); + absPosition = chartGraph.GetAbsoluteRectangle(absPosition); + + //*************************************************************** + //** Draw title background, border and shadow + //*************************************************************** + if(this.BackGroundIsVisible && Common.ProcessModePaint ) + { + chartGraph.FillRectangleRel( titlePosition, + BackColor, + BackHatchStyle, + BackImage, + BackImageWrapMode, + BackImageTransparentColor, + BackImageAlignment, + BackGradientStyle, + BackSecondaryColor, + BorderColor, + BorderWidth, + BorderDashStyle, + ShadowColor, + ShadowOffset, + PenAlignment.Inset); + } + else + { + // Adjust text position to be only around the text itself + SizeF titleArea = chartGraph.GetAbsoluteSize(titlePosition.Size); + SizeF titleSize = chartGraph.MeasureString( + "W" + titleText.Replace("\\n", "\n"), + this.Font, + titleArea, + StringFormat.GenericDefault, + this.GetTextOrientation()); + + // Convert text size to relative coordinates + titleSize = chartGraph.GetRelativeSize(titleSize); + + // Adjust position depending on alignment + RectangleF exactTitleRect = new RectangleF( + titlePosition.X, + titlePosition.Y, + titleSize.Width, + titleSize.Height); + if(this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.BottomLeft || + this.Alignment == ContentAlignment.BottomRight ) + { + exactTitleRect.Y = titlePosition.Bottom - exactTitleRect.Height; + } + else if(this.Alignment == ContentAlignment.MiddleCenter || + this.Alignment == ContentAlignment.MiddleLeft || + this.Alignment == ContentAlignment.MiddleRight ) + { + exactTitleRect.Y = titlePosition.Y + + titlePosition.Height / 2f - + exactTitleRect.Height / 2f; + } + + if(this.Alignment == ContentAlignment.BottomRight || + this.Alignment == ContentAlignment.MiddleRight || + this.Alignment == ContentAlignment.TopRight ) + { + exactTitleRect.X = titlePosition.Right - exactTitleRect.Width; + } + else if(this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.MiddleCenter || + this.Alignment == ContentAlignment.TopCenter ) + { + exactTitleRect.X = titlePosition.X + + titlePosition.Width / 2f - + exactTitleRect.Width / 2f; + } + + // NOTE: This approach for text selection can not be used with + // Flash animations because of the bug in Flash viewer. When the + // button shape is placed in the last frame the Alpha value of the + // color is ignored. + + // NOTE: Feature tested again with Flash Player 7 and it seems to be + // working fine. Code below is commented to enable selection in flash + // through transparent rectangle. + // Fixes issue #4172. + + bool drawRect = true; + + // Draw transparent rectangle in the text position + if(drawRect) + { + chartGraph.FillRectangleRel( + exactTitleRect, + Color.FromArgb(0, Color.White), + ChartHatchStyle.None, + String.Empty, + ChartImageWrapMode.Tile, + BackImageTransparentColor, + BackImageAlignment, + GradientStyle.None, + BackSecondaryColor, + Color.Transparent, + 0, + BorderDashStyle, + Color.Transparent, + 0, + PenAlignment.Inset); + } + + // End Selection mode + chartGraph.EndHotRegion( ); + } + + if( Common.ProcessModePaint) + Common.Chart.CallOnPrePaint(new ChartPaintEventArgs(this, chartGraph, Common, Position)); + + //*************************************************************** + //** Add spacing between text and border + //*************************************************************** + if(this.BackGroundIsVisible) + { + absPosition.Width -= this.titleBorderSpacing; + absPosition.Height -= this.titleBorderSpacing; + absPosition.X += this.titleBorderSpacing / 2f; + absPosition.Y += this.titleBorderSpacing / 2f; + } + + //*************************************************************** + //** Create string format + //*************************************************************** + using (StringFormat format = new StringFormat()) + { + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + if (this.Alignment == ContentAlignment.BottomCenter || + this.Alignment == ContentAlignment.BottomLeft || + this.Alignment == ContentAlignment.BottomRight) + { + format.LineAlignment = StringAlignment.Far; + } + else if (this.Alignment == ContentAlignment.TopCenter || + this.Alignment == ContentAlignment.TopLeft || + this.Alignment == ContentAlignment.TopRight) + { + format.LineAlignment = StringAlignment.Near; + } + + if (this.Alignment == ContentAlignment.BottomLeft || + this.Alignment == ContentAlignment.MiddleLeft || + this.Alignment == ContentAlignment.TopLeft) + { + format.Alignment = StringAlignment.Near; + } + else if (this.Alignment == ContentAlignment.BottomRight || + this.Alignment == ContentAlignment.MiddleRight || + this.Alignment == ContentAlignment.TopRight) + { + format.Alignment = StringAlignment.Far; + } + + //*************************************************************** + //** Draw text shadow for the default style when background is not drawn anf ShadowOffset is not null + //*************************************************************** + Color textShadowColor = ChartGraphics.GetGradientColor(this.ForeColor, Color.Black, 0.8); + int textShadowOffset = 1; + TextStyle textStyle = this.TextStyle; + if ((textStyle == TextStyle.Default || textStyle == TextStyle.Shadow) && + !this.BackGroundIsVisible && + ShadowOffset != 0) + { + // Draw shadowed text + textStyle = TextStyle.Shadow; + textShadowColor = ShadowColor; + textShadowOffset = ShadowOffset; + } + + if (textStyle == TextStyle.Shadow) + { + textShadowColor = (textShadowColor.A != 255) ? textShadowColor : Color.FromArgb(textShadowColor.A / 2, textShadowColor); + } + + //*************************************************************** + //** Replace new line characters + //*************************************************************** + titleText = titleText.Replace("\\n", "\n"); + + //*************************************************************** + //** Define text angle depending on the docking + //*************************************************************** + Matrix oldTransform = null; + if (this.IsTextVertical) + { + if (this.GetTextOrientation() == TextOrientation.Rotated270) + { + // IMPORTANT ! + // Right to Left flag has to be used because of bug with .net with multi line vertical text. As soon as .net bug is fixed this flag HAS TO be removed. Bug number 1870. + format.FormatFlags |= StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft; + + // Save old graphics transformation + oldTransform = chartGraph.Transform.Clone(); + + // Rotate tile 180 degrees at center + PointF center = PointF.Empty; + + center.X = absPosition.X + absPosition.Width / 2F; + center.Y = absPosition.Y + absPosition.Height / 2F; + + // Create and set new transformation matrix + Matrix newMatrix = chartGraph.Transform.Clone(); + newMatrix.RotateAt(180, center); + chartGraph.Transform = newMatrix; + } + else if (this.GetTextOrientation() == TextOrientation.Rotated90) + { + // IMPORTANT ! + // Right to Left flag has to be used because of bug with .net with multi line vertical text. As soon as .net bug is fixed this flag HAS TO be removed. Bug number 1870. + format.FormatFlags |= StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft; + } + } + try + { + chartGraph.IsTextClipped = !Position.Auto; + Title.DrawStringWithStyle(chartGraph, titleText, textStyle, this.Font, absPosition, this.ForeColor, textShadowColor, textShadowOffset, format, this.GetTextOrientation()); + } + finally + { + chartGraph.IsTextClipped = false; + } + // Call Paint event + if (Common.ProcessModePaint) + Common.Chart.CallOnPostPaint(new ChartPaintEventArgs(this, chartGraph, Common, Position)); + + //*************************************************************** + //** Restore old transformation + //*************************************************************** + if(oldTransform != null) + { + chartGraph.Transform = oldTransform; + } + + if( Common.ProcessModeRegions ) + { +#if !Microsoft_CONTROL + Common.HotRegionsList.AddHotRegion( titlePosition, this.ToolTip, this.Url, this.MapAreaAttributes, this.PostBackValue, this, ChartElementType.Title, string.Empty ); +#else + Common.HotRegionsList.AddHotRegion( titlePosition, this.ToolTip, null, null, null, this, ChartElementType.Title, null ); +#endif // !Microsoft_CONTROL + } + } + } + + /// + /// Draws the string with style. + /// + /// The chart graph. + /// The title text. + /// The text style. + /// The font. + /// The abs position. + /// Color of the fore. + /// Color of the shadow. + /// The shadow offset. + /// The format. + /// The orientation. + internal static void DrawStringWithStyle( + ChartGraphics chartGraph, + string titleText, + TextStyle textStyle, + Font font, + RectangleF absPosition, + Color foreColor, + Color shadowColor, + int shadowOffset, + StringFormat format, + TextOrientation orientation + ) + { + //*************************************************************** + //** Draw title text + //*************************************************************** + if (titleText.Length > 0) + { + if (textStyle == TextStyle.Default) + { + using (SolidBrush brush = new SolidBrush(foreColor)) + { + chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation); + } + } + else if (textStyle == TextStyle.Frame) + { + using (GraphicsPath graphicsPath = new GraphicsPath()) + { + graphicsPath.AddString( + titleText, + font.FontFamily, + (int)font.Style, + font.Size * 1.3f, + absPosition, + format); + graphicsPath.CloseAllFigures(); + + + using (Pen pen = new Pen(foreColor, 1)) + { + chartGraph.DrawPath(pen, graphicsPath); + } + } + } + else if (textStyle == TextStyle.Embed) + { + // Draw shadow + RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size); + shadowPosition.X -= 1; + shadowPosition.Y -= 1; + using (SolidBrush brush = new SolidBrush(shadowColor)) + { + chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation); + } + // Draw highlighting + shadowPosition.X += 2; + shadowPosition.Y += 2; + Color texthighlightColor = ChartGraphics.GetGradientColor(Color.White, foreColor, 0.3); + using (SolidBrush brush = new SolidBrush(texthighlightColor)) + { + chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation); + } + using (SolidBrush brush = new SolidBrush(foreColor)) + { + // Draw text + chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation); + } + } + else if (textStyle == TextStyle.Emboss) + { + // Draw shadow + RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size); + shadowPosition.X += 1; + shadowPosition.Y += 1; + using (SolidBrush brush = new SolidBrush(shadowColor)) + { + chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation); + } + // Draw highlighting + shadowPosition.X -= 2; + shadowPosition.Y -= 2; + Color texthighlightColor = ChartGraphics.GetGradientColor(Color.White, foreColor, 0.3); + using (SolidBrush brush = new SolidBrush(texthighlightColor)) + { + chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation); + } + // Draw text + using (SolidBrush brush = new SolidBrush(foreColor)) + { + chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation); + } + + } + else if (textStyle == TextStyle.Shadow) + { + // Draw shadow + RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size); + shadowPosition.X += shadowOffset; + shadowPosition.Y += shadowOffset; + using (SolidBrush brush = new SolidBrush(shadowColor)) + { + chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation); + } + // Draw text + using (SolidBrush brush = new SolidBrush(foreColor)) + { + chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation); + } + + } + } + } + + #endregion + + #region Position Calculation Methods + + /// + /// Recalculates title position. + /// + /// Chart graphics used. + /// Area where the title should be docked. + /// Position of the title in the frame. + /// Spacing size in percentage of the area. + internal void CalcTitlePosition( + ChartGraphics chartGraph, + ref RectangleF chartAreasRectangle, + ref RectangleF frameTitlePosition, + float elementSpacing) + { + // Special case for the first title docked to the top when the title frame is used + if(!frameTitlePosition.IsEmpty && + this.Position.Auto && + this.Docking == Docking.Top && + this.DockedToChartArea == Constants.NotSetValue) + { + this.Position.SetPositionNoAuto( + frameTitlePosition.X + elementSpacing, + frameTitlePosition.Y, + frameTitlePosition.Width - 2f * elementSpacing, + frameTitlePosition.Height); + frameTitlePosition = RectangleF.Empty; + return; + } + + // Get title size + RectangleF titlePosition = new RectangleF(); + SizeF layoutArea = new SizeF(chartAreasRectangle.Width, chartAreasRectangle.Height); + + // Switch width and height for vertical text + if (this.IsTextVertical) + { + float tempValue = layoutArea.Width; + layoutArea.Width = layoutArea.Height; + layoutArea.Height = tempValue; + } + + // Meausure text size + layoutArea.Width -= 2f * elementSpacing; + layoutArea.Height -= 2f * elementSpacing; + layoutArea = chartGraph.GetAbsoluteSize(layoutArea); + SizeF titleSize = chartGraph.MeasureString( + "W" + this.Text.Replace("\\n", "\n"), + this.Font, + layoutArea, + StringFormat.GenericDefault, + this.GetTextOrientation()); + + // Increase text size by 4 pixels + if(this.BackGroundIsVisible) + { + titleSize.Width += titleBorderSpacing; + titleSize.Height += titleBorderSpacing; + } + + // Switch width and height for vertical text + if (this.IsTextVertical) + { + float tempValue = titleSize.Width; + titleSize.Width = titleSize.Height; + titleSize.Height = tempValue; + } + + // Convert text size to relative coordinates + titleSize = chartGraph.GetRelativeSize(titleSize); + titlePosition.Height = titleSize.Height; + titlePosition.Width = titleSize.Width; + if(float.IsNaN(titleSize.Height) || float.IsNaN(titleSize.Width)) + { + return; + } + + // Calculate title position + if(this.Docking == Docking.Top) + { + titlePosition.Y = chartAreasRectangle.Y + elementSpacing; + titlePosition.X = chartAreasRectangle.X + elementSpacing; + titlePosition.Width = chartAreasRectangle.Right - titlePosition.X - elementSpacing; + if(titlePosition.Width < 0) + { + titlePosition.Width = 0; + } + + // Adjust position of the chart area(s) + chartAreasRectangle.Height -= titlePosition.Height + elementSpacing; + chartAreasRectangle.Y = titlePosition.Bottom; + } + else if(this.Docking == Docking.Bottom) + { + titlePosition.Y = chartAreasRectangle.Bottom - titleSize.Height - elementSpacing; + titlePosition.X = chartAreasRectangle.X + elementSpacing; + titlePosition.Width = chartAreasRectangle.Right - titlePosition.X - elementSpacing; + if(titlePosition.Width < 0) + { + titlePosition.Width = 0; + } + + // Adjust position of the chart area(s) + chartAreasRectangle.Height -= titlePosition.Height + elementSpacing; + } + if(this.Docking == Docking.Left) + { + titlePosition.X = chartAreasRectangle.X + elementSpacing; + titlePosition.Y = chartAreasRectangle.Y + elementSpacing; + titlePosition.Height = chartAreasRectangle.Bottom - titlePosition.Y - elementSpacing; + if(titlePosition.Height < 0) + { + titlePosition.Height = 0; + } + + // Adjust position of the chart area(s) + chartAreasRectangle.Width -= titlePosition.Width + elementSpacing; + chartAreasRectangle.X = titlePosition.Right; + } + if(this.Docking == Docking.Right) + { + titlePosition.X = chartAreasRectangle.Right - titleSize.Width - elementSpacing; + titlePosition.Y = chartAreasRectangle.Y + elementSpacing; + titlePosition.Height = chartAreasRectangle.Bottom - titlePosition.Y - elementSpacing; + if(titlePosition.Height < 0) + { + titlePosition.Height = 0; + } + + // Adjust position of the chart area(s) + chartAreasRectangle.Width -= titlePosition.Width + elementSpacing; + } + + + // Offset calculated docking position + if(this.DockingOffset != 0) + { + if(this.Docking == Docking.Top || this.Docking == Docking.Bottom) + { + titlePosition.Y += this.DockingOffset; + } + else + { + titlePosition.X += this.DockingOffset; + } + } + + this.Position.SetPositionNoAuto(titlePosition.X, titlePosition.Y, titlePosition.Width, titlePosition.Height); + } + + #endregion + + #region IDisposable Members + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_fontCache != null) + { + _fontCache.Dispose(); + _fontCache = null; + } + if (_position != null) + { + _position.Dispose(); + _position = null; + } + } + } + + + #endregion + } + + /// + /// The TitleCollection class is a strongly typed collection of Title classes. + /// Indexer of this collection can take the title index (integer) or unique + /// title name (string) as a parameter. + /// + [ + SRDescription("DescriptionAttributeTitles"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class TitleCollection : ChartNamedElementCollection + { + + #region Constructors + + /// <summary> + /// TitleCollection constructor. + /// </summary> + /// <param name="parent">Parent chart element.</param> + internal TitleCollection(IChartElement parent) + : base(parent) + { + } + + #endregion + + #region Methods + + /// <summary> + /// Creates a new Title with the specified name and adds it to the collection. + /// </summary> + /// <param name="name">The new chart area name.</param> + /// <returns>New title</returns> + public Title Add(string name) + { + Title title = new Title(name); + this.Add(title); + return title; + } + + + /// <summary> + /// Recalculates title position in the collection for titles docked outside of chart area. + /// </summary> + /// <param name="chartPicture">Chart picture object.</param> + /// <param name="chartGraph">Chart graphics used.</param> + /// <param name="area">Area the title is docked to.</param> + /// <param name="chartAreasRectangle">Area where the title should be positioned.</param> + /// <param name="elementSpacing">Spacing size in percentage of the area.</param> + internal static void CalcOutsideTitlePosition( + ChartPicture chartPicture, + ChartGraphics chartGraph, + ChartArea area, + ref RectangleF chartAreasRectangle, + float elementSpacing) + { + if(chartPicture != null) + { + // Get elemets spacing + float areaSpacing = Math.Min((chartAreasRectangle.Height/100F) * elementSpacing, (chartAreasRectangle.Width/100F) * elementSpacing); + + // Loop through all titles + foreach(Title title in chartPicture.Titles) + { + // Check if title visible + if(!title.IsVisible()) + { + continue; + } + + // Check if all chart area names are valid + if (title.DockedToChartArea != Constants.NotSetValue && chartPicture.ChartAreas.IndexOf(title.DockedToChartArea)<0) + { + throw (new ArgumentException(SR.ExceptionChartTitleDockedChartAreaIsMissing((string)title.DockedToChartArea))); + } + + // Process only titles docked to specified area + if(title.IsDockedInsideChartArea == false && + title.DockedToChartArea == area.Name && + title.Position.Auto) + { + // Calculate title position + RectangleF frameRect = RectangleF.Empty; + RectangleF prevChartAreasRectangle = chartAreasRectangle; + title.CalcTitlePosition(chartGraph, + ref chartAreasRectangle, + ref frameRect, + areaSpacing); + + // Adjust title position + RectangleF titlePosition = title.Position.ToRectangleF(); + if(title.Docking == Docking.Top) + { + titlePosition.Y -= areaSpacing; + if(!area.Position.Auto) + { + titlePosition.Y -= titlePosition.Height; + prevChartAreasRectangle.Y -= titlePosition.Height + areaSpacing; + prevChartAreasRectangle.Height += titlePosition.Height + areaSpacing; + } + } + else if(title.Docking == Docking.Bottom) + { + titlePosition.Y += areaSpacing; + if(!area.Position.Auto) + { + titlePosition.Y = prevChartAreasRectangle.Bottom + areaSpacing; + prevChartAreasRectangle.Height += titlePosition.Height +areaSpacing; + } + } + if(title.Docking == Docking.Left) + { + titlePosition.X -= areaSpacing; + if(!area.Position.Auto) + { + titlePosition.X -= titlePosition.Width; + prevChartAreasRectangle.X -= titlePosition.Width + areaSpacing; + prevChartAreasRectangle.Width += titlePosition.Width + areaSpacing; + } + } + if(title.Docking == Docking.Right) + { + titlePosition.X += areaSpacing; + if(!area.Position.Auto) + { + titlePosition.X = prevChartAreasRectangle.Right + areaSpacing; + prevChartAreasRectangle.Width += titlePosition.Width + areaSpacing; + } + } + + // Set title position without changing the 'Auto' flag + title.Position.SetPositionNoAuto(titlePosition.X, titlePosition.Y, titlePosition.Width, titlePosition.Height); + + // If custom position is used in the chart area reset the curent adjusted position + if (!area.Position.Auto) + { + chartAreasRectangle = prevChartAreasRectangle; + } + + } + } + + } + } + + /// <summary> + /// Recalculates all titles position inside chart area in the collection. + /// </summary> + /// <param name="chartPicture">Chart picture object.</param> + /// <param name="chartGraph">Chart graphics used.</param> + /// <param name="elementSpacing">Spacing size in percentage of the area.</param> + internal static void CalcInsideTitlePosition( + ChartPicture chartPicture, + ChartGraphics chartGraph, + float elementSpacing) + { + if(chartPicture != null) + { + // Check if all chart area names are valid + foreach(Title title in chartPicture.Titles) + { + // Check if title visible + if(!title.IsVisible()) + { + continue; + } + + if (title.DockedToChartArea != Constants.NotSetValue) + { + try + { + ChartArea area = chartPicture.ChartAreas[title.DockedToChartArea]; + } + catch + { + throw(new ArgumentException( SR.ExceptionChartTitleDockedChartAreaIsMissing( (string)title.DockedToChartArea ) ) ); + } + } + } + + // Loop through all chart areas + foreach(ChartArea area in chartPicture.ChartAreas) + { + + // Check if chart area is visible + if(area.Visible) + + { + // Get area position + RectangleF titlePlottingRectangle = area.PlotAreaPosition.ToRectangleF(); + + // Get elemets spacing + float areaSpacing = Math.Min((titlePlottingRectangle.Height/100F) * elementSpacing, (titlePlottingRectangle.Width/100F) * elementSpacing); + + // Loop through all titles + foreach(Title title in chartPicture.Titles) + { + if(title.IsDockedInsideChartArea == true && + title.DockedToChartArea == area.Name && + title.Position.Auto) + { + // Calculate title position + RectangleF frameRect = RectangleF.Empty; + title.CalcTitlePosition(chartGraph, + ref titlePlottingRectangle, + ref frameRect, + areaSpacing); + } + } + } + } + } + } + + #endregion + + #region Event handlers + internal void ChartAreaNameReferenceChanged(object sender, NameReferenceChangedEventArgs e) + { + //If all the chart areas are removed and then the first one is added we don't want to dock the titles + if (e.OldElement == null) + return; + + foreach (Title title in this) + if (title.DockedToChartArea == e.OldName) + title.DockedToChartArea = e.NewName; + } + #endregion + + + } +} diff --git a/System.Web.DataVisualization/Common/SR.cs b/System.Web.DataVisualization/Common/SR.cs new file mode 100644 index 000000000..c585a6720 --- /dev/null +++ b/System.Web.DataVisualization/Common/SR.cs @@ -0,0 +1,12528 @@ +// WARNING: +// This file was generated by the Microsoft DataWarehouse String Resource Tool 1.33.0.0 +// from information in SR.strings. +// DO NOT MODIFY THIS FILE'S CONTENTS, THEY WILL BE OVERWRITTEN +// +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + using System; + using System.Resources; + using System.Globalization; + + + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class SR + { + + protected SR() + { + } + + public static CultureInfo Culture + { + get + { + return Keys.Culture; + } + set + { + Keys.Culture = value; + } + } + + public static string ExceptionElementPositionConverter + { + get + { + return Keys.GetString(Keys.ExceptionElementPositionConverter); + } + } + + public static string ExceptionInvalidServiceContainer + { + get + { + return Keys.GetString(Keys.ExceptionInvalidServiceContainer); + } + } + + public static string ExceptionImageLoaderInvalidServiceContainer + { + get + { + return Keys.GetString(Keys.ExceptionImageLoaderInvalidServiceContainer); + } + } + + public static string ExceptionImageMapAddedHasWrongType + { + get + { + return Keys.GetString(Keys.ExceptionImageMapAddedHasWrongType); + } + } + + public static string ExceptionImageMapInsertedHasWrongType + { + get + { + return Keys.GetString(Keys.ExceptionImageMapInsertedHasWrongType); + } + } + + public static string ExceptionImageMapCircleShapeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionImageMapCircleShapeInvalid); + } + } + + public static string ExceptionImageMapRectangleShapeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionImageMapRectangleShapeInvalid); + } + } + + public static string ExceptionImageMapPolygonShapeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionImageMapPolygonShapeInvalid); + } + } + + public static string ExceptionAnnotationNameIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionAnnotationNameIsEmpty); + } + } + + public static string ExceptionAnnotationPathAddLineAsSegmentsInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAnnotationPathAddLineAsSegmentsInvalid); + } + } + + public static string ExceptionAnnotationLineWidthIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionAnnotationLineWidthIsNegative); + } + } + + public static string ExceptionAnnotationAnchorOffsetInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAnnotationAnchorOffsetInvalid); + } + } + + public static string ExceptionAnnotationGroupedAnchorDataPointMustBeEmpty + { + get + { + return Keys.GetString(Keys.ExceptionAnnotationGroupedAnchorDataPointMustBeEmpty); + } + } + + public static string ExceptionAnnotationGroupedUnableToStartPlacement + { + get + { + return Keys.GetString(Keys.ExceptionAnnotationGroupedUnableToStartPlacement); + } + } + + public static string ExceptionAnnotationNotInCollection + { + get + { + return Keys.GetString(Keys.ExceptionAnnotationNotInCollection); + } + } + + public static string ExceptionAnnotationGroupedAxisMustBeEmpty + { + get + { + return Keys.GetString(Keys.ExceptionAnnotationGroupedAxisMustBeEmpty); + } + } + + public static string ExceptionAnnotationArrowSizeIsZero + { + get + { + return Keys.GetString(Keys.ExceptionAnnotationArrowSizeIsZero); + } + } + + public static string ExceptionAnnotationArrowSizeMustBeLessThen100 + { + get + { + return Keys.GetString(Keys.ExceptionAnnotationArrowSizeMustBeLessThen100); + } + } + + public static string ExceptionAnnotationArrowStyleUnknown + { + get + { + return Keys.GetString(Keys.ExceptionAnnotationArrowStyleUnknown); + } + } + + public static string ExceptionInvalidIndexerArgumentType + { + get + { + return Keys.GetString(Keys.ExceptionInvalidIndexerArgumentType); + } + } + + public static string ExceptionTitleNameIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionTitleNameIsEmpty); + } + } + + public static string ExceptionDataSeriesObjectRequired + { + get + { + return Keys.GetString(Keys.ExceptionDataSeriesObjectRequired); + } + } + + public static string ExceptionDataSeriesNameIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionDataSeriesNameIsEmpty); + } + } + + public static string ExceptionDataSeriesYValuesPerPointIsZero + { + get + { + return Keys.GetString(Keys.ExceptionDataSeriesYValuesPerPointIsZero); + } + } + + public static string ExceptionDataSeriesYValueNumberInvalid + { + get + { + return Keys.GetString(Keys.ExceptionDataSeriesYValueNumberInvalid); + } + } + + public static string ExceptionSeriesNameIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionSeriesNameIsEmpty); + } + } + + public static string ExceptionEditorChartTypeRegistryServiceInaccessible + { + get + { + return Keys.GetString(Keys.ExceptionEditorChartTypeRegistryServiceInaccessible); + } + } + + public static string ExceptionEditorMultipleSeriesEditiingUnsupported + { + get + { + return Keys.GetString(Keys.ExceptionEditorMultipleSeriesEditiingUnsupported); + } + } + + public static string ExceptionEditorContectInstantsIsNotChartObject + { + get + { + return Keys.GetString(Keys.ExceptionEditorContectInstantsIsNotChartObject); + } + } + + public static string ExceptionEditorUITypeEditorInapplicable + { + get + { + return Keys.GetString(Keys.ExceptionEditorUITypeEditorInapplicable); + } + } + + public static string ExceptionEditorUITypeEditorInt32ApplicableOnly + { + get + { + return Keys.GetString(Keys.ExceptionEditorUITypeEditorInt32ApplicableOnly); + } + } + + public static string ExceptionRectangleConverterStringFormatInvalid + { + get + { + return Keys.GetString(Keys.ExceptionRectangleConverterStringFormatInvalid); + } + } + + public static string ExceptionChartAreaObjectRequired + { + get + { + return Keys.GetString(Keys.ExceptionChartAreaObjectRequired); + } + } + + public static string ExceptionChartAreaInsertedHasWrongType + { + get + { + return Keys.GetString(Keys.ExceptionChartAreaInsertedHasWrongType); + } + } + + public static string ExceptionChartAreaAlreadyExistsShort + { + get + { + return Keys.GetString(Keys.ExceptionChartAreaAlreadyExistsShort); + } + } + + public static string ExceptionChartAreaNameIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionChartAreaNameIsEmpty); + } + } + + public static string ExceptionChartArea3DPerspectiveInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartArea3DPerspectiveInvalid); + } + } + + public static string ExceptionChartArea3DInclinationInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartArea3DInclinationInvalid); + } + } + + public static string ExceptionChartArea3DRotationInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartArea3DRotationInvalid); + } + } + + public static string ExceptionChartArea3DWallWidthInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartArea3DWallWidthInvalid); + } + } + + public static string ExceptionChartArea3DPointsDepthInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartArea3DPointsDepthInvalid); + } + } + + public static string ExceptionChartArea3DPointsGapInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartArea3DPointsGapInvalid); + } + } + + public static string ExceptionCursorIntervalOffsetIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionCursorIntervalOffsetIsNegative); + } + } + + public static string ExceptionCursorLineWidthIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionCursorLineWidthIsNegative); + } + } + + public static string ExceptionGraphicsMarkerStyleUnknown + { + get + { + return Keys.GetString(Keys.ExceptionGraphicsMarkerStyleUnknown); + } + } + + public static string ExceptionGraphics3DMarkerStyleUnknown + { + get + { + return Keys.GetString(Keys.ExceptionGraphics3DMarkerStyleUnknown); + } + } + + public static string ExceptionGraphics3DCoordinatesInvalid + { + get + { + return Keys.GetString(Keys.ExceptionGraphics3DCoordinatesInvalid); + } + } + + public static string ExceptionAxisLabelsAutoFitMinFontSizeValueInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisLabelsAutoFitMinFontSizeValueInvalid); + } + } + + public static string ExceptionAxisLabelRowIndexIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionAxisLabelRowIndexIsNegative); + } + } + + public static string ExceptionAxisLabelRowIndexMustBe1Or2 + { + get + { + return Keys.GetString(Keys.ExceptionAxisLabelRowIndexMustBe1Or2); + } + } + + public static string ExceptionAxisLabelIndexIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionAxisLabelIndexIsNegative); + } + } + + public static string ExceptionAxisLabelFontAngleInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisLabelFontAngleInvalid); + } + } + + public static string ExceptionCustomLabelAddedHasWrongType + { + get + { + return Keys.GetString(Keys.ExceptionCustomLabelAddedHasWrongType); + } + } + + public static string ExceptionCustomLabelInsertedHasWrongType + { + get + { + return Keys.GetString(Keys.ExceptionCustomLabelInsertedHasWrongType); + } + } + + public static string ExceptionSmartLabelsDirectionUndefined + { + get + { + return Keys.GetString(Keys.ExceptionSmartLabelsDirectionUndefined); + } + } + + public static string ExceptionSmartLabelsMinMovingDistanceIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionSmartLabelsMinMovingDistanceIsNegative); + } + } + + public static string ExceptionSmartLabelsMaxMovingDistanceIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionSmartLabelsMaxMovingDistanceIsNegative); + } + } + + public static string ExceptionStripLineAddedHasWrongType + { + get + { + return Keys.GetString(Keys.ExceptionStripLineAddedHasWrongType); + } + } + + public static string ExceptionStripLineWidthIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionStripLineWidthIsNegative); + } + } + + public static string ExceptionAxisWidthIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionAxisWidthIsNegative); + } + } + + public static string ExceptionAxisDynamicIntervalCalculationFailed + { + get + { + return Keys.GetString(Keys.ExceptionAxisDynamicIntervalCalculationFailed); + } + } + + public static string ExceptionAxisIntervalDecreasingFailed + { + get + { + return Keys.GetString(Keys.ExceptionAxisIntervalDecreasingFailed); + } + } + + public static string ExceptionAxisIntervalIncreasingFailed + { + get + { + return Keys.GetString(Keys.ExceptionAxisIntervalIncreasingFailed); + } + } + + public static string ExceptionAxisLabelsAutoFitMaxFontSizeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisLabelsAutoFitMaxFontSizeInvalid); + } + } + + public static string ExceptionAxisMinimumMaximumInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisMinimumMaximumInvalid); + } + } + + public static string ExceptionAxisStackedChartsDataPointsNumberMismatch + { + get + { + return Keys.GetString(Keys.ExceptionAxisStackedChartsDataPointsNumberMismatch); + } + } + + public static string ExceptionAxisSeriesNotAligned + { + get + { + return Keys.GetString(Keys.ExceptionAxisSeriesNotAligned); + } + } + + public static string ExceptionAxisScaleLogarithmBaseInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleLogarithmBaseInvalid); + } + } + + public static string ExceptionAxisScalePositionInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisScalePositionInvalid); + } + } + + public static string ExceptionAxisScalePositionToValueCallFailed + { + get + { + return Keys.GetString(Keys.ExceptionAxisScalePositionToValueCallFailed); + } + } + + public static string ExceptionAxisScaleIntervalIsZero + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleIntervalIsZero); + } + } + + public static string ExceptionAxisScaleMinimumMaximumInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleMinimumMaximumInvalid); + } + } + + public static string ExceptionAxisScaleIntervalIsLessThen1Year + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleIntervalIsLessThen1Year); + } + } + + public static string ExceptionAxisScaleAutoIntervalInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleAutoIntervalInvalid); + } + } + + public static string ExceptionAxisScaleMinimumValueIsGreaterThenMaximumDataPoint + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleMinimumValueIsGreaterThenMaximumDataPoint); + } + } + + public static string ExceptionAxisScaleLogarithmicNegativeValues + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleLogarithmicNegativeValues); + } + } + + public static string ExceptionChartAreaAxisScaleLogarithmicUnsuitable + { + get + { + return Keys.GetString(Keys.ExceptionChartAreaAxisScaleLogarithmicUnsuitable); + } + } + + public static string ExceptionChartAreaChartTypesCanNotCombine + { + get + { + return Keys.GetString(Keys.ExceptionChartAreaChartTypesCanNotCombine); + } + } + + public static string ExceptionChartAreaSeriesNotFound + { + get + { + return Keys.GetString(Keys.ExceptionChartAreaSeriesNotFound); + } + } + + public static string ExceptionAxisScaleBreaksNumberInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleBreaksNumberInvalid); + } + } + + public static string ExceptionAxisScaleBreaksCollapsibleSpaceInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleBreaksCollapsibleSpaceInvalid); + } + } + + public static string ExceptionAxisScaleBreaksSpacingInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleBreaksSpacingInvalid); + } + } + + public static string ExceptionAxisScaleBreaksLineWidthInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleBreaksLineWidthInvalid); + } + } + + public static string ExceptionAxisScaleSegmentsPositionInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleSegmentsPositionInvalid); + } + } + + public static string ExceptionAxisScaleSegmentsSizeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleSegmentsSizeInvalid); + } + } + + public static string ExceptionAxisScaleSegmentsSpacingInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAxisScaleSegmentsSpacingInvalid); + } + } + + public static string ExceptionTickMarksIntervalIsZero + { + get + { + return Keys.GetString(Keys.ExceptionTickMarksIntervalIsZero); + } + } + + public static string ExceptionTickMarksIntervalIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionTickMarksIntervalIsNegative); + } + } + + public static string ExceptionScrollBarSizeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionScrollBarSizeInvalid); + } + } + + public static string ExceptionScrollBarZoomResetsNumberInvalid + { + get + { + return Keys.GetString(Keys.ExceptionScrollBarZoomResetsNumberInvalid); + } + } + + public static string ExceptionMarkerStepNegativeValue + { + get + { + return Keys.GetString(Keys.ExceptionMarkerStepNegativeValue); + } + } + + public static string ExceptionTextThresholdIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionTextThresholdIsNegative); + } + } + + public static string ExceptionNamedImageObjectRequired + { + get + { + return Keys.GetString(Keys.ExceptionNamedImageObjectRequired); + } + } + + public static string ExceptionNamedImageInsertedHasWrongType + { + get + { + return Keys.GetString(Keys.ExceptionNamedImageInsertedHasWrongType); + } + } + + public static string ExceptionLegendNameIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionLegendNameIsEmpty); + } + } + + public static string ExceptionLegendAddedHasWrongType + { + get + { + return Keys.GetString(Keys.ExceptionLegendAddedHasWrongType); + } + } + + public static string ExceptionLegendInsertedHasWrongType + { + get + { + return Keys.GetString(Keys.ExceptionLegendInsertedHasWrongType); + } + } + + public static string ExceptionBackSecondaryColorIsTransparent + { + get + { + return Keys.GetString(Keys.ExceptionBackSecondaryColorIsTransparent); + } + } + + public static string ExceptionLegendAutoFitMinFontSizeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionLegendAutoFitMinFontSizeInvalid); + } + } + + public static string ExceptionLegendMaximumAutoSizeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionLegendMaximumAutoSizeInvalid); + } + } + + public static string ExceptionLegendColumnSpacingInvalid + { + get + { + return Keys.GetString(Keys.ExceptionLegendColumnSpacingInvalid); + } + } + + public static string ExceptionLegendMarkerBorderWidthIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionLegendMarkerBorderWidthIsNegative); + } + } + + public static string ExceptionLegendItemAddedHasWrongType + { + get + { + return Keys.GetString(Keys.ExceptionLegendItemAddedHasWrongType); + } + } + + public static string ExceptionLegendItemInsertedHasWrongType + { + get + { + return Keys.GetString(Keys.ExceptionLegendItemInsertedHasWrongType); + } + } + + public static string ExceptionLegendColumnIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionLegendColumnIsEmpty); + } + } + + public static string ExceptionSeriesSymbolSizeIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionSeriesSymbolSizeIsNegative); + } + } + + public static string ExceptionMinimumCellWidthIsWrong + { + get + { + return Keys.GetString(Keys.ExceptionMinimumCellWidthIsWrong); + } + } + + public static string ExceptionMaximumCellWidthIsWrong + { + get + { + return Keys.GetString(Keys.ExceptionMaximumCellWidthIsWrong); + } + } + + public static string ExceptionLegendCellNameIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionLegendCellNameIsEmpty); + } + } + + public static string ExceptionLegendCellImageSizeIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionLegendCellImageSizeIsNegative); + } + } + + public static string ExceptionLegendCellSeriesSymbolSizeIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionLegendCellSeriesSymbolSizeIsNegative); + } + } + + public static string ExceptionLegendCellSpanIsLessThenOne + { + get + { + return Keys.GetString(Keys.ExceptionLegendCellSpanIsLessThenOne); + } + } + + public static string ExceptionMarginTopIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionMarginTopIsNegative); + } + } + + public static string ExceptionMarginBottomIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionMarginBottomIsNegative); + } + } + + public static string ExceptionMarginLeftIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionMarginLeftIsNegative); + } + } + + public static string ExceptionMarginRightIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionMarginRightIsNegative); + } + } + + public static string ExceptionElementPositionArgumentOutOfRange + { + get + { + return Keys.GetString(Keys.ExceptionElementPositionArgumentOutOfRange); + } + } + + public static string ExceptionChartHeightIsNotInPixels + { + get + { + return Keys.GetString(Keys.ExceptionChartHeightIsNotInPixels); + } + } + + public static string ExceptionChartWidthIsNotInPixels + { + get + { + return Keys.GetString(Keys.ExceptionChartWidthIsNotInPixels); + } + } + + public static string ExceptionChartBorderIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionChartBorderIsNegative); + } + } + + public static string ExceptionChartCompressionInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartCompressionInvalid); + } + } + + public static string ExceptionChartDataPointsAlignmentFaild + { + get + { + return Keys.GetString(Keys.ExceptionChartDataPointsAlignmentFaild); + } + } + + public static string ExceptionChartDataPointsAlignmentFaildAxisLabelsInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartDataPointsAlignmentFaildAxisLabelsInvalid); + } + } + + public static string ExceptionChartDataPointsInsertionFailedYValuesEmpty + { + get + { + return Keys.GetString(Keys.ExceptionChartDataPointsInsertionFailedYValuesEmpty); + } + } + + public static string ExceptionChartTypeHasNoInterface + { + get + { + return Keys.GetString(Keys.ExceptionChartTypeHasNoInterface); + } + } + + public static string ExceptionBorderTypeHasNoInterface + { + get + { + return Keys.GetString(Keys.ExceptionBorderTypeHasNoInterface); + } + } + + public static string ExceptionChartSerializerContentFlagUnsupported + { + get + { + return Keys.GetString(Keys.ExceptionChartSerializerContentFlagUnsupported); + } + } + + public static string ExceptionChartSerializerContentStringFormatInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartSerializerContentStringFormatInvalid); + } + } + + public static string ExceptionChartSerializerClassNameUndefined + { + get + { + return Keys.GetString(Keys.ExceptionChartSerializerClassNameUndefined); + } + } + + public static string ExceptionChartSerializerPropertyNameUndefined + { + get + { + return Keys.GetString(Keys.ExceptionChartSerializerPropertyNameUndefined); + } + } + + public static string ExceptionChartSerializerWriterObjectInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartSerializerWriterObjectInvalid); + } + } + + public static string ExceptionChartSerializerReaderObjectInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartSerializerReaderObjectInvalid); + } + } + + public static string ExceptionChartSerializerDestinationObjectInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartSerializerDestinationObjectInvalid); + } + } + + public static string ExceptionChartSerializerSourceObjectInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartSerializerSourceObjectInvalid); + } + } + + public static string ExceptionChartSerializerBinaryIgnoreUnknownAttributesUnsupported + { + get + { + return Keys.GetString(Keys.ExceptionChartSerializerBinaryIgnoreUnknownAttributesUnsupported); + } + } + + public static string ExceptionChartSerializerBinaryFromatInvalid + { + get + { + return Keys.GetString(Keys.ExceptionChartSerializerBinaryFromatInvalid); + } + } + + public static string ExceptionChartSerializerPropertyNotFound + { + get + { + return Keys.GetString(Keys.ExceptionChartSerializerPropertyNotFound); + } + } + + public static string ExceptionDataManipulatorPointCountIsZero + { + get + { + return Keys.GetString(Keys.ExceptionDataManipulatorPointCountIsZero); + } + } + + public static string ExceptionDataManipulatorIndexUndefined + { + get + { + return Keys.GetString(Keys.ExceptionDataManipulatorIndexUndefined); + } + } + + public static string ExceptionDataManipulatorIndexFormatInvalid + { + get + { + return Keys.GetString(Keys.ExceptionDataManipulatorIndexFormatInvalid); + } + } + + public static string ExceptionDataManipulatorGroupedSeriesNotSorted + { + get + { + return Keys.GetString(Keys.ExceptionDataManipulatorGroupedSeriesNotSorted); + } + } + + public static string ExceptionDataManipulatorGroupingFormulaUndefined + { + get + { + return Keys.GetString(Keys.ExceptionDataManipulatorGroupingFormulaUndefined); + } + } + + public static string ExceptionDataManipulatorGroupingFormulaUnsupported + { + get + { + return Keys.GetString(Keys.ExceptionDataManipulatorGroupingFormulaUnsupported); + } + } + + public static string ExceptionDataManipulatorGroupingInputSeriesUndefined + { + get + { + return Keys.GetString(Keys.ExceptionDataManipulatorGroupingInputSeriesUndefined); + } + } + + public static string ExceptionDataManipulatorGroupingInputOutputSeriesNumberMismatch + { + get + { + return Keys.GetString(Keys.ExceptionDataManipulatorGroupingInputOutputSeriesNumberMismatch); + } + } + + public static string ExceptionDataBindYValuesToString + { + get + { + return Keys.GetString(Keys.ExceptionDataBindYValuesToString); + } + } + + public static string ExceptionDataBindXValuesToString + { + get + { + return Keys.GetString(Keys.ExceptionDataBindXValuesToString); + } + } + + public static string ExceptionDataBindSeriesToString + { + get + { + return Keys.GetString(Keys.ExceptionDataBindSeriesToString); + } + } + + public static string ExceptionDataBindSeriesGroupByParameterIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionDataBindSeriesGroupByParameterIsEmpty); + } + } + + public static string ExceptionImageUrlIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionImageUrlIsEmpty); + } + } + + public static string ExceptionImageUrlInvalidFormatters + { + get + { + return Keys.GetString(Keys.ExceptionImageUrlInvalidFormatters); + } + } + + public static string ExceptionImageUrlInvalidFormat + { + get + { + return Keys.GetString(Keys.ExceptionImageUrlInvalidFormat); + } + } + + public static string ExceptionImageUrlMissedFormatter + { + get + { + return Keys.GetString(Keys.ExceptionImageUrlMissedFormatter); + } + } + + public static string ExceptionDataManager100StackedSeriesPointsNumeberMismatch + { + get + { + return Keys.GetString(Keys.ExceptionDataManager100StackedSeriesPointsNumeberMismatch); + } + } + + public static string ExceptionFormulaModuleHasNoInterface + { + get + { + return Keys.GetString(Keys.ExceptionFormulaModuleHasNoInterface); + } + } + + public static string ExceptionDataPointConverterInvalidSorting + { + get + { + return Keys.GetString(Keys.ExceptionDataPointConverterInvalidSorting); + } + } + + public static string ExceptionDataPointConverterWrongTypes + { + get + { + return Keys.GetString(Keys.ExceptionDataPointConverterWrongTypes); + } + } + + public static string ExceptionDataPointInsertionXValuesQtyIsLessYValues + { + get + { + return Keys.GetString(Keys.ExceptionDataPointInsertionXValuesQtyIsLessYValues); + } + } + + public static string ExceptionDataPointValueNameInvalid + { + get + { + return Keys.GetString(Keys.ExceptionDataPointValueNameInvalid); + } + } + + public static string ExceptionDataPointValueNameYIndexOutOfRange + { + get + { + return Keys.GetString(Keys.ExceptionDataPointValueNameYIndexOutOfRange); + } + } + + public static string ExceptionDataPointValueNameYIndexIsNotPositive + { + get + { + return Keys.GetString(Keys.ExceptionDataPointValueNameYIndexIsNotPositive); + } + } + + public static string ExceptionDataPointInsertionNoDataSource + { + get + { + return Keys.GetString(Keys.ExceptionDataPointInsertionNoDataSource); + } + } + + public static string ExceptionDataPointBindingYValueNotSpecified + { + get + { + return Keys.GetString(Keys.ExceptionDataPointBindingYValueNotSpecified); + } + } + + public static string ExceptionDataPointInsertionYValueNotSpecified + { + get + { + return Keys.GetString(Keys.ExceptionDataPointInsertionYValueNotSpecified); + } + } + + public static string ExceptionAttributeUnableToDelete + { + get + { + return Keys.GetString(Keys.ExceptionAttributeUnableToDelete); + } + } + + public static string ExceptionAttributeNameIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionAttributeNameIsEmpty); + } + } + + public static string ExceptionAttributeInvalidFormat + { + get + { + return Keys.GetString(Keys.ExceptionAttributeInvalidFormat); + } + } + + public static string ExceptionAttributeDrawSideBySideInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAttributeDrawSideBySideInvalid); + } + } + + public static string ExceptionLabelBorderIsNotPositive + { + get + { + return Keys.GetString(Keys.ExceptionLabelBorderIsNotPositive); + } + } + + public static string ExceptionBorderWidthIsNotPositive + { + get + { + return Keys.GetString(Keys.ExceptionBorderWidthIsNotPositive); + } + } + + public static string ExceptionAngleRangeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionAngleRangeInvalid); + } + } + + public static string ExceptionDataPointYValueStringFormat + { + get + { + return Keys.GetString(Keys.ExceptionDataPointYValueStringFormat); + } + } + + public static string ExceptionParameterFormatInvalid + { + get + { + return Keys.GetString(Keys.ExceptionParameterFormatInvalid); + } + } + + public static string ExceptionStatisticalAnalysesInvalidAlphaValue + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidAlphaValue); + } + } + + public static string ExceptionStatisticalAnalysesInvalidProbabilityValue + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidProbabilityValue); + } + } + + public static string ExceptionStatisticalAnalysesInvalidDegreeOfFreedom + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom); + } + } + + public static string ExceptionStatisticalAnalysesNegativeMeanDifference + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesNegativeMeanDifference); + } + } + + public static string ExceptionStatisticalAnalysesInvalidSeriesNumber + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidSeriesNumber); + } + } + + public static string ExceptionStatisticalAnalysesInvalidMeanDifference + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidMeanDifference); + } + } + + public static string ExceptionStatisticalAnalysesNotEnoughDataPoints + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesNotEnoughDataPoints); + } + } + + public static string ExceptionStatisticalAnalysesInvalidVariance + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidVariance); + } + } + + public static string ExceptionStatisticalAnalysesInvalidTValue + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidTValue); + } + } + + public static string ExceptionStatisticalAnalysesGammaBetaNegativeParameters + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesGammaBetaNegativeParameters); + } + } + + public static string ExceptionStatisticalAnalysesInvalidZValue + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidZValue); + } + } + + public static string ExceptionStatisticalAnalysesZeroVariance + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesZeroVariance); + } + } + + public static string ExceptionStatisticalAnalysesNotEnoughInputSeries + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesNotEnoughInputSeries); + } + } + + public static string ExceptionStatisticalAnalysesInvalidVariableRanges + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidVariableRanges); + } + } + + public static string ExceptionStatisticalAnalysesStudentsInvalidTValue + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesStudentsInvalidTValue); + } + } + + public static string ExceptionStatisticalAnalysesStudentsNegativeFreedomDegree + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesStudentsNegativeFreedomDegree); + } + } + + public static string ExceptionStatisticalAnalysesNormalInvalidProbabilityValue + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesNormalInvalidProbabilityValue); + } + } + + public static string ExceptionStatisticalAnalysesInvalidTailedParameter + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidTailedParameter); + } + } + + public static string ExceptionStatisticalAnalysesInvalidInputParameter + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidInputParameter); + } + } + + public static string ExceptionStatisticalAnalysesIncompleteBetaFunction + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesIncompleteBetaFunction); + } + } + + public static string ExceptionStatisticalAnalysesInvalidAnovaTest + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidAnovaTest); + } + } + + public static string ExceptionStatisticalAnalysesCovariance + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesCovariance); + } + } + + public static string ExceptionStatisticalAnalysesInvalidMedianConditions + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidMedianConditions); + } + } + + public static string ExceptionStatisticalAnalysesInvalidMeanConditions + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidMeanConditions); + } + } + + public static string ExceptionStatisticalAnalysesInvalidVarianceConditions + { + get + { + return Keys.GetString(Keys.ExceptionStatisticalAnalysesInvalidVarianceConditions); + } + } + + public static string ExceptionPeriodParameterIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionPeriodParameterIsNegative); + } + } + + public static string ExceptionPeriodAverageParameterIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionPeriodAverageParameterIsNegative); + } + } + + public static string ExceptionPeriodShortParameterIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionPeriodShortParameterIsNegative); + } + } + + public static string ExceptionPeriodLongParameterIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionPeriodLongParameterIsNegative); + } + } + + public static string ExceptionIndicatorsDeviationMissing + { + get + { + return Keys.GetString(Keys.ExceptionIndicatorsDeviationMissing); + } + } + + public static string ExceptionIndicatorsLongPeriodLessThenShortPeriod + { + get + { + return Keys.GetString(Keys.ExceptionIndicatorsLongPeriodLessThenShortPeriod); + } + } + + public static string ExceptionOscillatorObjectInvalidPeriod + { + get + { + return Keys.GetString(Keys.ExceptionOscillatorObjectInvalidPeriod); + } + } + + public static string ExceptionOscillatorNegativeSignalPeriod + { + get + { + return Keys.GetString(Keys.ExceptionOscillatorNegativeSignalPeriod); + } + } + + public static string ExceptionOscillatorNegativePeriodParameter + { + get + { + return Keys.GetString(Keys.ExceptionOscillatorNegativePeriodParameter); + } + } + + public static string ExceptionVolumeIndicatorStartValueMissing + { + get + { + return Keys.GetString(Keys.ExceptionVolumeIndicatorStartValueMissing); + } + } + + public static string ExceptionPriceIndicatorsShiftParameterMissing + { + get + { + return Keys.GetString(Keys.ExceptionPriceIndicatorsShiftParameterMissing); + } + } + + public static string ExceptionPriceIndicatorsSameYNumber + { + get + { + return Keys.GetString(Keys.ExceptionPriceIndicatorsSameYNumber); + } + } + + public static string ExceptionPriceIndicatorsSameXYNumber + { + get + { + return Keys.GetString(Keys.ExceptionPriceIndicatorsSameXYNumber); + } + } + + public static string ExceptionPriceIndicatorsPeriodMissing + { + get + { + return Keys.GetString(Keys.ExceptionPriceIndicatorsPeriodMissing); + } + } + + public static string ExceptionPriceIndicatorsNotEnoughPoints + { + get + { + return Keys.GetString(Keys.ExceptionPriceIndicatorsNotEnoughPoints); + } + } + + public static string ExceptionPriceIndicatorsFormulaRequiresOneArray + { + get + { + return Keys.GetString(Keys.ExceptionPriceIndicatorsFormulaRequiresOneArray); + } + } + + public static string ExceptionPriceIndicatorsFormulaRequiresTwoArrays + { + get + { + return Keys.GetString(Keys.ExceptionPriceIndicatorsFormulaRequiresTwoArrays); + } + } + + public static string ExceptionPriceIndicatorsFormulaRequiresThreeArrays + { + get + { + return Keys.GetString(Keys.ExceptionPriceIndicatorsFormulaRequiresThreeArrays); + } + } + + public static string ExceptionPriceIndicatorsFormulaRequiresFourArrays + { + get + { + return Keys.GetString(Keys.ExceptionPriceIndicatorsFormulaRequiresFourArrays); + } + } + + public static string ExceptionObjectReferenceIsNull + { + get + { + return Keys.GetString(Keys.ExceptionObjectReferenceIsNull); + } + } + + public static string ExceptionThreeLineBreakCanNotCobine + { + get + { + return Keys.GetString(Keys.ExceptionThreeLineBreakCanNotCobine); + } + } + + public static string ExceptionThreeLineBreakNullReference + { + get + { + return Keys.GetString(Keys.ExceptionThreeLineBreakNullReference); + } + } + + public static string ExceptionThreeLineBreakUsedYValueOutOfRange + { + get + { + return Keys.GetString(Keys.ExceptionThreeLineBreakUsedYValueOutOfRange); + } + } + + public static string ExceptionThreeLineBreakNumberOfLinesInBreakFormatInvalid + { + get + { + return Keys.GetString(Keys.ExceptionThreeLineBreakNumberOfLinesInBreakFormatInvalid); + } + } + + public static string ExceptionThreeLineBreakUpBrickColorInvalid + { + get + { + return Keys.GetString(Keys.ExceptionThreeLineBreakUpBrickColorInvalid); + } + } + + public static string ExceptionThreeLineBreakUsedYValueInvalid + { + get + { + return Keys.GetString(Keys.ExceptionThreeLineBreakUsedYValueInvalid); + } + } + + public static string ExceptionThreeLineBreakNumberOfLinesInBreakValueInvalid + { + get + { + return Keys.GetString(Keys.ExceptionThreeLineBreakNumberOfLinesInBreakValueInvalid); + } + } + + public static string ExceptionRenkoCanNotCobine + { + get + { + return Keys.GetString(Keys.ExceptionRenkoCanNotCobine); + } + } + + public static string ExceptionRenkoNullReference + { + get + { + return Keys.GetString(Keys.ExceptionRenkoNullReference); + } + } + + public static string ExceptionRenkoUsedYValueOutOfRange + { + get + { + return Keys.GetString(Keys.ExceptionRenkoUsedYValueOutOfRange); + } + } + + public static string ExceptionRenkoBoxSizeFormatInvalid + { + get + { + return Keys.GetString(Keys.ExceptionRenkoBoxSizeFormatInvalid); + } + } + + public static string ExceptionRenkoUpBrickColorInvalid + { + get + { + return Keys.GetString(Keys.ExceptionRenkoUpBrickColorInvalid); + } + } + + public static string ExceptionRenkoUsedYValueFormatInvalid + { + get + { + return Keys.GetString(Keys.ExceptionRenkoUsedYValueFormatInvalid); + } + } + + public static string ExceptionPieIntervalsInvalid + { + get + { + return Keys.GetString(Keys.ExceptionPieIntervalsInvalid); + } + } + + public static string ExceptionPieUnassignedFrontBackPoints + { + get + { + return Keys.GetString(Keys.ExceptionPieUnassignedFrontBackPoints); + } + } + + public static string ExceptionPiePointOrderInvalid + { + get + { + return Keys.GetString(Keys.ExceptionPiePointOrderInvalid); + } + } + + public static string ExceptionPieHorizontalLineSizeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionPieHorizontalLineSizeInvalid); + } + } + + public static string ExceptionPieRadialLineSizeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionPieRadialLineSizeInvalid); + } + } + + public static string ExceptionPie3DLabelLineSizeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionPie3DLabelLineSizeInvalid); + } + } + + public static string ExceptionPieRadiusInvalid + { + get + { + return Keys.GetString(Keys.ExceptionPieRadiusInvalid); + } + } + + public static string ExceptionPieMinimumRelativePieSizeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionPieMinimumRelativePieSizeInvalid); + } + } + + public static string ExceptionPieOrderOperationInvalid + { + get + { + return Keys.GetString(Keys.ExceptionPieOrderOperationInvalid); + } + } + + public static string ExceptionPieIntervalsOverlapping + { + get + { + return Keys.GetString(Keys.ExceptionPieIntervalsOverlapping); + } + } + + public static string ExceptionDoughnutNullReference + { + get + { + return Keys.GetString(Keys.ExceptionDoughnutNullReference); + } + } + + public static string ExceptionDoughnutThresholdInvalid + { + get + { + return Keys.GetString(Keys.ExceptionDoughnutThresholdInvalid); + } + } + + public static string ExceptionDoughnutCollectedThresholdUsePercentInvalid + { + get + { + return Keys.GetString(Keys.ExceptionDoughnutCollectedThresholdUsePercentInvalid); + } + } + + public static string ExceptionDoughnutCollectedColorInvalidFormat + { + get + { + return Keys.GetString(Keys.ExceptionDoughnutCollectedColorInvalidFormat); + } + } + + public static string ExceptionDoughnutCollectedThresholdInvalidFormat + { + get + { + return Keys.GetString(Keys.ExceptionDoughnutCollectedThresholdInvalidFormat); + } + } + + public static string ExceptionDoughnutCollectedThresholdInvalidRange + { + get + { + return Keys.GetString(Keys.ExceptionDoughnutCollectedThresholdInvalidRange); + } + } + + public static string ExceptionPointAndFigureUpBrickColorInvalidFormat + { + get + { + return Keys.GetString(Keys.ExceptionPointAndFigureUpBrickColorInvalidFormat); + } + } + + public static string ExceptionPointAndFigureCanNotCombine + { + get + { + return Keys.GetString(Keys.ExceptionPointAndFigureCanNotCombine); + } + } + + public static string ExceptionPointAndFigureNullReference + { + get + { + return Keys.GetString(Keys.ExceptionPointAndFigureNullReference); + } + } + + public static string ExceptionPointAndFigureUsedYValueHighOutOfRange + { + get + { + return Keys.GetString(Keys.ExceptionPointAndFigureUsedYValueHighOutOfRange); + } + } + + public static string ExceptionPointAndFigureUsedYValueLowOutOfrange + { + get + { + return Keys.GetString(Keys.ExceptionPointAndFigureUsedYValueLowOutOfrange); + } + } + + public static string ExceptionPointAndFigureReversalAmountInvalidFormat + { + get + { + return Keys.GetString(Keys.ExceptionPointAndFigureReversalAmountInvalidFormat); + } + } + + public static string ExceptionPointAndFigureUsedYValueHighInvalidFormat + { + get + { + return Keys.GetString(Keys.ExceptionPointAndFigureUsedYValueHighInvalidFormat); + } + } + + public static string ExceptionPointAndFigureUsedYValueLowInvalidFormat + { + get + { + return Keys.GetString(Keys.ExceptionPointAndFigureUsedYValueLowInvalidFormat); + } + } + + public static string ExceptionFastPointMarkerStyleUnknown + { + get + { + return Keys.GetString(Keys.ExceptionFastPointMarkerStyleUnknown); + } + } + + public static string ExceptionFunnelAngleRangeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionFunnelAngleRangeInvalid); + } + } + + public static string ExceptionFunnelCanNotCombine + { + get + { + return Keys.GetString(Keys.ExceptionFunnelCanNotCombine); + } + } + + public static string ExceptionFunnelNeckHeightInvalid + { + get + { + return Keys.GetString(Keys.ExceptionFunnelNeckHeightInvalid); + } + } + + public static string ExceptionFunnelNeckWidthInvalid + { + get + { + return Keys.GetString(Keys.ExceptionFunnelNeckWidthInvalid); + } + } + + public static string ExceptionKagiNullReference + { + get + { + return Keys.GetString(Keys.ExceptionKagiNullReference); + } + } + + public static string ExceptionKagiCanNotCombine + { + get + { + return Keys.GetString(Keys.ExceptionKagiCanNotCombine); + } + } + + public static string ExceptionStackedAreaChartSeriesDataPointsNumberMismatch + { + get + { + return Keys.GetString(Keys.ExceptionStackedAreaChartSeriesDataPointsNumberMismatch); + } + } + + public static string Exception3DPieLabelsIndexInvalid + { + get + { + return Keys.GetString(Keys.Exception3DPieLabelsIndexInvalid); + } + } + + public static string Exception3DChartPointsXValuesUnsorted + { + get + { + return Keys.GetString(Keys.Exception3DChartPointsXValuesUnsorted); + } + } + + public static string ExceptionFunnelMinimumPointHeightAttributeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionFunnelMinimumPointHeightAttributeInvalid); + } + } + + public static string ExceptionErrorBarParameterUndefined + { + get + { + return Keys.GetString(Keys.ExceptionErrorBarParameterUndefined); + } + } + + public static string Exception3DSplineY1ValueIsLessThenY2 + { + get + { + return Keys.GetString(Keys.Exception3DSplineY1ValueIsLessThenY2); + } + } + + public static string ExceptionCustomAttributeDefaultValueTypeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionCustomAttributeDefaultValueTypeInvalid); + } + } + + public static string ExceptionFormulaDataItemsNumberMismatch + { + get + { + return Keys.GetString(Keys.ExceptionFormulaDataItemsNumberMismatch); + } + } + + public static string ExceptionFormulaDataItemsNumberMismatch2 + { + get + { + return Keys.GetString(Keys.ExceptionFormulaDataItemsNumberMismatch2); + } + } + + public static string ExceptionFormulaDataOutputSeriesNumberYValuesIncorrect + { + get + { + return Keys.GetString(Keys.ExceptionFormulaDataOutputSeriesNumberYValuesIncorrect); + } + } + + public static string ExceptionFormulaYIndexInvalid + { + get + { + return Keys.GetString(Keys.ExceptionFormulaYIndexInvalid); + } + } + + public static string ExceptionFormulaXValuesNotAligned + { + get + { + return Keys.GetString(Keys.ExceptionFormulaXValuesNotAligned); + } + } + + public static string ExceptionFormulaInputOutputSeriesMismatch + { + get + { + return Keys.GetString(Keys.ExceptionFormulaInputOutputSeriesMismatch); + } + } + + public static string ExceptionForecastingDegreeInvalid + { + get + { + return Keys.GetString(Keys.ExceptionForecastingDegreeInvalid); + } + } + + public static string ExceptionForecastingExponentialRegressionHasZeroYValues + { + get + { + return Keys.GetString(Keys.ExceptionForecastingExponentialRegressionHasZeroYValues); + } + } + + public static string ExceptionForecastingPowerRegressionHasZeroYValues + { + get + { + return Keys.GetString(Keys.ExceptionForecastingPowerRegressionHasZeroYValues); + } + } + + public static string ExceptionBorderWidthIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionBorderWidthIsNegative); + } + } + + public static string ExceptionBorderWidthIsZero + { + get + { + return Keys.GetString(Keys.ExceptionBorderWidthIsZero); + } + } + + public static string ExceptionLegendBorderWidthIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionLegendBorderWidthIsNegative); + } + } + + public static string ExceptionTitleBorderWidthIsNegative + { + get + { + return Keys.GetString(Keys.ExceptionTitleBorderWidthIsNegative); + } + } + + public static string ExceptionMatrix3DNotinitialized + { + get + { + return Keys.GetString(Keys.ExceptionMatrix3DNotinitialized); + } + } + + public static string ExceptionPaletteIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionPaletteIsEmpty); + } + } + + public static string ExceptionChartPreviewNotAvailable + { + get + { + return Keys.GetString(Keys.ExceptionChartPreviewNotAvailable); + } + } + + public static string ExceptionChartPreviewNotAvailableShort + { + get + { + return Keys.GetString(Keys.ExceptionChartPreviewNotAvailableShort); + } + } + + public static string ExceptionChartOutOfLimits + { + get + { + return Keys.GetString(Keys.ExceptionChartOutOfLimits); + } + } + + public static string ExceptionHttpHandlerCanNotSave + { + get + { + return Keys.GetString(Keys.ExceptionHttpHandlerCanNotSave); + } + } + + public static string ExceptionHttpHandlerValueInvalid + { + get + { + return Keys.GetString(Keys.ExceptionHttpHandlerValueInvalid); + } + } + + public static string ExceptionHttpHandlerTimeoutParameterInvalid + { + get + { + return Keys.GetString(Keys.ExceptionHttpHandlerTimeoutParameterInvalid); + } + } + + public static string ExceptionHttpHandlerUrlMissing + { + get + { + return Keys.GetString(Keys.ExceptionHttpHandlerUrlMissing); + } + } + + public static string ExceptionHttpHandlerUrlInvalid + { + get + { + return Keys.GetString(Keys.ExceptionHttpHandlerUrlInvalid); + } + } + + public static string ExceptionHttpHandlerInvalidLocation + { + get + { + return Keys.GetString(Keys.ExceptionHttpHandlerInvalidLocation); + } + } + + public static string ExceptionHttpHandlerImageNotFound + { + get + { + return Keys.GetString(Keys.ExceptionHttpHandlerImageNotFound); + } + } + + public static string DescriptionCustomAttributeEmptyPointValue + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeEmptyPointValue); + } + } + + public static string DescriptionCustomAttributeIsXAxisQuantitive + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeIsXAxisQuantitive); + } + } + + public static string DescriptionCustomAttributePieDonutExploded + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePieDonutExploded); + } + } + + public static string DescriptionCustomAttributeProportionalSymbols + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeProportionalSymbols); + } + } + + public static string DescriptionCustomAttributeDrawSideBySide + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeDrawSideBySide); + } + } + + public static string DescriptionCustomAttributeShowMarkerLines + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeShowMarkerLines); + } + } + + public static string DescriptionCustomAttributeShowOpenClose + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeShowOpenClose); + } + } + + public static string DescriptionCustomAttributeBoxPlotShowAverage + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBoxPlotShowAverage); + } + } + + public static string DescriptionCustomAttributeBubbleUseSizeForLabel + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBubbleUseSizeForLabel); + } + } + + public static string DescriptionCustomAttributeBoxPlotShowMedian + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBoxPlotShowMedian); + } + } + + public static string DescriptionCustomAttributeBoxPlotShowUnusualValues + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBoxPlotShowUnusualValues); + } + } + + public static string DescriptionCustomAttributeBoxPlotSeries + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBoxPlotSeries); + } + } + + public static string DescriptionCustomAttributePieStartAngle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePieStartAngle); + } + } + + public static string DescriptionCustomAttributeLabelStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeLabelStyle); + } + } + + public static string DescriptionCustomAttributeFunnelLabelStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeFunnelLabelStyle); + } + } + + public static string DescriptionCustomAttributeFunnelStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeFunnelStyle); + } + } + + public static string DescriptionCustomAttributePolarDrawingStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePolarDrawingStyle); + } + } + + public static string DescriptionCustomAttributePyramidLabelStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePyramidLabelStyle); + } + } + + public static string DescriptionCustomAttributeRadarDrawingStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeRadarDrawingStyle); + } + } + + public static string DescriptionCustomAttributeBoxSize + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBoxSize); + } + } + + public static string DescriptionCustomAttributeCollectedColor + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeCollectedColor); + } + } + + public static string DescriptionCustomAttributeCollectedLabel + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeCollectedLabel); + } + } + + public static string DescriptionCustomAttributeCollectedLegendText + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeCollectedLegendText); + } + } + + public static string DescriptionCustomAttributeCollectedLegendDefaultText + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeCollectedLegendDefaultText); + } + } + + public static string DescriptionCustomAttributeCollectedLabelDefaultText + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeCollectedLabelDefaultText); + } + } + + public static string DescriptionCustomAttributeCollectedToolTip + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeCollectedToolTip); + } + } + + public static string DescriptionCustomAttributePyramidValueType + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePyramidValueType); + } + } + + public static string DescriptionCustomAttribute_3DLabelLineSize + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttribute_3DLabelLineSize); + } + } + + public static string DescriptionCustomAttributeFunnel3DRotationAngle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeFunnel3DRotationAngle); + } + } + + public static string DescriptionCustomAttributePyramid3DRotationAngle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePyramid3DRotationAngle); + } + } + + public static string DescriptionCustomAttributePixelPointDepth + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePixelPointDepth); + } + } + + public static string DescriptionCustomAttributePixelPointGapDepth + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePixelPointGapDepth); + } + } + + public static string DescriptionCustomAttributeErrorBarCenterMarkerStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeErrorBarCenterMarkerStyle); + } + } + + public static string DescriptionCustomAttributePointFigureBoxSize + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePointFigureBoxSize); + } + } + + public static string DescriptionCustomAttributeBubbleScaleMax + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBubbleScaleMax); + } + } + + public static string DescriptionCustomAttributeBubbleScaleMin + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBubbleScaleMin); + } + } + + public static string DescriptionCustomAttributeCollectedThreshold + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeCollectedThreshold); + } + } + + public static string DescriptionCustomAttributePieLineColor + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePieLineColor); + } + } + + public static string DescriptionCustomAttributeCalloutLineColor + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeCalloutLineColor); + } + } + + public static string DescriptionCustomAttributePieLabelStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePieLabelStyle); + } + } + + public static string DescriptionCustomAttributeFunnel3DDrawingStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeFunnel3DDrawingStyle); + } + } + + public static string DescriptionCustomAttributePyramid3DDrawingStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePyramid3DDrawingStyle); + } + } + + public static string DescriptionCustomAttributeDrawingStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeDrawingStyle); + } + } + + public static string DescriptionCustomAttributePieDrawingStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePieDrawingStyle); + } + } + + public static string DescriptionCustomAttributeCollectedSliceExploded + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeCollectedSliceExploded); + } + } + + public static string DescriptionCustomAttributeCollectedThresholdUsePercent + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeCollectedThresholdUsePercent); + } + } + + public static string DescriptionCustomAttributeFunnelNeckHeight + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeFunnelNeckHeight); + } + } + + public static string DescriptionCustomAttributeFunnelNeckWidth + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeFunnelNeckWidth); + } + } + + public static string DescriptionCustomAttributePyramidPointGap + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePyramidPointGap); + } + } + + public static string DescriptionCustomAttributeFunnelPointGap + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeFunnelPointGap); + } + } + + public static string DescriptionCustomAttributeLabelsHorizontalLineSize + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeLabelsHorizontalLineSize); + } + } + + public static string DescriptionCustomAttributeDoughnutRadius + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeDoughnutRadius); + } + } + + public static string DescriptionCustomAttributePolarCircularLabelsStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePolarCircularLabelsStyle); + } + } + + public static string DescriptionCustomAttributeRadarCircularLabelsStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeRadarCircularLabelsStyle); + } + } + + public static string DescriptionCustomAttributeOpenCloseStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeOpenCloseStyle); + } + } + + public static string DescriptionCustomAttributeBubbleMaxSize + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBubbleMaxSize); + } + } + + public static string DescriptionCustomAttributeMaxPixelPointWidth + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeMaxPixelPointWidth); + } + } + + public static string DescriptionCustomAttributePyramidMinPointHeight + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePyramidMinPointHeight); + } + } + + public static string DescriptionCustomAttributeFunnelMinPointHeight + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeFunnelMinPointHeight); + } + } + + public static string DescriptionCustomAttributeMinimumRelativePieSize + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeMinimumRelativePieSize); + } + } + + public static string DescriptionCustomAttributeMinPixelPointWidth + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeMinPixelPointWidth); + } + } + + public static string DescriptionCustomAttributeErrorBarSeries + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeErrorBarSeries); + } + } + + public static string DescriptionCustomAttributeNumberOfLinesInBreak + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeNumberOfLinesInBreak); + } + } + + public static string DescriptionCustomAttributePyramidOutsideLabelPlacement + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePyramidOutsideLabelPlacement); + } + } + + public static string DescriptionCustomAttributeFunnelOutsideLabelPlacement + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeFunnelOutsideLabelPlacement); + } + } + + public static string DescriptionCustomAttributeBoxPlotPercentile + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBoxPlotPercentile); + } + } + + public static string DescriptionCustomAttributeBoxPlotWhiskerPercentile + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBoxPlotWhiskerPercentile); + } + } + + public static string DescriptionCustomAttributeBarLabelStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBarLabelStyle); + } + } + + public static string DescriptionCustomAttributeLabelsRadialLineSize + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeLabelsRadialLineSize); + } + } + + public static string DescriptionCustomAttributePointWidth + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePointWidth); + } + } + + public static string DescriptionCustomAttributeReversalAmount + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeReversalAmount); + } + } + + public static string DescriptionCustomAttributePolarAreaDrawingStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePolarAreaDrawingStyle); + } + } + + public static string DescriptionCustomAttributeRadarAreaDrawingStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeRadarAreaDrawingStyle); + } + } + + public static string DescriptionCustomAttributeStackedGroupName + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeStackedGroupName); + } + } + + public static string DescriptionCustomAttributeLineTension + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeLineTension); + } + } + + public static string DescriptionCustomAttributeCandlePriceUpColor + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeCandlePriceUpColor); + } + } + + public static string DescriptionCustomAttributeBarsPriceUpColor + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeBarsPriceUpColor); + } + } + + public static string DescriptionCustomAttributePriceDownColor + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePriceDownColor); + } + } + + public static string DescriptionCustomAttributeUsedYValueHigh + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeUsedYValueHigh); + } + } + + public static string DescriptionCustomAttributeUsedYValueLow + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeUsedYValueLow); + } + } + + public static string DescriptionCustomAttributeRenkoUsedYValue + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeRenkoUsedYValue); + } + } + + public static string DescriptionCustomAttributeThreeLineBreakUsedYValue + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeThreeLineBreakUsedYValue); + } + } + + public static string DescriptionCustomAttributePyramidInsideLabelAlignment + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePyramidInsideLabelAlignment); + } + } + + public static string DescriptionCustomAttributeFunnelInsideLabelAlignment + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeFunnelInsideLabelAlignment); + } + } + + public static string DescriptionCustomAttributeErrorBarStyle + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeErrorBarStyle); + } + } + + public static string DescriptionCustomAttributePixelPointWidth + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributePixelPointWidth); + } + } + + public static string DescriptionCustomAttributeLabelValueType + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeLabelValueType); + } + } + + public static string DescriptionCustomAttributeUsedYValue + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeUsedYValue); + } + } + + public static string DescriptionCustomAttributeKagiReversalAmount + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeKagiReversalAmount); + } + } + + public static string DescriptionCustomAttributeErrorBarType + { + get + { + return Keys.GetString(Keys.DescriptionCustomAttributeErrorBarType); + } + } + + public static string DescriptionAttributeChart_ImageStorageMode + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_ImageStorageMode); + } + } + + public static string DescriptionKeyWordAverageYValues + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordAverageYValues); + } + } + + public static string DescriptionKeyWordAxisLabelDataPoint + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordAxisLabelDataPoint); + } + } + + public static string DescriptionKeyWordIndexDataPoint + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordIndexDataPoint); + } + } + + public static string DescriptionKeyWordLabelDataPoint + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordLabelDataPoint); + } + } + + public static string DescriptionKeyWordYValuePercentTotal + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordYValuePercentTotal); + } + } + + public static string DescriptionKeyWordIndexDataPoint2 + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordIndexDataPoint2); + } + } + + public static string DescriptionKeyWordLegendText + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordLegendText); + } + } + + public static string DescriptionKeyWordMaximumYValues + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordMaximumYValues); + } + } + + public static string DescriptionKeyWordMinimumYValues + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordMinimumYValues); + } + } + + public static string DescriptionKeyWordSeriesName + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordSeriesName); + } + } + + public static string DescriptionKeyWordTotalYValues + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordTotalYValues); + } + } + + public static string DescriptionKeyWordXValue + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordXValue); + } + } + + public static string DescriptionKeyWordFirstPointYValue + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordFirstPointYValue); + } + } + + public static string DescriptionKeyWordLastPointYValue + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordLastPointYValue); + } + } + + public static string DescriptionKeyWordYValue + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordYValue); + } + } + + public static string DescriptionKeyWordNameIndexDataPoint + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameIndexDataPoint); + } + } + + public static string DescriptionKeyWordNameXValue + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameXValue); + } + } + + public static string DescriptionKeyWordNameYValue + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameYValue); + } + } + + public static string DescriptionKeyWordNameTotalYValues + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameTotalYValues); + } + } + + public static string DescriptionKeyWordNameYValuePercentTotal + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameYValuePercentTotal); + } + } + + public static string DescriptionKeyWordNameIndexTheDataPoint + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameIndexTheDataPoint); + } + } + + public static string DescriptionKeyWordNameLabelDataPoint + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameLabelDataPoint); + } + } + + public static string DescriptionKeyWordNameAxisLabelDataPoint + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameAxisLabelDataPoint); + } + } + + public static string DescriptionKeyWordNameLegendText + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameLegendText); + } + } + + public static string DescriptionKeyWordNameSeriesName + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameSeriesName); + } + } + + public static string DescriptionKeyWordNameAverageYValues + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameAverageYValues); + } + } + + public static string DescriptionKeyWordNameMaximumYValues + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameMaximumYValues); + } + } + + public static string DescriptionKeyWordNameMinimumYValues + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameMinimumYValues); + } + } + + public static string DescriptionKeyWordNameLastPointYValue + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameLastPointYValue); + } + } + + public static string DescriptionKeyWordNameFirstPointYValue + { + get + { + return Keys.GetString(Keys.DescriptionKeyWordNameFirstPointYValue); + } + } + + public static string DescriptionNumberFormatTypeCurrency + { + get + { + return Keys.GetString(Keys.DescriptionNumberFormatTypeCurrency); + } + } + + public static string DescriptionNumberFormatTypeDecimal + { + get + { + return Keys.GetString(Keys.DescriptionNumberFormatTypeDecimal); + } + } + + public static string DescriptionNumberFormatTypeScientific + { + get + { + return Keys.GetString(Keys.DescriptionNumberFormatTypeScientific); + } + } + + public static string DescriptionNumberFormatTypeFixedPoint + { + get + { + return Keys.GetString(Keys.DescriptionNumberFormatTypeFixedPoint); + } + } + + public static string DescriptionNumberFormatTypeGeneral + { + get + { + return Keys.GetString(Keys.DescriptionNumberFormatTypeGeneral); + } + } + + public static string DescriptionNumberFormatTypeNumber + { + get + { + return Keys.GetString(Keys.DescriptionNumberFormatTypeNumber); + } + } + + public static string DescriptionNumberFormatTypePercent + { + get + { + return Keys.GetString(Keys.DescriptionNumberFormatTypePercent); + } + } + + public static string DescriptionTypeNone + { + get + { + return Keys.GetString(Keys.DescriptionTypeNone); + } + } + + public static string DescriptionTypeCustom + { + get + { + return Keys.GetString(Keys.DescriptionTypeCustom); + } + } + + public static string DescriptionTypeEmpty + { + get + { + return Keys.GetString(Keys.DescriptionTypeEmpty); + } + } + + public static string DescriptionTypePoint + { + get + { + return Keys.GetString(Keys.DescriptionTypePoint); + } + } + + public static string LabelKeyFormat + { + get + { + return Keys.GetString(Keys.LabelKeyFormat); + } + } + + public static string LabelKeyCustomFormat + { + get + { + return Keys.GetString(Keys.LabelKeyCustomFormat); + } + } + + public static string LabelStringWithKeywords + { + get + { + return Keys.GetString(Keys.LabelStringWithKeywords); + } + } + + public static string LabelEditKeyword + { + get + { + return Keys.GetString(Keys.LabelEditKeyword); + } + } + + public static string LabelInsertNewKeyword + { + get + { + return Keys.GetString(Keys.LabelInsertNewKeyword); + } + } + + public static string LabelStringKeywordsEditor + { + get + { + return Keys.GetString(Keys.LabelStringKeywordsEditor); + } + } + + public static string LabelKeywordEditor + { + get + { + return Keys.GetString(Keys.LabelKeywordEditor); + } + } + + public static string LabelDescription + { + get + { + return Keys.GetString(Keys.LabelDescription); + } + } + + public static string LabelFormatKeySample + { + get + { + return Keys.GetString(Keys.LabelFormatKeySample); + } + } + + public static string LabelKeyYValueIndex + { + get + { + return Keys.GetString(Keys.LabelKeyYValueIndex); + } + } + + public static string LabelKeyPrecision + { + get + { + return Keys.GetString(Keys.LabelKeyPrecision); + } + } + + public static string LabelKeyKeywords + { + get + { + return Keys.GetString(Keys.LabelKeyKeywords); + } + } + + public static string LabelValueFormatting + { + get + { + return Keys.GetString(Keys.LabelValueFormatting); + } + } + + public static string LabelButtonOk + { + get + { + return Keys.GetString(Keys.LabelButtonOk); + } + } + + public static string LabelButtonCancel + { + get + { + return Keys.GetString(Keys.LabelButtonCancel); + } + } + + public static string DescriptionToolTipCustomFormatCharacters + { + get + { + return Keys.GetString(Keys.DescriptionToolTipCustomFormatCharacters); + } + } + + public static string DesciptionCustomLabelEditorTitle + { + get + { + return Keys.GetString(Keys.DesciptionCustomLabelEditorTitle); + } + } + + public static string DesciptionCustomLabelFormatInvalid + { + get + { + return Keys.GetString(Keys.DesciptionCustomLabelFormatInvalid); + } + } + + public static string LabelStatisticalSumOfSquaresBetweenGroups + { + get + { + return Keys.GetString(Keys.LabelStatisticalSumOfSquaresBetweenGroups); + } + } + + public static string LabelStatisticalSumOfSquaresWithinGroups + { + get + { + return Keys.GetString(Keys.LabelStatisticalSumOfSquaresWithinGroups); + } + } + + public static string LabelStatisticalSumOfSquaresTotal + { + get + { + return Keys.GetString(Keys.LabelStatisticalSumOfSquaresTotal); + } + } + + public static string LabelStatisticalDegreesOfFreedomBetweenGroups + { + get + { + return Keys.GetString(Keys.LabelStatisticalDegreesOfFreedomBetweenGroups); + } + } + + public static string LabelStatisticalDegreesOfFreedomWithinGroups + { + get + { + return Keys.GetString(Keys.LabelStatisticalDegreesOfFreedomWithinGroups); + } + } + + public static string LabelStatisticalDegreesOfFreedomTotal + { + get + { + return Keys.GetString(Keys.LabelStatisticalDegreesOfFreedomTotal); + } + } + + public static string LabelStatisticalMeanSquareVarianceBetweenGroups + { + get + { + return Keys.GetString(Keys.LabelStatisticalMeanSquareVarianceBetweenGroups); + } + } + + public static string LabelStatisticalMeanSquareVarianceWithinGroups + { + get + { + return Keys.GetString(Keys.LabelStatisticalMeanSquareVarianceWithinGroups); + } + } + + public static string LabelStatisticalFRatio + { + get + { + return Keys.GetString(Keys.LabelStatisticalFRatio); + } + } + + public static string LabelStatisticalFCriteria + { + get + { + return Keys.GetString(Keys.LabelStatisticalFCriteria); + } + } + + public static string LabelStatisticalCorrelation + { + get + { + return Keys.GetString(Keys.LabelStatisticalCorrelation); + } + } + + public static string LabelStatisticalCovariance + { + get + { + return Keys.GetString(Keys.LabelStatisticalCovariance); + } + } + + public static string LabelStatisticalProbability + { + get + { + return Keys.GetString(Keys.LabelStatisticalProbability); + } + } + + public static string LabelStatisticalAverage + { + get + { + return Keys.GetString(Keys.LabelStatisticalAverage); + } + } + + public static string LabelStatisticalVariance + { + get + { + return Keys.GetString(Keys.LabelStatisticalVariance); + } + } + + public static string LabelStatisticalMedian + { + get + { + return Keys.GetString(Keys.LabelStatisticalMedian); + } + } + + public static string LabelStatisticalBetaFunction + { + get + { + return Keys.GetString(Keys.LabelStatisticalBetaFunction); + } + } + + public static string LabelStatisticalGammaFunction + { + get + { + return Keys.GetString(Keys.LabelStatisticalGammaFunction); + } + } + + public static string LabelStatisticalTheFirstGroupMean + { + get + { + return Keys.GetString(Keys.LabelStatisticalTheFirstGroupMean); + } + } + + public static string LabelStatisticalTheSecondGroupMean + { + get + { + return Keys.GetString(Keys.LabelStatisticalTheSecondGroupMean); + } + } + + public static string LabelStatisticalTheFirstGroupVariance + { + get + { + return Keys.GetString(Keys.LabelStatisticalTheFirstGroupVariance); + } + } + + public static string LabelStatisticalTheSecondGroupVariance + { + get + { + return Keys.GetString(Keys.LabelStatisticalTheSecondGroupVariance); + } + } + + public static string LabelStatisticalFValue + { + get + { + return Keys.GetString(Keys.LabelStatisticalFValue); + } + } + + public static string LabelStatisticalFCriticalValueOneTail + { + get + { + return Keys.GetString(Keys.LabelStatisticalFCriticalValueOneTail); + } + } + + public static string LabelStatisticalZValue + { + get + { + return Keys.GetString(Keys.LabelStatisticalZValue); + } + } + + public static string LabelStatisticalZCriticalValueOneTail + { + get + { + return Keys.GetString(Keys.LabelStatisticalZCriticalValueOneTail); + } + } + + public static string LabelStatisticalZCriticalValueTwoTail + { + get + { + return Keys.GetString(Keys.LabelStatisticalZCriticalValueTwoTail); + } + } + + public static string LabelStatisticalPZLessEqualSmallZOneTail + { + get + { + return Keys.GetString(Keys.LabelStatisticalPZLessEqualSmallZOneTail); + } + } + + public static string LabelStatisticalPZLessEqualSmallZTwoTail + { + get + { + return Keys.GetString(Keys.LabelStatisticalPZLessEqualSmallZTwoTail); + } + } + + public static string LabelStatisticalPFLessEqualSmallFOneTail + { + get + { + return Keys.GetString(Keys.LabelStatisticalPFLessEqualSmallFOneTail); + } + } + + public static string LabelStatisticalTValue + { + get + { + return Keys.GetString(Keys.LabelStatisticalTValue); + } + } + + public static string LabelStatisticalDegreeOfFreedom + { + get + { + return Keys.GetString(Keys.LabelStatisticalDegreeOfFreedom); + } + } + + public static string LabelStatisticalPTLessEqualSmallTOneTail + { + get + { + return Keys.GetString(Keys.LabelStatisticalPTLessEqualSmallTOneTail); + } + } + + public static string LabelStatisticalSmallTCrititcalOneTail + { + get + { + return Keys.GetString(Keys.LabelStatisticalSmallTCrititcalOneTail); + } + } + + public static string LabelStatisticalPTLessEqualSmallTTwoTail + { + get + { + return Keys.GetString(Keys.LabelStatisticalPTLessEqualSmallTTwoTail); + } + } + + public static string LabelStatisticalSmallTCrititcalTwoTail + { + get + { + return Keys.GetString(Keys.LabelStatisticalSmallTCrititcalTwoTail); + } + } + + public static string MessagePrecisionInvalid + { + get + { + return Keys.GetString(Keys.MessagePrecisionInvalid); + } + } + + public static string MessageChangingChartAreaPositionProperty + { + get + { + return Keys.GetString(Keys.MessageChangingChartAreaPositionProperty); + } + } + + public static string MessageChangingChartAreaPositionConfirmAutomatic + { + get + { + return Keys.GetString(Keys.MessageChangingChartAreaPositionConfirmAutomatic); + } + } + + public static string MessageChangingChartAreaPositionConfirmCustom + { + get + { + return Keys.GetString(Keys.MessageChangingChartAreaPositionConfirmCustom); + } + } + + public static string MessageChartException + { + get + { + return Keys.GetString(Keys.MessageChartException); + } + } + + public static string MessageSite + { + get + { + return Keys.GetString(Keys.MessageSite); + } + } + + public static string MessageStackTrace + { + get + { + return Keys.GetString(Keys.MessageStackTrace); + } + } + + public static string MessageChartTitle + { + get + { + return Keys.GetString(Keys.MessageChartTitle); + } + } + + public static string TitleAxisX + { + get + { + return Keys.GetString(Keys.TitleAxisX); + } + } + + public static string TitleAxisY + { + get + { + return Keys.GetString(Keys.TitleAxisY); + } + } + + public static string TitleAxisX2 + { + get + { + return Keys.GetString(Keys.TitleAxisX2); + } + } + + public static string TitleAxisY2 + { + get + { + return Keys.GetString(Keys.TitleAxisY2); + } + } + + public static string FormulaNamePriceIndicators + { + get + { + return Keys.GetString(Keys.FormulaNamePriceIndicators); + } + } + + public static string FormulaNameGeneralTechnicalIndicators + { + get + { + return Keys.GetString(Keys.FormulaNameGeneralTechnicalIndicators); + } + } + + public static string FormulaNameTechnicalVolumeIndicators + { + get + { + return Keys.GetString(Keys.FormulaNameTechnicalVolumeIndicators); + } + } + + public static string FormulaNameOscillator + { + get + { + return Keys.GetString(Keys.FormulaNameOscillator); + } + } + + public static string FormulaNameGeneralFormulas + { + get + { + return Keys.GetString(Keys.FormulaNameGeneralFormulas); + } + } + + public static string FormulaNameTimeSeriesAndForecasting + { + get + { + return Keys.GetString(Keys.FormulaNameTimeSeriesAndForecasting); + } + } + + public static string FormulaNameStatisticalAnalysis + { + get + { + return Keys.GetString(Keys.FormulaNameStatisticalAnalysis); + } + } + + public static string FormulaNameVolumeIndicators + { + get + { + return Keys.GetString(Keys.FormulaNameVolumeIndicators); + } + } + + public static string LabelTextRow + { + get + { + return Keys.GetString(Keys.LabelTextRow); + } + } + + public static string DescriptionAttributeBackImage + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBackImage); + } + } + + public static string DescriptionAttributeMarkerImage + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMarkerImage); + } + } + + public static string DescriptionAttributeAnnotationBaseY + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationBaseY); + } + } + + public static string DescriptionAttributeAnnotationWidth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationWidth); + } + } + + public static string DescriptionAttributeAnnotationHeight + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationHeight); + } + } + + public static string DescriptionAttributeAnnotationClipToChartArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationClipToChartArea); + } + } + + public static string DescriptionAttributeAnnotationBaseX + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationBaseX); + } + } + + public static string DescriptionAttributeChartImageType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartImageType); + } + } + + public static string DescriptionAttributeMultiValueSeparator + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMultiValueSeparator); + } + } + + public static string DescriptionAttributeDataSeriesGroupID + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataSeriesGroupID); + } + } + + public static string DescriptionAttributeSuppressCodeExceptions + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSuppressCodeExceptions); + } + } + + public static string DescriptionAttributeNoDataMessage + { + get + { + return Keys.GetString(Keys.DescriptionAttributeNoDataMessage); + } + } + + public static string DescriptionAttributeReverseSeriesOrder + { + get + { + return Keys.GetString(Keys.DescriptionAttributeReverseSeriesOrder); + } + } + + public static string DescriptionAttributeUserDefined + { + get + { + return Keys.GetString(Keys.DescriptionAttributeUserDefined); + } + } + + public static string DescriptionAttributeChartEvent_GetToolTipText + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_GetToolTipText); + } + } + + public static string DescriptionAttributeArrowAnnotation_ArrowSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeArrowAnnotation_ArrowSize); + } + } + + public static string DescriptionAttributeChartSerializer_Content + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartSerializer_Content); + } + } + + public static string DescriptionAttributeLegend_Enabled + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_Enabled); + } + } + + public static string DescriptionAttributeEnabled5 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeEnabled5); + } + } + + public static string DescriptionAttributeAxisScaleBreakStyle_Enabled + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleBreakStyle_Enabled); + } + } + + public static string DescriptionAttributeEnabled7 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeEnabled7); + } + } + + public static string DescriptionAttributeLabel_Enabled + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_Enabled); + } + } + + public static string DescriptionAttributeLegendItem_Enabled + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_Enabled); + } + } + + public static string DescriptionAttributeAxisScrollBar_Enabled + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScrollBar_Enabled); + } + } + + public static string DescriptionAttributeEnabled13 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeEnabled13); + } + } + + public static string DescriptionAttributeSeries_Enabled + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_Enabled); + } + } + + public static string DescriptionAttributeLegendCell_CellSpan + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCell_CellSpan); + } + } + + public static string DescriptionAttributeCursor_SelectionColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_SelectionColor); + } + } + + public static string DescriptionAttributeInterlaced + { + get + { + return Keys.GetString(Keys.DescriptionAttributeInterlaced); + } + } + + public static string DescriptionAttributeMapArea_Coordinates + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMapArea_Coordinates); + } + } + + public static string DescriptionAttributeChartEvent_PostPaint + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_PostPaint); + } + } + + public static string DescriptionAttributeStripLine_Title + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_Title); + } + } + + public static string DescriptionAttributeLegend_Title + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_Title); + } + } + + public static string DescriptionAttributeTitle5 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle5); + } + } + + public static string DescriptionAttributeTitle6 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle6); + } + } + + public static string DescriptionAttributeAnnotation_Annotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotation_Annotation); + } + } + + public static string DescriptionAttributeTitleFont + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitleFont); + } + } + + public static string DescriptionAttributeChartArea_Axes + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_Axes); + } + } + + public static string DescriptionAttributeChartSerializer_NonSerializableContent + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartSerializer_NonSerializableContent); + } + } + + public static string DescriptionAttributeShadowOffset + { + get + { + return Keys.GetString(Keys.DescriptionAttributeShadowOffset); + } + } + + public static string DescriptionAttributeCalloutLineAnchorCap + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCalloutLineAnchorCap); + } + } + + public static string DescriptionAttributeMapAreaAttributes + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMapAreaAttributes); + } + } + + public static string DescriptionAttributeSubAxis_SubAxis + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSubAxis_SubAxis); + } + } + + public static string DescriptionAttributeMajorGrid + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMajorGrid); + } + } + + public static string DescriptionAttributeElementPosition_Y + { + get + { + return Keys.GetString(Keys.DescriptionAttributeElementPosition_Y); + } + } + + public static string DescriptionAttributeAnnotationPathPoint_Y + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationPathPoint_Y); + } + } + + public static string DescriptionAttributeToolTipEventArgs_Y + { + get + { + return Keys.GetString(Keys.DescriptionAttributeToolTipEventArgs_Y); + } + } + + public static string DescriptionAttributePoint3D_Y + { + get + { + return Keys.GetString(Keys.DescriptionAttributePoint3D_Y); + } + } + + public static string DescriptionAttributePoint3D_Z + { + get + { + return Keys.GetString(Keys.DescriptionAttributePoint3D_Z); + } + } + + public static string DescriptionAttributeMajorTickMark + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMajorTickMark); + } + } + + public static string DescriptionAttributeDrawInfinitive + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDrawInfinitive); + } + } + + public static string DescriptionAttributeAxisDataView_MinSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_MinSize); + } + } + + public static string DescriptionAttributeLegendCellColumnCollection_LegendCellColumnCollection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumnCollection_LegendCellColumnCollection); + } + } + + public static string DescriptionAttributeMarkerOverlapping + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMarkerOverlapping); + } + } + + public static string DescriptionAttributeChart_OnCustomizeLegend + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_OnCustomizeLegend); + } + } + + public static string DescriptionAttributeLegendCellColumn_HeaderTextAlignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_HeaderTextAlignment); + } + } + + public static string DescriptionAttributeScrollBarEventArgs_MousePositionY + { + get + { + return Keys.GetString(Keys.DescriptionAttributeScrollBarEventArgs_MousePositionY); + } + } + + public static string DescriptionAttributeNamedImage_NamedImage + { + get + { + return Keys.GetString(Keys.DescriptionAttributeNamedImage_NamedImage); + } + } + + public static string DescriptionAttributeScrollBar + { + get + { + return Keys.GetString(Keys.DescriptionAttributeScrollBar); + } + } + + public static string DescriptionAttributeMapArea_MapArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMapArea_MapArea); + } + } + + public static string DescriptionAttributeLegend_CustomItems + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_CustomItems); + } + } + + public static string DescriptionAttributeAnnotationSmartLabelsStyle_AnnotationSmartLabelsStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationSmartLabelsStyle_AnnotationSmartLabelsStyle); + } + } + + public static string DescriptionAttributePolylineAnnotation_PolylineAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributePolylineAnnotation_PolylineAnnotation); + } + } + + public static string DescriptionAttributeChartEvent_AxisViewChanged + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_AxisViewChanged); + } + } + + public static string DescriptionAttributeCrossing + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCrossing); + } + } + + public static string DescriptionAttributeMargins_Top + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMargins_Top); + } + } + + public static string DescriptionAttributeLegendCellColumn_HeaderFont + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_HeaderFont); + } + } + + public static string DescriptionAttributeLegend_InterlacedRows + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_InterlacedRows); + } + } + + public static string DescriptionAttributeAxisDataView_MinSizeType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_MinSizeType); + } + } + + public static string DescriptionAttributeLineWidth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLineWidth); + } + } + + public static string DescriptionAttributeDataPoint_XValue + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataPoint_XValue); + } + } + + public static string DescriptionAttributeChartArea_AxisY2 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_AxisY2); + } + } + + public static string DescriptionAttributeChartArea_AxisX2 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_AxisX2); + } + } + + public static string DescriptionAttributeChartEvent_AnnotationPositionChanging + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_AnnotationPositionChanging); + } + } + + public static string DescriptionAttributeStripLine_StripLine + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_StripLine); + } + } + + public static string DescriptionAttributeBorderColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBorderColor); + } + } + + public static string DescriptionAttributeMarkerBorderColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMarkerBorderColor); + } + } + + public static string DescriptionAttributeLegendText + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendText); + } + } + + public static string DescriptionAttributeCustomLabel_LabelMark + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_LabelMark); + } + } + + public static string DescriptionAttributeTextAntiAliasingQuality + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTextAntiAliasingQuality); + } + } + + public static string DescriptionAttributeAllowMoving + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAllowMoving); + } + } + + public static string DescriptionAttributeCalloutAnnotation_CalloutAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCalloutAnnotation_CalloutAnnotation); + } + } + + public static string DescriptionAttributeStripLine_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_Name); + } + } + + public static string DescriptionAttributeTitle_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle_Name); + } + } + + public static string DescriptionAttributeName4 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeName4); + } + } + + public static string DescriptionAttributeAnnotationPathPoint_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationPathPoint_Name); + } + } + + public static string DescriptionAttributeLegendCell_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCell_Name); + } + } + + public static string DescriptionAttributeMapArea_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMapArea_Name); + } + } + + public static string DescriptionAttributeSeries_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_Name); + } + } + + public static string DescriptionAttributeAxis_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxis_Name); + } + } + + public static string DescriptionAttributeNamedImage_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeNamedImage_Name); + } + } + + public static string DescriptionAttributeSubAxis_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSubAxis_Name); + } + } + + public static string DescriptionAttributeDataPoint_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataPoint_Name); + } + } + + public static string DescriptionAttributeLegendCellColumn_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_Name); + } + } + + public static string DescriptionAttributeLegendItem_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_Name); + } + } + + public static string DescriptionAttributeLegend_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_Name); + } + } + + public static string DescriptionAttributeCustomLabel_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_Name); + } + } + + public static string DescriptionAttributeChartArea_Name + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_Name); + } + } + + public static string DescriptionAttributeCursor_Cursor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_Cursor); + } + } + + public static string DescriptionAttributeAnchorX + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnchorX); + } + } + + public static string DescriptionAttributeToolTip + { + get + { + return Keys.GetString(Keys.DescriptionAttributeToolTip); + } + } + + public static string DescriptionAttributeLegend_TableStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_TableStyle); + } + } + + public static string DescriptionAttributeDataPoint_Empty + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataPoint_Empty); + } + } + + public static string DescriptionAttributeScrollBarEventArgs_Handled + { + get + { + return Keys.GetString(Keys.DescriptionAttributeScrollBarEventArgs_Handled); + } + } + + public static string DescriptionAttributeAxisLabel + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisLabel); + } + } + + public static string DescriptionAttributeAnnotationGroup_AllowPathEditing + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationGroup_AllowPathEditing); + } + } + + public static string DescriptionAttributeAllowPathEditing3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAllowPathEditing3); + } + } + + public static string DescriptionAttributeChart_OnPaint + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_OnPaint); + } + } + + public static string DescriptionAttributeCalloutAnnotation_AnchorOffsetX + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCalloutAnnotation_AnchorOffsetX); + } + } + + public static string DescriptionAttributeAnchorOffsetX3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnchorOffsetX3); + } + } + + public static string DescriptionAttributeCalloutAnnotation_AnchorOffsetY + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCalloutAnnotation_AnchorOffsetY); + } + } + + public static string DescriptionAttributeAnchorOffsetY3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnchorOffsetY3); + } + } + + public static string DescriptionAttributeChartEvent_CursorPositionChanging + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_CursorPositionChanging); + } + } + + public static string DescriptionAttributeScrollBarEventArgs_ButtonType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeScrollBarEventArgs_ButtonType); + } + } + + public static string DescriptionAttributeLabelsAutoFitStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabelsAutoFitStyle); + } + } + + public static string DescriptionAttributeLabelStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabelStyle); + } + } + + public static string DescriptionAttributeStripLine_IntervalOffsetType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_IntervalOffsetType); + } + } + + public static string DescriptionAttributeLabel_IntervalOffsetType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_IntervalOffsetType); + } + } + + public static string DescriptionAttributeIntervalOffsetType4 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeIntervalOffsetType4); + } + } + + public static string DescriptionAttributeCursor_IntervalOffsetType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_IntervalOffsetType); + } + } + + public static string DescriptionAttributeIntervalOffsetType6 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeIntervalOffsetType6); + } + } + + public static string DescriptionAttributeAxisScaleSegment_IntervalOffsetType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegment_IntervalOffsetType); + } + } + + public static string DescriptionAttributeReverse + { + get + { + return Keys.GetString(Keys.DescriptionAttributeReverse); + } + } + + public static string DescriptionAttributeSeries_Points + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_Points); + } + } + + public static string DescriptionAttributeBorderSkin_SkinStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBorderSkin_SkinStyle); + } + } + + public static string DescriptionAttributeChartArea3DStyle_Clustered + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea3DStyle_Clustered); + } + } + + public static string DescriptionAttributeAnchorDataPointName + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnchorDataPointName); + } + } + + public static string DescriptionAttributeChartEvent_AnnotationPositionChanged + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_AnnotationPositionChanged); + } + } + + public static string DescriptionAttributeChartArea3DStyle_PointGapDepth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea3DStyle_PointGapDepth); + } + } + + public static string DescriptionAttributeLegend_Reversed + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_Reversed); + } + } + + public static string DescriptionAttributeAnnotation_AnnotationType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotation_AnnotationType); + } + } + + public static string DescriptionAttributeTextAnnotation_AnnotationType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTextAnnotation_AnnotationType); + } + } + + public static string DescriptionAttributeAnnotationType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationType); + } + } + + public static string DescriptionAttributeBorderSkin_FrameBorderDashStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBorderSkin_FrameBorderDashStyle); + } + } + + public static string DescriptionAttributeLegend_HeaderSeparatorColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_HeaderSeparatorColor); + } + } + + public static string DescriptionAttributeChartEvent_AnnotationSelectionChanged + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_AnnotationSelectionChanged); + } + } + + public static string DescriptionAttributeFont + { + get + { + return Keys.GetString(Keys.DescriptionAttributeFont); + } + } + + public static string DescriptionAttributeLegend_Font + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_Font); + } + } + + public static string DescriptionAttributeLegendCellColumn_Font + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_Font); + } + } + + public static string DescriptionAttributeLabel_Font + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_Font); + } + } + + public static string DescriptionAttributeTitle_Font + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle_Font); + } + } + + public static string DescriptionAttributeLegendCell_Font + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCell_Font); + } + } + + public static string DescriptionAttributeSeries_ValueMemberX + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_ValueMemberX); + } + } + + public static string DescriptionAttributeArrows + { + get + { + return Keys.GetString(Keys.DescriptionAttributeArrows); + } + } + + public static string DescriptionAttributeType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeType); + } + } + + public static string DescriptionAttributeSeries_Type + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_Type); + } + } + + public static string DescriptionAttributeBorder3DAnnotation_Border3DAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBorder3DAnnotation_Border3DAnnotation); + } + } + + public static string DescriptionAttributeChart_Images + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_Images); + } + } + + public static string DescriptionAttributeLegendToolTip + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendToolTip); + } + } + + public static string DescriptionAttributeCustomLabel_CustomLabel + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_CustomLabel); + } + } + + public static string DescriptionAttributeChartEvent_AnnotationPlaced + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_AnnotationPlaced); + } + } + + public static string DescriptionAttributeBackColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBackColor); + } + } + + public static string DescriptionAttributeCalloutBackColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCalloutBackColor); + } + } + + public static string DescriptionAttributeFrameBackColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeFrameBackColor); + } + } + + public static string DescriptionAttributeTitleBackColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitleBackColor); + } + } + + public static string DescriptionAttributeLabelBackColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabelBackColor); + } + } + + public static string DescriptionAttributeHeaderBackColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeHeaderBackColor); + } + } + + public static string DescriptionAttributeLabel_ShowEndLabels + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_ShowEndLabels); + } + } + + public static string DescriptionAttributeLabelToolTip + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabelToolTip); + } + } + + public static string DescriptionAttributeSeries_MarkerStep + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_MarkerStep); + } + } + + public static string DescriptionAttributeTickMark_Style + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTickMark_Style); + } + } + + public static string DescriptionAttribute_TextOrientation + { + get + { + return Keys.GetString(Keys.DescriptionAttribute_TextOrientation); + } + } + + public static string DescriptionAttributeLegendItem_Style + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_Style); + } + } + + public static string DescriptionAttributeChartArea3DStyle_Rotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea3DStyle_Rotation); + } + } + + public static string DescriptionAttributeSizeAlwaysRelative + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSizeAlwaysRelative); + } + } + + public static string DescriptionAttributeSizeAlwaysRelative3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSizeAlwaysRelative3); + } + } + + public static string DescriptionAttributeAnnotationGroup_SizeAlwaysRelative + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationGroup_SizeAlwaysRelative); + } + } + + public static string DescriptionAttributeChart_BorderlineWidth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_BorderlineWidth); + } + } + + public static string DescriptionAttributeSeries_XValueIndexed + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_XValueIndexed); + } + } + + public static string DescriptionAttributeEllipseAnnotation_EllipseAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeEllipseAnnotation_EllipseAnnotation); + } + } + + public static string DescriptionAttributeAnchorAlignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnchorAlignment); + } + } + + public static string DescriptionAttributeWidth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeWidth); + } + } + + public static string DescriptionAttributeElementPosition_Width + { + get + { + return Keys.GetString(Keys.DescriptionAttributeElementPosition_Width); + } + } + + public static string DescriptionAttributeAxisXName + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisXName); + } + } + + public static string DescriptionAttributeChartArea3DStyle_Inclination + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea3DStyle_Inclination); + } + } + + public static string DescriptionAttributeLegendCollection_LegendCollection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCollection_LegendCollection); + } + } + + public static string DescriptionAttributeAxisYName + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisYName); + } + } + + public static string DescriptionAttributeAxisScaleSegment_Spacing + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegment_Spacing); + } + } + + public static string DescriptionAttributeAxisScaleBreakStyle_Spacing + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleBreakStyle_Spacing); + } + } + + public static string DescriptionAttributeSelected + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSelected); + } + } + + public static string DescriptionAttributeAnnotationGroup_Selected + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationGroup_Selected); + } + } + + public static string DescriptionAttributeVerticalLineAnnotation_VerticalLineAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeVerticalLineAnnotation_VerticalLineAnnotation); + } + } + + public static string DescriptionAttributeLabelsAutoFitMaxFontSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabelsAutoFitMaxFontSize); + } + } + + public static string DescriptionAttributeFreeDrawPlacement + { + get + { + return Keys.GetString(Keys.DescriptionAttributeFreeDrawPlacement); + } + } + + public static string DescriptionAttributeStripLinesCollection_StripLinesCollection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLinesCollection_StripLinesCollection); + } + } + + public static string DescriptionAttributeAxisDataView_IsZoomed + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_IsZoomed); + } + } + + public static string DescriptionAttributeChartArea3DStyle_Perspective + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea3DStyle_Perspective); + } + } + + public static string DescriptionAttributeChart_OnCustomize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_OnCustomize); + } + } + + public static string DescriptionAttributeLabel + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel); + } + } + + public static string DescriptionAttributeLabel_Label + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_Label); + } + } + + public static string DescriptionAttributeStartCap3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStartCap3); + } + } + + public static string DescriptionAttributeFontColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeFontColor); + } + } + + public static string DescriptionAttributeLegendFontColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendFontColor); + } + } + + public static string DescriptionAttributeLabel_OffsetLabels + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_OffsetLabels); + } + } + + public static string DescriptionAttributeMargin + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMargin); + } + } + + public static string DescriptionAttributeAnnotationPositionChangingEventArgs_AnnotationPositionChangingEventArgs + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationPositionChangingEventArgs_AnnotationPositionChangingEventArgs); + } + } + + public static string DescriptionAttributeCursorEventArgs_NewSelectionStart + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursorEventArgs_NewSelectionStart); + } + } + + public static string DescriptionAttributeSeries_XSubAxisName + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_XSubAxisName); + } + } + + public static string DescriptionAttributeHideOverlapped + { + get + { + return Keys.GetString(Keys.DescriptionAttributeHideOverlapped); + } + } + + public static string DescriptionAttributeLegendCellColumn_MaximumWidth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_MaximumWidth); + } + } + + public static string DescriptionAttributeLegend_InsideChartArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_InsideChartArea); + } + } + + public static string DescriptionAttributeImageTransparentColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeImageTransparentColor); + } + } + + public static string DescriptionAttributeLegend_EquallySpacedItems + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_EquallySpacedItems); + } + } + + public static string DescriptionAttributeChartArea_CursorY + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_CursorY); + } + } + + public static string DescriptionAttributeChart_Printing + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_Printing); + } + } + + public static string DescriptionAttributeAxis + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxis); + } + } + + public static string DescriptionAttributeAxis_Axis + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxis_Axis); + } + } + + public static string DescriptionAttributeBackImageAlign + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBackImageAlign); + } + } + + public static string DescriptionAttributeShowInLegend + { + get + { + return Keys.GetString(Keys.DescriptionAttributeShowInLegend); + } + } + + public static string DescriptionAttributeChartSerializer_ChartSerializer + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartSerializer_ChartSerializer); + } + } + + public static string DescriptionAttributeChart_Compression + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_Compression); + } + } + + public static string DescriptionAttributeChartImage_Compression + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartImage_Compression); + } + } + + public static string DescriptionAttributeCursor_AutoScroll + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_AutoScroll); + } + } + + public static string DescriptionAttributeElementPosition_Height + { + get + { + return Keys.GetString(Keys.DescriptionAttributeElementPosition_Height); + } + } + + public static string DescriptionAttributeHeight3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeHeight3); + } + } + + public static string DescriptionAttributeChart_ViewStateContent + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_ViewStateContent); + } + } + + public static string DescriptionAttributeAxisDataView_SmallScrollSizeType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_SmallScrollSizeType); + } + } + + public static string DescriptionAttributeLegend_CellColumns + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_CellColumns); + } + } + + public static string DescriptionAttributeAxisScrollBar_Buttons + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScrollBar_Buttons); + } + } + + public static string DescriptionAttributeLegends + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegends); + } + } + + public static string DescriptionAttributeElementPosition_X + { + get + { + return Keys.GetString(Keys.DescriptionAttributeElementPosition_X); + } + } + + public static string DescriptionAttributeAnnotationPathPoint_X + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationPathPoint_X); + } + } + + public static string DescriptionAttributePoint3D_X + { + get + { + return Keys.GetString(Keys.DescriptionAttributePoint3D_X); + } + } + + public static string DescriptionAttributeToolTipEventArgs_X + { + get + { + return Keys.GetString(Keys.DescriptionAttributeToolTipEventArgs_X); + } + } + + public static string DescriptionAttributeCustomAttributesExtended + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomAttributesExtended); + } + } + + public static string DescriptionAttributeMargins_Left + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMargins_Left); + } + } + + public static string DescriptionAttributeAxisScrollBar_PositionInside + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScrollBar_PositionInside); + } + } + + public static string DescriptionAttributeSeries_ValueMembersY + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_ValueMembersY); + } + } + + public static string DescriptionAttributeSmartLabelsStyle_SmartLabelsStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSmartLabelsStyle_SmartLabelsStyle); + } + } + + public static string DescriptionAttributeChartEvent_SelectionRangeChanging + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_SelectionRangeChanging); + } + } + + public static string DescriptionAttributeLabelsAutoFitMinFontSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabelsAutoFitMinFontSize); + } + } + + public static string DescriptionAttributeMaxMovingDistance + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMaxMovingDistance); + } + } + + public static string DescriptionAttributeTitle_DockToChartArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle_DockToChartArea); + } + } + + public static string DescriptionAttributeLegend_DockToChartArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_DockToChartArea); + } + } + + public static string DescriptionAttributeChartArea3DStyle_RightAngleAxes + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea3DStyle_RightAngleAxes); + } + } + + public static string DescriptionAttributeLegend_LegendStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_LegendStyle); + } + } + + public static string DescriptionAttributeAxisDataView_AxisDataView + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_AxisDataView); + } + } + + public static string DescriptionAttributeBorderDashStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBorderDashStyle); + } + } + + public static string DescriptionAttributeLabelBorderDashStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabelBorderDashStyle); + } + } + + public static string DescriptionAttributeBackSecondaryColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBackSecondaryColor); + } + } + + public static string DescriptionAttributeBorderSkin_FrameBackSecondaryColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBorderSkin_FrameBackSecondaryColor); + } + } + + public static string DescriptionAttributeLegend_TitleSeparator + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_TitleSeparator); + } + } + + public static string DescriptionAttributeChartArea_InnerPlotPosition + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_InnerPlotPosition); + } + } + + public static string DescriptionAttributeChartEvent_CustomizeLegend + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_CustomizeLegend); + } + } + + public static string DescriptionAttributeAnnotationPathPoint_AnnotationPathPoint + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationPathPoint_AnnotationPathPoint); + } + } + + public static string DescriptionAttributeDataPoint_YValues + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataPoint_YValues); + } + } + + public static string DescriptionAttributeCustomLabel_RowIndex + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_RowIndex); + } + } + + public static string DescriptionAttributeSeries_YSubAxisName + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_YSubAxisName); + } + } + + public static string DescriptionAttributeChartArea_AlignType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_AlignType); + } + } + + public static string DescriptionAttributeAllowResizing + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAllowResizing); + } + } + + public static string DescriptionAttributeShowLabelAsValue + { + get + { + return Keys.GetString(Keys.DescriptionAttributeShowLabelAsValue); + } + } + + public static string DescriptionAttributeForeColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeForeColor); + } + } + + public static string DescriptionAttributePathPoints + { + get + { + return Keys.GetString(Keys.DescriptionAttributePathPoints); + } + } + + public static string DescriptionAttributeViewEventArgs_NewSizeType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeViewEventArgs_NewSizeType); + } + } + + public static string DescriptionAttributeChart_BuildNumber + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_BuildNumber); + } + } + + public static string DescriptionAttributeAxisScaleSegmentCollection_AxisScaleSegmentCollection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegmentCollection_AxisScaleSegmentCollection); + } + } + + public static string DescriptionAttributeMarkerSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMarkerSize); + } + } + + public static string DescriptionAttributeLegendItem_MarkerSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_MarkerSize); + } + } + + public static string DescriptionAttributeLegendCell_SeriesSymbolSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCell_SeriesSymbolSize); + } + } + + public static string DescriptionAttributeLegendCellColumn_SeriesSymbolSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_SeriesSymbolSize); + } + } + + public static string DescriptionAttributeDisabled + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDisabled); + } + } + + public static string DescriptionAttributeChartSerializer_ResetWhenLoading + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartSerializer_ResetWhenLoading); + } + } + + public static string DescriptionAttributeBackGradientStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBackGradientStyle); + } + } + + public static string DescriptionAttributeDataSource + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataSource); + } + } + + public static string DescriptionAttributeCustomLabels + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabels); + } + } + + public static string DescriptionAttributeArrowAnnotation_ArrowAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeArrowAnnotation_ArrowAnnotation); + } + } + + public static string DescriptionAttributeCursor_AxisType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_AxisType); + } + } + + public static string DescriptionAttributeLegendItem_Cells + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_Cells); + } + } + + public static string DescriptionAttributeBorderSkin + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBorderSkin); + } + } + + public static string DescriptionAttributeBorderSkin_BorderSkin + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBorderSkin_BorderSkin); + } + } + + public static string DescriptionAttributeSubAxisCollection_SubAxisCollection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSubAxisCollection_SubAxisCollection); + } + } + + public static string DescriptionAttributeAllowSelecting + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAllowSelecting); + } + } + + public static string DescriptionAttributeChartEvent_Customize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_Customize); + } + } + + public static string DescriptionAttributeChartEvent_Click + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_Click); + } + } + + public static string DescriptionAttributeImageAnnotation_ImageAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeImageAnnotation_ImageAnnotation); + } + } + + public static string DescriptionAttributeAxisDataView_SmallScrollSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_SmallScrollSize); + } + } + + public static string DescriptionAttributeAxisScaleSegment_Interval + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegment_Interval); + } + } + + public static string DescriptionAttributeCursor_Interval + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_Interval); + } + } + + public static string DescriptionAttributeInterval4 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeInterval4); + } + } + + public static string DescriptionAttributeStripLine_Interval + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_Interval); + } + } + + public static string DescriptionAttributeInterval6 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeInterval6); + } + } + + public static string DescriptionAttributeLabel_Interval + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_Interval); + } + } + + public static string DescriptionAttributeStripLine_TitleLineAlignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_TitleLineAlignment); + } + } + + public static string DescriptionAttributeMaximum + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMaximum); + } + } + + public static string DescriptionAttributeElementPosition_Auto + { + get + { + return Keys.GetString(Keys.DescriptionAttributeElementPosition_Auto); + } + } + + public static string DescriptionAttributeSeries_YAxisType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_YAxisType); + } + } + + public static string DescriptionAttributeLineDashStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLineDashStyle); + } + } + + public static string DescriptionAttributeLogarithmBase + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLogarithmBase); + } + } + + public static string DescriptionAttributeAntiAlias + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAntiAlias); + } + } + + public static string DescriptionAttributeImageWrapMode + { + get + { + return Keys.GetString(Keys.DescriptionAttributeImageWrapMode); + } + } + + public static string DescriptionAttributeChartSerializer_IgnoreUnknownXmlAttributes + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartSerializer_IgnoreUnknownXmlAttributes); + } + } + + public static string DescriptionAttributeAxisScaleSegment_Tag + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegment_Tag); + } + } + + public static string DescriptionAttributeTag + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTag); + } + } + + public static string DescriptionAttributeLegend + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend); + } + } + + public static string DescriptionAttributeLegend_Legend + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_Legend); + } + } + + public static string DescriptionAttributeSeries_Legend + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_Legend); + } + } + + public static string DescriptionAttributeDataPointComparer_DataPointComparer + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataPointComparer_DataPointComparer); + } + } + + public static string DescriptionAttributeBackHatchStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBackHatchStyle); + } + } + + public static string DescriptionAttributeFrameBackHatchStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeFrameBackHatchStyle); + } + } + + public static string DescriptionAttributeChartAreaCollection_Item + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartAreaCollection_Item); + } + } + + public static string DescriptionAttributeLegendCollection_Item + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCollection_Item); + } + } + + public static string DescriptionAttributeAnnotationCollection_Item + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationCollection_Item); + } + } + + public static string DescriptionAttributeSubAxisCollection_Item + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSubAxisCollection_Item); + } + } + + public static string DescriptionAttributeSeriesCollection_Item + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeriesCollection_Item); + } + } + + public static string DescriptionAttributeAnnotationPathPointCollection_Item + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationPathPointCollection_Item); + } + } + + public static string DescriptionAttributeLegendCellColumnCollection_Item + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumnCollection_Item); + } + } + + public static string DescriptionAttributeAxisScaleSegmentCollection_Item + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegmentCollection_Item); + } + } + + public static string DescriptionAttributeLegendCellCollection_Item + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellCollection_Item); + } + } + + public static string DescriptionAttributeNamedImagesCollection_Item + { + get + { + return Keys.GetString(Keys.DescriptionAttributeNamedImagesCollection_Item); + } + } + + public static string DescriptionAttributeAxisScaleSegment_ScaleMinimum + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegment_ScaleMinimum); + } + } + + public static string DescriptionAttributeSmartLabels + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSmartLabels); + } + } + + public static string DescriptionAttributeSeries_SmartLabels + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_SmartLabels); + } + } + + public static string DescriptionAttributeSmartLabels_SmartLabels + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSmartLabels_SmartLabels); + } + } + + public static string DescriptionAttributeMinorTickMark + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMinorTickMark); + } + } + + public static string DescriptionAttributeMapAreasCollection_MapAreasCollection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMapAreasCollection_MapAreasCollection); + } + } + + public static string DescriptionAttributeMovingDirection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMovingDirection); + } + } + + public static string DescriptionAttributeCursor_UserSelection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_UserSelection); + } + } + + public static string DescriptionAttributeChartArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea); + } + } + + public static string DescriptionAttributeSeries_ChartArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_ChartArea); + } + } + + public static string DescriptionAttributeChartArea_ChartArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_ChartArea); + } + } + + public static string DescriptionAttributeToolTipEventArgs_HitTestResult + { + get + { + return Keys.GetString(Keys.DescriptionAttributeToolTipEventArgs_HitTestResult); + } + } + + public static string DescriptionAttributeAxisScaleSegment_AxisScaleSegment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegment_AxisScaleSegment); + } + } + + public static string DescriptionAttributeLegend_ItemColumnSeparatorColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_ItemColumnSeparatorColor); + } + } + + public static string DescriptionAttributeDataManipulator + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataManipulator); + } + } + + public static string DescriptionAttributeTitle_Color + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle_Color); + } + } + + public static string DescriptionAttributeLegendItem_Color + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_Color); + } + } + + public static string DescriptionAttributeColor4 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeColor4); + } + } + + public static string DescriptionAttributeMargins_Right + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMargins_Right); + } + } + + public static string DescriptionAttributeRight3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeRight3); + } + } + + public static string DescriptionAttributeChart_OnBackPaint + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_OnBackPaint); + } + } + + public static string DescriptionAttributeLineColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLineColor); + } + } + + public static string DescriptionAttributeCalloutLineColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCalloutLineColor); + } + } + + public static string DescriptionAttributeArrowAnnotation_ArrowStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeArrowAnnotation_ArrowStyle); + } + } + + public static string DescriptionAttributeArrowStyle_ArrowStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeArrowStyle_ArrowStyle); + } + } + + public static string DescriptionAttributeSeries_XValueType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_XValueType); + } + } + + public static string DescriptionAttributeAnnotationGroup_Annotations + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationGroup_Annotations); + } + } + + public static string DescriptionAttributeAnnotations3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotations3); + } + } + + public static string DescriptionAttributeMinorGrid + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMinorGrid); + } + } + + public static string DescriptionAttributeMapArea_Custom + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMapArea_Custom); + } + } + + public static string DescriptionAttributeChart_EnableViewState + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_EnableViewState); + } + } + + public static string DescriptionAttributeChartArea3DStyle_Enable3D + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea3DStyle_Enable3D); + } + } + + public static string DescriptionAttributeInterlacedColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeInterlacedColor); + } + } + + public static string DescriptionAttributeLegendCellColumn_Margins + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_Margins); + } + } + + public static string DescriptionAttributeMargins_Margins + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMargins_Margins); + } + } + + public static string DescriptionAttributeLegendCell_Margins + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCell_Margins); + } + } + + public static string DescriptionAttributeLegendItem_MarkerColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_MarkerColor); + } + } + + public static string DescriptionAttributeMarkerColor3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMarkerColor3); + } + } + + public static string DescriptionAttributeChart_Size + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_Size); + } + } + + public static string DescriptionAttributeTickMark_Size + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTickMark_Size); + } + } + + public static string DescriptionAttributeAxisScaleSegment_Size + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegment_Size); + } + } + + public static string DescriptionAttributeAxisDataView_Size + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_Size); + } + } + + public static string DescriptionAttributeAxisScrollBar_Size + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScrollBar_Size); + } + } + + public static string DescriptionAttributeViewEventArgs_NewSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeViewEventArgs_NewSize); + } + } + + public static string DescriptionAttributeSeries_XAxisType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_XAxisType); + } + } + + public static string DescriptionAttributeAllowOutsidePlotArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAllowOutsidePlotArea); + } + } + + public static string DescriptionAttributeLegendItem_MarkerStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_MarkerStyle); + } + } + + public static string DescriptionAttributeMarkerStyle4 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMarkerStyle4); + } + } + + public static string DescriptionAttributeLegendCell_ImageSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCell_ImageSize); + } + } + + public static string DescriptionAttributeView + { + get + { + return Keys.GetString(Keys.DescriptionAttributeView); + } + } + + public static string DescriptionAttributeSeriesCollection_SeriesCollection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeriesCollection_SeriesCollection); + } + } + + public static string DescriptionAttributeCursorEventArgs_NewPosition + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursorEventArgs_NewPosition); + } + } + + public static string DescriptionAttributeViewEventArgs_NewPosition + { + get + { + return Keys.GetString(Keys.DescriptionAttributeViewEventArgs_NewPosition); + } + } + + public static string DescriptionAttributeLegendCell_Image + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCell_Image); + } + } + + public static string DescriptionAttributeNamedImage_Image + { + get + { + return Keys.GetString(Keys.DescriptionAttributeNamedImage_Image); + } + } + + public static string DescriptionAttributeImageAnnotation_Image + { + get + { + return Keys.GetString(Keys.DescriptionAttributeImageAnnotation_Image); + } + } + + public static string DescriptionAttributeLegendItem_Image + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_Image); + } + } + + public static string DescriptionAttributeCustomLabel_Image + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_Image); + } + } + + public static string DescriptionAttributeAxisScaleSegment_IntervalOffset + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegment_IntervalOffset); + } + } + + public static string DescriptionAttributeIntervalOffset3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeIntervalOffset3); + } + } + + public static string DescriptionAttributeLabel_IntervalOffset + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_IntervalOffset); + } + } + + public static string DescriptionAttributeCursor_IntervalOffset + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_IntervalOffset); + } + } + + public static string DescriptionAttributeIntervalOffset6 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeIntervalOffset6); + } + } + + public static string DescriptionAttributeStripLine_IntervalOffset + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_IntervalOffset); + } + } + + public static string DescriptionAttributeLegend_DockInsideChartArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_DockInsideChartArea); + } + } + + public static string DescriptionAttributeTitle_DockInsideChartArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle_DockInsideChartArea); + } + } + + public static string DescriptionAttributeChart_RenderType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_RenderType); + } + } + + public static string DescriptionAttributeAxisScaleBreakStyle_CollapsibleSpaceThreshold + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleBreakStyle_CollapsibleSpaceThreshold); + } + } + + public static string DescriptionAttributeChartEvent_AxisViewChanging + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_AxisViewChanging); + } + } + + public static string DescriptionAttributeLabelCalloutStyle_LabelCalloutStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabelCalloutStyle_LabelCalloutStyle); + } + } + + public static string DescriptionAttributePath + { + get + { + return Keys.GetString(Keys.DescriptionAttributePath); + } + } + + public static string DescriptionAttributeLegendItem_SeriesPointIndex + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_SeriesPointIndex); + } + } + + public static string DescriptionAttributeMapAreas + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMapAreas); + } + } + + public static string DescriptionAttributeTickMark_TickMark + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTickMark_TickMark); + } + } + + public static string DescriptionAttributeLegendCellColumn_LegendCellColumn + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_LegendCellColumn); + } + } + + public static string DescriptionAttributeLegendItem_LegendItem + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_LegendItem); + } + } + + public static string DescriptionAttributeTitleAlignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitleAlignment); + } + } + + public static string DescriptionAttributeStripLine_TitleAlignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_TitleAlignment); + } + } + + public static string DescriptionAttributeLegend_TitleAlignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_TitleAlignment); + } + } + + public static string DescriptionAttributeElementPosition_ElementPosition + { + get + { + return Keys.GetString(Keys.DescriptionAttributeElementPosition_ElementPosition); + } + } + + public static string DescriptionAttributeCustomLabel_To + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_To); + } + } + + public static string DescriptionAttributeLabel_FontAngle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_FontAngle); + } + } + + public static string DescriptionAttributeIntervalAutoMode + { + get + { + return Keys.GetString(Keys.DescriptionAttributeIntervalAutoMode); + } + } + + public static string DescriptionAttributeStripLine_StripWidth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_StripWidth); + } + } + + public static string DescriptionAttributeCursor_UserEnabled + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_UserEnabled); + } + } + + public static string DescriptionAttributeBorderSkin_FrameBorderWidth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBorderSkin_FrameBorderWidth); + } + } + + public static string DescriptionAttributeAxisScaleSegment_Position + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegment_Position); + } + } + + public static string DescriptionAttributeAxisDataView_Position + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_Position); + } + } + + public static string DescriptionAttributeTitle_Position + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle_Position); + } + } + + public static string DescriptionAttributeLegend_Position + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_Position); + } + } + + public static string DescriptionAttributeChartArea_Position + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_Position); + } + } + + public static string DescriptionAttributeCursor_Position + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_Position); + } + } + + public static string DescriptionAttributeSubAxis_ParentAxis + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSubAxis_ParentAxis); + } + } + + public static string DescriptionAttributeAnnotationCollectionEditor_AnnotationCollectionEditor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationCollectionEditor_AnnotationCollectionEditor); + } + } + + public static string DescriptionAttributeBottom + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBottom); + } + } + + public static string DescriptionAttributeMargins_Bottom + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMargins_Bottom); + } + } + + public static string DescriptionAttributeAxisScaleBreakStyle_AxisScaleBreakStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleBreakStyle_AxisScaleBreakStyle); + } + } + + public static string DescriptionAttributeLegend_HeaderSeparator + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_HeaderSeparator); + } + } + + public static string DescriptionAttributeChartArea3DStyle_PointDepth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea3DStyle_PointDepth); + } + } + + public static string DescriptionAttributeAnnotationGroup_AnnotationGroup + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationGroup_AnnotationGroup); + } + } + + public static string DescriptionAttributeAnnotationPathPointCollection_AnnotationPathPointCollection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationPathPointCollection_AnnotationPathPointCollection); + } + } + + public static string DescriptionAttributeStripLine_StripWidthType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_StripWidthType); + } + } + + public static string DescriptionAttributeCustomLabel_From + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_From); + } + } + + public static string DescriptionAttributePoint3D_PointF + { + get + { + return Keys.GetString(Keys.DescriptionAttributePoint3D_PointF); + } + } + + public static string DescriptionAttributeBorderWidth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBorderWidth); + } + } + + public static string DescriptionAttributeMarkerBorderWidth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMarkerBorderWidth); + } + } + + public static string DescriptionAttributeCursor_SelectionEnd + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_SelectionEnd); + } + } + + public static string DescriptionAttributeLineAnnotation_LineAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLineAnnotation_LineAnnotation); + } + } + + public static string DescriptionAttributeAnnotationSmartLabels_AnnotationSmartLabels + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationSmartLabels_AnnotationSmartLabels); + } + } + + public static string DescriptionAttributeAnnotationGroup_Visible + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationGroup_Visible); + } + } + + public static string DescriptionAttributeChartArea_Visible + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_Visible); + } + } + + public static string DescriptionAttributeTitle_Visible + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle_Visible); + } + } + + public static string DescriptionAttributeVisible + { + get + { + return Keys.GetString(Keys.DescriptionAttributeVisible); + } + } + + public static string DescriptionAttributeLegendItem_Separator + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_Separator); + } + } + + public static string DescriptionAttributeLegendCell_CellType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCell_CellType); + } + } + + public static string DescriptionAttributeChart_Serializer + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_Serializer); + } + } + + public static string DescriptionAttributeAxisX + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisX); + } + } + + public static string DescriptionAttributeChartArea_AxisX + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_AxisX); + } + } + + public static string DescriptionAttributeImageType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeImageType); + } + } + + public static string DescriptionAttributeCursor_SelectionStart + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_SelectionStart); + } + } + + public static string DescriptionAttributeLabelsAutoFit + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabelsAutoFit); + } + } + + public static string DescriptionAttributeLegendCellColumn_HeaderText + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_HeaderText); + } + } + + public static string DescriptionAttributeMapEnabled + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMapEnabled); + } + } + + public static string DescriptionAttributeAxisDataView_Zoomable + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_Zoomable); + } + } + + public static string DescriptionAttributeDataManager_PaletteCustomColors + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataManager_PaletteCustomColors); + } + } + + public static string DescriptionAttributeChart_PaletteCustomColors + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_PaletteCustomColors); + } + } + + public static string DescriptionAttributeLegend_ItemColumnSeparator + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_ItemColumnSeparator); + } + } + + public static string DescriptionAttributeCursorEventArgs_NewSelectionEnd + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursorEventArgs_NewSelectionEnd); + } + } + + public static string DescriptionAttributeLegendItem_SeriesName + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_SeriesName); + } + } + + public static string DescriptionAttributeChartAreas + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartAreas); + } + } + + public static string DescriptionAttributeChartArea_AlignWithChartArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_AlignWithChartArea); + } + } + + public static string DescriptionAttributeLegend_MaxAutoSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_MaxAutoSize); + } + } + + public static string DescriptionAttributeAxis_MaxAutoSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxis_MaxAutoSize); + } + } + + public static string DescriptionAttributeGrid_Grid + { + get + { + return Keys.GetString(Keys.DescriptionAttributeGrid_Grid); + } + } + + public static string DescriptionAttributeChartArea_EquallySizedAxesFont + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_EquallySizedAxesFont); + } + } + + public static string DescriptionAttributeChartEvent_CustomizeMapAreas + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_CustomizeMapAreas); + } + } + + public static string DescriptionAttributeChartArea3DStyle_WallWidth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea3DStyle_WallWidth); + } + } + + public static string DescriptionAttributeCustomLabel_Row + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_Row); + } + } + + public static string DescriptionAttributeLegend_TitleSeparatorColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_TitleSeparatorColor); + } + } + + public static string DescriptionAttributeChartSerializer_TemplateMode + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartSerializer_TemplateMode); + } + } + + public static string DescriptionAttributeShadowColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeShadowColor); + } + } + + public static string DescriptionAttributeAxisScaleBreakStyle_MaxNumberOfBreaks + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleBreakStyle_MaxNumberOfBreaks); + } + } + + public static string DescriptionAttributeChartEvent_AxisScrollBarClicked + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_AxisScrollBarClicked); + } + } + + public static string DescriptionAttributeAnchorY + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnchorY); + } + } + + public static string DescriptionAttributeLegend_AutoFitMinFontSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_AutoFitMinFontSize); + } + } + + public static string DescriptionAttributeChartEvent_AnnotationTextChanged + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_AnnotationTextChanged); + } + } + + public static string DescriptionAttributeChart_Series + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_Series); + } + } + + public static string DescriptionAttributeSeries_Series + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_Series); + } + } + + public static string DescriptionAttributeMapArea_Shape + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMapArea_Shape); + } + } + + public static string DescriptionAttributeLegend_TextWrapThreshold + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_TextWrapThreshold); + } + } + + public static string DescriptionAttributeLabelOutsidePlotAreaStyle_LabelOutsidePlotAreaStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabelOutsidePlotAreaStyle_LabelOutsidePlotAreaStyle); + } + } + + public static string DescriptionAttributeSubAxes + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSubAxes); + } + } + + public static string DescriptionAttributeAxisScaleBreakStyle_StartFromZero + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleBreakStyle_StartFromZero); + } + } + + public static string DescriptionAttributeStartFromZero3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStartFromZero3); + } + } + + public static string DescriptionAttributeRectangleAnnotation_RectangleAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeRectangleAnnotation_RectangleAnnotation); + } + } + + public static string DescriptionAttributeUrl + { + get + { + return Keys.GetString(Keys.DescriptionAttributeUrl); + } + } + + public static string DescriptionAttributeAxisScaleBreakStyle_BreakLineType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleBreakStyle_BreakLineType); + } + } + + public static string DescriptionAttributeChartEvent_CursorPositionChanged + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_CursorPositionChanged); + } + } + + public static string DescriptionAttributeChartSerializer_SerializableContent + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartSerializer_SerializableContent); + } + } + + public static string DescriptionAttributeCalloutAnnotation_CalloutStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCalloutAnnotation_CalloutStyle); + } + } + + public static string DescriptionAttributeCalloutStyle3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCalloutStyle3); + } + } + + public static string DescriptionAttributeCalloutStyle_CalloutStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCalloutStyle_CalloutStyle); + } + } + + public static string DescriptionAttributeTitle_Docking + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle_Docking); + } + } + + public static string DescriptionAttributeLegend_Docking + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_Docking); + } + } + + public static string DescriptionAttributeAnnotationGroup_AllowAnchorMoving + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationGroup_AllowAnchorMoving); + } + } + + public static string DescriptionAttributeAllowAnchorMoving3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAllowAnchorMoving3); + } + } + + public static string DescriptionAttributeTitleColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitleColor); + } + } + + public static string DescriptionAttributeStripLine_TitleColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_TitleColor); + } + } + + public static string DescriptionAttributeLegend_TitleColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_TitleColor); + } + } + + public static string DescriptionAttributeTitles + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitles); + } + } + + public static string DescriptionAttributePolygonAnnotation_PolygonAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributePolygonAnnotation_PolygonAnnotation); + } + } + + public static string DescriptionAttributeLabel_IntervalType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_IntervalType); + } + } + + public static string DescriptionAttributeIntervalType3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeIntervalType3); + } + } + + public static string DescriptionAttributeIntervalType4 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeIntervalType4); + } + } + + public static string DescriptionAttributeStripLine_IntervalType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLine_IntervalType); + } + } + + public static string DescriptionAttributeAxisScaleSegment_IntervalType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegment_IntervalType); + } + } + + public static string DescriptionAttributeCursor_IntervalType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCursor_IntervalType); + } + } + + public static string DescriptionAttributeLegendItem_SeparatorColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendItem_SeparatorColor); + } + } + + public static string DescriptionAttributeSeries_YValuesPerPoint + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_YValuesPerPoint); + } + } + + public static string DescriptionAttributeChartEvent_PrePaint + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_PrePaint); + } + } + + public static string DescriptionAttributeLegendUrl + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendUrl); + } + } + + public static string DescriptionAttributeCustomLabel_ImageUrl + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_ImageUrl); + } + } + + public static string DescriptionAttributeLabel_Format + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_Format); + } + } + + public static string DescriptionAttributeChartSerializer_Format + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartSerializer_Format); + } + } + + public static string DescriptionAttributeStripLines + { + get + { + return Keys.GetString(Keys.DescriptionAttributeStripLines); + } + } + + public static string DescriptionAttributeChart_ViewStateData + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_ViewStateData); + } + } + + public static string DescriptionAttributeTitle_DockOffset + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle_DockOffset); + } + } + + public static string DescriptionAttributeAnchorDataPoint + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnchorDataPoint); + } + } + + public static string DescriptionAttributeLabelFormat + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabelFormat); + } + } + + public static string DescriptionAttributeSuppressExceptions + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSuppressExceptions); + } + } + + public static string DescriptionAttributeSeries_EmptyPointStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_EmptyPointStyle); + } + } + + public static string DescriptionAttributeCustomAttributes + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomAttributes); + } + } + + public static string DescriptionAttributeLegendCellCollection_LegendCellCollection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellCollection_LegendCellCollection); + } + } + + public static string DescriptionAttributeCustomLabelsCollection_CustomLabelsCollection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabelsCollection_CustomLabelsCollection); + } + } + + public static string DescriptionAttributeCustomLabel_MarkColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_MarkColor); + } + } + + public static string DescriptionAttributePalette + { + get + { + return Keys.GetString(Keys.DescriptionAttributePalette); + } + } + + public static string DescriptionAttributeScaleBreakStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeScaleBreakStyle); + } + } + + public static string DescriptionAttributeChart_ImageUrl + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_ImageUrl); + } + } + + public static string DescriptionAttributeLegend_InterlacedRowsColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_InterlacedRowsColor); + } + } + + public static string DescriptionAttributeLegendCellColumn_ColumnType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_ColumnType); + } + } + + public static string DescriptionAttributeChartArea_AlignOrientation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_AlignOrientation); + } + } + + public static string DescriptionAttributeChart_SoftShadows + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_SoftShadows); + } + } + + public static string DescriptionAttributeSoftShadows3 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSoftShadows3); + } + } + + public static string DescriptionAttributePrintingManager_PrintDocument + { + get + { + return Keys.GetString(Keys.DescriptionAttributePrintingManager_PrintDocument); + } + } + + public static string DescriptionAttributeMinimum + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMinimum); + } + } + + public static string DescriptionAttributeAxisScaleSegment_ScaleMaximum + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScaleSegment_ScaleMaximum); + } + } + + public static string DescriptionAttributeScrollBarEventArgs_MousePositionX + { + get + { + return Keys.GetString(Keys.DescriptionAttributeScrollBarEventArgs_MousePositionX); + } + } + + public static string DescriptionAttributeLabel_TruncatedLabels + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLabel_TruncatedLabels); + } + } + + public static string DescriptionAttributeCustomLabel_GridTicks + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_GridTicks); + } + } + + public static string DescriptionAttributeImageAnnotation_Alignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeImageAnnotation_Alignment); + } + } + + public static string DescriptionAttributeLegendCellColumn_Alignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_Alignment); + } + } + + public static string DescriptionAttributeTitle_Alignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle_Alignment); + } + } + + public static string DescriptionAttributeLegendCell_Alignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCell_Alignment); + } + } + + public static string DescriptionAttributeLegend_Alignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_Alignment); + } + } + + public static string DescriptionAttributeAlignment + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAlignment); + } + } + + public static string DescriptionAttributeChart_OnCustomizeMapAreas + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_OnCustomizeMapAreas); + } + } + + public static string DescriptionAttributeSubAxis_LocationOffset + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSubAxis_LocationOffset); + } + } + + public static string DescriptionAttributeLegendCellColumn_MinimumWidth + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_MinimumWidth); + } + } + + public static string DescriptionAttributeSelectionPointsStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSelectionPointsStyle); + } + } + + public static string DescriptionAttributeAxisY + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisY); + } + } + + public static string DescriptionAttributeChartArea_AxisY + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_AxisY); + } + } + + public static string DescriptionAttributeTextFont + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTextFont); + } + } + + public static string DescriptionAttributeTextFont4 + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTextFont4); + } + } + + public static string DescriptionAttributeAxisDataView_SizeType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_SizeType); + } + } + + public static string DescriptionAttributeMinMovingDistance + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMinMovingDistance); + } + } + + public static string DescriptionAttributeChartArea_CursorX + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea_CursorX); + } + } + + public static string DescriptionAttributeAxisDataView_SmallScrollMinSize + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_SmallScrollMinSize); + } + } + + public static string DescriptionAttributeAxisDataView_SmallScrollMinSizeType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisDataView_SmallScrollMinSizeType); + } + } + + public static string DescriptionAttributeAxisScrollBar_ButtonColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAxisScrollBar_ButtonColor); + } + } + + public static string DescriptionAttributeArea3DStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeArea3DStyle); + } + } + + public static string DescriptionAttributeChart + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart); + } + } + + public static string DescriptionAttributeChart_Chart + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChart_Chart); + } + } + + public static string DescriptionAttributeBorderSkin_PageColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeBorderSkin_PageColor); + } + } + + public static string DescriptionAttributeDataPoint_DataPoint + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataPoint_DataPoint); + } + } + + public static string DescriptionAttributeChartArea3DStyle_Light + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartArea3DStyle_Light); + } + } + + public static string DescriptionAttributeDataPointCustomProperties_DataPointCustomProperties + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataPointCustomProperties_DataPointCustomProperties); + } + } + + public static string DescriptionAttributeLegend_AutoFitText + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_AutoFitText); + } + } + + public static string DescriptionAttributeAllowTextEditing + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAllowTextEditing); + } + } + + public static string DescriptionAttributeCustomLabel_Text + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCustomLabel_Text); + } + } + + public static string DescriptionAttributeLegendCell_Text + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCell_Text); + } + } + + public static string DescriptionAttributeText + { + get + { + return Keys.GetString(Keys.DescriptionAttributeText); + } + } + + public static string DescriptionAttributeTitle_Text + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTitle_Text); + } + } + + public static string DescriptionAttributeLegendCellColumn_Text + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_Text); + } + } + + public static string DescriptionAttributeToolTipEventArgs_Text + { + get + { + return Keys.GetString(Keys.DescriptionAttributeToolTipEventArgs_Text); + } + } + + public static string DescriptionAttributeMultiline + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMultiline); + } + } + + public static string DescriptionAttributeTextAnnotation_TextAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTextAnnotation_TextAnnotation); + } + } + + public static string DescriptionAttributeAnnotationGroup_ClipToChartArea + { + get + { + return Keys.GetString(Keys.DescriptionAttributeAnnotationGroup_ClipToChartArea); + } + } + + public static string DescriptionAttributeSeries_YValueType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeSeries_YValueType); + } + } + + public static string DescriptionAttributeInternalIntervalType + { + get + { + return Keys.GetString(Keys.DescriptionAttributeInternalIntervalType); + } + } + + public static string DescriptionAttributeCalloutAnnotation_CalloutAnchorCap + { + get + { + return Keys.GetString(Keys.DescriptionAttributeCalloutAnnotation_CalloutAnchorCap); + } + } + + public static string DescriptionAttributeLogarithmic + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLogarithmic); + } + } + + public static string DescriptionAttributeLegend_ItemColumnSpacing + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegend_ItemColumnSpacing); + } + } + + public static string DescriptionAttributeMarksNextToAxis + { + get + { + return Keys.GetString(Keys.DescriptionAttributeMarksNextToAxis); + } + } + + public static string DescriptionAttributeChartEvent_SelectionRangeChanged + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartEvent_SelectionRangeChanged); + } + } + + public static string DescriptionAttributeDataPointCollection_DataPointCollection + { + get + { + return Keys.GetString(Keys.DescriptionAttributeDataPointCollection_DataPointCollection); + } + } + + public static string DescriptionAttributeHorizontalLineAnnotation_HorizontalLineAnnotation + { + get + { + return Keys.GetString(Keys.DescriptionAttributeHorizontalLineAnnotation_HorizontalLineAnnotation); + } + } + + public static string DescriptionAttributeLegendCellColumn_HeaderColor + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCellColumn_HeaderColor); + } + } + + public static string DescriptionAttributeLegendCell_LegendCell + { + get + { + return Keys.GetString(Keys.DescriptionAttributeLegendCell_LegendCell); + } + } + + public static string DescriptionAttributeChartImageDescriptionUrl + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartImageDescriptionUrl); + } + } + + public static string DescriptionAttributeChartImageAlternateText + { + get + { + return Keys.GetString(Keys.DescriptionAttributeChartImageAlternateText); + } + } + + public static string DescriptionAttributePostBackValue + { + get + { + return Keys.GetString(Keys.DescriptionAttributePostBackValue); + } + } + + public static string DescriptionAttributeTextStyle + { + get + { + return Keys.GetString(Keys.DescriptionAttributeTextStyle); + } + } + + public static string DescriptionAttributeIsMapAreaAttributesEncoded + { + get + { + return Keys.GetString(Keys.DescriptionAttributeIsMapAreaAttributesEncoded); + } + } + + public static string DescriptionAttributeRightToLeft + { + get + { + return Keys.GetString(Keys.DescriptionAttributeRightToLeft); + } + } + + public static string CategoryAttributeCellColumns + { + get + { + return Keys.GetString(Keys.CategoryAttributeCellColumns); + } + } + + public static string CategoryAttributeAxis + { + get + { + return Keys.GetString(Keys.CategoryAttributeAxis); + } + } + + public static string CategoryAttributeEditing + { + get + { + return Keys.GetString(Keys.CategoryAttributeEditing); + } + } + + public static string CategoryAttributeSize + { + get + { + return Keys.GetString(Keys.CategoryAttributeSize); + } + } + + public static string CategoryAttributePosition + { + get + { + return Keys.GetString(Keys.CategoryAttributePosition); + } + } + + public static string CategoryAttributeViewState + { + get + { + return Keys.GetString(Keys.CategoryAttributeViewState); + } + } + + public static string CategoryAttributeInterval + { + get + { + return Keys.GetString(Keys.CategoryAttributeInterval); + } + } + + public static string CategoryAttributeAppearance + { + get + { + return Keys.GetString(Keys.CategoryAttributeAppearance); + } + } + + public static string CategoryAttributeDocking + { + get + { + return Keys.GetString(Keys.CategoryAttributeDocking); + } + } + + public static string CategoryAttributeDataSource + { + get + { + return Keys.GetString(Keys.CategoryAttributeDataSource); + } + } + + public static string CategoryAttributeAxisView + { + get + { + return Keys.GetString(Keys.CategoryAttributeAxisView); + } + } + + public static string CategoryAttributeLayout + { + get + { + return Keys.GetString(Keys.CategoryAttributeLayout); + } + } + + public static string CategoryAttribute3D + { + get + { + return Keys.GetString(Keys.CategoryAttribute3D); + } + } + + public static string CategoryAttributeData + { + get + { + return Keys.GetString(Keys.CategoryAttributeData); + } + } + + public static string CategoryAttributeTitle + { + get + { + return Keys.GetString(Keys.CategoryAttributeTitle); + } + } + + public static string CategoryAttributeToolTips + { + get + { + return Keys.GetString(Keys.CategoryAttributeToolTips); + } + } + + public static string CategoryAttributeLabels + { + get + { + return Keys.GetString(Keys.CategoryAttributeLabels); + } + } + + public static string CategoryAttributeGridTickMarks + { + get + { + return Keys.GetString(Keys.CategoryAttributeGridTickMarks); + } + } + + public static string CategoryAttributeLabelAppearance + { + get + { + return Keys.GetString(Keys.CategoryAttributeLabelAppearance); + } + } + + public static string CategoryAttributeHeader + { + get + { + return Keys.GetString(Keys.CategoryAttributeHeader); + } + } + + public static string CategoryAttributeAxes + { + get + { + return Keys.GetString(Keys.CategoryAttributeAxes); + } + } + + public static string CategoryAttributeImage + { + get + { + return Keys.GetString(Keys.CategoryAttributeImage); + } + } + + public static string CategoryAttributeEmptyPoints + { + get + { + return Keys.GetString(Keys.CategoryAttributeEmptyPoints); + } + } + + public static string CategoryAttributeAlignment + { + get + { + return Keys.GetString(Keys.CategoryAttributeAlignment); + } + } + + public static string CategoryAttributeAnnotation + { + get + { + return Keys.GetString(Keys.CategoryAttributeAnnotation); + } + } + + public static string CategoryAttributeMarker + { + get + { + return Keys.GetString(Keys.CategoryAttributeMarker); + } + } + + public static string CategoryAttributeChart + { + get + { + return Keys.GetString(Keys.CategoryAttributeChart); + } + } + + public static string CategoryAttributeLocation + { + get + { + return Keys.GetString(Keys.CategoryAttributeLocation); + } + } + + public static string CategoryAttributeToolTip + { + get + { + return Keys.GetString(Keys.CategoryAttributeToolTip); + } + } + + public static string CategoryAttributeMap + { + get + { + return Keys.GetString(Keys.CategoryAttributeMap); + } + } + + public static string CategoryAttributeMapArea + { + get + { + return Keys.GetString(Keys.CategoryAttributeMapArea); + } + } + + public static string CategoryAttributeLabel + { + get + { + return Keys.GetString(Keys.CategoryAttributeLabel); + } + } + + public static string CategoryAttributeShape + { + get + { + return Keys.GetString(Keys.CategoryAttributeShape); + } + } + + public static string CategoryAttributeMisc + { + get + { + return Keys.GetString(Keys.CategoryAttributeMisc); + } + } + + public static string CategoryAttributeSerializer + { + get + { + return Keys.GetString(Keys.CategoryAttributeSerializer); + } + } + + public static string CategoryAttributeSubAxes + { + get + { + return Keys.GetString(Keys.CategoryAttributeSubAxes); + } + } + + public static string CategoryAttributeSeriesItems + { + get + { + return Keys.GetString(Keys.CategoryAttributeSeriesItems); + } + } + + public static string CategoryAttributeDataView + { + get + { + return Keys.GetString(Keys.CategoryAttributeDataView); + } + } + + public static string CategoryAttributeCharttitle + { + get + { + return Keys.GetString(Keys.CategoryAttributeCharttitle); + } + } + + public static string CategoryAttributeLegend + { + get + { + return Keys.GetString(Keys.CategoryAttributeLegend); + } + } + + public static string CategoryAttributeAction + { + get + { + return Keys.GetString(Keys.CategoryAttributeAction); + } + } + + public static string CategoryAttributeScale + { + get + { + return Keys.GetString(Keys.CategoryAttributeScale); + } + } + + public static string CategoryAttributeAnnotations + { + get + { + return Keys.GetString(Keys.CategoryAttributeAnnotations); + } + } + + public static string CategoryAttributeAnchor + { + get + { + return Keys.GetString(Keys.CategoryAttributeAnchor); + } + } + + public static string CategoryAttributeBehavior + { + get + { + return Keys.GetString(Keys.CategoryAttributeBehavior); + } + } + + public static string CategoryAttributeCursor + { + get + { + return Keys.GetString(Keys.CategoryAttributeCursor); + } + } + + public static string CategoryAttributeAnchorAxes + { + get + { + return Keys.GetString(Keys.CategoryAttributeAnchorAxes); + } + } + + public static string CategoryAttributeAccessibility + { + get + { + return Keys.GetString(Keys.CategoryAttributeAccessibility); + } + } + + public static string FormatErrorString + { + get + { + return Keys.GetString(Keys.FormatErrorString); + } + } + + public static string ExceptionNameIsEmpty + { + get + { + return Keys.GetString(Keys.ExceptionNameIsEmpty); + } + } + + public static string ActionListSeriesChartType + { + get + { + return Keys.GetString(Keys.ActionListSeriesChartType); + } + } + + public static string ActionListSeriesXValueMember + { + get + { + return Keys.GetString(Keys.ActionListSeriesXValueMember); + } + } + + public static string ActionListSeriesYValueMembers + { + get + { + return Keys.GetString(Keys.ActionListSeriesYValueMembers); + } + } + + public static string DiagnosticHeader + { + get + { + return Keys.GetString(Keys.DiagnosticHeader); + } + } + + public static string DiagnosticSettingsHeader + { + get + { + return Keys.GetString(Keys.DiagnosticSettingsHeader); + } + } + + public static string DiagnosticSettingsKey + { + get + { + return Keys.GetString(Keys.DiagnosticSettingsKey); + } + } + + public static string DiagnosticSettingsValue + { + get + { + return Keys.GetString(Keys.DiagnosticSettingsValue); + } + } + + public static string DiagnosticSettingsInfo + { + get + { + return Keys.GetString(Keys.DiagnosticSettingsInfo); + } + } + + public static string DiagnosticQueueStateHeader + { + get + { + return Keys.GetString(Keys.DiagnosticQueueStateHeader); + } + } + + public static string DiagnosticQueueStateName + { + get + { + return Keys.GetString(Keys.DiagnosticQueueStateName); + } + } + + public static string DiagnosticQueueStateAccess + { + get + { + return Keys.GetString(Keys.DiagnosticQueueStateAccess); + } + } + + public static string DiagnosticQueueStateAccessOK + { + get + { + return Keys.GetString(Keys.DiagnosticQueueStateAccessOK); + } + } + + public static string DiagnosticQueueStateAccessFail + { + get + { + return Keys.GetString(Keys.DiagnosticQueueStateAccessFail); + } + } + + public static string DiagnosticQueueStateAccessInfo + { + get + { + return Keys.GetString(Keys.DiagnosticQueueStateAccessInfo); + } + } + + public static string DiagnosticActivityHeader + { + get + { + return Keys.GetString(Keys.DiagnosticActivityHeader); + } + } + + public static string DiagnosticActivityTime + { + get + { + return Keys.GetString(Keys.DiagnosticActivityTime); + } + } + + public static string DiagnosticActivityMessage + { + get + { + return Keys.GetString(Keys.DiagnosticActivityMessage); + } + } + + public static string DiagnosticActivityError + { + get + { + return Keys.GetString(Keys.DiagnosticActivityError); + } + } + + public static string DiagnosticChartImageServedFailNotFound + { + get + { + return Keys.GetString(Keys.DiagnosticChartImageServedFailNotFound); + } + } + + public static string ExceptionImageLoaderUnsupportedType(String typeName) + { + return Keys.GetString(Keys.ExceptionImageLoaderUnsupportedType, typeName); + } + + public static string ExceptionImageLoaderIncorrectImageUrl(String url) + { + return Keys.GetString(Keys.ExceptionImageLoaderIncorrectImageUrl, url); + } + + public static string ExceptionImageLoaderIncorrectImageLocation(String location) + { + return Keys.GetString(Keys.ExceptionImageLoaderIncorrectImageLocation, location); + } + + public static string ExceptionAnnotationNameIsNotUnique(String name) + { + return Keys.GetString(Keys.ExceptionAnnotationNameIsNotUnique, name); + } + + public static string ExceptionAnnotationNameAlreadyExistsInCollection(string name) + { + return Keys.GetString(Keys.ExceptionAnnotationNameAlreadyExistsInCollection, name); + } + + public static string ExceptionAnnotationNameNotFound(String name) + { + return Keys.GetString(Keys.ExceptionAnnotationNameNotFound, name); + } + + public static string ExceptionTitleNameIsNotUnique(String name) + { + return Keys.GetString(Keys.ExceptionTitleNameIsNotUnique, name); + } + + public static string ExceptionTitleNameAddedIsNotUnique(String name) + { + return Keys.GetString(Keys.ExceptionTitleNameAddedIsNotUnique, name); + } + + public static string ExceptionTitleNameNotFound(String name) + { + return Keys.GetString(Keys.ExceptionTitleNameNotFound, name); + } + + public static string ExceptionDataSeriesNameNotFound(string name) + { + return Keys.GetString(Keys.ExceptionDataSeriesNameNotFound, name); + } + + public static string ExceptionDataSeriesPointTypeUnsupported(string type) + { + return Keys.GetString(Keys.ExceptionDataSeriesPointTypeUnsupported, type); + } + + public static string ExceptionDataSeriesYValueIndexNotExists(string yValueIndex, string seriesName) + { + return Keys.GetString(Keys.ExceptionDataSeriesYValueIndexNotExists, yValueIndex, seriesName); + } + + public static string ExceptionDataSeriesKeywordFormatInvalid(string format) + { + return Keys.GetString(Keys.ExceptionDataSeriesKeywordFormatInvalid, format); + } + + public static string ExceptionDataSeriesChartAreaInvalid(string chartArea, string seriesName) + { + return Keys.GetString(Keys.ExceptionDataSeriesChartAreaInvalid, chartArea, seriesName); + } + + public static string ExceptionSeriesNameIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionSeriesNameIsNotUnique, name); + } + + public static string ExceptionSeriesNameAddedIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionSeriesNameAddedIsNotUnique, name); + } + + public static string ExceptionEditorChartTypeRegistryServiceInObjectInaccessible(string objectName) + { + return Keys.GetString(Keys.ExceptionEditorChartTypeRegistryServiceInObjectInaccessible, objectName); + } + + public static string ExceptionLegendDesignerMarginObjectInvalid(string @string) + { + return Keys.GetString(Keys.ExceptionLegendDesignerMarginObjectInvalid, @string); + } + + public static string ExceptionChartAreaAddedIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionChartAreaAddedIsNotUnique, name); + } + + public static string ExceptionChartAreaInsertedIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionChartAreaInsertedIsNotUnique, name); + } + + public static string ExceptionChartAreaAlreadyExistsInCollection(string name) + { + return Keys.GetString(Keys.ExceptionChartAreaAlreadyExistsInCollection, name); + } + + public static string ExceptionAxisLabelsIntervalTypeUnsupported(string type) + { + return Keys.GetString(Keys.ExceptionAxisLabelsIntervalTypeUnsupported, type); + } + + public static string ExceptionSubAxisNameNotFoundShort(string name) + { + return Keys.GetString(Keys.ExceptionSubAxisNameNotFoundShort, name); + } + + public static string ExceptionSubAxisNameIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionSubAxisNameIsNotUnique, name); + } + + public static string ExceptionEnumInvalid(string name) + { + return Keys.GetString(Keys.ExceptionEnumInvalid, name); + } + + public static string ExceptionNamedImageNotFound(string name) + { + return Keys.GetString(Keys.ExceptionNamedImageNotFound, name); + } + + public static string ExceptionNamedImageAddedIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionNamedImageAddedIsNotUnique, name); + } + + public static string ExceptionNamedImageInsertedIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionNamedImageInsertedIsNotUnique, name); + } + + public static string ExceptionLegendNameIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionLegendNameIsNotUnique, name); + } + + public static string ExceptionLegendNotFound(string name) + { + return Keys.GetString(Keys.ExceptionLegendNotFound, name); + } + + public static string ExceptionLegendAddedIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionLegendAddedIsNotUnique, name); + } + + public static string ExceptionLegendDockedChartAreaIsMissing(string name) + { + return Keys.GetString(Keys.ExceptionLegendDockedChartAreaIsMissing, name); + } + + public static string ExceptionLegendReferencedInSeriesNotFound(string seriesName, string legendName) + { + return Keys.GetString(Keys.ExceptionLegendReferencedInSeriesNotFound, seriesName, legendName); + } + + public static string ExceptionLegendSeparatorTypeUnknown(string type) + { + return Keys.GetString(Keys.ExceptionLegendSeparatorTypeUnknown, type); + } + + public static string ExceptionLegendCellTypeUnknown(string type) + { + return Keys.GetString(Keys.ExceptionLegendCellTypeUnknown, type); + } + + public static string ExceptionLegendColumnAlreadyExistsInCollection(string name) + { + return Keys.GetString(Keys.ExceptionLegendColumnAlreadyExistsInCollection, name); + } + + public static string ExceptionLegendCellNameAlreadyExistsInCollection(string name) + { + return Keys.GetString(Keys.ExceptionLegendCellNameAlreadyExistsInCollection, name); + } + + public static string ExceptionLegendCellNotFound(string name) + { + return Keys.GetString(Keys.ExceptionLegendCellNotFound, name); + } + + public static string ExceptionLegendCellColumnNotFound(string name) + { + return Keys.GetString(Keys.ExceptionLegendCellColumnNotFound, name); + } + + public static string ExceptionLegendCellColumnAlreadyExistsInCollection(string name) + { + return Keys.GetString(Keys.ExceptionLegendCellColumnAlreadyExistsInCollection, name); + } + + public static string ExceptionChartAreaNameReferenceInvalid(string chartArea1, string chartArea2) + { + return Keys.GetString(Keys.ExceptionChartAreaNameReferenceInvalid, chartArea1, chartArea2); + } + + public static string ExceptionTraceManagerUnsupportedType(string name) + { + return Keys.GetString(Keys.ExceptionTraceManagerUnsupportedType, name); + } + + public static string ExceptionChartTypeRegistryUnsupportedType(string name) + { + return Keys.GetString(Keys.ExceptionChartTypeRegistryUnsupportedType, name); + } + + public static string ExceptionChartTypeNameIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionChartTypeNameIsNotUnique, name); + } + + public static string ExceptionChartTypeUnknown(string name) + { + return Keys.GetString(Keys.ExceptionChartTypeUnknown, name); + } + + public static string ExceptionChartTypeRequiresYValues(string name, string yValues) + { + return Keys.GetString(Keys.ExceptionChartTypeRequiresYValues, name, yValues); + } + + public static string ExceptionChartTypeSecondaryYAxisUnsupported(string name) + { + return Keys.GetString(Keys.ExceptionChartTypeSecondaryYAxisUnsupported, name); + } + + public static string ExceptionChartTypeSecondaryXAxisUnsupported(string name) + { + return Keys.GetString(Keys.ExceptionChartTypeSecondaryXAxisUnsupported, name); + } + + public static string ExceptionChartTypeCanNotCombine(string type1, string type2) + { + return Keys.GetString(Keys.ExceptionChartTypeCanNotCombine, type1, type2); + } + + public static string ExceptionBorderTypeRegistryUnsupportedType(string name) + { + return Keys.GetString(Keys.ExceptionBorderTypeRegistryUnsupportedType, name); + } + + public static string ExceptionBorderTypeNameIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionBorderTypeNameIsNotUnique, name); + } + + public static string ExceptionBorderTypeUnknown(string name) + { + return Keys.GetString(Keys.ExceptionBorderTypeUnknown, name); + } + + public static string ExceptionChartSerializerUnsupportedType(string name) + { + return Keys.GetString(Keys.ExceptionChartSerializerUnsupportedType, name); + } + + public static string ExceptionChartSerializerDefaultConstructorUndefined(string property) + { + return Keys.GetString(Keys.ExceptionChartSerializerDefaultConstructorUndefined, property); + } + + public static string ExceptionChartSerializerTypeUnsupported(string type) + { + return Keys.GetString(Keys.ExceptionChartSerializerTypeUnsupported, type); + } + + public static string ExceptionChartSerializerPropertyNameUnknown(string property, string @object) + { + return Keys.GetString(Keys.ExceptionChartSerializerPropertyNameUnknown, property, @object); + } + + public static string ExceptionChartSerializerBinaryTypeUnsupported(string type) + { + return Keys.GetString(Keys.ExceptionChartSerializerBinaryTypeUnsupported, type); + } + + public static string ExceptionChartSerializerBinaryHashCodeDuplicate(string anem1, string name2) + { + return Keys.GetString(Keys.ExceptionChartSerializerBinaryHashCodeDuplicate, anem1, name2); + } + + public static string ExceptionDataManipulatorYValuesIndexExceeded(string formula) + { + return Keys.GetString(Keys.ExceptionDataManipulatorYValuesIndexExceeded, formula); + } + + public static string ExceptionDataManipulatorGroupingFormulaAlreadyDefined(string formulaName) + { + return Keys.GetString(Keys.ExceptionDataManipulatorGroupingFormulaAlreadyDefined, formulaName); + } + + public static string ExceptionDataManipulatorGroupingFormulaFormatInvalid(string formula) + { + return Keys.GetString(Keys.ExceptionDataManipulatorGroupingFormulaFormatInvalid, formula); + } + + public static string ExceptionDataManipulatorGroupingFormulaNameInvalid(string name) + { + return Keys.GetString(Keys.ExceptionDataManipulatorGroupingFormulaNameInvalid, name); + } + + public static string ExceptionChartPictureUnsupportedType(string name) + { + return Keys.GetString(Keys.ExceptionChartPictureUnsupportedType, name); + } + + public static string ExceptionSubAxisNameNotFound(string name) + { + return Keys.GetString(Keys.ExceptionSubAxisNameNotFound, name); + } + + public static string ExceptionSubAxisNameAlreadyExistsInCollection(string name) + { + return Keys.GetString(Keys.ExceptionSubAxisNameAlreadyExistsInCollection, name); + } + + public static string ExceptionChartTitleSetIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionChartTitleSetIsNotUnique, name); + } + + public static string ExceptionChartTitleAddedIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionChartTitleAddedIsNotUnique, name); + } + + public static string ExceptionChartTitleDockedChartAreaIsMissing(string name) + { + return Keys.GetString(Keys.ExceptionChartTitleDockedChartAreaIsMissing, name); + } + + public static string ExceptionDataManagerUnsupportedType(string name) + { + return Keys.GetString(Keys.ExceptionDataManagerUnsupportedType, name); + } + + public static string ExceptionKeywordsRegistryUnsupportedType(string name) + { + return Keys.GetString(Keys.ExceptionKeywordsRegistryUnsupportedType, name); + } + + public static string ExceptionCustomAttributesRegistryUnsupportedType(string name) + { + return Keys.GetString(Keys.ExceptionCustomAttributesRegistryUnsupportedType, name); + } + + public static string ExceptionFormulaModuleNameIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionFormulaModuleNameIsNotUnique, name); + } + + public static string ExceptionFormulaModuleRegistryUnsupportedType(string name) + { + return Keys.GetString(Keys.ExceptionFormulaModuleRegistryUnsupportedType, name); + } + + public static string ExceptionFormulaModuleNameUnknown(string name) + { + return Keys.GetString(Keys.ExceptionFormulaModuleNameUnknown, name); + } + + public static string ExceptionColumnNameNotFound(string name) + { + return Keys.GetString(Keys.ExceptionColumnNameNotFound, name); + } + + public static string ExceptionDataPointConverterUnavailableSorting(string value, string count) + { + return Keys.GetString(Keys.ExceptionDataPointConverterUnavailableSorting, value, count); + } + + public static string ExceptionDataPointYValuesCountMismatch(string count) + { + return Keys.GetString(Keys.ExceptionDataPointYValuesCountMismatch, count); + } + + public static string ExceptionDataPointYValuesBindingCountMismatch(string count) + { + return Keys.GetString(Keys.ExceptionDataPointYValuesBindingCountMismatch, count); + } + + public static string ExceptionDataPointYValuesSettingCountMismatch(string count) + { + return Keys.GetString(Keys.ExceptionDataPointYValuesSettingCountMismatch, count); + } + + public static string ExceptionAttributeNameIsNotUnique(string name) + { + return Keys.GetString(Keys.ExceptionAttributeNameIsNotUnique, name); + } + + public static string ExceptionFormulaInvalidPeriod(string name) + { + return Keys.GetString(Keys.ExceptionFormulaInvalidPeriod, name); + } + + public static string ExceptionFormulaNotEnoughDataPoints(string name) + { + return Keys.GetString(Keys.ExceptionFormulaNotEnoughDataPoints, name); + } + + public static string ExceptionKagiAttributeFormatInvalid(string attribute) + { + return Keys.GetString(Keys.ExceptionKagiAttributeFormatInvalid, attribute); + } + + public static string ExceptionKagiAttributeOutOfRange(string name) + { + return Keys.GetString(Keys.ExceptionKagiAttributeOutOfRange, name); + } + + public static string ExceptionFunnelStyleUnknown(string style) + { + return Keys.GetString(Keys.ExceptionFunnelStyleUnknown, style); + } + + public static string ExceptionErrorBarTypeInvalid(string type) + { + return Keys.GetString(Keys.ExceptionErrorBarTypeInvalid, type); + } + + public static string ExceptionErrorBarTypeFormatInvalid(string format) + { + return Keys.GetString(Keys.ExceptionErrorBarTypeFormatInvalid, format); + } + + public static string ExceptionChartCanNotCombine(string name) + { + return Keys.GetString(Keys.ExceptionChartCanNotCombine, name); + } + + public static string ExceptionCustomAttributeValueInvalid(string value, string name) + { + return Keys.GetString(Keys.ExceptionCustomAttributeValueInvalid, value, name); + } + + public static string ExceptionCustomAttributeValueInvalid2(string name) + { + return Keys.GetString(Keys.ExceptionCustomAttributeValueInvalid2, name); + } + + public static string ExceptionCustomAttributeAngleOutOfRange(string name) + { + return Keys.GetString(Keys.ExceptionCustomAttributeAngleOutOfRange, name); + } + + public static string ExceptionCustomAttributeIsNotInRange0to1(string name) + { + return Keys.GetString(Keys.ExceptionCustomAttributeIsNotInRange0to1, name); + } + + public static string ExceptionCustomAttributeIsNotInRange0to100(string name) + { + return Keys.GetString(Keys.ExceptionCustomAttributeIsNotInRange0to100, name); + } + + public static string ExceptionCustomAttributeIsNotLargerThenZiro(string name) + { + return Keys.GetString(Keys.ExceptionCustomAttributeIsNotLargerThenZiro, name); + } + + public static string ExceptionCustomAttributeIsNotInRange0to50(string name) + { + return Keys.GetString(Keys.ExceptionCustomAttributeIsNotInRange0to50, name); + } + + public static string ExceptionCustomAttributeSeriesNameNotFound(string attributeName, string seriesName) + { + return Keys.GetString(Keys.ExceptionCustomAttributeSeriesNameNotFound, attributeName, seriesName); + } + + public static string ExceptionCustomAttributeMustBeMoreThenValue(string attributeName, string value) + { + return Keys.GetString(Keys.ExceptionCustomAttributeMustBeMoreThenValue, attributeName, value); + } + + public static string ExceptionCustomAttributeMustBeBiggerThenValue(string attributeName, string value) + { + return Keys.GetString(Keys.ExceptionCustomAttributeMustBeBiggerThenValue, attributeName, value); + } + + public static string ExceptionCustomAttributeMustBeInRange(string attributeName, string fromValue, string toValue) + { + return Keys.GetString(Keys.ExceptionCustomAttributeMustBeInRange, attributeName, fromValue, toValue); + } + + public static string ExceptionCustomAttributeTypeUnsupported(string type) + { + return Keys.GetString(Keys.ExceptionCustomAttributeTypeUnsupported, type); + } + + public static string ExceptionCustomAttributeTypeOrMaximumPossibleValueInvalid(string attributeName) + { + return Keys.GetString(Keys.ExceptionCustomAttributeTypeOrMaximumPossibleValueInvalid, attributeName); + } + + public static string ExceptionCustomAttributeTypeOrMinimumPossibleValueUnsupported(string name) + { + return Keys.GetString(Keys.ExceptionCustomAttributeTypeOrMinimumPossibleValueUnsupported, name); + } + + public static string ExceptionCustomAttributeTypeOrMinimumPossibleValueInvalid(string attributeName) + { + return Keys.GetString(Keys.ExceptionCustomAttributeTypeOrMinimumPossibleValueInvalid, attributeName); + } + + public static string ExceptionFormulaDataSeriesNameNotFoundInCollection(string name) + { + return Keys.GetString(Keys.ExceptionFormulaDataSeriesNameNotFoundInCollection, name); + } + + public static string ExceptionFormulaDataSeriesNameNotFound(string name) + { + return Keys.GetString(Keys.ExceptionFormulaDataSeriesNameNotFound, name); + } + + public static string ExceptionFormulaDataFormatInvalid(string name) + { + return Keys.GetString(Keys.ExceptionFormulaDataFormatInvalid, name); + } + + public static string ExceptionFormulaDataSeriesAreNotAlignedDifferentXValues(string series1, string series2) + { + return Keys.GetString(Keys.ExceptionFormulaDataSeriesAreNotAlignedDifferentXValues, series1, series2); + } + + public static string ExceptionFormulaDataSeriesAreNotAlignedDifferentDataPoints(string series1, string series2) + { + return Keys.GetString(Keys.ExceptionFormulaDataSeriesAreNotAlignedDifferentDataPoints, series1, series2); + } + + public static string ExceptionFormulaNotFound(string name) + { + return Keys.GetString(Keys.ExceptionFormulaNotFound, name); + } + + public static string ExceptionForecastingNotEnoughDataPoints(string minimum) + { + return Keys.GetString(Keys.ExceptionForecastingNotEnoughDataPoints, minimum); + } + + public static string ExceptionValueMustBeGreaterThan(string propertyName, string value) + { + return Keys.GetString(Keys.ExceptionValueMustBeGreaterThan, propertyName, value); + } + + public static string ExceptionValueMustBeLessThan(string propertyName, string value) + { + return Keys.GetString(Keys.ExceptionValueMustBeLessThan, propertyName, value); + } + + public static string ExceptionValueMustBeInRange(string propertyName, string fromValue, string toValue) + { + return Keys.GetString(Keys.ExceptionValueMustBeInRange, propertyName, fromValue, toValue); + } + + public static string ExceptionHttpHandlerCanNotLoadType(string type) + { + return Keys.GetString(Keys.ExceptionHttpHandlerCanNotLoadType, type); + } + + public static string ExceptionHttpHandlerImageHandlerInterfaceUnsupported(string name) + { + return Keys.GetString(Keys.ExceptionHttpHandlerImageHandlerInterfaceUnsupported, name); + } + + public static string ExceptionHttpHandlerParameterUnknown(string name, string value) + { + return Keys.GetString(Keys.ExceptionHttpHandlerParameterUnknown, name, value); + } + + public static string ExceptionHttpHandlerParameterInvalid(string name, string value) + { + return Keys.GetString(Keys.ExceptionHttpHandlerParameterInvalid, name, value); + } + + public static string ExceptionHttpHandlerPrivacyKeyInvalid(string name, string value) + { + return Keys.GetString(Keys.ExceptionHttpHandlerPrivacyKeyInvalid, name, value); + } + + public static string ExceptionHttpHandlerTempDirectoryInvalid(string directory) + { + return Keys.GetString(Keys.ExceptionHttpHandlerTempDirectoryInvalid, directory); + } + + public static string ExceptionHttpHandlerTempDirectoryUnaccesible(string directory) + { + return Keys.GetString(Keys.ExceptionHttpHandlerTempDirectoryUnaccesible, directory); + } + + public static string ExceptionHttpHandlerStorageTypeUnsupported(string type) + { + return Keys.GetString(Keys.ExceptionHttpHandlerStorageTypeUnsupported, type); + } + + public static string ExceptionWebConfigUpdateFailed(string message) + { + return Keys.GetString(Keys.ExceptionWebConfigUpdateFailed, message); + } + + public static string EvenLogMessageChartImageFileTimeToLive(string minutes) + { + return Keys.GetString(Keys.EvenLogMessageChartImageFileTimeToLive, minutes); + } + + public static string MessageYValueIndexInvalid(string maxIndex) + { + return Keys.GetString(Keys.MessageYValueIndexInvalid, maxIndex); + } + + public static string AccessibilityTitleName(string name) + { + return Keys.GetString(Keys.AccessibilityTitleName, name); + } + + public static string AccessibilityAnnotationName(string name) + { + return Keys.GetString(Keys.AccessibilityAnnotationName, name); + } + + public static string AccessibilityLegendName(string name) + { + return Keys.GetString(Keys.AccessibilityLegendName, name); + } + + public static string AccessibilitySeriesName(string name) + { + return Keys.GetString(Keys.AccessibilitySeriesName, name); + } + + public static string AccessibilityDataPointName(int index) + { + return Keys.GetString(Keys.AccessibilityDataPointName, index); + } + + public static string AccessibilityDataPointLabelName(int index) + { + return Keys.GetString(Keys.AccessibilityDataPointLabelName, index); + } + + public static string AccessibilityLegendTitleName(string name) + { + return Keys.GetString(Keys.AccessibilityLegendTitleName, name); + } + + public static string AccessibilityChartAreaName(string name) + { + return Keys.GetString(Keys.AccessibilityChartAreaName, name); + } + + public static string AccessibilityChartAxisTitleName(string name) + { + return Keys.GetString(Keys.AccessibilityChartAxisTitleName, name); + } + + public static string AccessibilityChartAxisMajorGridlinesName(string name) + { + return Keys.GetString(Keys.AccessibilityChartAxisMajorGridlinesName, name); + } + + public static string AccessibilityChartAxisMinorGridlinesName(string name) + { + return Keys.GetString(Keys.AccessibilityChartAxisMinorGridlinesName, name); + } + + public static string ExceptionNameAlreadyExistsInCollection(string name, string collection) + { + return Keys.GetString(Keys.ExceptionNameAlreadyExistsInCollection, name, collection); + } + + public static string ExceptionNameNotFound(string name, string collection) + { + return Keys.GetString(Keys.ExceptionNameNotFound, name, collection); + } + + public static string ActionListSeriesDataGroup(string name) + { + return Keys.GetString(Keys.ActionListSeriesDataGroup, name); + } + + public static string DiagnosticSettingsConfig(string s) + { + return Keys.GetString(Keys.DiagnosticSettingsConfig, s); + } + + public static string DiagnosticChartImageSaved(string name) + { + return Keys.GetString(Keys.DiagnosticChartImageSaved, name); + } + + public static string DiagnosticChartImageSavedPrivate(string name, string keyType) + { + return Keys.GetString(Keys.DiagnosticChartImageSavedPrivate, name, keyType); + } + + public static string DiagnosticChartImageDeleted(string name) + { + return Keys.GetString(Keys.DiagnosticChartImageDeleted, name); + } + + public static string DiagnosticChartImageServed(string name) + { + return Keys.GetString(Keys.DiagnosticChartImageServed, name); + } + + public static string DiagnosticChartImageServedFail(string name, string reason) + { + return Keys.GetString(Keys.DiagnosticChartImageServedFail, name, reason); + } + + public static string DiagnosticChartImageServedFailPrivacyFail(string keyType) + { + return Keys.GetString(Keys.DiagnosticChartImageServedFailPrivacyFail, keyType); + } + + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Keys + { + + static ResourceManager resourceManager = new ResourceManager(typeof(SR).FullName, typeof(SR).Module.Assembly); + + static CultureInfo _culture = null; + + public const string ExceptionElementPositionConverter = "ExceptionElementPositionConverter"; + + public const string ExceptionInvalidServiceContainer = "ExceptionInvalidServiceContainer"; + + public const string ExceptionImageLoaderInvalidServiceContainer = "ExceptionImageLoaderInvalidServiceContainer"; + + public const string ExceptionImageLoaderUnsupportedType = "ExceptionImageLoaderUnsupportedType"; + + public const string ExceptionImageLoaderIncorrectImageUrl = "ExceptionImageLoaderIncorrectImageUrl"; + + public const string ExceptionImageLoaderIncorrectImageLocation = "ExceptionImageLoaderIncorrectImageLocation"; + + public const string ExceptionImageMapAddedHasWrongType = "ExceptionImageMapAddedHasWrongType"; + + public const string ExceptionImageMapInsertedHasWrongType = "ExceptionImageMapInsertedHasWrongType"; + + public const string ExceptionImageMapCircleShapeInvalid = "ExceptionImageMapCircleShapeInvalid"; + + public const string ExceptionImageMapRectangleShapeInvalid = "ExceptionImageMapRectangleShapeInvalid"; + + public const string ExceptionImageMapPolygonShapeInvalid = "ExceptionImageMapPolygonShapeInvalid"; + + public const string ExceptionAnnotationNameIsEmpty = "ExceptionAnnotationNameIsEmpty"; + + public const string ExceptionAnnotationNameIsNotUnique = "ExceptionAnnotationNameIsNotUnique"; + + public const string ExceptionAnnotationNameAlreadyExistsInCollection = "ExceptionAnnotationNameAlreadyExistsInCollection"; + + public const string ExceptionAnnotationNameNotFound = "ExceptionAnnotationNameNotFound"; + + public const string ExceptionAnnotationPathAddLineAsSegmentsInvalid = "ExceptionAnnotationPathAddLineAsSegmentsInvalid"; + + public const string ExceptionAnnotationLineWidthIsNegative = "ExceptionAnnotationLineWidthIsNegative"; + + public const string ExceptionAnnotationAnchorOffsetInvalid = "ExceptionAnnotationAnchorOffsetInvalid"; + + public const string ExceptionAnnotationGroupedAnchorDataPointMustBeEmpty = "ExceptionAnnotationGroupedAnchorDataPointMustBeEmpty"; + + public const string ExceptionAnnotationGroupedUnableToStartPlacement = "ExceptionAnnotationGroupedUnableToStartPlacement"; + + public const string ExceptionAnnotationNotInCollection = "ExceptionAnnotationNotInCollection"; + + public const string ExceptionAnnotationGroupedAxisMustBeEmpty = "ExceptionAnnotationGroupedAxisMustBeEmpty"; + + public const string ExceptionAnnotationArrowSizeIsZero = "ExceptionAnnotationArrowSizeIsZero"; + + public const string ExceptionAnnotationArrowSizeMustBeLessThen100 = "ExceptionAnnotationArrowSizeMustBeLessThen100"; + + public const string ExceptionAnnotationArrowStyleUnknown = "ExceptionAnnotationArrowStyleUnknown"; + + public const string ExceptionInvalidIndexerArgumentType = "ExceptionInvalidIndexerArgumentType"; + + public const string ExceptionTitleNameIsNotUnique = "ExceptionTitleNameIsNotUnique"; + + public const string ExceptionTitleNameAddedIsNotUnique = "ExceptionTitleNameAddedIsNotUnique"; + + public const string ExceptionTitleNameNotFound = "ExceptionTitleNameNotFound"; + + public const string ExceptionTitleNameIsEmpty = "ExceptionTitleNameIsEmpty"; + + public const string ExceptionDataSeriesNameNotFound = "ExceptionDataSeriesNameNotFound"; + + public const string ExceptionDataSeriesObjectRequired = "ExceptionDataSeriesObjectRequired"; + + public const string ExceptionDataSeriesNameIsEmpty = "ExceptionDataSeriesNameIsEmpty"; + + public const string ExceptionDataSeriesYValuesPerPointIsZero = "ExceptionDataSeriesYValuesPerPointIsZero"; + + public const string ExceptionDataSeriesPointTypeUnsupported = "ExceptionDataSeriesPointTypeUnsupported"; + + public const string ExceptionDataSeriesYValueIndexNotExists = "ExceptionDataSeriesYValueIndexNotExists"; + + public const string ExceptionDataSeriesKeywordFormatInvalid = "ExceptionDataSeriesKeywordFormatInvalid"; + + public const string ExceptionDataSeriesChartAreaInvalid = "ExceptionDataSeriesChartAreaInvalid"; + + public const string ExceptionDataSeriesYValueNumberInvalid = "ExceptionDataSeriesYValueNumberInvalid"; + + public const string ExceptionSeriesNameIsNotUnique = "ExceptionSeriesNameIsNotUnique"; + + public const string ExceptionSeriesNameAddedIsNotUnique = "ExceptionSeriesNameAddedIsNotUnique"; + + public const string ExceptionSeriesNameIsEmpty = "ExceptionSeriesNameIsEmpty"; + + public const string ExceptionEditorChartTypeRegistryServiceInaccessible = "ExceptionEditorChartTypeRegistryServiceInaccessible"; + + public const string ExceptionEditorChartTypeRegistryServiceInObjectInaccessible = "ExceptionEditorChartTypeRegistryServiceInObjectInaccessible"; + + public const string ExceptionEditorMultipleSeriesEditiingUnsupported = "ExceptionEditorMultipleSeriesEditiingUnsupported"; + + public const string ExceptionEditorContectInstantsIsNotChartObject = "ExceptionEditorContectInstantsIsNotChartObject"; + + public const string ExceptionEditorUITypeEditorInapplicable = "ExceptionEditorUITypeEditorInapplicable"; + + public const string ExceptionEditorUITypeEditorInt32ApplicableOnly = "ExceptionEditorUITypeEditorInt32ApplicableOnly"; + + public const string ExceptionLegendDesignerMarginObjectInvalid = "ExceptionLegendDesignerMarginObjectInvalid"; + + public const string ExceptionRectangleConverterStringFormatInvalid = "ExceptionRectangleConverterStringFormatInvalid"; + + public const string ExceptionChartAreaAddedIsNotUnique = "ExceptionChartAreaAddedIsNotUnique"; + + public const string ExceptionChartAreaInsertedIsNotUnique = "ExceptionChartAreaInsertedIsNotUnique"; + + public const string ExceptionChartAreaObjectRequired = "ExceptionChartAreaObjectRequired"; + + public const string ExceptionChartAreaAlreadyExistsInCollection = "ExceptionChartAreaAlreadyExistsInCollection"; + + public const string ExceptionChartAreaInsertedHasWrongType = "ExceptionChartAreaInsertedHasWrongType"; + + public const string ExceptionChartAreaAlreadyExistsShort = "ExceptionChartAreaAlreadyExistsShort"; + + public const string ExceptionChartAreaNameIsEmpty = "ExceptionChartAreaNameIsEmpty"; + + public const string ExceptionChartArea3DPerspectiveInvalid = "ExceptionChartArea3DPerspectiveInvalid"; + + public const string ExceptionChartArea3DInclinationInvalid = "ExceptionChartArea3DInclinationInvalid"; + + public const string ExceptionChartArea3DRotationInvalid = "ExceptionChartArea3DRotationInvalid"; + + public const string ExceptionChartArea3DWallWidthInvalid = "ExceptionChartArea3DWallWidthInvalid"; + + public const string ExceptionChartArea3DPointsDepthInvalid = "ExceptionChartArea3DPointsDepthInvalid"; + + public const string ExceptionChartArea3DPointsGapInvalid = "ExceptionChartArea3DPointsGapInvalid"; + + public const string ExceptionCursorIntervalOffsetIsNegative = "ExceptionCursorIntervalOffsetIsNegative"; + + public const string ExceptionCursorLineWidthIsNegative = "ExceptionCursorLineWidthIsNegative"; + + public const string ExceptionGraphicsMarkerStyleUnknown = "ExceptionGraphicsMarkerStyleUnknown"; + + public const string ExceptionGraphics3DMarkerStyleUnknown = "ExceptionGraphics3DMarkerStyleUnknown"; + + public const string ExceptionGraphics3DCoordinatesInvalid = "ExceptionGraphics3DCoordinatesInvalid"; + + public const string ExceptionAxisLabelsAutoFitMinFontSizeValueInvalid = "ExceptionAxisLabelsAutoFitMinFontSizeValueInvalid"; + + public const string ExceptionAxisLabelsIntervalTypeUnsupported = "ExceptionAxisLabelsIntervalTypeUnsupported"; + + public const string ExceptionAxisLabelRowIndexIsNegative = "ExceptionAxisLabelRowIndexIsNegative"; + + public const string ExceptionAxisLabelRowIndexMustBe1Or2 = "ExceptionAxisLabelRowIndexMustBe1Or2"; + + public const string ExceptionAxisLabelIndexIsNegative = "ExceptionAxisLabelIndexIsNegative"; + + public const string ExceptionAxisLabelFontAngleInvalid = "ExceptionAxisLabelFontAngleInvalid"; + + public const string ExceptionCustomLabelAddedHasWrongType = "ExceptionCustomLabelAddedHasWrongType"; + + public const string ExceptionCustomLabelInsertedHasWrongType = "ExceptionCustomLabelInsertedHasWrongType"; + + public const string ExceptionSmartLabelsDirectionUndefined = "ExceptionSmartLabelsDirectionUndefined"; + + public const string ExceptionSmartLabelsMinMovingDistanceIsNegative = "ExceptionSmartLabelsMinMovingDistanceIsNegative"; + + public const string ExceptionSmartLabelsMaxMovingDistanceIsNegative = "ExceptionSmartLabelsMaxMovingDistanceIsNegative"; + + public const string ExceptionStripLineAddedHasWrongType = "ExceptionStripLineAddedHasWrongType"; + + public const string ExceptionStripLineWidthIsNegative = "ExceptionStripLineWidthIsNegative"; + + public const string ExceptionAxisWidthIsNegative = "ExceptionAxisWidthIsNegative"; + + public const string ExceptionAxisDynamicIntervalCalculationFailed = "ExceptionAxisDynamicIntervalCalculationFailed"; + + public const string ExceptionAxisIntervalDecreasingFailed = "ExceptionAxisIntervalDecreasingFailed"; + + public const string ExceptionAxisIntervalIncreasingFailed = "ExceptionAxisIntervalIncreasingFailed"; + + public const string ExceptionAxisLabelsAutoFitMaxFontSizeInvalid = "ExceptionAxisLabelsAutoFitMaxFontSizeInvalid"; + + public const string ExceptionAxisMinimumMaximumInvalid = "ExceptionAxisMinimumMaximumInvalid"; + + public const string ExceptionAxisStackedChartsDataPointsNumberMismatch = "ExceptionAxisStackedChartsDataPointsNumberMismatch"; + + public const string ExceptionAxisSeriesNotAligned = "ExceptionAxisSeriesNotAligned"; + + public const string ExceptionSubAxisNameNotFoundShort = "ExceptionSubAxisNameNotFoundShort"; + + public const string ExceptionSubAxisNameIsNotUnique = "ExceptionSubAxisNameIsNotUnique"; + + public const string ExceptionEnumInvalid = "ExceptionEnumInvalid"; + + public const string ExceptionAxisScaleLogarithmBaseInvalid = "ExceptionAxisScaleLogarithmBaseInvalid"; + + public const string ExceptionAxisScalePositionInvalid = "ExceptionAxisScalePositionInvalid"; + + public const string ExceptionAxisScalePositionToValueCallFailed = "ExceptionAxisScalePositionToValueCallFailed"; + + public const string ExceptionAxisScaleIntervalIsZero = "ExceptionAxisScaleIntervalIsZero"; + + public const string ExceptionAxisScaleMinimumMaximumInvalid = "ExceptionAxisScaleMinimumMaximumInvalid"; + + public const string ExceptionAxisScaleIntervalIsLessThen1Year = "ExceptionAxisScaleIntervalIsLessThen1Year"; + + public const string ExceptionAxisScaleAutoIntervalInvalid = "ExceptionAxisScaleAutoIntervalInvalid"; + + public const string ExceptionAxisScaleMinimumValueIsGreaterThenMaximumDataPoint = "ExceptionAxisScaleMinimumValueIsGreaterThenMaximumDataPoint"; + + public const string ExceptionAxisScaleLogarithmicNegativeValues = "ExceptionAxisScaleLogarithmicNegativeValues"; + + public const string ExceptionChartAreaAxisScaleLogarithmicUnsuitable = "ExceptionChartAreaAxisScaleLogarithmicUnsuitable"; + + public const string ExceptionChartAreaChartTypesCanNotCombine = "ExceptionChartAreaChartTypesCanNotCombine"; + + public const string ExceptionChartAreaSeriesNotFound = "ExceptionChartAreaSeriesNotFound"; + + public const string ExceptionAxisScaleBreaksNumberInvalid = "ExceptionAxisScaleBreaksNumberInvalid"; + + public const string ExceptionAxisScaleBreaksCollapsibleSpaceInvalid = "ExceptionAxisScaleBreaksCollapsibleSpaceInvalid"; + + public const string ExceptionAxisScaleBreaksSpacingInvalid = "ExceptionAxisScaleBreaksSpacingInvalid"; + + public const string ExceptionAxisScaleBreaksLineWidthInvalid = "ExceptionAxisScaleBreaksLineWidthInvalid"; + + public const string ExceptionAxisScaleSegmentsPositionInvalid = "ExceptionAxisScaleSegmentsPositionInvalid"; + + public const string ExceptionAxisScaleSegmentsSizeInvalid = "ExceptionAxisScaleSegmentsSizeInvalid"; + + public const string ExceptionAxisScaleSegmentsSpacingInvalid = "ExceptionAxisScaleSegmentsSpacingInvalid"; + + public const string ExceptionTickMarksIntervalIsZero = "ExceptionTickMarksIntervalIsZero"; + + public const string ExceptionTickMarksIntervalIsNegative = "ExceptionTickMarksIntervalIsNegative"; + + public const string ExceptionScrollBarSizeInvalid = "ExceptionScrollBarSizeInvalid"; + + public const string ExceptionScrollBarZoomResetsNumberInvalid = "ExceptionScrollBarZoomResetsNumberInvalid"; + + public const string ExceptionMarkerStepNegativeValue = "ExceptionMarkerStepNegativeValue"; + + public const string ExceptionTextThresholdIsNegative = "ExceptionTextThresholdIsNegative"; + + public const string ExceptionNamedImageObjectRequired = "ExceptionNamedImageObjectRequired"; + + public const string ExceptionNamedImageNotFound = "ExceptionNamedImageNotFound"; + + public const string ExceptionNamedImageAddedIsNotUnique = "ExceptionNamedImageAddedIsNotUnique"; + + public const string ExceptionNamedImageInsertedIsNotUnique = "ExceptionNamedImageInsertedIsNotUnique"; + + public const string ExceptionNamedImageInsertedHasWrongType = "ExceptionNamedImageInsertedHasWrongType"; + + public const string ExceptionLegendNameIsEmpty = "ExceptionLegendNameIsEmpty"; + + public const string ExceptionLegendNameIsNotUnique = "ExceptionLegendNameIsNotUnique"; + + public const string ExceptionLegendNotFound = "ExceptionLegendNotFound"; + + public const string ExceptionLegendAddedIsNotUnique = "ExceptionLegendAddedIsNotUnique"; + + public const string ExceptionLegendAddedHasWrongType = "ExceptionLegendAddedHasWrongType"; + + public const string ExceptionLegendInsertedHasWrongType = "ExceptionLegendInsertedHasWrongType"; + + public const string ExceptionLegendDockedChartAreaIsMissing = "ExceptionLegendDockedChartAreaIsMissing"; + + public const string ExceptionBackSecondaryColorIsTransparent = "ExceptionBackSecondaryColorIsTransparent"; + + public const string ExceptionLegendReferencedInSeriesNotFound = "ExceptionLegendReferencedInSeriesNotFound"; + + public const string ExceptionLegendAutoFitMinFontSizeInvalid = "ExceptionLegendAutoFitMinFontSizeInvalid"; + + public const string ExceptionLegendMaximumAutoSizeInvalid = "ExceptionLegendMaximumAutoSizeInvalid"; + + public const string ExceptionLegendColumnSpacingInvalid = "ExceptionLegendColumnSpacingInvalid"; + + public const string ExceptionLegendSeparatorTypeUnknown = "ExceptionLegendSeparatorTypeUnknown"; + + public const string ExceptionLegendMarkerBorderWidthIsNegative = "ExceptionLegendMarkerBorderWidthIsNegative"; + + public const string ExceptionLegendCellTypeUnknown = "ExceptionLegendCellTypeUnknown"; + + public const string ExceptionLegendItemAddedHasWrongType = "ExceptionLegendItemAddedHasWrongType"; + + public const string ExceptionLegendItemInsertedHasWrongType = "ExceptionLegendItemInsertedHasWrongType"; + + public const string ExceptionLegendColumnIsEmpty = "ExceptionLegendColumnIsEmpty"; + + public const string ExceptionLegendColumnAlreadyExistsInCollection = "ExceptionLegendColumnAlreadyExistsInCollection"; + + public const string ExceptionSeriesSymbolSizeIsNegative = "ExceptionSeriesSymbolSizeIsNegative"; + + public const string ExceptionMinimumCellWidthIsWrong = "ExceptionMinimumCellWidthIsWrong"; + + public const string ExceptionMaximumCellWidthIsWrong = "ExceptionMaximumCellWidthIsWrong"; + + public const string ExceptionLegendCellNameAlreadyExistsInCollection = "ExceptionLegendCellNameAlreadyExistsInCollection"; + + public const string ExceptionLegendCellNameIsEmpty = "ExceptionLegendCellNameIsEmpty"; + + public const string ExceptionLegendCellImageSizeIsNegative = "ExceptionLegendCellImageSizeIsNegative"; + + public const string ExceptionLegendCellSeriesSymbolSizeIsNegative = "ExceptionLegendCellSeriesSymbolSizeIsNegative"; + + public const string ExceptionLegendCellSpanIsLessThenOne = "ExceptionLegendCellSpanIsLessThenOne"; + + public const string ExceptionLegendCellNotFound = "ExceptionLegendCellNotFound"; + + public const string ExceptionLegendCellColumnNotFound = "ExceptionLegendCellColumnNotFound"; + + public const string ExceptionLegendCellColumnAlreadyExistsInCollection = "ExceptionLegendCellColumnAlreadyExistsInCollection"; + + public const string ExceptionMarginTopIsNegative = "ExceptionMarginTopIsNegative"; + + public const string ExceptionMarginBottomIsNegative = "ExceptionMarginBottomIsNegative"; + + public const string ExceptionMarginLeftIsNegative = "ExceptionMarginLeftIsNegative"; + + public const string ExceptionMarginRightIsNegative = "ExceptionMarginRightIsNegative"; + + public const string ExceptionElementPositionArgumentOutOfRange = "ExceptionElementPositionArgumentOutOfRange"; + + public const string ExceptionChartHeightIsNotInPixels = "ExceptionChartHeightIsNotInPixels"; + + public const string ExceptionChartWidthIsNotInPixels = "ExceptionChartWidthIsNotInPixels"; + + public const string ExceptionChartBorderIsNegative = "ExceptionChartBorderIsNegative"; + + public const string ExceptionChartAreaNameReferenceInvalid = "ExceptionChartAreaNameReferenceInvalid"; + + public const string ExceptionChartCompressionInvalid = "ExceptionChartCompressionInvalid"; + + public const string ExceptionChartDataPointsAlignmentFaild = "ExceptionChartDataPointsAlignmentFaild"; + + public const string ExceptionChartDataPointsAlignmentFaildAxisLabelsInvalid = "ExceptionChartDataPointsAlignmentFaildAxisLabelsInvalid"; + + public const string ExceptionChartDataPointsInsertionFailedYValuesEmpty = "ExceptionChartDataPointsInsertionFailedYValuesEmpty"; + + public const string ExceptionTraceManagerUnsupportedType = "ExceptionTraceManagerUnsupportedType"; + + public const string ExceptionChartTypeRegistryUnsupportedType = "ExceptionChartTypeRegistryUnsupportedType"; + + public const string ExceptionChartTypeNameIsNotUnique = "ExceptionChartTypeNameIsNotUnique"; + + public const string ExceptionChartTypeHasNoInterface = "ExceptionChartTypeHasNoInterface"; + + public const string ExceptionChartTypeUnknown = "ExceptionChartTypeUnknown"; + + public const string ExceptionChartTypeRequiresYValues = "ExceptionChartTypeRequiresYValues"; + + public const string ExceptionChartTypeSecondaryYAxisUnsupported = "ExceptionChartTypeSecondaryYAxisUnsupported"; + + public const string ExceptionChartTypeSecondaryXAxisUnsupported = "ExceptionChartTypeSecondaryXAxisUnsupported"; + + public const string ExceptionChartTypeCanNotCombine = "ExceptionChartTypeCanNotCombine"; + + public const string ExceptionBorderTypeRegistryUnsupportedType = "ExceptionBorderTypeRegistryUnsupportedType"; + + public const string ExceptionBorderTypeNameIsNotUnique = "ExceptionBorderTypeNameIsNotUnique"; + + public const string ExceptionBorderTypeHasNoInterface = "ExceptionBorderTypeHasNoInterface"; + + public const string ExceptionBorderTypeUnknown = "ExceptionBorderTypeUnknown"; + + public const string ExceptionChartSerializerUnsupportedType = "ExceptionChartSerializerUnsupportedType"; + + public const string ExceptionChartSerializerContentFlagUnsupported = "ExceptionChartSerializerContentFlagUnsupported"; + + public const string ExceptionChartSerializerDefaultConstructorUndefined = "ExceptionChartSerializerDefaultConstructorUndefined"; + + public const string ExceptionChartSerializerContentStringFormatInvalid = "ExceptionChartSerializerContentStringFormatInvalid"; + + public const string ExceptionChartSerializerClassNameUndefined = "ExceptionChartSerializerClassNameUndefined"; + + public const string ExceptionChartSerializerPropertyNameUndefined = "ExceptionChartSerializerPropertyNameUndefined"; + + public const string ExceptionChartSerializerTypeUnsupported = "ExceptionChartSerializerTypeUnsupported"; + + public const string ExceptionChartSerializerWriterObjectInvalid = "ExceptionChartSerializerWriterObjectInvalid"; + + public const string ExceptionChartSerializerReaderObjectInvalid = "ExceptionChartSerializerReaderObjectInvalid"; + + public const string ExceptionChartSerializerPropertyNameUnknown = "ExceptionChartSerializerPropertyNameUnknown"; + + public const string ExceptionChartSerializerDestinationObjectInvalid = "ExceptionChartSerializerDestinationObjectInvalid"; + + public const string ExceptionChartSerializerSourceObjectInvalid = "ExceptionChartSerializerSourceObjectInvalid"; + + public const string ExceptionChartSerializerBinaryTypeUnsupported = "ExceptionChartSerializerBinaryTypeUnsupported"; + + public const string ExceptionChartSerializerBinaryHashCodeDuplicate = "ExceptionChartSerializerBinaryHashCodeDuplicate"; + + public const string ExceptionChartSerializerBinaryIgnoreUnknownAttributesUnsupported = "ExceptionChartSerializerBinaryIgnoreUnknownAttributesUnsupported"; + + public const string ExceptionChartSerializerBinaryFromatInvalid = "ExceptionChartSerializerBinaryFromatInvalid"; + + public const string ExceptionChartSerializerPropertyNotFound = "ExceptionChartSerializerPropertyNotFound"; + + public const string ExceptionDataManipulatorPointCountIsZero = "ExceptionDataManipulatorPointCountIsZero"; + + public const string ExceptionDataManipulatorIndexUndefined = "ExceptionDataManipulatorIndexUndefined"; + + public const string ExceptionDataManipulatorIndexFormatInvalid = "ExceptionDataManipulatorIndexFormatInvalid"; + + public const string ExceptionDataManipulatorGroupedSeriesNotSorted = "ExceptionDataManipulatorGroupedSeriesNotSorted"; + + public const string ExceptionDataManipulatorGroupingFormulaUndefined = "ExceptionDataManipulatorGroupingFormulaUndefined"; + + public const string ExceptionDataManipulatorYValuesIndexExceeded = "ExceptionDataManipulatorYValuesIndexExceeded"; + + public const string ExceptionDataManipulatorGroupingFormulaAlreadyDefined = "ExceptionDataManipulatorGroupingFormulaAlreadyDefined"; + + public const string ExceptionDataManipulatorGroupingFormulaUnsupported = "ExceptionDataManipulatorGroupingFormulaUnsupported"; + + public const string ExceptionDataManipulatorGroupingFormulaFormatInvalid = "ExceptionDataManipulatorGroupingFormulaFormatInvalid"; + + public const string ExceptionDataManipulatorGroupingInputSeriesUndefined = "ExceptionDataManipulatorGroupingInputSeriesUndefined"; + + public const string ExceptionDataManipulatorGroupingInputOutputSeriesNumberMismatch = "ExceptionDataManipulatorGroupingInputOutputSeriesNumberMismatch"; + + public const string ExceptionDataManipulatorGroupingFormulaNameInvalid = "ExceptionDataManipulatorGroupingFormulaNameInvalid"; + + public const string ExceptionDataBindYValuesToString = "ExceptionDataBindYValuesToString"; + + public const string ExceptionDataBindXValuesToString = "ExceptionDataBindXValuesToString"; + + public const string ExceptionDataBindSeriesToString = "ExceptionDataBindSeriesToString"; + + public const string ExceptionDataBindSeriesGroupByParameterIsEmpty = "ExceptionDataBindSeriesGroupByParameterIsEmpty"; + + public const string ExceptionChartPictureUnsupportedType = "ExceptionChartPictureUnsupportedType"; + + public const string ExceptionImageUrlIsEmpty = "ExceptionImageUrlIsEmpty"; + + public const string ExceptionImageUrlInvalidFormatters = "ExceptionImageUrlInvalidFormatters"; + + public const string ExceptionImageUrlInvalidFormat = "ExceptionImageUrlInvalidFormat"; + + public const string ExceptionImageUrlMissedFormatter = "ExceptionImageUrlMissedFormatter"; + + public const string ExceptionSubAxisNameNotFound = "ExceptionSubAxisNameNotFound"; + + public const string ExceptionSubAxisNameAlreadyExistsInCollection = "ExceptionSubAxisNameAlreadyExistsInCollection"; + + public const string ExceptionChartTitleSetIsNotUnique = "ExceptionChartTitleSetIsNotUnique"; + + public const string ExceptionChartTitleAddedIsNotUnique = "ExceptionChartTitleAddedIsNotUnique"; + + public const string ExceptionChartTitleDockedChartAreaIsMissing = "ExceptionChartTitleDockedChartAreaIsMissing"; + + public const string ExceptionDataManagerUnsupportedType = "ExceptionDataManagerUnsupportedType"; + + public const string ExceptionDataManager100StackedSeriesPointsNumeberMismatch = "ExceptionDataManager100StackedSeriesPointsNumeberMismatch"; + + public const string ExceptionKeywordsRegistryUnsupportedType = "ExceptionKeywordsRegistryUnsupportedType"; + + public const string ExceptionCustomAttributesRegistryUnsupportedType = "ExceptionCustomAttributesRegistryUnsupportedType"; + + public const string ExceptionFormulaModuleNameIsNotUnique = "ExceptionFormulaModuleNameIsNotUnique"; + + public const string ExceptionFormulaModuleHasNoInterface = "ExceptionFormulaModuleHasNoInterface"; + + public const string ExceptionFormulaModuleRegistryUnsupportedType = "ExceptionFormulaModuleRegistryUnsupportedType"; + + public const string ExceptionFormulaModuleNameUnknown = "ExceptionFormulaModuleNameUnknown"; + + public const string ExceptionColumnNameNotFound = "ExceptionColumnNameNotFound"; + + public const string ExceptionDataPointConverterInvalidSorting = "ExceptionDataPointConverterInvalidSorting"; + + public const string ExceptionDataPointConverterUnavailableSorting = "ExceptionDataPointConverterUnavailableSorting"; + + public const string ExceptionDataPointConverterWrongTypes = "ExceptionDataPointConverterWrongTypes"; + + public const string ExceptionDataPointInsertionXValuesQtyIsLessYValues = "ExceptionDataPointInsertionXValuesQtyIsLessYValues"; + + public const string ExceptionDataPointValueNameInvalid = "ExceptionDataPointValueNameInvalid"; + + public const string ExceptionDataPointValueNameYIndexOutOfRange = "ExceptionDataPointValueNameYIndexOutOfRange"; + + public const string ExceptionDataPointValueNameYIndexIsNotPositive = "ExceptionDataPointValueNameYIndexIsNotPositive"; + + public const string ExceptionDataPointInsertionNoDataSource = "ExceptionDataPointInsertionNoDataSource"; + + public const string ExceptionDataPointYValuesCountMismatch = "ExceptionDataPointYValuesCountMismatch"; + + public const string ExceptionDataPointYValuesBindingCountMismatch = "ExceptionDataPointYValuesBindingCountMismatch"; + + public const string ExceptionDataPointYValuesSettingCountMismatch = "ExceptionDataPointYValuesSettingCountMismatch"; + + public const string ExceptionDataPointBindingYValueNotSpecified = "ExceptionDataPointBindingYValueNotSpecified"; + + public const string ExceptionDataPointInsertionYValueNotSpecified = "ExceptionDataPointInsertionYValueNotSpecified"; + + public const string ExceptionAttributeUnableToDelete = "ExceptionAttributeUnableToDelete"; + + public const string ExceptionAttributeNameIsEmpty = "ExceptionAttributeNameIsEmpty"; + + public const string ExceptionAttributeInvalidFormat = "ExceptionAttributeInvalidFormat"; + + public const string ExceptionAttributeNameIsNotUnique = "ExceptionAttributeNameIsNotUnique"; + + public const string ExceptionAttributeDrawSideBySideInvalid = "ExceptionAttributeDrawSideBySideInvalid"; + + public const string ExceptionLabelBorderIsNotPositive = "ExceptionLabelBorderIsNotPositive"; + + public const string ExceptionBorderWidthIsNotPositive = "ExceptionBorderWidthIsNotPositive"; + + public const string ExceptionAngleRangeInvalid = "ExceptionAngleRangeInvalid"; + + public const string ExceptionDataPointYValueStringFormat = "ExceptionDataPointYValueStringFormat"; + + public const string ExceptionParameterFormatInvalid = "ExceptionParameterFormatInvalid"; + + public const string ExceptionStatisticalAnalysesInvalidAlphaValue = "ExceptionStatisticalAnalysesInvalidAlphaValue"; + + public const string ExceptionStatisticalAnalysesInvalidProbabilityValue = "ExceptionStatisticalAnalysesInvalidProbabilityValue"; + + public const string ExceptionStatisticalAnalysesInvalidDegreeOfFreedom = "ExceptionStatisticalAnalysesInvalidDegreeOfFreedom"; + + public const string ExceptionStatisticalAnalysesNegativeMeanDifference = "ExceptionStatisticalAnalysesNegativeMeanDifference"; + + public const string ExceptionStatisticalAnalysesInvalidSeriesNumber = "ExceptionStatisticalAnalysesInvalidSeriesNumber"; + + public const string ExceptionStatisticalAnalysesInvalidMeanDifference = "ExceptionStatisticalAnalysesInvalidMeanDifference"; + + public const string ExceptionStatisticalAnalysesNotEnoughDataPoints = "ExceptionStatisticalAnalysesNotEnoughDataPoints"; + + public const string ExceptionStatisticalAnalysesInvalidVariance = "ExceptionStatisticalAnalysesInvalidVariance"; + + public const string ExceptionStatisticalAnalysesInvalidTValue = "ExceptionStatisticalAnalysesInvalidTValue"; + + public const string ExceptionStatisticalAnalysesGammaBetaNegativeParameters = "ExceptionStatisticalAnalysesGammaBetaNegativeParameters"; + + public const string ExceptionStatisticalAnalysesInvalidZValue = "ExceptionStatisticalAnalysesInvalidZValue"; + + public const string ExceptionStatisticalAnalysesZeroVariance = "ExceptionStatisticalAnalysesZeroVariance"; + + public const string ExceptionStatisticalAnalysesNotEnoughInputSeries = "ExceptionStatisticalAnalysesNotEnoughInputSeries"; + + public const string ExceptionStatisticalAnalysesInvalidVariableRanges = "ExceptionStatisticalAnalysesInvalidVariableRanges"; + + public const string ExceptionStatisticalAnalysesStudentsInvalidTValue = "ExceptionStatisticalAnalysesStudentsInvalidTValue"; + + public const string ExceptionStatisticalAnalysesStudentsNegativeFreedomDegree = "ExceptionStatisticalAnalysesStudentsNegativeFreedomDegree"; + + public const string ExceptionStatisticalAnalysesNormalInvalidProbabilityValue = "ExceptionStatisticalAnalysesNormalInvalidProbabilityValue"; + + public const string ExceptionStatisticalAnalysesInvalidTailedParameter = "ExceptionStatisticalAnalysesInvalidTailedParameter"; + + public const string ExceptionStatisticalAnalysesInvalidInputParameter = "ExceptionStatisticalAnalysesInvalidInputParameter"; + + public const string ExceptionStatisticalAnalysesIncompleteBetaFunction = "ExceptionStatisticalAnalysesIncompleteBetaFunction"; + + public const string ExceptionStatisticalAnalysesInvalidAnovaTest = "ExceptionStatisticalAnalysesInvalidAnovaTest"; + + public const string ExceptionStatisticalAnalysesCovariance = "ExceptionStatisticalAnalysesCovariance"; + + public const string ExceptionStatisticalAnalysesInvalidMedianConditions = "ExceptionStatisticalAnalysesInvalidMedianConditions"; + + public const string ExceptionStatisticalAnalysesInvalidMeanConditions = "ExceptionStatisticalAnalysesInvalidMeanConditions"; + + public const string ExceptionStatisticalAnalysesInvalidVarianceConditions = "ExceptionStatisticalAnalysesInvalidVarianceConditions"; + + public const string ExceptionPeriodParameterIsNegative = "ExceptionPeriodParameterIsNegative"; + + public const string ExceptionPeriodAverageParameterIsNegative = "ExceptionPeriodAverageParameterIsNegative"; + + public const string ExceptionPeriodShortParameterIsNegative = "ExceptionPeriodShortParameterIsNegative"; + + public const string ExceptionPeriodLongParameterIsNegative = "ExceptionPeriodLongParameterIsNegative"; + + public const string ExceptionFormulaInvalidPeriod = "ExceptionFormulaInvalidPeriod"; + + public const string ExceptionFormulaNotEnoughDataPoints = "ExceptionFormulaNotEnoughDataPoints"; + + public const string ExceptionIndicatorsDeviationMissing = "ExceptionIndicatorsDeviationMissing"; + + public const string ExceptionIndicatorsLongPeriodLessThenShortPeriod = "ExceptionIndicatorsLongPeriodLessThenShortPeriod"; + + public const string ExceptionOscillatorObjectInvalidPeriod = "ExceptionOscillatorObjectInvalidPeriod"; + + public const string ExceptionOscillatorNegativeSignalPeriod = "ExceptionOscillatorNegativeSignalPeriod"; + + public const string ExceptionOscillatorNegativePeriodParameter = "ExceptionOscillatorNegativePeriodParameter"; + + public const string ExceptionVolumeIndicatorStartValueMissing = "ExceptionVolumeIndicatorStartValueMissing"; + + public const string ExceptionPriceIndicatorsShiftParameterMissing = "ExceptionPriceIndicatorsShiftParameterMissing"; + + public const string ExceptionPriceIndicatorsSameYNumber = "ExceptionPriceIndicatorsSameYNumber"; + + public const string ExceptionPriceIndicatorsSameXYNumber = "ExceptionPriceIndicatorsSameXYNumber"; + + public const string ExceptionPriceIndicatorsPeriodMissing = "ExceptionPriceIndicatorsPeriodMissing"; + + public const string ExceptionPriceIndicatorsNotEnoughPoints = "ExceptionPriceIndicatorsNotEnoughPoints"; + + public const string ExceptionPriceIndicatorsFormulaRequiresOneArray = "ExceptionPriceIndicatorsFormulaRequiresOneArray"; + + public const string ExceptionPriceIndicatorsFormulaRequiresTwoArrays = "ExceptionPriceIndicatorsFormulaRequiresTwoArrays"; + + public const string ExceptionPriceIndicatorsFormulaRequiresThreeArrays = "ExceptionPriceIndicatorsFormulaRequiresThreeArrays"; + + public const string ExceptionPriceIndicatorsFormulaRequiresFourArrays = "ExceptionPriceIndicatorsFormulaRequiresFourArrays"; + + public const string ExceptionObjectReferenceIsNull = "ExceptionObjectReferenceIsNull"; + + public const string ExceptionThreeLineBreakCanNotCobine = "ExceptionThreeLineBreakCanNotCobine"; + + public const string ExceptionThreeLineBreakNullReference = "ExceptionThreeLineBreakNullReference"; + + public const string ExceptionThreeLineBreakUsedYValueOutOfRange = "ExceptionThreeLineBreakUsedYValueOutOfRange"; + + public const string ExceptionThreeLineBreakNumberOfLinesInBreakFormatInvalid = "ExceptionThreeLineBreakNumberOfLinesInBreakFormatInvalid"; + + public const string ExceptionThreeLineBreakUpBrickColorInvalid = "ExceptionThreeLineBreakUpBrickColorInvalid"; + + public const string ExceptionThreeLineBreakUsedYValueInvalid = "ExceptionThreeLineBreakUsedYValueInvalid"; + + public const string ExceptionThreeLineBreakNumberOfLinesInBreakValueInvalid = "ExceptionThreeLineBreakNumberOfLinesInBreakValueInvalid"; + + public const string ExceptionRenkoCanNotCobine = "ExceptionRenkoCanNotCobine"; + + public const string ExceptionRenkoNullReference = "ExceptionRenkoNullReference"; + + public const string ExceptionRenkoUsedYValueOutOfRange = "ExceptionRenkoUsedYValueOutOfRange"; + + public const string ExceptionRenkoBoxSizeFormatInvalid = "ExceptionRenkoBoxSizeFormatInvalid"; + + public const string ExceptionRenkoUpBrickColorInvalid = "ExceptionRenkoUpBrickColorInvalid"; + + public const string ExceptionRenkoUsedYValueFormatInvalid = "ExceptionRenkoUsedYValueFormatInvalid"; + + public const string ExceptionPieIntervalsInvalid = "ExceptionPieIntervalsInvalid"; + + public const string ExceptionPieUnassignedFrontBackPoints = "ExceptionPieUnassignedFrontBackPoints"; + + public const string ExceptionPiePointOrderInvalid = "ExceptionPiePointOrderInvalid"; + + public const string ExceptionPieHorizontalLineSizeInvalid = "ExceptionPieHorizontalLineSizeInvalid"; + + public const string ExceptionPieRadialLineSizeInvalid = "ExceptionPieRadialLineSizeInvalid"; + + public const string ExceptionPie3DLabelLineSizeInvalid = "ExceptionPie3DLabelLineSizeInvalid"; + + public const string ExceptionPieRadiusInvalid = "ExceptionPieRadiusInvalid"; + + public const string ExceptionPieMinimumRelativePieSizeInvalid = "ExceptionPieMinimumRelativePieSizeInvalid"; + + public const string ExceptionPieOrderOperationInvalid = "ExceptionPieOrderOperationInvalid"; + + public const string ExceptionPieIntervalsOverlapping = "ExceptionPieIntervalsOverlapping"; + + public const string ExceptionDoughnutNullReference = "ExceptionDoughnutNullReference"; + + public const string ExceptionDoughnutThresholdInvalid = "ExceptionDoughnutThresholdInvalid"; + + public const string ExceptionDoughnutCollectedThresholdUsePercentInvalid = "ExceptionDoughnutCollectedThresholdUsePercentInvalid"; + + public const string ExceptionDoughnutCollectedColorInvalidFormat = "ExceptionDoughnutCollectedColorInvalidFormat"; + + public const string ExceptionDoughnutCollectedThresholdInvalidFormat = "ExceptionDoughnutCollectedThresholdInvalidFormat"; + + public const string ExceptionDoughnutCollectedThresholdInvalidRange = "ExceptionDoughnutCollectedThresholdInvalidRange"; + + public const string ExceptionPointAndFigureUpBrickColorInvalidFormat = "ExceptionPointAndFigureUpBrickColorInvalidFormat"; + + public const string ExceptionPointAndFigureCanNotCombine = "ExceptionPointAndFigureCanNotCombine"; + + public const string ExceptionPointAndFigureNullReference = "ExceptionPointAndFigureNullReference"; + + public const string ExceptionPointAndFigureUsedYValueHighOutOfRange = "ExceptionPointAndFigureUsedYValueHighOutOfRange"; + + public const string ExceptionPointAndFigureUsedYValueLowOutOfrange = "ExceptionPointAndFigureUsedYValueLowOutOfrange"; + + public const string ExceptionPointAndFigureReversalAmountInvalidFormat = "ExceptionPointAndFigureReversalAmountInvalidFormat"; + + public const string ExceptionPointAndFigureUsedYValueHighInvalidFormat = "ExceptionPointAndFigureUsedYValueHighInvalidFormat"; + + public const string ExceptionPointAndFigureUsedYValueLowInvalidFormat = "ExceptionPointAndFigureUsedYValueLowInvalidFormat"; + + public const string ExceptionFastPointMarkerStyleUnknown = "ExceptionFastPointMarkerStyleUnknown"; + + public const string ExceptionFunnelAngleRangeInvalid = "ExceptionFunnelAngleRangeInvalid"; + + public const string ExceptionFunnelCanNotCombine = "ExceptionFunnelCanNotCombine"; + + public const string ExceptionFunnelNeckHeightInvalid = "ExceptionFunnelNeckHeightInvalid"; + + public const string ExceptionFunnelNeckWidthInvalid = "ExceptionFunnelNeckWidthInvalid"; + + public const string ExceptionKagiAttributeFormatInvalid = "ExceptionKagiAttributeFormatInvalid"; + + public const string ExceptionKagiNullReference = "ExceptionKagiNullReference"; + + public const string ExceptionKagiCanNotCombine = "ExceptionKagiCanNotCombine"; + + public const string ExceptionKagiAttributeOutOfRange = "ExceptionKagiAttributeOutOfRange"; + + public const string ExceptionStackedAreaChartSeriesDataPointsNumberMismatch = "ExceptionStackedAreaChartSeriesDataPointsNumberMismatch"; + + public const string Exception3DPieLabelsIndexInvalid = "Exception3DPieLabelsIndexInvalid"; + + public const string Exception3DChartPointsXValuesUnsorted = "Exception3DChartPointsXValuesUnsorted"; + + public const string ExceptionFunnelStyleUnknown = "ExceptionFunnelStyleUnknown"; + + public const string ExceptionFunnelMinimumPointHeightAttributeInvalid = "ExceptionFunnelMinimumPointHeightAttributeInvalid"; + + public const string ExceptionErrorBarParameterUndefined = "ExceptionErrorBarParameterUndefined"; + + public const string ExceptionErrorBarTypeInvalid = "ExceptionErrorBarTypeInvalid"; + + public const string ExceptionErrorBarTypeFormatInvalid = "ExceptionErrorBarTypeFormatInvalid"; + + public const string Exception3DSplineY1ValueIsLessThenY2 = "Exception3DSplineY1ValueIsLessThenY2"; + + public const string ExceptionChartCanNotCombine = "ExceptionChartCanNotCombine"; + + public const string ExceptionCustomAttributeValueInvalid = "ExceptionCustomAttributeValueInvalid"; + + public const string ExceptionCustomAttributeValueInvalid2 = "ExceptionCustomAttributeValueInvalid2"; + + public const string ExceptionCustomAttributeAngleOutOfRange = "ExceptionCustomAttributeAngleOutOfRange"; + + public const string ExceptionCustomAttributeIsNotInRange0to1 = "ExceptionCustomAttributeIsNotInRange0to1"; + + public const string ExceptionCustomAttributeIsNotInRange0to100 = "ExceptionCustomAttributeIsNotInRange0to100"; + + public const string ExceptionCustomAttributeIsNotLargerThenZiro = "ExceptionCustomAttributeIsNotLargerThenZiro"; + + public const string ExceptionCustomAttributeIsNotInRange0to50 = "ExceptionCustomAttributeIsNotInRange0to50"; + + public const string ExceptionCustomAttributeSeriesNameNotFound = "ExceptionCustomAttributeSeriesNameNotFound"; + + public const string ExceptionCustomAttributeMustBeMoreThenValue = "ExceptionCustomAttributeMustBeMoreThenValue"; + + public const string ExceptionCustomAttributeMustBeBiggerThenValue = "ExceptionCustomAttributeMustBeBiggerThenValue"; + + public const string ExceptionCustomAttributeMustBeInRange = "ExceptionCustomAttributeMustBeInRange"; + + public const string ExceptionCustomAttributeDefaultValueTypeInvalid = "ExceptionCustomAttributeDefaultValueTypeInvalid"; + + public const string ExceptionCustomAttributeTypeUnsupported = "ExceptionCustomAttributeTypeUnsupported"; + + public const string ExceptionCustomAttributeTypeOrMaximumPossibleValueInvalid = "ExceptionCustomAttributeTypeOrMaximumPossibleValueInvalid"; + + public const string ExceptionCustomAttributeTypeOrMinimumPossibleValueUnsupported = "ExceptionCustomAttributeTypeOrMinimumPossibleValueUnsupported"; + + public const string ExceptionCustomAttributeTypeOrMinimumPossibleValueInvalid = "ExceptionCustomAttributeTypeOrMinimumPossibleValueInvalid"; + + public const string ExceptionFormulaDataItemsNumberMismatch = "ExceptionFormulaDataItemsNumberMismatch"; + + public const string ExceptionFormulaDataItemsNumberMismatch2 = "ExceptionFormulaDataItemsNumberMismatch2"; + + public const string ExceptionFormulaDataSeriesNameNotFoundInCollection = "ExceptionFormulaDataSeriesNameNotFoundInCollection"; + + public const string ExceptionFormulaDataSeriesNameNotFound = "ExceptionFormulaDataSeriesNameNotFound"; + + public const string ExceptionFormulaDataFormatInvalid = "ExceptionFormulaDataFormatInvalid"; + + public const string ExceptionFormulaDataOutputSeriesNumberYValuesIncorrect = "ExceptionFormulaDataOutputSeriesNumberYValuesIncorrect"; + + public const string ExceptionFormulaDataSeriesAreNotAlignedDifferentXValues = "ExceptionFormulaDataSeriesAreNotAlignedDifferentXValues"; + + public const string ExceptionFormulaDataSeriesAreNotAlignedDifferentDataPoints = "ExceptionFormulaDataSeriesAreNotAlignedDifferentDataPoints"; + + public const string ExceptionFormulaYIndexInvalid = "ExceptionFormulaYIndexInvalid"; + + public const string ExceptionFormulaXValuesNotAligned = "ExceptionFormulaXValuesNotAligned"; + + public const string ExceptionFormulaInputOutputSeriesMismatch = "ExceptionFormulaInputOutputSeriesMismatch"; + + public const string ExceptionFormulaNotFound = "ExceptionFormulaNotFound"; + + public const string ExceptionForecastingDegreeInvalid = "ExceptionForecastingDegreeInvalid"; + + public const string ExceptionForecastingNotEnoughDataPoints = "ExceptionForecastingNotEnoughDataPoints"; + + public const string ExceptionForecastingExponentialRegressionHasZeroYValues = "ExceptionForecastingExponentialRegressionHasZeroYValues"; + + public const string ExceptionForecastingPowerRegressionHasZeroYValues = "ExceptionForecastingPowerRegressionHasZeroYValues"; + + public const string ExceptionBorderWidthIsNegative = "ExceptionBorderWidthIsNegative"; + + public const string ExceptionBorderWidthIsZero = "ExceptionBorderWidthIsZero"; + + public const string ExceptionLegendBorderWidthIsNegative = "ExceptionLegendBorderWidthIsNegative"; + + public const string ExceptionTitleBorderWidthIsNegative = "ExceptionTitleBorderWidthIsNegative"; + + public const string ExceptionMatrix3DNotinitialized = "ExceptionMatrix3DNotinitialized"; + + public const string ExceptionPaletteIsEmpty = "ExceptionPaletteIsEmpty"; + + public const string ExceptionValueMustBeGreaterThan = "ExceptionValueMustBeGreaterThan"; + + public const string ExceptionValueMustBeLessThan = "ExceptionValueMustBeLessThan"; + + public const string ExceptionValueMustBeInRange = "ExceptionValueMustBeInRange"; + + public const string ExceptionChartPreviewNotAvailable = "ExceptionChartPreviewNotAvailable"; + + public const string ExceptionChartPreviewNotAvailableShort = "ExceptionChartPreviewNotAvailableShort"; + + public const string ExceptionChartOutOfLimits = "ExceptionChartOutOfLimits"; + + public const string ExceptionHttpHandlerCanNotSave = "ExceptionHttpHandlerCanNotSave"; + + public const string ExceptionHttpHandlerCanNotLoadType = "ExceptionHttpHandlerCanNotLoadType"; + + public const string ExceptionHttpHandlerImageHandlerInterfaceUnsupported = "ExceptionHttpHandlerImageHandlerInterfaceUnsupported"; + + public const string ExceptionHttpHandlerParameterUnknown = "ExceptionHttpHandlerParameterUnknown"; + + public const string ExceptionHttpHandlerParameterInvalid = "ExceptionHttpHandlerParameterInvalid"; + + public const string ExceptionHttpHandlerPrivacyKeyInvalid = "ExceptionHttpHandlerPrivacyKeyInvalid"; + + public const string ExceptionHttpHandlerValueInvalid = "ExceptionHttpHandlerValueInvalid"; + + public const string ExceptionHttpHandlerTimeoutParameterInvalid = "ExceptionHttpHandlerTimeoutParameterInvalid"; + + public const string ExceptionHttpHandlerUrlMissing = "ExceptionHttpHandlerUrlMissing"; + + public const string ExceptionHttpHandlerUrlInvalid = "ExceptionHttpHandlerUrlInvalid"; + + public const string ExceptionHttpHandlerTempDirectoryInvalid = "ExceptionHttpHandlerTempDirectoryInvalid"; + + public const string ExceptionHttpHandlerTempDirectoryUnaccesible = "ExceptionHttpHandlerTempDirectoryUnaccesible"; + + public const string ExceptionHttpHandlerStorageTypeUnsupported = "ExceptionHttpHandlerStorageTypeUnsupported"; + + public const string ExceptionHttpHandlerInvalidLocation = "ExceptionHttpHandlerInvalidLocation"; + + public const string ExceptionHttpHandlerImageNotFound = "ExceptionHttpHandlerImageNotFound"; + + public const string ExceptionWebConfigUpdateFailed = "ExceptionWebConfigUpdateFailed"; + + public const string DescriptionCustomAttributeEmptyPointValue = "DescriptionCustomAttributeEmptyPointValue"; + + public const string DescriptionCustomAttributeIsXAxisQuantitive = "DescriptionCustomAttributeIsXAxisQuantitive"; + + public const string DescriptionCustomAttributePieDonutExploded = "DescriptionCustomAttributePieDonutExploded"; + + public const string DescriptionCustomAttributeProportionalSymbols = "DescriptionCustomAttributeProportionalSymbols"; + + public const string DescriptionCustomAttributeDrawSideBySide = "DescriptionCustomAttributeDrawSideBySide"; + + public const string DescriptionCustomAttributeShowMarkerLines = "DescriptionCustomAttributeShowMarkerLines"; + + public const string DescriptionCustomAttributeShowOpenClose = "DescriptionCustomAttributeShowOpenClose"; + + public const string DescriptionCustomAttributeBoxPlotShowAverage = "DescriptionCustomAttributeBoxPlotShowAverage"; + + public const string DescriptionCustomAttributeBubbleUseSizeForLabel = "DescriptionCustomAttributeBubbleUseSizeForLabel"; + + public const string DescriptionCustomAttributeBoxPlotShowMedian = "DescriptionCustomAttributeBoxPlotShowMedian"; + + public const string DescriptionCustomAttributeBoxPlotShowUnusualValues = "DescriptionCustomAttributeBoxPlotShowUnusualValues"; + + public const string DescriptionCustomAttributeBoxPlotSeries = "DescriptionCustomAttributeBoxPlotSeries"; + + public const string DescriptionCustomAttributePieStartAngle = "DescriptionCustomAttributePieStartAngle"; + + public const string DescriptionCustomAttributeLabelStyle = "DescriptionCustomAttributeLabelStyle"; + + public const string DescriptionCustomAttributeFunnelLabelStyle = "DescriptionCustomAttributeFunnelLabelStyle"; + + public const string DescriptionCustomAttributeFunnelStyle = "DescriptionCustomAttributeFunnelStyle"; + + public const string DescriptionCustomAttributePolarDrawingStyle = "DescriptionCustomAttributePolarDrawingStyle"; + + public const string DescriptionCustomAttributePyramidLabelStyle = "DescriptionCustomAttributePyramidLabelStyle"; + + public const string DescriptionCustomAttributeRadarDrawingStyle = "DescriptionCustomAttributeRadarDrawingStyle"; + + public const string DescriptionCustomAttributeBoxSize = "DescriptionCustomAttributeBoxSize"; + + public const string DescriptionCustomAttributeCollectedColor = "DescriptionCustomAttributeCollectedColor"; + + public const string DescriptionCustomAttributeCollectedLabel = "DescriptionCustomAttributeCollectedLabel"; + + public const string DescriptionCustomAttributeCollectedLegendText = "DescriptionCustomAttributeCollectedLegendText"; + + public const string DescriptionCustomAttributeCollectedLegendDefaultText = "DescriptionCustomAttributeCollectedLegendDefaultText"; + + public const string DescriptionCustomAttributeCollectedLabelDefaultText = "DescriptionCustomAttributeCollectedLabelDefaultText"; + + public const string DescriptionCustomAttributeCollectedToolTip = "DescriptionCustomAttributeCollectedToolTip"; + + public const string DescriptionCustomAttributePyramidValueType = "DescriptionCustomAttributePyramidValueType"; + + public const string DescriptionCustomAttribute_3DLabelLineSize = "DescriptionCustomAttribute_3DLabelLineSize"; + + public const string DescriptionCustomAttributeFunnel3DRotationAngle = "DescriptionCustomAttributeFunnel3DRotationAngle"; + + public const string DescriptionCustomAttributePyramid3DRotationAngle = "DescriptionCustomAttributePyramid3DRotationAngle"; + + public const string DescriptionCustomAttributePixelPointDepth = "DescriptionCustomAttributePixelPointDepth"; + + public const string DescriptionCustomAttributePixelPointGapDepth = "DescriptionCustomAttributePixelPointGapDepth"; + + public const string DescriptionCustomAttributeErrorBarCenterMarkerStyle = "DescriptionCustomAttributeErrorBarCenterMarkerStyle"; + + public const string DescriptionCustomAttributePointFigureBoxSize = "DescriptionCustomAttributePointFigureBoxSize"; + + public const string DescriptionCustomAttributeBubbleScaleMax = "DescriptionCustomAttributeBubbleScaleMax"; + + public const string DescriptionCustomAttributeBubbleScaleMin = "DescriptionCustomAttributeBubbleScaleMin"; + + public const string DescriptionCustomAttributeCollectedThreshold = "DescriptionCustomAttributeCollectedThreshold"; + + public const string DescriptionCustomAttributePieLineColor = "DescriptionCustomAttributePieLineColor"; + + public const string DescriptionCustomAttributeCalloutLineColor = "DescriptionCustomAttributeCalloutLineColor"; + + public const string DescriptionCustomAttributePieLabelStyle = "DescriptionCustomAttributePieLabelStyle"; + + public const string DescriptionCustomAttributeFunnel3DDrawingStyle = "DescriptionCustomAttributeFunnel3DDrawingStyle"; + + public const string DescriptionCustomAttributePyramid3DDrawingStyle = "DescriptionCustomAttributePyramid3DDrawingStyle"; + + public const string DescriptionCustomAttributeDrawingStyle = "DescriptionCustomAttributeDrawingStyle"; + + public const string DescriptionCustomAttributePieDrawingStyle = "DescriptionCustomAttributePieDrawingStyle"; + + public const string DescriptionCustomAttributeCollectedSliceExploded = "DescriptionCustomAttributeCollectedSliceExploded"; + + public const string DescriptionCustomAttributeCollectedThresholdUsePercent = "DescriptionCustomAttributeCollectedThresholdUsePercent"; + + public const string DescriptionCustomAttributeFunnelNeckHeight = "DescriptionCustomAttributeFunnelNeckHeight"; + + public const string DescriptionCustomAttributeFunnelNeckWidth = "DescriptionCustomAttributeFunnelNeckWidth"; + + public const string DescriptionCustomAttributePyramidPointGap = "DescriptionCustomAttributePyramidPointGap"; + + public const string DescriptionCustomAttributeFunnelPointGap = "DescriptionCustomAttributeFunnelPointGap"; + + public const string DescriptionCustomAttributeLabelsHorizontalLineSize = "DescriptionCustomAttributeLabelsHorizontalLineSize"; + + public const string DescriptionCustomAttributeDoughnutRadius = "DescriptionCustomAttributeDoughnutRadius"; + + public const string DescriptionCustomAttributePolarCircularLabelsStyle = "DescriptionCustomAttributePolarCircularLabelsStyle"; + + public const string DescriptionCustomAttributeRadarCircularLabelsStyle = "DescriptionCustomAttributeRadarCircularLabelsStyle"; + + public const string DescriptionCustomAttributeOpenCloseStyle = "DescriptionCustomAttributeOpenCloseStyle"; + + public const string DescriptionCustomAttributeBubbleMaxSize = "DescriptionCustomAttributeBubbleMaxSize"; + + public const string DescriptionCustomAttributeMaxPixelPointWidth = "DescriptionCustomAttributeMaxPixelPointWidth"; + + public const string DescriptionCustomAttributePyramidMinPointHeight = "DescriptionCustomAttributePyramidMinPointHeight"; + + public const string DescriptionCustomAttributeFunnelMinPointHeight = "DescriptionCustomAttributeFunnelMinPointHeight"; + + public const string DescriptionCustomAttributeMinimumRelativePieSize = "DescriptionCustomAttributeMinimumRelativePieSize"; + + public const string DescriptionCustomAttributeMinPixelPointWidth = "DescriptionCustomAttributeMinPixelPointWidth"; + + public const string DescriptionCustomAttributeErrorBarSeries = "DescriptionCustomAttributeErrorBarSeries"; + + public const string DescriptionCustomAttributeNumberOfLinesInBreak = "DescriptionCustomAttributeNumberOfLinesInBreak"; + + public const string DescriptionCustomAttributePyramidOutsideLabelPlacement = "DescriptionCustomAttributePyramidOutsideLabelPlacement"; + + public const string DescriptionCustomAttributeFunnelOutsideLabelPlacement = "DescriptionCustomAttributeFunnelOutsideLabelPlacement"; + + public const string DescriptionCustomAttributeBoxPlotPercentile = "DescriptionCustomAttributeBoxPlotPercentile"; + + public const string DescriptionCustomAttributeBoxPlotWhiskerPercentile = "DescriptionCustomAttributeBoxPlotWhiskerPercentile"; + + public const string DescriptionCustomAttributeBarLabelStyle = "DescriptionCustomAttributeBarLabelStyle"; + + public const string DescriptionCustomAttributeLabelsRadialLineSize = "DescriptionCustomAttributeLabelsRadialLineSize"; + + public const string DescriptionCustomAttributePointWidth = "DescriptionCustomAttributePointWidth"; + + public const string DescriptionCustomAttributeReversalAmount = "DescriptionCustomAttributeReversalAmount"; + + public const string DescriptionCustomAttributePolarAreaDrawingStyle = "DescriptionCustomAttributePolarAreaDrawingStyle"; + + public const string DescriptionCustomAttributeRadarAreaDrawingStyle = "DescriptionCustomAttributeRadarAreaDrawingStyle"; + + public const string DescriptionCustomAttributeStackedGroupName = "DescriptionCustomAttributeStackedGroupName"; + + public const string DescriptionCustomAttributeLineTension = "DescriptionCustomAttributeLineTension"; + + public const string DescriptionCustomAttributeCandlePriceUpColor = "DescriptionCustomAttributeCandlePriceUpColor"; + + public const string DescriptionCustomAttributeBarsPriceUpColor = "DescriptionCustomAttributeBarsPriceUpColor"; + + public const string DescriptionCustomAttributePriceDownColor = "DescriptionCustomAttributePriceDownColor"; + + public const string DescriptionCustomAttributeUsedYValueHigh = "DescriptionCustomAttributeUsedYValueHigh"; + + public const string DescriptionCustomAttributeUsedYValueLow = "DescriptionCustomAttributeUsedYValueLow"; + + public const string DescriptionCustomAttributeRenkoUsedYValue = "DescriptionCustomAttributeRenkoUsedYValue"; + + public const string DescriptionCustomAttributeThreeLineBreakUsedYValue = "DescriptionCustomAttributeThreeLineBreakUsedYValue"; + + public const string DescriptionCustomAttributePyramidInsideLabelAlignment = "DescriptionCustomAttributePyramidInsideLabelAlignment"; + + public const string DescriptionCustomAttributeFunnelInsideLabelAlignment = "DescriptionCustomAttributeFunnelInsideLabelAlignment"; + + public const string DescriptionCustomAttributeErrorBarStyle = "DescriptionCustomAttributeErrorBarStyle"; + + public const string DescriptionCustomAttributePixelPointWidth = "DescriptionCustomAttributePixelPointWidth"; + + public const string DescriptionCustomAttributeLabelValueType = "DescriptionCustomAttributeLabelValueType"; + + public const string DescriptionCustomAttributeUsedYValue = "DescriptionCustomAttributeUsedYValue"; + + public const string DescriptionCustomAttributeKagiReversalAmount = "DescriptionCustomAttributeKagiReversalAmount"; + + public const string DescriptionCustomAttributeErrorBarType = "DescriptionCustomAttributeErrorBarType"; + + public const string DescriptionAttributeChart_ImageStorageMode = "DescriptionAttributeChart_ImageStorageMode"; + + public const string DescriptionKeyWordAverageYValues = "DescriptionKeyWordAverageYValues"; + + public const string DescriptionKeyWordAxisLabelDataPoint = "DescriptionKeyWordAxisLabelDataPoint"; + + public const string DescriptionKeyWordIndexDataPoint = "DescriptionKeyWordIndexDataPoint"; + + public const string DescriptionKeyWordLabelDataPoint = "DescriptionKeyWordLabelDataPoint"; + + public const string DescriptionKeyWordYValuePercentTotal = "DescriptionKeyWordYValuePercentTotal"; + + public const string DescriptionKeyWordIndexDataPoint2 = "DescriptionKeyWordIndexDataPoint2"; + + public const string DescriptionKeyWordLegendText = "DescriptionKeyWordLegendText"; + + public const string DescriptionKeyWordMaximumYValues = "DescriptionKeyWordMaximumYValues"; + + public const string DescriptionKeyWordMinimumYValues = "DescriptionKeyWordMinimumYValues"; + + public const string DescriptionKeyWordSeriesName = "DescriptionKeyWordSeriesName"; + + public const string DescriptionKeyWordTotalYValues = "DescriptionKeyWordTotalYValues"; + + public const string DescriptionKeyWordXValue = "DescriptionKeyWordXValue"; + + public const string DescriptionKeyWordFirstPointYValue = "DescriptionKeyWordFirstPointYValue"; + + public const string DescriptionKeyWordLastPointYValue = "DescriptionKeyWordLastPointYValue"; + + public const string DescriptionKeyWordYValue = "DescriptionKeyWordYValue"; + + public const string DescriptionKeyWordNameIndexDataPoint = "DescriptionKeyWordNameIndexDataPoint"; + + public const string DescriptionKeyWordNameXValue = "DescriptionKeyWordNameXValue"; + + public const string DescriptionKeyWordNameYValue = "DescriptionKeyWordNameYValue"; + + public const string DescriptionKeyWordNameTotalYValues = "DescriptionKeyWordNameTotalYValues"; + + public const string DescriptionKeyWordNameYValuePercentTotal = "DescriptionKeyWordNameYValuePercentTotal"; + + public const string DescriptionKeyWordNameIndexTheDataPoint = "DescriptionKeyWordNameIndexTheDataPoint"; + + public const string DescriptionKeyWordNameLabelDataPoint = "DescriptionKeyWordNameLabelDataPoint"; + + public const string DescriptionKeyWordNameAxisLabelDataPoint = "DescriptionKeyWordNameAxisLabelDataPoint"; + + public const string DescriptionKeyWordNameLegendText = "DescriptionKeyWordNameLegendText"; + + public const string DescriptionKeyWordNameSeriesName = "DescriptionKeyWordNameSeriesName"; + + public const string DescriptionKeyWordNameAverageYValues = "DescriptionKeyWordNameAverageYValues"; + + public const string DescriptionKeyWordNameMaximumYValues = "DescriptionKeyWordNameMaximumYValues"; + + public const string DescriptionKeyWordNameMinimumYValues = "DescriptionKeyWordNameMinimumYValues"; + + public const string DescriptionKeyWordNameLastPointYValue = "DescriptionKeyWordNameLastPointYValue"; + + public const string DescriptionKeyWordNameFirstPointYValue = "DescriptionKeyWordNameFirstPointYValue"; + + public const string DescriptionNumberFormatTypeCurrency = "DescriptionNumberFormatTypeCurrency"; + + public const string DescriptionNumberFormatTypeDecimal = "DescriptionNumberFormatTypeDecimal"; + + public const string DescriptionNumberFormatTypeScientific = "DescriptionNumberFormatTypeScientific"; + + public const string DescriptionNumberFormatTypeFixedPoint = "DescriptionNumberFormatTypeFixedPoint"; + + public const string DescriptionNumberFormatTypeGeneral = "DescriptionNumberFormatTypeGeneral"; + + public const string DescriptionNumberFormatTypeNumber = "DescriptionNumberFormatTypeNumber"; + + public const string DescriptionNumberFormatTypePercent = "DescriptionNumberFormatTypePercent"; + + public const string DescriptionTypeNone = "DescriptionTypeNone"; + + public const string DescriptionTypeCustom = "DescriptionTypeCustom"; + + public const string DescriptionTypeEmpty = "DescriptionTypeEmpty"; + + public const string DescriptionTypePoint = "DescriptionTypePoint"; + + public const string LabelKeyFormat = "LabelKeyFormat"; + + public const string LabelKeyCustomFormat = "LabelKeyCustomFormat"; + + public const string LabelStringWithKeywords = "LabelStringWithKeywords"; + + public const string LabelEditKeyword = "LabelEditKeyword"; + + public const string LabelInsertNewKeyword = "LabelInsertNewKeyword"; + + public const string LabelStringKeywordsEditor = "LabelStringKeywordsEditor"; + + public const string LabelKeywordEditor = "LabelKeywordEditor"; + + public const string LabelDescription = "LabelDescription"; + + public const string LabelFormatKeySample = "LabelFormatKeySample"; + + public const string LabelKeyYValueIndex = "LabelKeyYValueIndex"; + + public const string LabelKeyPrecision = "LabelKeyPrecision"; + + public const string LabelKeyKeywords = "LabelKeyKeywords"; + + public const string LabelValueFormatting = "LabelValueFormatting"; + + public const string LabelButtonOk = "LabelButtonOk"; + + public const string LabelButtonCancel = "LabelButtonCancel"; + + public const string DescriptionToolTipCustomFormatCharacters = "DescriptionToolTipCustomFormatCharacters"; + + public const string DesciptionCustomLabelEditorTitle = "DesciptionCustomLabelEditorTitle"; + + public const string DesciptionCustomLabelFormatInvalid = "DesciptionCustomLabelFormatInvalid"; + + public const string LabelStatisticalSumOfSquaresBetweenGroups = "LabelStatisticalSumOfSquaresBetweenGroups"; + + public const string LabelStatisticalSumOfSquaresWithinGroups = "LabelStatisticalSumOfSquaresWithinGroups"; + + public const string LabelStatisticalSumOfSquaresTotal = "LabelStatisticalSumOfSquaresTotal"; + + public const string LabelStatisticalDegreesOfFreedomBetweenGroups = "LabelStatisticalDegreesOfFreedomBetweenGroups"; + + public const string LabelStatisticalDegreesOfFreedomWithinGroups = "LabelStatisticalDegreesOfFreedomWithinGroups"; + + public const string LabelStatisticalDegreesOfFreedomTotal = "LabelStatisticalDegreesOfFreedomTotal"; + + public const string LabelStatisticalMeanSquareVarianceBetweenGroups = "LabelStatisticalMeanSquareVarianceBetweenGroups"; + + public const string LabelStatisticalMeanSquareVarianceWithinGroups = "LabelStatisticalMeanSquareVarianceWithinGroups"; + + public const string LabelStatisticalFRatio = "LabelStatisticalFRatio"; + + public const string LabelStatisticalFCriteria = "LabelStatisticalFCriteria"; + + public const string LabelStatisticalCorrelation = "LabelStatisticalCorrelation"; + + public const string LabelStatisticalCovariance = "LabelStatisticalCovariance"; + + public const string LabelStatisticalProbability = "LabelStatisticalProbability"; + + public const string LabelStatisticalAverage = "LabelStatisticalAverage"; + + public const string LabelStatisticalVariance = "LabelStatisticalVariance"; + + public const string LabelStatisticalMedian = "LabelStatisticalMedian"; + + public const string LabelStatisticalBetaFunction = "LabelStatisticalBetaFunction"; + + public const string LabelStatisticalGammaFunction = "LabelStatisticalGammaFunction"; + + public const string LabelStatisticalTheFirstGroupMean = "LabelStatisticalTheFirstGroupMean"; + + public const string LabelStatisticalTheSecondGroupMean = "LabelStatisticalTheSecondGroupMean"; + + public const string LabelStatisticalTheFirstGroupVariance = "LabelStatisticalTheFirstGroupVariance"; + + public const string LabelStatisticalTheSecondGroupVariance = "LabelStatisticalTheSecondGroupVariance"; + + public const string LabelStatisticalFValue = "LabelStatisticalFValue"; + + public const string LabelStatisticalFCriticalValueOneTail = "LabelStatisticalFCriticalValueOneTail"; + + public const string LabelStatisticalZValue = "LabelStatisticalZValue"; + + public const string LabelStatisticalZCriticalValueOneTail = "LabelStatisticalZCriticalValueOneTail"; + + public const string LabelStatisticalZCriticalValueTwoTail = "LabelStatisticalZCriticalValueTwoTail"; + + public const string LabelStatisticalPZLessEqualSmallZOneTail = "LabelStatisticalPZLessEqualSmallZOneTail"; + + public const string LabelStatisticalPZLessEqualSmallZTwoTail = "LabelStatisticalPZLessEqualSmallZTwoTail"; + + public const string LabelStatisticalPFLessEqualSmallFOneTail = "LabelStatisticalPFLessEqualSmallFOneTail"; + + public const string LabelStatisticalTValue = "LabelStatisticalTValue"; + + public const string LabelStatisticalDegreeOfFreedom = "LabelStatisticalDegreeOfFreedom"; + + public const string LabelStatisticalPTLessEqualSmallTOneTail = "LabelStatisticalPTLessEqualSmallTOneTail"; + + public const string LabelStatisticalSmallTCrititcalOneTail = "LabelStatisticalSmallTCrititcalOneTail"; + + public const string LabelStatisticalPTLessEqualSmallTTwoTail = "LabelStatisticalPTLessEqualSmallTTwoTail"; + + public const string LabelStatisticalSmallTCrititcalTwoTail = "LabelStatisticalSmallTCrititcalTwoTail"; + + public const string EvenLogMessageChartImageFileTimeToLive = "EvenLogMessageChartImageFileTimeToLive"; + + public const string MessageYValueIndexInvalid = "MessageYValueIndexInvalid"; + + public const string MessagePrecisionInvalid = "MessagePrecisionInvalid"; + + public const string MessageChangingChartAreaPositionProperty = "MessageChangingChartAreaPositionProperty"; + + public const string MessageChangingChartAreaPositionConfirmAutomatic = "MessageChangingChartAreaPositionConfirmAutomatic"; + + public const string MessageChangingChartAreaPositionConfirmCustom = "MessageChangingChartAreaPositionConfirmCustom"; + + public const string MessageChartException = "MessageChartException"; + + public const string MessageSite = "MessageSite"; + + public const string MessageStackTrace = "MessageStackTrace"; + + public const string MessageChartTitle = "MessageChartTitle"; + + public const string TitleAxisX = "TitleAxisX"; + + public const string TitleAxisY = "TitleAxisY"; + + public const string TitleAxisX2 = "TitleAxisX2"; + + public const string TitleAxisY2 = "TitleAxisY2"; + + public const string FormulaNamePriceIndicators = "FormulaNamePriceIndicators"; + + public const string FormulaNameGeneralTechnicalIndicators = "FormulaNameGeneralTechnicalIndicators"; + + public const string FormulaNameTechnicalVolumeIndicators = "FormulaNameTechnicalVolumeIndicators"; + + public const string FormulaNameOscillator = "FormulaNameOscillator"; + + public const string FormulaNameGeneralFormulas = "FormulaNameGeneralFormulas"; + + public const string FormulaNameTimeSeriesAndForecasting = "FormulaNameTimeSeriesAndForecasting"; + + public const string FormulaNameStatisticalAnalysis = "FormulaNameStatisticalAnalysis"; + + public const string FormulaNameVolumeIndicators = "FormulaNameVolumeIndicators"; + + public const string LabelTextRow = "LabelTextRow"; + + public const string DescriptionAttributeBackImage = "DescriptionAttributeBackImage"; + + public const string DescriptionAttributeMarkerImage = "DescriptionAttributeMarkerImage"; + + public const string DescriptionAttributeAnnotationBaseY = "DescriptionAttributeAnnotationBaseY"; + + public const string DescriptionAttributeAnnotationWidth = "DescriptionAttributeAnnotationWidth"; + + public const string DescriptionAttributeAnnotationHeight = "DescriptionAttributeAnnotationHeight"; + + public const string DescriptionAttributeAnnotationClipToChartArea = "DescriptionAttributeAnnotationClipToChartArea"; + + public const string DescriptionAttributeAnnotationBaseX = "DescriptionAttributeAnnotationBaseX"; + + public const string DescriptionAttributeChartImageType = "DescriptionAttributeChartImageType"; + + public const string DescriptionAttributeMultiValueSeparator = "DescriptionAttributeMultiValueSeparator"; + + public const string DescriptionAttributeDataSeriesGroupID = "DescriptionAttributeDataSeriesGroupID"; + + public const string DescriptionAttributeSuppressCodeExceptions = "DescriptionAttributeSuppressCodeExceptions"; + + public const string DescriptionAttributeNoDataMessage = "DescriptionAttributeNoDataMessage"; + + public const string DescriptionAttributeReverseSeriesOrder = "DescriptionAttributeReverseSeriesOrder"; + + public const string DescriptionAttributeUserDefined = "DescriptionAttributeUserDefined"; + + public const string DescriptionAttributeChartEvent_GetToolTipText = "DescriptionAttributeChartEvent_GetToolTipText"; + + public const string DescriptionAttributeArrowAnnotation_ArrowSize = "DescriptionAttributeArrowAnnotation_ArrowSize"; + + public const string DescriptionAttributeChartSerializer_Content = "DescriptionAttributeChartSerializer_Content"; + + public const string DescriptionAttributeLegend_Enabled = "DescriptionAttributeLegend_Enabled"; + + public const string DescriptionAttributeEnabled5 = "DescriptionAttributeEnabled5"; + + public const string DescriptionAttributeAxisScaleBreakStyle_Enabled = "DescriptionAttributeAxisScaleBreakStyle_Enabled"; + + public const string DescriptionAttributeEnabled7 = "DescriptionAttributeEnabled7"; + + public const string DescriptionAttributeLabel_Enabled = "DescriptionAttributeLabel_Enabled"; + + public const string DescriptionAttributeLegendItem_Enabled = "DescriptionAttributeLegendItem_Enabled"; + + public const string DescriptionAttributeAxisScrollBar_Enabled = "DescriptionAttributeAxisScrollBar_Enabled"; + + public const string DescriptionAttributeEnabled13 = "DescriptionAttributeEnabled13"; + + public const string DescriptionAttributeSeries_Enabled = "DescriptionAttributeSeries_Enabled"; + + public const string DescriptionAttributeLegendCell_CellSpan = "DescriptionAttributeLegendCell_CellSpan"; + + public const string DescriptionAttributeCursor_SelectionColor = "DescriptionAttributeCursor_SelectionColor"; + + public const string DescriptionAttributeInterlaced = "DescriptionAttributeInterlaced"; + + public const string DescriptionAttributeMapArea_Coordinates = "DescriptionAttributeMapArea_Coordinates"; + + public const string DescriptionAttributeChartEvent_PostPaint = "DescriptionAttributeChartEvent_PostPaint"; + + public const string DescriptionAttributeStripLine_Title = "DescriptionAttributeStripLine_Title"; + + public const string DescriptionAttributeLegend_Title = "DescriptionAttributeLegend_Title"; + + public const string DescriptionAttributeTitle5 = "DescriptionAttributeTitle5"; + + public const string DescriptionAttributeTitle6 = "DescriptionAttributeTitle6"; + + public const string DescriptionAttributeAnnotation_Annotation = "DescriptionAttributeAnnotation_Annotation"; + + public const string DescriptionAttributeTitleFont = "DescriptionAttributeTitleFont"; + + public const string DescriptionAttributeChartArea_Axes = "DescriptionAttributeChartArea_Axes"; + + public const string DescriptionAttributeChartSerializer_NonSerializableContent = "DescriptionAttributeChartSerializer_NonSerializableContent"; + + public const string DescriptionAttributeShadowOffset = "DescriptionAttributeShadowOffset"; + + public const string DescriptionAttributeCalloutLineAnchorCap = "DescriptionAttributeCalloutLineAnchorCap"; + + public const string DescriptionAttributeMapAreaAttributes = "DescriptionAttributeMapAreaAttributes"; + + public const string DescriptionAttributeSubAxis_SubAxis = "DescriptionAttributeSubAxis_SubAxis"; + + public const string DescriptionAttributeMajorGrid = "DescriptionAttributeMajorGrid"; + + public const string DescriptionAttributeElementPosition_Y = "DescriptionAttributeElementPosition_Y"; + + public const string DescriptionAttributeAnnotationPathPoint_Y = "DescriptionAttributeAnnotationPathPoint_Y"; + + public const string DescriptionAttributeToolTipEventArgs_Y = "DescriptionAttributeToolTipEventArgs_Y"; + + public const string DescriptionAttributePoint3D_Y = "DescriptionAttributePoint3D_Y"; + + public const string DescriptionAttributePoint3D_Z = "DescriptionAttributePoint3D_Z"; + + public const string DescriptionAttributeMajorTickMark = "DescriptionAttributeMajorTickMark"; + + public const string DescriptionAttributeDrawInfinitive = "DescriptionAttributeDrawInfinitive"; + + public const string DescriptionAttributeAxisDataView_MinSize = "DescriptionAttributeAxisDataView_MinSize"; + + public const string DescriptionAttributeLegendCellColumnCollection_LegendCellColumnCollection = "DescriptionAttributeLegendCellColumnCollection_LegendCellColumnCollection"; + + public const string DescriptionAttributeMarkerOverlapping = "DescriptionAttributeMarkerOverlapping"; + + public const string DescriptionAttributeChart_OnCustomizeLegend = "DescriptionAttributeChart_OnCustomizeLegend"; + + public const string DescriptionAttributeLegendCellColumn_HeaderTextAlignment = "DescriptionAttributeLegendCellColumn_HeaderTextAlignment"; + + public const string DescriptionAttributeScrollBarEventArgs_MousePositionY = "DescriptionAttributeScrollBarEventArgs_MousePositionY"; + + public const string DescriptionAttributeNamedImage_NamedImage = "DescriptionAttributeNamedImage_NamedImage"; + + public const string DescriptionAttributeScrollBar = "DescriptionAttributeScrollBar"; + + public const string DescriptionAttributeMapArea_MapArea = "DescriptionAttributeMapArea_MapArea"; + + public const string DescriptionAttributeLegend_CustomItems = "DescriptionAttributeLegend_CustomItems"; + + public const string DescriptionAttributeAnnotationSmartLabelsStyle_AnnotationSmartLabelsStyle = "DescriptionAttributeAnnotationSmartLabelsStyle_AnnotationSmartLabelsStyle"; + + public const string DescriptionAttributePolylineAnnotation_PolylineAnnotation = "DescriptionAttributePolylineAnnotation_PolylineAnnotation"; + + public const string DescriptionAttributeChartEvent_AxisViewChanged = "DescriptionAttributeChartEvent_AxisViewChanged"; + + public const string DescriptionAttributeCrossing = "DescriptionAttributeCrossing"; + + public const string DescriptionAttributeMargins_Top = "DescriptionAttributeMargins_Top"; + + public const string DescriptionAttributeLegendCellColumn_HeaderFont = "DescriptionAttributeLegendCellColumn_HeaderFont"; + + public const string DescriptionAttributeLegend_InterlacedRows = "DescriptionAttributeLegend_InterlacedRows"; + + public const string DescriptionAttributeAxisDataView_MinSizeType = "DescriptionAttributeAxisDataView_MinSizeType"; + + public const string DescriptionAttributeLineWidth = "DescriptionAttributeLineWidth"; + + public const string DescriptionAttributeDataPoint_XValue = "DescriptionAttributeDataPoint_XValue"; + + public const string DescriptionAttributeChartArea_AxisY2 = "DescriptionAttributeChartArea_AxisY2"; + + public const string DescriptionAttributeChartArea_AxisX2 = "DescriptionAttributeChartArea_AxisX2"; + + public const string DescriptionAttributeChartEvent_AnnotationPositionChanging = "DescriptionAttributeChartEvent_AnnotationPositionChanging"; + + public const string DescriptionAttributeStripLine_StripLine = "DescriptionAttributeStripLine_StripLine"; + + public const string DescriptionAttributeBorderColor = "DescriptionAttributeBorderColor"; + + public const string DescriptionAttributeMarkerBorderColor = "DescriptionAttributeMarkerBorderColor"; + + public const string DescriptionAttributeLegendText = "DescriptionAttributeLegendText"; + + public const string DescriptionAttributeCustomLabel_LabelMark = "DescriptionAttributeCustomLabel_LabelMark"; + + public const string DescriptionAttributeTextAntiAliasingQuality = "DescriptionAttributeTextAntiAliasingQuality"; + + public const string DescriptionAttributeAllowMoving = "DescriptionAttributeAllowMoving"; + + public const string DescriptionAttributeCalloutAnnotation_CalloutAnnotation = "DescriptionAttributeCalloutAnnotation_CalloutAnnotation"; + + public const string DescriptionAttributeStripLine_Name = "DescriptionAttributeStripLine_Name"; + + public const string DescriptionAttributeTitle_Name = "DescriptionAttributeTitle_Name"; + + public const string DescriptionAttributeName4 = "DescriptionAttributeName4"; + + public const string DescriptionAttributeAnnotationPathPoint_Name = "DescriptionAttributeAnnotationPathPoint_Name"; + + public const string DescriptionAttributeLegendCell_Name = "DescriptionAttributeLegendCell_Name"; + + public const string DescriptionAttributeMapArea_Name = "DescriptionAttributeMapArea_Name"; + + public const string DescriptionAttributeSeries_Name = "DescriptionAttributeSeries_Name"; + + public const string DescriptionAttributeAxis_Name = "DescriptionAttributeAxis_Name"; + + public const string DescriptionAttributeNamedImage_Name = "DescriptionAttributeNamedImage_Name"; + + public const string DescriptionAttributeSubAxis_Name = "DescriptionAttributeSubAxis_Name"; + + public const string DescriptionAttributeDataPoint_Name = "DescriptionAttributeDataPoint_Name"; + + public const string DescriptionAttributeLegendCellColumn_Name = "DescriptionAttributeLegendCellColumn_Name"; + + public const string DescriptionAttributeLegendItem_Name = "DescriptionAttributeLegendItem_Name"; + + public const string DescriptionAttributeLegend_Name = "DescriptionAttributeLegend_Name"; + + public const string DescriptionAttributeCustomLabel_Name = "DescriptionAttributeCustomLabel_Name"; + + public const string DescriptionAttributeChartArea_Name = "DescriptionAttributeChartArea_Name"; + + public const string DescriptionAttributeCursor_Cursor = "DescriptionAttributeCursor_Cursor"; + + public const string DescriptionAttributeAnchorX = "DescriptionAttributeAnchorX"; + + public const string DescriptionAttributeToolTip = "DescriptionAttributeToolTip"; + + public const string DescriptionAttributeLegend_TableStyle = "DescriptionAttributeLegend_TableStyle"; + + public const string DescriptionAttributeDataPoint_Empty = "DescriptionAttributeDataPoint_Empty"; + + public const string DescriptionAttributeScrollBarEventArgs_Handled = "DescriptionAttributeScrollBarEventArgs_Handled"; + + public const string DescriptionAttributeAxisLabel = "DescriptionAttributeAxisLabel"; + + public const string DescriptionAttributeAnnotationGroup_AllowPathEditing = "DescriptionAttributeAnnotationGroup_AllowPathEditing"; + + public const string DescriptionAttributeAllowPathEditing3 = "DescriptionAttributeAllowPathEditing3"; + + public const string DescriptionAttributeChart_OnPaint = "DescriptionAttributeChart_OnPaint"; + + public const string DescriptionAttributeCalloutAnnotation_AnchorOffsetX = "DescriptionAttributeCalloutAnnotation_AnchorOffsetX"; + + public const string DescriptionAttributeAnchorOffsetX3 = "DescriptionAttributeAnchorOffsetX3"; + + public const string DescriptionAttributeCalloutAnnotation_AnchorOffsetY = "DescriptionAttributeCalloutAnnotation_AnchorOffsetY"; + + public const string DescriptionAttributeAnchorOffsetY3 = "DescriptionAttributeAnchorOffsetY3"; + + public const string DescriptionAttributeChartEvent_CursorPositionChanging = "DescriptionAttributeChartEvent_CursorPositionChanging"; + + public const string DescriptionAttributeScrollBarEventArgs_ButtonType = "DescriptionAttributeScrollBarEventArgs_ButtonType"; + + public const string DescriptionAttributeLabelsAutoFitStyle = "DescriptionAttributeLabelsAutoFitStyle"; + + public const string DescriptionAttributeLabelStyle = "DescriptionAttributeLabelStyle"; + + public const string DescriptionAttributeStripLine_IntervalOffsetType = "DescriptionAttributeStripLine_IntervalOffsetType"; + + public const string DescriptionAttributeLabel_IntervalOffsetType = "DescriptionAttributeLabel_IntervalOffsetType"; + + public const string DescriptionAttributeIntervalOffsetType4 = "DescriptionAttributeIntervalOffsetType4"; + + public const string DescriptionAttributeCursor_IntervalOffsetType = "DescriptionAttributeCursor_IntervalOffsetType"; + + public const string DescriptionAttributeIntervalOffsetType6 = "DescriptionAttributeIntervalOffsetType6"; + + public const string DescriptionAttributeAxisScaleSegment_IntervalOffsetType = "DescriptionAttributeAxisScaleSegment_IntervalOffsetType"; + + public const string DescriptionAttributeReverse = "DescriptionAttributeReverse"; + + public const string DescriptionAttributeSeries_Points = "DescriptionAttributeSeries_Points"; + + public const string DescriptionAttributeBorderSkin_SkinStyle = "DescriptionAttributeBorderSkin_SkinStyle"; + + public const string DescriptionAttributeChartArea3DStyle_Clustered = "DescriptionAttributeChartArea3DStyle_Clustered"; + + public const string DescriptionAttributeAnchorDataPointName = "DescriptionAttributeAnchorDataPointName"; + + public const string DescriptionAttributeChartEvent_AnnotationPositionChanged = "DescriptionAttributeChartEvent_AnnotationPositionChanged"; + + public const string DescriptionAttributeChartArea3DStyle_PointGapDepth = "DescriptionAttributeChartArea3DStyle_PointGapDepth"; + + public const string DescriptionAttributeLegend_Reversed = "DescriptionAttributeLegend_Reversed"; + + public const string DescriptionAttributeAnnotation_AnnotationType = "DescriptionAttributeAnnotation_AnnotationType"; + + public const string DescriptionAttributeTextAnnotation_AnnotationType = "DescriptionAttributeTextAnnotation_AnnotationType"; + + public const string DescriptionAttributeAnnotationType = "DescriptionAttributeAnnotationType"; + + public const string DescriptionAttributeBorderSkin_FrameBorderDashStyle = "DescriptionAttributeBorderSkin_FrameBorderDashStyle"; + + public const string DescriptionAttributeLegend_HeaderSeparatorColor = "DescriptionAttributeLegend_HeaderSeparatorColor"; + + public const string DescriptionAttributeChartEvent_AnnotationSelectionChanged = "DescriptionAttributeChartEvent_AnnotationSelectionChanged"; + + public const string DescriptionAttributeFont = "DescriptionAttributeFont"; + + public const string DescriptionAttributeLegend_Font = "DescriptionAttributeLegend_Font"; + + public const string DescriptionAttributeLegendCellColumn_Font = "DescriptionAttributeLegendCellColumn_Font"; + + public const string DescriptionAttributeLabel_Font = "DescriptionAttributeLabel_Font"; + + public const string DescriptionAttributeTitle_Font = "DescriptionAttributeTitle_Font"; + + public const string DescriptionAttributeLegendCell_Font = "DescriptionAttributeLegendCell_Font"; + + public const string DescriptionAttributeSeries_ValueMemberX = "DescriptionAttributeSeries_ValueMemberX"; + + public const string DescriptionAttributeArrows = "DescriptionAttributeArrows"; + + public const string DescriptionAttributeType = "DescriptionAttributeType"; + + public const string DescriptionAttributeSeries_Type = "DescriptionAttributeSeries_Type"; + + public const string DescriptionAttributeBorder3DAnnotation_Border3DAnnotation = "DescriptionAttributeBorder3DAnnotation_Border3DAnnotation"; + + public const string DescriptionAttributeChart_Images = "DescriptionAttributeChart_Images"; + + public const string DescriptionAttributeLegendToolTip = "DescriptionAttributeLegendToolTip"; + + public const string DescriptionAttributeCustomLabel_CustomLabel = "DescriptionAttributeCustomLabel_CustomLabel"; + + public const string DescriptionAttributeChartEvent_AnnotationPlaced = "DescriptionAttributeChartEvent_AnnotationPlaced"; + + public const string DescriptionAttributeBackColor = "DescriptionAttributeBackColor"; + + public const string DescriptionAttributeCalloutBackColor = "DescriptionAttributeCalloutBackColor"; + + public const string DescriptionAttributeFrameBackColor = "DescriptionAttributeFrameBackColor"; + + public const string DescriptionAttributeTitleBackColor = "DescriptionAttributeTitleBackColor"; + + public const string DescriptionAttributeLabelBackColor = "DescriptionAttributeLabelBackColor"; + + public const string DescriptionAttributeHeaderBackColor = "DescriptionAttributeHeaderBackColor"; + + public const string DescriptionAttributeLabel_ShowEndLabels = "DescriptionAttributeLabel_ShowEndLabels"; + + public const string DescriptionAttributeLabelToolTip = "DescriptionAttributeLabelToolTip"; + + public const string DescriptionAttributeSeries_MarkerStep = "DescriptionAttributeSeries_MarkerStep"; + + public const string DescriptionAttributeTickMark_Style = "DescriptionAttributeTickMark_Style"; + + public const string DescriptionAttribute_TextOrientation = "DescriptionAttribute_TextOrientation"; + + public const string DescriptionAttributeLegendItem_Style = "DescriptionAttributeLegendItem_Style"; + + public const string DescriptionAttributeChartArea3DStyle_Rotation = "DescriptionAttributeChartArea3DStyle_Rotation"; + + public const string DescriptionAttributeSizeAlwaysRelative = "DescriptionAttributeSizeAlwaysRelative"; + + public const string DescriptionAttributeSizeAlwaysRelative3 = "DescriptionAttributeSizeAlwaysRelative3"; + + public const string DescriptionAttributeAnnotationGroup_SizeAlwaysRelative = "DescriptionAttributeAnnotationGroup_SizeAlwaysRelative"; + + public const string DescriptionAttributeChart_BorderlineWidth = "DescriptionAttributeChart_BorderlineWidth"; + + public const string DescriptionAttributeSeries_XValueIndexed = "DescriptionAttributeSeries_XValueIndexed"; + + public const string DescriptionAttributeEllipseAnnotation_EllipseAnnotation = "DescriptionAttributeEllipseAnnotation_EllipseAnnotation"; + + public const string DescriptionAttributeAnchorAlignment = "DescriptionAttributeAnchorAlignment"; + + public const string DescriptionAttributeWidth = "DescriptionAttributeWidth"; + + public const string DescriptionAttributeElementPosition_Width = "DescriptionAttributeElementPosition_Width"; + + public const string DescriptionAttributeAxisXName = "DescriptionAttributeAxisXName"; + + public const string DescriptionAttributeChartArea3DStyle_Inclination = "DescriptionAttributeChartArea3DStyle_Inclination"; + + public const string DescriptionAttributeLegendCollection_LegendCollection = "DescriptionAttributeLegendCollection_LegendCollection"; + + public const string DescriptionAttributeAxisYName = "DescriptionAttributeAxisYName"; + + public const string DescriptionAttributeAxisScaleSegment_Spacing = "DescriptionAttributeAxisScaleSegment_Spacing"; + + public const string DescriptionAttributeAxisScaleBreakStyle_Spacing = "DescriptionAttributeAxisScaleBreakStyle_Spacing"; + + public const string DescriptionAttributeSelected = "DescriptionAttributeSelected"; + + public const string DescriptionAttributeAnnotationGroup_Selected = "DescriptionAttributeAnnotationGroup_Selected"; + + public const string DescriptionAttributeVerticalLineAnnotation_VerticalLineAnnotation = "DescriptionAttributeVerticalLineAnnotation_VerticalLineAnnotation"; + + public const string DescriptionAttributeLabelsAutoFitMaxFontSize = "DescriptionAttributeLabelsAutoFitMaxFontSize"; + + public const string DescriptionAttributeFreeDrawPlacement = "DescriptionAttributeFreeDrawPlacement"; + + public const string DescriptionAttributeStripLinesCollection_StripLinesCollection = "DescriptionAttributeStripLinesCollection_StripLinesCollection"; + + public const string DescriptionAttributeAxisDataView_IsZoomed = "DescriptionAttributeAxisDataView_IsZoomed"; + + public const string DescriptionAttributeChartArea3DStyle_Perspective = "DescriptionAttributeChartArea3DStyle_Perspective"; + + public const string DescriptionAttributeChart_OnCustomize = "DescriptionAttributeChart_OnCustomize"; + + public const string DescriptionAttributeLabel = "DescriptionAttributeLabel"; + + public const string DescriptionAttributeLabel_Label = "DescriptionAttributeLabel_Label"; + + public const string DescriptionAttributeStartCap3 = "DescriptionAttributeStartCap3"; + + public const string DescriptionAttributeFontColor = "DescriptionAttributeFontColor"; + + public const string DescriptionAttributeLegendFontColor = "DescriptionAttributeLegendFontColor"; + + public const string DescriptionAttributeLabel_OffsetLabels = "DescriptionAttributeLabel_OffsetLabels"; + + public const string DescriptionAttributeMargin = "DescriptionAttributeMargin"; + + public const string DescriptionAttributeAnnotationPositionChangingEventArgs_AnnotationPositionChangingEventArgs = "DescriptionAttributeAnnotationPositionChangingEventArgs_AnnotationPositionChangin" + + "gEventArgs"; + + public const string DescriptionAttributeCursorEventArgs_NewSelectionStart = "DescriptionAttributeCursorEventArgs_NewSelectionStart"; + + public const string DescriptionAttributeSeries_XSubAxisName = "DescriptionAttributeSeries_XSubAxisName"; + + public const string DescriptionAttributeHideOverlapped = "DescriptionAttributeHideOverlapped"; + + public const string DescriptionAttributeLegendCellColumn_MaximumWidth = "DescriptionAttributeLegendCellColumn_MaximumWidth"; + + public const string DescriptionAttributeLegend_InsideChartArea = "DescriptionAttributeLegend_InsideChartArea"; + + public const string DescriptionAttributeImageTransparentColor = "DescriptionAttributeImageTransparentColor"; + + public const string DescriptionAttributeLegend_EquallySpacedItems = "DescriptionAttributeLegend_EquallySpacedItems"; + + public const string DescriptionAttributeChartArea_CursorY = "DescriptionAttributeChartArea_CursorY"; + + public const string DescriptionAttributeChart_Printing = "DescriptionAttributeChart_Printing"; + + public const string DescriptionAttributeAxis = "DescriptionAttributeAxis"; + + public const string DescriptionAttributeAxis_Axis = "DescriptionAttributeAxis_Axis"; + + public const string DescriptionAttributeBackImageAlign = "DescriptionAttributeBackImageAlign"; + + public const string DescriptionAttributeShowInLegend = "DescriptionAttributeShowInLegend"; + + public const string DescriptionAttributeChartSerializer_ChartSerializer = "DescriptionAttributeChartSerializer_ChartSerializer"; + + public const string DescriptionAttributeChart_Compression = "DescriptionAttributeChart_Compression"; + + public const string DescriptionAttributeChartImage_Compression = "DescriptionAttributeChartImage_Compression"; + + public const string DescriptionAttributeCursor_AutoScroll = "DescriptionAttributeCursor_AutoScroll"; + + public const string DescriptionAttributeElementPosition_Height = "DescriptionAttributeElementPosition_Height"; + + public const string DescriptionAttributeHeight3 = "DescriptionAttributeHeight3"; + + public const string DescriptionAttributeChart_ViewStateContent = "DescriptionAttributeChart_ViewStateContent"; + + public const string DescriptionAttributeAxisDataView_SmallScrollSizeType = "DescriptionAttributeAxisDataView_SmallScrollSizeType"; + + public const string DescriptionAttributeLegend_CellColumns = "DescriptionAttributeLegend_CellColumns"; + + public const string DescriptionAttributeAxisScrollBar_Buttons = "DescriptionAttributeAxisScrollBar_Buttons"; + + public const string DescriptionAttributeLegends = "DescriptionAttributeLegends"; + + public const string DescriptionAttributeElementPosition_X = "DescriptionAttributeElementPosition_X"; + + public const string DescriptionAttributeAnnotationPathPoint_X = "DescriptionAttributeAnnotationPathPoint_X"; + + public const string DescriptionAttributePoint3D_X = "DescriptionAttributePoint3D_X"; + + public const string DescriptionAttributeToolTipEventArgs_X = "DescriptionAttributeToolTipEventArgs_X"; + + public const string DescriptionAttributeCustomAttributesExtended = "DescriptionAttributeCustomAttributesExtended"; + + public const string DescriptionAttributeMargins_Left = "DescriptionAttributeMargins_Left"; + + public const string DescriptionAttributeAxisScrollBar_PositionInside = "DescriptionAttributeAxisScrollBar_PositionInside"; + + public const string DescriptionAttributeSeries_ValueMembersY = "DescriptionAttributeSeries_ValueMembersY"; + + public const string DescriptionAttributeSmartLabelsStyle_SmartLabelsStyle = "DescriptionAttributeSmartLabelsStyle_SmartLabelsStyle"; + + public const string DescriptionAttributeChartEvent_SelectionRangeChanging = "DescriptionAttributeChartEvent_SelectionRangeChanging"; + + public const string DescriptionAttributeLabelsAutoFitMinFontSize = "DescriptionAttributeLabelsAutoFitMinFontSize"; + + public const string DescriptionAttributeMaxMovingDistance = "DescriptionAttributeMaxMovingDistance"; + + public const string DescriptionAttributeTitle_DockToChartArea = "DescriptionAttributeTitle_DockToChartArea"; + + public const string DescriptionAttributeLegend_DockToChartArea = "DescriptionAttributeLegend_DockToChartArea"; + + public const string DescriptionAttributeChartArea3DStyle_RightAngleAxes = "DescriptionAttributeChartArea3DStyle_RightAngleAxes"; + + public const string DescriptionAttributeLegend_LegendStyle = "DescriptionAttributeLegend_LegendStyle"; + + public const string DescriptionAttributeAxisDataView_AxisDataView = "DescriptionAttributeAxisDataView_AxisDataView"; + + public const string DescriptionAttributeBorderDashStyle = "DescriptionAttributeBorderDashStyle"; + + public const string DescriptionAttributeLabelBorderDashStyle = "DescriptionAttributeLabelBorderDashStyle"; + + public const string DescriptionAttributeBackSecondaryColor = "DescriptionAttributeBackSecondaryColor"; + + public const string DescriptionAttributeBorderSkin_FrameBackSecondaryColor = "DescriptionAttributeBorderSkin_FrameBackSecondaryColor"; + + public const string DescriptionAttributeLegend_TitleSeparator = "DescriptionAttributeLegend_TitleSeparator"; + + public const string DescriptionAttributeChartArea_InnerPlotPosition = "DescriptionAttributeChartArea_InnerPlotPosition"; + + public const string DescriptionAttributeChartEvent_CustomizeLegend = "DescriptionAttributeChartEvent_CustomizeLegend"; + + public const string DescriptionAttributeAnnotationPathPoint_AnnotationPathPoint = "DescriptionAttributeAnnotationPathPoint_AnnotationPathPoint"; + + public const string DescriptionAttributeDataPoint_YValues = "DescriptionAttributeDataPoint_YValues"; + + public const string DescriptionAttributeCustomLabel_RowIndex = "DescriptionAttributeCustomLabel_RowIndex"; + + public const string DescriptionAttributeSeries_YSubAxisName = "DescriptionAttributeSeries_YSubAxisName"; + + public const string DescriptionAttributeChartArea_AlignType = "DescriptionAttributeChartArea_AlignType"; + + public const string DescriptionAttributeAllowResizing = "DescriptionAttributeAllowResizing"; + + public const string DescriptionAttributeShowLabelAsValue = "DescriptionAttributeShowLabelAsValue"; + + public const string DescriptionAttributeForeColor = "DescriptionAttributeForeColor"; + + public const string DescriptionAttributePathPoints = "DescriptionAttributePathPoints"; + + public const string DescriptionAttributeViewEventArgs_NewSizeType = "DescriptionAttributeViewEventArgs_NewSizeType"; + + public const string DescriptionAttributeChart_BuildNumber = "DescriptionAttributeChart_BuildNumber"; + + public const string DescriptionAttributeAxisScaleSegmentCollection_AxisScaleSegmentCollection = "DescriptionAttributeAxisScaleSegmentCollection_AxisScaleSegmentCollection"; + + public const string DescriptionAttributeMarkerSize = "DescriptionAttributeMarkerSize"; + + public const string DescriptionAttributeLegendItem_MarkerSize = "DescriptionAttributeLegendItem_MarkerSize"; + + public const string DescriptionAttributeLegendCell_SeriesSymbolSize = "DescriptionAttributeLegendCell_SeriesSymbolSize"; + + public const string DescriptionAttributeLegendCellColumn_SeriesSymbolSize = "DescriptionAttributeLegendCellColumn_SeriesSymbolSize"; + + public const string DescriptionAttributeDisabled = "DescriptionAttributeDisabled"; + + public const string DescriptionAttributeChartSerializer_ResetWhenLoading = "DescriptionAttributeChartSerializer_ResetWhenLoading"; + + public const string DescriptionAttributeBackGradientStyle = "DescriptionAttributeBackGradientStyle"; + + public const string DescriptionAttributeDataSource = "DescriptionAttributeDataSource"; + + public const string DescriptionAttributeCustomLabels = "DescriptionAttributeCustomLabels"; + + public const string DescriptionAttributeArrowAnnotation_ArrowAnnotation = "DescriptionAttributeArrowAnnotation_ArrowAnnotation"; + + public const string DescriptionAttributeCursor_AxisType = "DescriptionAttributeCursor_AxisType"; + + public const string DescriptionAttributeLegendItem_Cells = "DescriptionAttributeLegendItem_Cells"; + + public const string DescriptionAttributeBorderSkin = "DescriptionAttributeBorderSkin"; + + public const string DescriptionAttributeBorderSkin_BorderSkin = "DescriptionAttributeBorderSkin_BorderSkin"; + + public const string DescriptionAttributeSubAxisCollection_SubAxisCollection = "DescriptionAttributeSubAxisCollection_SubAxisCollection"; + + public const string DescriptionAttributeAllowSelecting = "DescriptionAttributeAllowSelecting"; + + public const string DescriptionAttributeChartEvent_Customize = "DescriptionAttributeChartEvent_Customize"; + + public const string DescriptionAttributeChartEvent_Click = "DescriptionAttributeChartEvent_Click"; + + public const string DescriptionAttributeImageAnnotation_ImageAnnotation = "DescriptionAttributeImageAnnotation_ImageAnnotation"; + + public const string DescriptionAttributeAxisDataView_SmallScrollSize = "DescriptionAttributeAxisDataView_SmallScrollSize"; + + public const string DescriptionAttributeAxisScaleSegment_Interval = "DescriptionAttributeAxisScaleSegment_Interval"; + + public const string DescriptionAttributeCursor_Interval = "DescriptionAttributeCursor_Interval"; + + public const string DescriptionAttributeInterval4 = "DescriptionAttributeInterval4"; + + public const string DescriptionAttributeStripLine_Interval = "DescriptionAttributeStripLine_Interval"; + + public const string DescriptionAttributeInterval6 = "DescriptionAttributeInterval6"; + + public const string DescriptionAttributeLabel_Interval = "DescriptionAttributeLabel_Interval"; + + public const string DescriptionAttributeStripLine_TitleLineAlignment = "DescriptionAttributeStripLine_TitleLineAlignment"; + + public const string DescriptionAttributeMaximum = "DescriptionAttributeMaximum"; + + public const string DescriptionAttributeElementPosition_Auto = "DescriptionAttributeElementPosition_Auto"; + + public const string DescriptionAttributeSeries_YAxisType = "DescriptionAttributeSeries_YAxisType"; + + public const string DescriptionAttributeLineDashStyle = "DescriptionAttributeLineDashStyle"; + + public const string DescriptionAttributeLogarithmBase = "DescriptionAttributeLogarithmBase"; + + public const string DescriptionAttributeAntiAlias = "DescriptionAttributeAntiAlias"; + + public const string DescriptionAttributeImageWrapMode = "DescriptionAttributeImageWrapMode"; + + public const string DescriptionAttributeChartSerializer_IgnoreUnknownXmlAttributes = "DescriptionAttributeChartSerializer_IgnoreUnknownXmlAttributes"; + + public const string DescriptionAttributeAxisScaleSegment_Tag = "DescriptionAttributeAxisScaleSegment_Tag"; + + public const string DescriptionAttributeTag = "DescriptionAttributeTag"; + + public const string DescriptionAttributeLegend = "DescriptionAttributeLegend"; + + public const string DescriptionAttributeLegend_Legend = "DescriptionAttributeLegend_Legend"; + + public const string DescriptionAttributeSeries_Legend = "DescriptionAttributeSeries_Legend"; + + public const string DescriptionAttributeDataPointComparer_DataPointComparer = "DescriptionAttributeDataPointComparer_DataPointComparer"; + + public const string DescriptionAttributeBackHatchStyle = "DescriptionAttributeBackHatchStyle"; + + public const string DescriptionAttributeFrameBackHatchStyle = "DescriptionAttributeFrameBackHatchStyle"; + + public const string DescriptionAttributeChartAreaCollection_Item = "DescriptionAttributeChartAreaCollection_Item"; + + public const string DescriptionAttributeLegendCollection_Item = "DescriptionAttributeLegendCollection_Item"; + + public const string DescriptionAttributeAnnotationCollection_Item = "DescriptionAttributeAnnotationCollection_Item"; + + public const string DescriptionAttributeSubAxisCollection_Item = "DescriptionAttributeSubAxisCollection_Item"; + + public const string DescriptionAttributeSeriesCollection_Item = "DescriptionAttributeSeriesCollection_Item"; + + public const string DescriptionAttributeAnnotationPathPointCollection_Item = "DescriptionAttributeAnnotationPathPointCollection_Item"; + + public const string DescriptionAttributeLegendCellColumnCollection_Item = "DescriptionAttributeLegendCellColumnCollection_Item"; + + public const string DescriptionAttributeAxisScaleSegmentCollection_Item = "DescriptionAttributeAxisScaleSegmentCollection_Item"; + + public const string DescriptionAttributeLegendCellCollection_Item = "DescriptionAttributeLegendCellCollection_Item"; + + public const string DescriptionAttributeNamedImagesCollection_Item = "DescriptionAttributeNamedImagesCollection_Item"; + + public const string DescriptionAttributeAxisScaleSegment_ScaleMinimum = "DescriptionAttributeAxisScaleSegment_ScaleMinimum"; + + public const string DescriptionAttributeSmartLabels = "DescriptionAttributeSmartLabels"; + + public const string DescriptionAttributeSeries_SmartLabels = "DescriptionAttributeSeries_SmartLabels"; + + public const string DescriptionAttributeSmartLabels_SmartLabels = "DescriptionAttributeSmartLabels_SmartLabels"; + + public const string DescriptionAttributeMinorTickMark = "DescriptionAttributeMinorTickMark"; + + public const string DescriptionAttributeMapAreasCollection_MapAreasCollection = "DescriptionAttributeMapAreasCollection_MapAreasCollection"; + + public const string DescriptionAttributeMovingDirection = "DescriptionAttributeMovingDirection"; + + public const string DescriptionAttributeCursor_UserSelection = "DescriptionAttributeCursor_UserSelection"; + + public const string DescriptionAttributeChartArea = "DescriptionAttributeChartArea"; + + public const string DescriptionAttributeSeries_ChartArea = "DescriptionAttributeSeries_ChartArea"; + + public const string DescriptionAttributeChartArea_ChartArea = "DescriptionAttributeChartArea_ChartArea"; + + public const string DescriptionAttributeToolTipEventArgs_HitTestResult = "DescriptionAttributeToolTipEventArgs_HitTestResult"; + + public const string DescriptionAttributeAxisScaleSegment_AxisScaleSegment = "DescriptionAttributeAxisScaleSegment_AxisScaleSegment"; + + public const string DescriptionAttributeLegend_ItemColumnSeparatorColor = "DescriptionAttributeLegend_ItemColumnSeparatorColor"; + + public const string DescriptionAttributeDataManipulator = "DescriptionAttributeDataManipulator"; + + public const string DescriptionAttributeTitle_Color = "DescriptionAttributeTitle_Color"; + + public const string DescriptionAttributeLegendItem_Color = "DescriptionAttributeLegendItem_Color"; + + public const string DescriptionAttributeColor4 = "DescriptionAttributeColor4"; + + public const string DescriptionAttributeMargins_Right = "DescriptionAttributeMargins_Right"; + + public const string DescriptionAttributeRight3 = "DescriptionAttributeRight3"; + + public const string DescriptionAttributeChart_OnBackPaint = "DescriptionAttributeChart_OnBackPaint"; + + public const string DescriptionAttributeLineColor = "DescriptionAttributeLineColor"; + + public const string DescriptionAttributeCalloutLineColor = "DescriptionAttributeCalloutLineColor"; + + public const string DescriptionAttributeArrowAnnotation_ArrowStyle = "DescriptionAttributeArrowAnnotation_ArrowStyle"; + + public const string DescriptionAttributeArrowStyle_ArrowStyle = "DescriptionAttributeArrowStyle_ArrowStyle"; + + public const string DescriptionAttributeSeries_XValueType = "DescriptionAttributeSeries_XValueType"; + + public const string DescriptionAttributeAnnotationGroup_Annotations = "DescriptionAttributeAnnotationGroup_Annotations"; + + public const string DescriptionAttributeAnnotations3 = "DescriptionAttributeAnnotations3"; + + public const string DescriptionAttributeMinorGrid = "DescriptionAttributeMinorGrid"; + + public const string DescriptionAttributeMapArea_Custom = "DescriptionAttributeMapArea_Custom"; + + public const string DescriptionAttributeChart_EnableViewState = "DescriptionAttributeChart_EnableViewState"; + + public const string DescriptionAttributeChartArea3DStyle_Enable3D = "DescriptionAttributeChartArea3DStyle_Enable3D"; + + public const string DescriptionAttributeInterlacedColor = "DescriptionAttributeInterlacedColor"; + + public const string DescriptionAttributeLegendCellColumn_Margins = "DescriptionAttributeLegendCellColumn_Margins"; + + public const string DescriptionAttributeMargins_Margins = "DescriptionAttributeMargins_Margins"; + + public const string DescriptionAttributeLegendCell_Margins = "DescriptionAttributeLegendCell_Margins"; + + public const string DescriptionAttributeLegendItem_MarkerColor = "DescriptionAttributeLegendItem_MarkerColor"; + + public const string DescriptionAttributeMarkerColor3 = "DescriptionAttributeMarkerColor3"; + + public const string DescriptionAttributeChart_Size = "DescriptionAttributeChart_Size"; + + public const string DescriptionAttributeTickMark_Size = "DescriptionAttributeTickMark_Size"; + + public const string DescriptionAttributeAxisScaleSegment_Size = "DescriptionAttributeAxisScaleSegment_Size"; + + public const string DescriptionAttributeAxisDataView_Size = "DescriptionAttributeAxisDataView_Size"; + + public const string DescriptionAttributeAxisScrollBar_Size = "DescriptionAttributeAxisScrollBar_Size"; + + public const string DescriptionAttributeViewEventArgs_NewSize = "DescriptionAttributeViewEventArgs_NewSize"; + + public const string DescriptionAttributeSeries_XAxisType = "DescriptionAttributeSeries_XAxisType"; + + public const string DescriptionAttributeAllowOutsidePlotArea = "DescriptionAttributeAllowOutsidePlotArea"; + + public const string DescriptionAttributeLegendItem_MarkerStyle = "DescriptionAttributeLegendItem_MarkerStyle"; + + public const string DescriptionAttributeMarkerStyle4 = "DescriptionAttributeMarkerStyle4"; + + public const string DescriptionAttributeLegendCell_ImageSize = "DescriptionAttributeLegendCell_ImageSize"; + + public const string DescriptionAttributeView = "DescriptionAttributeView"; + + public const string DescriptionAttributeSeriesCollection_SeriesCollection = "DescriptionAttributeSeriesCollection_SeriesCollection"; + + public const string DescriptionAttributeCursorEventArgs_NewPosition = "DescriptionAttributeCursorEventArgs_NewPosition"; + + public const string DescriptionAttributeViewEventArgs_NewPosition = "DescriptionAttributeViewEventArgs_NewPosition"; + + public const string DescriptionAttributeLegendCell_Image = "DescriptionAttributeLegendCell_Image"; + + public const string DescriptionAttributeNamedImage_Image = "DescriptionAttributeNamedImage_Image"; + + public const string DescriptionAttributeImageAnnotation_Image = "DescriptionAttributeImageAnnotation_Image"; + + public const string DescriptionAttributeLegendItem_Image = "DescriptionAttributeLegendItem_Image"; + + public const string DescriptionAttributeCustomLabel_Image = "DescriptionAttributeCustomLabel_Image"; + + public const string DescriptionAttributeAxisScaleSegment_IntervalOffset = "DescriptionAttributeAxisScaleSegment_IntervalOffset"; + + public const string DescriptionAttributeIntervalOffset3 = "DescriptionAttributeIntervalOffset3"; + + public const string DescriptionAttributeLabel_IntervalOffset = "DescriptionAttributeLabel_IntervalOffset"; + + public const string DescriptionAttributeCursor_IntervalOffset = "DescriptionAttributeCursor_IntervalOffset"; + + public const string DescriptionAttributeIntervalOffset6 = "DescriptionAttributeIntervalOffset6"; + + public const string DescriptionAttributeStripLine_IntervalOffset = "DescriptionAttributeStripLine_IntervalOffset"; + + public const string DescriptionAttributeLegend_DockInsideChartArea = "DescriptionAttributeLegend_DockInsideChartArea"; + + public const string DescriptionAttributeTitle_DockInsideChartArea = "DescriptionAttributeTitle_DockInsideChartArea"; + + public const string DescriptionAttributeChart_RenderType = "DescriptionAttributeChart_RenderType"; + + public const string DescriptionAttributeAxisScaleBreakStyle_CollapsibleSpaceThreshold = "DescriptionAttributeAxisScaleBreakStyle_CollapsibleSpaceThreshold"; + + public const string DescriptionAttributeChartEvent_AxisViewChanging = "DescriptionAttributeChartEvent_AxisViewChanging"; + + public const string DescriptionAttributeLabelCalloutStyle_LabelCalloutStyle = "DescriptionAttributeLabelCalloutStyle_LabelCalloutStyle"; + + public const string DescriptionAttributePath = "DescriptionAttributePath"; + + public const string DescriptionAttributeLegendItem_SeriesPointIndex = "DescriptionAttributeLegendItem_SeriesPointIndex"; + + public const string DescriptionAttributeMapAreas = "DescriptionAttributeMapAreas"; + + public const string DescriptionAttributeTickMark_TickMark = "DescriptionAttributeTickMark_TickMark"; + + public const string DescriptionAttributeLegendCellColumn_LegendCellColumn = "DescriptionAttributeLegendCellColumn_LegendCellColumn"; + + public const string DescriptionAttributeLegendItem_LegendItem = "DescriptionAttributeLegendItem_LegendItem"; + + public const string DescriptionAttributeTitleAlignment = "DescriptionAttributeTitleAlignment"; + + public const string DescriptionAttributeStripLine_TitleAlignment = "DescriptionAttributeStripLine_TitleAlignment"; + + public const string DescriptionAttributeLegend_TitleAlignment = "DescriptionAttributeLegend_TitleAlignment"; + + public const string DescriptionAttributeElementPosition_ElementPosition = "DescriptionAttributeElementPosition_ElementPosition"; + + public const string DescriptionAttributeCustomLabel_To = "DescriptionAttributeCustomLabel_To"; + + public const string DescriptionAttributeLabel_FontAngle = "DescriptionAttributeLabel_FontAngle"; + + public const string DescriptionAttributeIntervalAutoMode = "DescriptionAttributeIntervalAutoMode"; + + public const string DescriptionAttributeStripLine_StripWidth = "DescriptionAttributeStripLine_StripWidth"; + + public const string DescriptionAttributeCursor_UserEnabled = "DescriptionAttributeCursor_UserEnabled"; + + public const string DescriptionAttributeBorderSkin_FrameBorderWidth = "DescriptionAttributeBorderSkin_FrameBorderWidth"; + + public const string DescriptionAttributeAxisScaleSegment_Position = "DescriptionAttributeAxisScaleSegment_Position"; + + public const string DescriptionAttributeAxisDataView_Position = "DescriptionAttributeAxisDataView_Position"; + + public const string DescriptionAttributeTitle_Position = "DescriptionAttributeTitle_Position"; + + public const string DescriptionAttributeLegend_Position = "DescriptionAttributeLegend_Position"; + + public const string DescriptionAttributeChartArea_Position = "DescriptionAttributeChartArea_Position"; + + public const string DescriptionAttributeCursor_Position = "DescriptionAttributeCursor_Position"; + + public const string DescriptionAttributeSubAxis_ParentAxis = "DescriptionAttributeSubAxis_ParentAxis"; + + public const string DescriptionAttributeAnnotationCollectionEditor_AnnotationCollectionEditor = "DescriptionAttributeAnnotationCollectionEditor_AnnotationCollectionEditor"; + + public const string DescriptionAttributeBottom = "DescriptionAttributeBottom"; + + public const string DescriptionAttributeMargins_Bottom = "DescriptionAttributeMargins_Bottom"; + + public const string DescriptionAttributeAxisScaleBreakStyle_AxisScaleBreakStyle = "DescriptionAttributeAxisScaleBreakStyle_AxisScaleBreakStyle"; + + public const string DescriptionAttributeLegend_HeaderSeparator = "DescriptionAttributeLegend_HeaderSeparator"; + + public const string DescriptionAttributeChartArea3DStyle_PointDepth = "DescriptionAttributeChartArea3DStyle_PointDepth"; + + public const string DescriptionAttributeAnnotationGroup_AnnotationGroup = "DescriptionAttributeAnnotationGroup_AnnotationGroup"; + + public const string DescriptionAttributeAnnotationPathPointCollection_AnnotationPathPointCollection = "DescriptionAttributeAnnotationPathPointCollection_AnnotationPathPointCollection"; + + public const string DescriptionAttributeStripLine_StripWidthType = "DescriptionAttributeStripLine_StripWidthType"; + + public const string DescriptionAttributeCustomLabel_From = "DescriptionAttributeCustomLabel_From"; + + public const string DescriptionAttributePoint3D_PointF = "DescriptionAttributePoint3D_PointF"; + + public const string DescriptionAttributeBorderWidth = "DescriptionAttributeBorderWidth"; + + public const string DescriptionAttributeMarkerBorderWidth = "DescriptionAttributeMarkerBorderWidth"; + + public const string DescriptionAttributeCursor_SelectionEnd = "DescriptionAttributeCursor_SelectionEnd"; + + public const string DescriptionAttributeLineAnnotation_LineAnnotation = "DescriptionAttributeLineAnnotation_LineAnnotation"; + + public const string DescriptionAttributeAnnotationSmartLabels_AnnotationSmartLabels = "DescriptionAttributeAnnotationSmartLabels_AnnotationSmartLabels"; + + public const string DescriptionAttributeAnnotationGroup_Visible = "DescriptionAttributeAnnotationGroup_Visible"; + + public const string DescriptionAttributeChartArea_Visible = "DescriptionAttributeChartArea_Visible"; + + public const string DescriptionAttributeTitle_Visible = "DescriptionAttributeTitle_Visible"; + + public const string DescriptionAttributeVisible = "DescriptionAttributeVisible"; + + public const string DescriptionAttributeLegendItem_Separator = "DescriptionAttributeLegendItem_Separator"; + + public const string DescriptionAttributeLegendCell_CellType = "DescriptionAttributeLegendCell_CellType"; + + public const string DescriptionAttributeChart_Serializer = "DescriptionAttributeChart_Serializer"; + + public const string DescriptionAttributeAxisX = "DescriptionAttributeAxisX"; + + public const string DescriptionAttributeChartArea_AxisX = "DescriptionAttributeChartArea_AxisX"; + + public const string DescriptionAttributeImageType = "DescriptionAttributeImageType"; + + public const string DescriptionAttributeCursor_SelectionStart = "DescriptionAttributeCursor_SelectionStart"; + + public const string DescriptionAttributeLabelsAutoFit = "DescriptionAttributeLabelsAutoFit"; + + public const string DescriptionAttributeLegendCellColumn_HeaderText = "DescriptionAttributeLegendCellColumn_HeaderText"; + + public const string DescriptionAttributeMapEnabled = "DescriptionAttributeMapEnabled"; + + public const string DescriptionAttributeAxisDataView_Zoomable = "DescriptionAttributeAxisDataView_Zoomable"; + + public const string DescriptionAttributeDataManager_PaletteCustomColors = "DescriptionAttributeDataManager_PaletteCustomColors"; + + public const string DescriptionAttributeChart_PaletteCustomColors = "DescriptionAttributeChart_PaletteCustomColors"; + + public const string DescriptionAttributeLegend_ItemColumnSeparator = "DescriptionAttributeLegend_ItemColumnSeparator"; + + public const string DescriptionAttributeCursorEventArgs_NewSelectionEnd = "DescriptionAttributeCursorEventArgs_NewSelectionEnd"; + + public const string DescriptionAttributeLegendItem_SeriesName = "DescriptionAttributeLegendItem_SeriesName"; + + public const string DescriptionAttributeChartAreas = "DescriptionAttributeChartAreas"; + + public const string DescriptionAttributeChartArea_AlignWithChartArea = "DescriptionAttributeChartArea_AlignWithChartArea"; + + public const string DescriptionAttributeLegend_MaxAutoSize = "DescriptionAttributeLegend_MaxAutoSize"; + + public const string DescriptionAttributeAxis_MaxAutoSize = "DescriptionAttributeAxis_MaxAutoSize"; + + public const string DescriptionAttributeGrid_Grid = "DescriptionAttributeGrid_Grid"; + + public const string DescriptionAttributeChartArea_EquallySizedAxesFont = "DescriptionAttributeChartArea_EquallySizedAxesFont"; + + public const string DescriptionAttributeChartEvent_CustomizeMapAreas = "DescriptionAttributeChartEvent_CustomizeMapAreas"; + + public const string DescriptionAttributeChartArea3DStyle_WallWidth = "DescriptionAttributeChartArea3DStyle_WallWidth"; + + public const string DescriptionAttributeCustomLabel_Row = "DescriptionAttributeCustomLabel_Row"; + + public const string DescriptionAttributeLegend_TitleSeparatorColor = "DescriptionAttributeLegend_TitleSeparatorColor"; + + public const string DescriptionAttributeChartSerializer_TemplateMode = "DescriptionAttributeChartSerializer_TemplateMode"; + + public const string DescriptionAttributeShadowColor = "DescriptionAttributeShadowColor"; + + public const string DescriptionAttributeAxisScaleBreakStyle_MaxNumberOfBreaks = "DescriptionAttributeAxisScaleBreakStyle_MaxNumberOfBreaks"; + + public const string DescriptionAttributeChartEvent_AxisScrollBarClicked = "DescriptionAttributeChartEvent_AxisScrollBarClicked"; + + public const string DescriptionAttributeAnchorY = "DescriptionAttributeAnchorY"; + + public const string DescriptionAttributeLegend_AutoFitMinFontSize = "DescriptionAttributeLegend_AutoFitMinFontSize"; + + public const string DescriptionAttributeChartEvent_AnnotationTextChanged = "DescriptionAttributeChartEvent_AnnotationTextChanged"; + + public const string DescriptionAttributeChart_Series = "DescriptionAttributeChart_Series"; + + public const string DescriptionAttributeSeries_Series = "DescriptionAttributeSeries_Series"; + + public const string DescriptionAttributeMapArea_Shape = "DescriptionAttributeMapArea_Shape"; + + public const string DescriptionAttributeLegend_TextWrapThreshold = "DescriptionAttributeLegend_TextWrapThreshold"; + + public const string DescriptionAttributeLabelOutsidePlotAreaStyle_LabelOutsidePlotAreaStyle = "DescriptionAttributeLabelOutsidePlotAreaStyle_LabelOutsidePlotAreaStyle"; + + public const string DescriptionAttributeSubAxes = "DescriptionAttributeSubAxes"; + + public const string DescriptionAttributeAxisScaleBreakStyle_StartFromZero = "DescriptionAttributeAxisScaleBreakStyle_StartFromZero"; + + public const string DescriptionAttributeStartFromZero3 = "DescriptionAttributeStartFromZero3"; + + public const string DescriptionAttributeRectangleAnnotation_RectangleAnnotation = "DescriptionAttributeRectangleAnnotation_RectangleAnnotation"; + + public const string DescriptionAttributeUrl = "DescriptionAttributeUrl"; + + public const string DescriptionAttributeAxisScaleBreakStyle_BreakLineType = "DescriptionAttributeAxisScaleBreakStyle_BreakLineType"; + + public const string DescriptionAttributeChartEvent_CursorPositionChanged = "DescriptionAttributeChartEvent_CursorPositionChanged"; + + public const string DescriptionAttributeChartSerializer_SerializableContent = "DescriptionAttributeChartSerializer_SerializableContent"; + + public const string DescriptionAttributeCalloutAnnotation_CalloutStyle = "DescriptionAttributeCalloutAnnotation_CalloutStyle"; + + public const string DescriptionAttributeCalloutStyle3 = "DescriptionAttributeCalloutStyle3"; + + public const string DescriptionAttributeCalloutStyle_CalloutStyle = "DescriptionAttributeCalloutStyle_CalloutStyle"; + + public const string DescriptionAttributeTitle_Docking = "DescriptionAttributeTitle_Docking"; + + public const string DescriptionAttributeLegend_Docking = "DescriptionAttributeLegend_Docking"; + + public const string DescriptionAttributeAnnotationGroup_AllowAnchorMoving = "DescriptionAttributeAnnotationGroup_AllowAnchorMoving"; + + public const string DescriptionAttributeAllowAnchorMoving3 = "DescriptionAttributeAllowAnchorMoving3"; + + public const string DescriptionAttributeTitleColor = "DescriptionAttributeTitleColor"; + + public const string DescriptionAttributeStripLine_TitleColor = "DescriptionAttributeStripLine_TitleColor"; + + public const string DescriptionAttributeLegend_TitleColor = "DescriptionAttributeLegend_TitleColor"; + + public const string DescriptionAttributeTitles = "DescriptionAttributeTitles"; + + public const string DescriptionAttributePolygonAnnotation_PolygonAnnotation = "DescriptionAttributePolygonAnnotation_PolygonAnnotation"; + + public const string DescriptionAttributeLabel_IntervalType = "DescriptionAttributeLabel_IntervalType"; + + public const string DescriptionAttributeIntervalType3 = "DescriptionAttributeIntervalType3"; + + public const string DescriptionAttributeIntervalType4 = "DescriptionAttributeIntervalType4"; + + public const string DescriptionAttributeStripLine_IntervalType = "DescriptionAttributeStripLine_IntervalType"; + + public const string DescriptionAttributeAxisScaleSegment_IntervalType = "DescriptionAttributeAxisScaleSegment_IntervalType"; + + public const string DescriptionAttributeCursor_IntervalType = "DescriptionAttributeCursor_IntervalType"; + + public const string DescriptionAttributeLegendItem_SeparatorColor = "DescriptionAttributeLegendItem_SeparatorColor"; + + public const string DescriptionAttributeSeries_YValuesPerPoint = "DescriptionAttributeSeries_YValuesPerPoint"; + + public const string DescriptionAttributeChartEvent_PrePaint = "DescriptionAttributeChartEvent_PrePaint"; + + public const string DescriptionAttributeLegendUrl = "DescriptionAttributeLegendUrl"; + + public const string DescriptionAttributeCustomLabel_ImageUrl = "DescriptionAttributeCustomLabel_ImageUrl"; + + public const string DescriptionAttributeLabel_Format = "DescriptionAttributeLabel_Format"; + + public const string DescriptionAttributeChartSerializer_Format = "DescriptionAttributeChartSerializer_Format"; + + public const string DescriptionAttributeStripLines = "DescriptionAttributeStripLines"; + + public const string DescriptionAttributeChart_ViewStateData = "DescriptionAttributeChart_ViewStateData"; + + public const string DescriptionAttributeTitle_DockOffset = "DescriptionAttributeTitle_DockOffset"; + + public const string DescriptionAttributeAnchorDataPoint = "DescriptionAttributeAnchorDataPoint"; + + public const string DescriptionAttributeLabelFormat = "DescriptionAttributeLabelFormat"; + + public const string DescriptionAttributeSuppressExceptions = "DescriptionAttributeSuppressExceptions"; + + public const string DescriptionAttributeSeries_EmptyPointStyle = "DescriptionAttributeSeries_EmptyPointStyle"; + + public const string DescriptionAttributeCustomAttributes = "DescriptionAttributeCustomAttributes"; + + public const string DescriptionAttributeLegendCellCollection_LegendCellCollection = "DescriptionAttributeLegendCellCollection_LegendCellCollection"; + + public const string DescriptionAttributeCustomLabelsCollection_CustomLabelsCollection = "DescriptionAttributeCustomLabelsCollection_CustomLabelsCollection"; + + public const string DescriptionAttributeCustomLabel_MarkColor = "DescriptionAttributeCustomLabel_MarkColor"; + + public const string DescriptionAttributePalette = "DescriptionAttributePalette"; + + public const string DescriptionAttributeScaleBreakStyle = "DescriptionAttributeScaleBreakStyle"; + + public const string DescriptionAttributeChart_ImageUrl = "DescriptionAttributeChart_ImageUrl"; + + public const string DescriptionAttributeLegend_InterlacedRowsColor = "DescriptionAttributeLegend_InterlacedRowsColor"; + + public const string DescriptionAttributeLegendCellColumn_ColumnType = "DescriptionAttributeLegendCellColumn_ColumnType"; + + public const string DescriptionAttributeChartArea_AlignOrientation = "DescriptionAttributeChartArea_AlignOrientation"; + + public const string DescriptionAttributeChart_SoftShadows = "DescriptionAttributeChart_SoftShadows"; + + public const string DescriptionAttributeSoftShadows3 = "DescriptionAttributeSoftShadows3"; + + public const string DescriptionAttributePrintingManager_PrintDocument = "DescriptionAttributePrintingManager_PrintDocument"; + + public const string DescriptionAttributeMinimum = "DescriptionAttributeMinimum"; + + public const string DescriptionAttributeAxisScaleSegment_ScaleMaximum = "DescriptionAttributeAxisScaleSegment_ScaleMaximum"; + + public const string DescriptionAttributeScrollBarEventArgs_MousePositionX = "DescriptionAttributeScrollBarEventArgs_MousePositionX"; + + public const string DescriptionAttributeLabel_TruncatedLabels = "DescriptionAttributeLabel_TruncatedLabels"; + + public const string DescriptionAttributeCustomLabel_GridTicks = "DescriptionAttributeCustomLabel_GridTicks"; + + public const string DescriptionAttributeImageAnnotation_Alignment = "DescriptionAttributeImageAnnotation_Alignment"; + + public const string DescriptionAttributeLegendCellColumn_Alignment = "DescriptionAttributeLegendCellColumn_Alignment"; + + public const string DescriptionAttributeTitle_Alignment = "DescriptionAttributeTitle_Alignment"; + + public const string DescriptionAttributeLegendCell_Alignment = "DescriptionAttributeLegendCell_Alignment"; + + public const string DescriptionAttributeLegend_Alignment = "DescriptionAttributeLegend_Alignment"; + + public const string DescriptionAttributeAlignment = "DescriptionAttributeAlignment"; + + public const string DescriptionAttributeChart_OnCustomizeMapAreas = "DescriptionAttributeChart_OnCustomizeMapAreas"; + + public const string DescriptionAttributeSubAxis_LocationOffset = "DescriptionAttributeSubAxis_LocationOffset"; + + public const string DescriptionAttributeLegendCellColumn_MinimumWidth = "DescriptionAttributeLegendCellColumn_MinimumWidth"; + + public const string DescriptionAttributeSelectionPointsStyle = "DescriptionAttributeSelectionPointsStyle"; + + public const string DescriptionAttributeAxisY = "DescriptionAttributeAxisY"; + + public const string DescriptionAttributeChartArea_AxisY = "DescriptionAttributeChartArea_AxisY"; + + public const string DescriptionAttributeTextFont = "DescriptionAttributeTextFont"; + + public const string DescriptionAttributeTextFont4 = "DescriptionAttributeTextFont4"; + + public const string DescriptionAttributeAxisDataView_SizeType = "DescriptionAttributeAxisDataView_SizeType"; + + public const string DescriptionAttributeMinMovingDistance = "DescriptionAttributeMinMovingDistance"; + + public const string DescriptionAttributeChartArea_CursorX = "DescriptionAttributeChartArea_CursorX"; + + public const string DescriptionAttributeAxisDataView_SmallScrollMinSize = "DescriptionAttributeAxisDataView_SmallScrollMinSize"; + + public const string DescriptionAttributeAxisDataView_SmallScrollMinSizeType = "DescriptionAttributeAxisDataView_SmallScrollMinSizeType"; + + public const string DescriptionAttributeAxisScrollBar_ButtonColor = "DescriptionAttributeAxisScrollBar_ButtonColor"; + + public const string DescriptionAttributeArea3DStyle = "DescriptionAttributeArea3DStyle"; + + public const string DescriptionAttributeChart = "DescriptionAttributeChart"; + + public const string DescriptionAttributeChart_Chart = "DescriptionAttributeChart_Chart"; + + public const string DescriptionAttributeBorderSkin_PageColor = "DescriptionAttributeBorderSkin_PageColor"; + + public const string DescriptionAttributeDataPoint_DataPoint = "DescriptionAttributeDataPoint_DataPoint"; + + public const string DescriptionAttributeChartArea3DStyle_Light = "DescriptionAttributeChartArea3DStyle_Light"; + + public const string DescriptionAttributeDataPointCustomProperties_DataPointCustomProperties = "DescriptionAttributeDataPointCustomProperties_DataPointCustomProperties"; + + public const string DescriptionAttributeLegend_AutoFitText = "DescriptionAttributeLegend_AutoFitText"; + + public const string DescriptionAttributeAllowTextEditing = "DescriptionAttributeAllowTextEditing"; + + public const string DescriptionAttributeCustomLabel_Text = "DescriptionAttributeCustomLabel_Text"; + + public const string DescriptionAttributeLegendCell_Text = "DescriptionAttributeLegendCell_Text"; + + public const string DescriptionAttributeText = "DescriptionAttributeText"; + + public const string DescriptionAttributeTitle_Text = "DescriptionAttributeTitle_Text"; + + public const string DescriptionAttributeLegendCellColumn_Text = "DescriptionAttributeLegendCellColumn_Text"; + + public const string DescriptionAttributeToolTipEventArgs_Text = "DescriptionAttributeToolTipEventArgs_Text"; + + public const string DescriptionAttributeMultiline = "DescriptionAttributeMultiline"; + + public const string DescriptionAttributeTextAnnotation_TextAnnotation = "DescriptionAttributeTextAnnotation_TextAnnotation"; + + public const string DescriptionAttributeAnnotationGroup_ClipToChartArea = "DescriptionAttributeAnnotationGroup_ClipToChartArea"; + + public const string DescriptionAttributeSeries_YValueType = "DescriptionAttributeSeries_YValueType"; + + public const string DescriptionAttributeInternalIntervalType = "DescriptionAttributeInternalIntervalType"; + + public const string DescriptionAttributeCalloutAnnotation_CalloutAnchorCap = "DescriptionAttributeCalloutAnnotation_CalloutAnchorCap"; + + public const string DescriptionAttributeLogarithmic = "DescriptionAttributeLogarithmic"; + + public const string DescriptionAttributeLegend_ItemColumnSpacing = "DescriptionAttributeLegend_ItemColumnSpacing"; + + public const string DescriptionAttributeMarksNextToAxis = "DescriptionAttributeMarksNextToAxis"; + + public const string DescriptionAttributeChartEvent_SelectionRangeChanged = "DescriptionAttributeChartEvent_SelectionRangeChanged"; + + public const string DescriptionAttributeDataPointCollection_DataPointCollection = "DescriptionAttributeDataPointCollection_DataPointCollection"; + + public const string DescriptionAttributeHorizontalLineAnnotation_HorizontalLineAnnotation = "DescriptionAttributeHorizontalLineAnnotation_HorizontalLineAnnotation"; + + public const string DescriptionAttributeLegendCellColumn_HeaderColor = "DescriptionAttributeLegendCellColumn_HeaderColor"; + + public const string DescriptionAttributeLegendCell_LegendCell = "DescriptionAttributeLegendCell_LegendCell"; + + public const string DescriptionAttributeChartImageDescriptionUrl = "DescriptionAttributeChartImageDescriptionUrl"; + + public const string DescriptionAttributeChartImageAlternateText = "DescriptionAttributeChartImageAlternateText"; + + public const string DescriptionAttributePostBackValue = "DescriptionAttributePostBackValue"; + + public const string DescriptionAttributeTextStyle = "DescriptionAttributeTextStyle"; + + public const string DescriptionAttributeIsMapAreaAttributesEncoded = "DescriptionAttributeIsMapAreaAttributesEncoded"; + + public const string DescriptionAttributeRightToLeft = "DescriptionAttributeRightToLeft"; + + public const string CategoryAttributeCellColumns = "CategoryAttributeCellColumns"; + + public const string CategoryAttributeAxis = "CategoryAttributeAxis"; + + public const string CategoryAttributeEditing = "CategoryAttributeEditing"; + + public const string CategoryAttributeSize = "CategoryAttributeSize"; + + public const string CategoryAttributePosition = "CategoryAttributePosition"; + + public const string CategoryAttributeViewState = "CategoryAttributeViewState"; + + public const string CategoryAttributeInterval = "CategoryAttributeInterval"; + + public const string CategoryAttributeAppearance = "CategoryAttributeAppearance"; + + public const string CategoryAttributeDocking = "CategoryAttributeDocking"; + + public const string CategoryAttributeDataSource = "CategoryAttributeDataSource"; + + public const string CategoryAttributeAxisView = "CategoryAttributeAxisView"; + + public const string CategoryAttributeLayout = "CategoryAttributeLayout"; + + public const string CategoryAttribute3D = "CategoryAttribute3D"; + + public const string CategoryAttributeData = "CategoryAttributeData"; + + public const string CategoryAttributeTitle = "CategoryAttributeTitle"; + + public const string CategoryAttributeToolTips = "CategoryAttributeToolTips"; + + public const string CategoryAttributeLabels = "CategoryAttributeLabels"; + + public const string CategoryAttributeGridTickMarks = "CategoryAttributeGridTickMarks"; + + public const string CategoryAttributeLabelAppearance = "CategoryAttributeLabelAppearance"; + + public const string CategoryAttributeHeader = "CategoryAttributeHeader"; + + public const string CategoryAttributeAxes = "CategoryAttributeAxes"; + + public const string CategoryAttributeImage = "CategoryAttributeImage"; + + public const string CategoryAttributeEmptyPoints = "CategoryAttributeEmptyPoints"; + + public const string CategoryAttributeAlignment = "CategoryAttributeAlignment"; + + public const string CategoryAttributeAnnotation = "CategoryAttributeAnnotation"; + + public const string CategoryAttributeMarker = "CategoryAttributeMarker"; + + public const string CategoryAttributeChart = "CategoryAttributeChart"; + + public const string CategoryAttributeLocation = "CategoryAttributeLocation"; + + public const string CategoryAttributeToolTip = "CategoryAttributeToolTip"; + + public const string CategoryAttributeMap = "CategoryAttributeMap"; + + public const string CategoryAttributeMapArea = "CategoryAttributeMapArea"; + + public const string CategoryAttributeLabel = "CategoryAttributeLabel"; + + public const string CategoryAttributeShape = "CategoryAttributeShape"; + + public const string CategoryAttributeMisc = "CategoryAttributeMisc"; + + public const string CategoryAttributeSerializer = "CategoryAttributeSerializer"; + + public const string CategoryAttributeSubAxes = "CategoryAttributeSubAxes"; + + public const string CategoryAttributeSeriesItems = "CategoryAttributeSeriesItems"; + + public const string CategoryAttributeDataView = "CategoryAttributeDataView"; + + public const string CategoryAttributeCharttitle = "CategoryAttributeCharttitle"; + + public const string CategoryAttributeLegend = "CategoryAttributeLegend"; + + public const string CategoryAttributeAction = "CategoryAttributeAction"; + + public const string CategoryAttributeScale = "CategoryAttributeScale"; + + public const string CategoryAttributeAnnotations = "CategoryAttributeAnnotations"; + + public const string CategoryAttributeAnchor = "CategoryAttributeAnchor"; + + public const string CategoryAttributeBehavior = "CategoryAttributeBehavior"; + + public const string CategoryAttributeCursor = "CategoryAttributeCursor"; + + public const string CategoryAttributeAnchorAxes = "CategoryAttributeAnchorAxes"; + + public const string CategoryAttributeAccessibility = "CategoryAttributeAccessibility"; + + public const string AccessibilityTitleName = "AccessibilityTitleName"; + + public const string AccessibilityAnnotationName = "AccessibilityAnnotationName"; + + public const string AccessibilityLegendName = "AccessibilityLegendName"; + + public const string AccessibilitySeriesName = "AccessibilitySeriesName"; + + public const string AccessibilityDataPointName = "AccessibilityDataPointName"; + + public const string AccessibilityDataPointLabelName = "AccessibilityDataPointLabelName"; + + public const string AccessibilityLegendTitleName = "AccessibilityLegendTitleName"; + + public const string AccessibilityChartAreaName = "AccessibilityChartAreaName"; + + public const string AccessibilityChartAxisTitleName = "AccessibilityChartAxisTitleName"; + + public const string AccessibilityChartAxisMajorGridlinesName = "AccessibilityChartAxisMajorGridlinesName"; + + public const string AccessibilityChartAxisMinorGridlinesName = "AccessibilityChartAxisMinorGridlinesName"; + + public const string FormatErrorString = "FormatErrorString"; + + public const string ExceptionNameIsEmpty = "ExceptionNameIsEmpty"; + + public const string ExceptionNameAlreadyExistsInCollection = "ExceptionNameAlreadyExistsInCollection"; + + public const string ExceptionNameNotFound = "ExceptionNameNotFound"; + + public const string ActionListSeriesChartType = "ActionListSeriesChartType"; + + public const string ActionListSeriesDataGroup = "ActionListSeriesDataGroup"; + + public const string ActionListSeriesXValueMember = "ActionListSeriesXValueMember"; + + public const string ActionListSeriesYValueMembers = "ActionListSeriesYValueMembers"; + + public const string DiagnosticHeader = "DiagnosticHeader"; + + public const string DiagnosticSettingsConfig = "DiagnosticSettingsConfig"; + + public const string DiagnosticSettingsHeader = "DiagnosticSettingsHeader"; + + public const string DiagnosticSettingsKey = "DiagnosticSettingsKey"; + + public const string DiagnosticSettingsValue = "DiagnosticSettingsValue"; + + public const string DiagnosticSettingsInfo = "DiagnosticSettingsInfo"; + + public const string DiagnosticQueueStateHeader = "DiagnosticQueueStateHeader"; + + public const string DiagnosticQueueStateName = "DiagnosticQueueStateName"; + + public const string DiagnosticQueueStateAccess = "DiagnosticQueueStateAccess"; + + public const string DiagnosticQueueStateAccessOK = "DiagnosticQueueStateAccessOK"; + + public const string DiagnosticQueueStateAccessFail = "DiagnosticQueueStateAccessFail"; + + public const string DiagnosticQueueStateAccessInfo = "DiagnosticQueueStateAccessInfo"; + + public const string DiagnosticActivityHeader = "DiagnosticActivityHeader"; + + public const string DiagnosticActivityTime = "DiagnosticActivityTime"; + + public const string DiagnosticActivityMessage = "DiagnosticActivityMessage"; + + public const string DiagnosticActivityError = "DiagnosticActivityError"; + + public const string DiagnosticChartImageSaved = "DiagnosticChartImageSaved"; + + public const string DiagnosticChartImageSavedPrivate = "DiagnosticChartImageSavedPrivate"; + + public const string DiagnosticChartImageDeleted = "DiagnosticChartImageDeleted"; + + public const string DiagnosticChartImageServed = "DiagnosticChartImageServed"; + + public const string DiagnosticChartImageServedFail = "DiagnosticChartImageServedFail"; + + public const string DiagnosticChartImageServedFailNotFound = "DiagnosticChartImageServedFailNotFound"; + + public const string DiagnosticChartImageServedFailPrivacyFail = "DiagnosticChartImageServedFailPrivacyFail"; + + private Keys() + { + } + + public static CultureInfo Culture + { + get + { + return _culture; + } + set + { + _culture = value; + } + } + + public static string GetString(string key) + { + return resourceManager.GetString(key, _culture); + } + + public static string GetString(string key, object arg0) + { + return string.Format(global::System.Globalization.CultureInfo.CurrentCulture, resourceManager.GetString(key, _culture), arg0); + } + + public static string GetString(string key, object arg0, object arg1) + { + return string.Format(global::System.Globalization.CultureInfo.CurrentCulture, resourceManager.GetString(key, _culture), arg0, arg1); + } + + public static string GetString(string key, object arg0, object arg1, object arg2) + { + return string.Format(global::System.Globalization.CultureInfo.CurrentCulture, resourceManager.GetString(key, _culture), arg0, arg1, arg2); + } + } + } +} diff --git a/System.Web.DataVisualization/Common/SRCategoryAttribute.cs b/System.Web.DataVisualization/Common/SRCategoryAttribute.cs new file mode 100644 index 000000000..7020a508d --- /dev/null +++ b/System.Web.DataVisualization/Common/SRCategoryAttribute.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + [AttributeUsage(AttributeTargets.All)] + internal sealed class SRCategoryAttribute : CategoryAttribute + { + // Methods + public SRCategoryAttribute(string category) + : base(category) + { + } + + protected override string GetLocalizedString(string value) + { + return SR.Keys.GetString(value); + } + } +} diff --git a/System.Web.DataVisualization/Common/SRDescriptionAttribute.cs b/System.Web.DataVisualization/Common/SRDescriptionAttribute.cs new file mode 100644 index 000000000..590dfbd61 --- /dev/null +++ b/System.Web.DataVisualization/Common/SRDescriptionAttribute.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +#if Microsoft_CONTROL +namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting +#endif +{ + [AttributeUsage(AttributeTargets.All)] + internal sealed class SRDescriptionAttribute : DescriptionAttribute + { + // Fields + private bool replaced; + + // Methods + public SRDescriptionAttribute(string description) + : base(description) + { + } + + // Properties + public override string Description + { + get + { + if (!this.replaced) + { + this.replaced = true; + base.DescriptionValue = SR.Keys.GetString(base.Description); + } + return base.Description; + } + } + } + + + +} diff --git a/System.Web.DataVisualization/Common/Utilities/ColorPalette.cs b/System.Web.DataVisualization/Common/Utilities/ColorPalette.cs new file mode 100644 index 000000000..639e6d73b --- /dev/null +++ b/System.Web.DataVisualization/Common/Utilities/ColorPalette.cs @@ -0,0 +1,396 @@ +//------------------------------------------------------------- +// <copyright company=’Microsoft Corporation’> +// Copyright © Microsoft Corporation. All Rights Reserved. +// </copyright> +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ColorPalette.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// System.Web.UI.WebControls[Windows.Forms].Charting.Utilities +// +// Classes: ChartPaletteColors +// +// Purpose: A utility class which defines chart palette colors. +// These palettes are used to assign unique colors to +// different chart series. For some chart types, like +// Pie, different colors are applied on the data point +// level. +// +// Selected chart series/points palette is exposed +// through Chart.Palette property. Series.Palette +// property should be used to set different palette +// color for each point of the series. +// +// Reviewed: AG - August 7, 2002 +// AG - Microsoft 5, 2007 +// +//=================================================================== + +#region Used Namespaces + +using System; +using System.Drawing; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web.UI.DataVisualization.Charting; +#endif +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + #region Color palettes enumeration + + /// <summary> + /// Chart color palettes enumeration + /// </summary> + public enum ChartColorPalette + { + /// <summary> + /// Palette not set. + /// </summary> + None, + + /// <summary> + /// Bright palette. + /// </summary> + Bright, + + /// <summary> + /// Palette with gray scale colors. + /// </summary> + Grayscale, + + /// <summary> + /// Palette with Excel style colors. + /// </summary> + Excel, + + /// <summary> + /// Palette with LightStyle style colors. + /// </summary> + Light, + + /// <summary> + /// Palette with Pastel style colors. + /// </summary> + Pastel, + + /// <summary> + /// Palette with Earth Tones style colors. + /// </summary> + EarthTones, + + /// <summary> + /// Palette with SemiTransparent style colors. + /// </summary> + SemiTransparent, + + /// <summary> + /// Palette with Berry style colors. + /// </summary> + Berry, + + /// <summary> + /// Palette with Chocolate style colors. + /// </summary> + Chocolate, + + /// <summary> + /// Palette with Fire style colors. + /// </summary> + Fire, + + /// <summary> + /// Palette with SeaGreen style colors. + /// </summary> + SeaGreen, + + /// <summary> + /// Bright pastel palette. + /// </summary> + BrightPastel + }; + + #endregion +} + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Utilities +#else + namespace System.Web.UI.DataVisualization.Charting.Utilities +#endif +{ + /// <summary> + /// ChartPaletteColors is a utility class which provides access + /// to the predefined chart color palettes. These palettes are + /// used to assign unique colors to different chart series. + /// For some chart types, like Pie, different colors are applied + /// on the data point level. + /// + /// GetPaletteColors method takes a ChartColorPalette enumeration + /// as a parameter and returns back an array of Colors. Each + /// palette contains different number of colors but it is a + /// good practice to keep this number around 15. + /// </summary> + internal static class ChartPaletteColors + { + #region Fields + + // Fields which store the palette color values + private static Color[] _colorsGrayScale = InitializeGrayScaleColors(); + private static Color[] _colorsDefault = { + Color.Green, + Color.Blue, + Color.Purple, + Color.Lime, + Color.Fuchsia, + Color.Teal, + Color.Yellow, + Color.Gray, + Color.Aqua, + Color.Navy, + Color.Maroon, + Color.Red, + Color.Olive, + Color.Silver, + Color.Tomato, + Color.Moccasin + }; + + private static Color[] _colorsPastel = { + Color.SkyBlue, + Color.LimeGreen, + Color.MediumOrchid, + Color.LightCoral, + Color.SteelBlue, + Color.YellowGreen, + Color.Turquoise, + Color.HotPink, + Color.Khaki, + Color.Tan, + Color.DarkSeaGreen, + Color.CornflowerBlue, + Color.Plum, + Color.CadetBlue, + Color.PeachPuff, + Color.LightSalmon + }; + + private static Color[] _colorsEarth = { + Color.FromArgb(255, 128, 0), + Color.DarkGoldenrod, + Color.FromArgb(192, 64, 0), + Color.OliveDrab, + Color.Peru, + Color.FromArgb(192, 192, 0), + Color.ForestGreen, + Color.Chocolate, + Color.Olive, + Color.LightSeaGreen, + Color.SandyBrown, + Color.FromArgb(0, 192, 0), + Color.DarkSeaGreen, + Color.Firebrick, + Color.SaddleBrown, + Color.FromArgb(192, 0, 0) + }; + + private static Color[] _colorsSemiTransparent = { + Color.FromArgb(150, 255, 0, 0), + Color.FromArgb(150, 0, 255, 0), + Color.FromArgb(150, 0, 0, 255), + Color.FromArgb(150, 255, 255, 0), + Color.FromArgb(150, 0, 255, 255), + Color.FromArgb(150, 255, 0, 255), + Color.FromArgb(150, 170, 120, 20), + Color.FromArgb(80, 255, 0, 0), + Color.FromArgb(80, 0, 255, 0), + Color.FromArgb(80, 0, 0, 255), + Color.FromArgb(80, 255, 255, 0), + Color.FromArgb(80, 0, 255, 255), + Color.FromArgb(80, 255, 0, 255), + Color.FromArgb(80, 170, 120, 20), + Color.FromArgb(150, 100, 120, 50), + Color.FromArgb(150, 40, 90, 150) + }; + + private static Color[] _colorsLight = { + Color.Lavender, + Color.LavenderBlush, + Color.PeachPuff, + Color.LemonChiffon, + Color.MistyRose, + Color.Honeydew, + Color.AliceBlue, + Color.WhiteSmoke, + Color.AntiqueWhite, + Color.LightCyan + }; + + private static Color[] _colorsExcel = { + Color.FromArgb(153,153,255), + Color.FromArgb(153,51,102), + Color.FromArgb(255,255,204), + Color.FromArgb(204,255,255), + Color.FromArgb(102,0,102), + Color.FromArgb(255,128,128), + Color.FromArgb(0,102,204), + Color.FromArgb(204,204,255), + Color.FromArgb(0,0,128), + Color.FromArgb(255,0,255), + Color.FromArgb(255,255,0), + Color.FromArgb(0,255,255), + Color.FromArgb(128,0,128), + Color.FromArgb(128,0,0), + Color.FromArgb(0,128,128), + Color.FromArgb(0,0,255)}; + + private static Color[] _colorsBerry = { + Color.BlueViolet, + Color.MediumOrchid, + Color.RoyalBlue, + Color.MediumVioletRed, + Color.Blue, + Color.BlueViolet, + Color.Orchid, + Color.MediumSlateBlue, + Color.FromArgb(192, 0, 192), + Color.MediumBlue, + Color.Purple + }; + + private static Color[] _colorsChocolate = { + Color.Sienna, + Color.Chocolate, + Color.DarkRed, + Color.Peru, + Color.Brown, + Color.SandyBrown, + Color.SaddleBrown, + Color.FromArgb(192, 64, 0), + Color.Firebrick, + Color.FromArgb(182, 92, 58) + }; + + private static Color[] _colorsFire = { + Color.Gold, + Color.Red, + Color.DeepPink, + Color.Crimson, + Color.DarkOrange, + Color.Magenta, + Color.Yellow, + Color.OrangeRed, + Color.MediumVioletRed, + Color.FromArgb(221, 226, 33) + }; + + private static Color[] _colorsSeaGreen = { + Color.SeaGreen, + Color.MediumAquamarine, + Color.SteelBlue, + Color.DarkCyan, + Color.CadetBlue, + Color.MediumSeaGreen, + Color.MediumTurquoise, + Color.LightSteelBlue, + Color.DarkSeaGreen, + Color.SkyBlue + }; + + private static Color[] _colorsBrightPastel = { + Color.FromArgb(65, 140, 240), + Color.FromArgb(252, 180, 65), + Color.FromArgb(224, 64, 10), + Color.FromArgb(5, 100, 146), + Color.FromArgb(191, 191, 191), + Color.FromArgb(26, 59, 105), + Color.FromArgb(255, 227, 130), + Color.FromArgb(18, 156, 221), + Color.FromArgb(202, 107, 75), + Color.FromArgb(0, 92, 219), + Color.FromArgb(243, 210, 136), + Color.FromArgb(80, 99, 129), + Color.FromArgb(241, 185, 168), + Color.FromArgb(224, 131, 10), + Color.FromArgb(120, 147, 190) + }; + + #endregion + + #region Constructor + + /// <summary> + /// Initializes the GrayScale color array + /// </summary> + private static Color[] InitializeGrayScaleColors() + { + // Define gray scale colors + Color[] grayScale = new Color[16]; + for(int i = 0; i < grayScale.Length; i++) + { + int colorValue = 200 - i * (180/16); + grayScale[i] = Color.FromArgb(colorValue, colorValue, colorValue); + } + + return grayScale; + } + + #endregion + + #region Methods + + /// <summary> + /// Return array of colors for the specified palette. Number of + /// colors returned varies depending on the palette selected. + /// </summary> + /// <param name="palette">Palette to get the colors for.</param> + /// <returns>Array of colors.</returns> + public static Color[] GetPaletteColors(ChartColorPalette palette) + { + switch(palette) + { + case(ChartColorPalette.None): + { + throw (new ArgumentException(SR.ExceptionPaletteIsEmpty)); + } + case(ChartColorPalette.Bright): + return _colorsDefault; + case(ChartColorPalette.Grayscale): + return _colorsGrayScale; + case(ChartColorPalette.Excel): + return _colorsExcel; + case(ChartColorPalette.Pastel): + return _colorsPastel; + case(ChartColorPalette.Light): + return _colorsLight; + case(ChartColorPalette.EarthTones): + return _colorsEarth; + case(ChartColorPalette.SemiTransparent): + return _colorsSemiTransparent; + case(ChartColorPalette.Berry): + return _colorsBerry; + case(ChartColorPalette.Chocolate): + return _colorsChocolate; + case(ChartColorPalette.Fire): + return _colorsFire; + case(ChartColorPalette.SeaGreen): + return _colorsSeaGreen; + case(ChartColorPalette.BrightPastel): + return _colorsBrightPastel; + } + return null; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Utilities/CustomAttributesRegistry.cs b/System.Web.DataVisualization/Common/Utilities/CustomAttributesRegistry.cs new file mode 100644 index 000000000..67a41ff1b --- /dev/null +++ b/System.Web.DataVisualization/Common/Utilities/CustomAttributesRegistry.cs @@ -0,0 +1,1974 @@ +//------------------------------------------------------------- +// <copyright company=’Microsoft Corporation’> +// Copyright © Microsoft Corporation. All Rights Reserved. +// </copyright> +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: CustomProperties.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Utilities +// +// Classes: CustomPropertyRegistry, CustomPropertyInfo, +// CustomPropertyName +// +// Purpose: CustomPropertyRegistry contains information for all +// chart custom properties. This informatin is used at +// design-time to provide simple editors for the +// CustomProperty property of the Series and DataPoint. +// +// Custom Properties Overview: +// --------------------------- +// +// Different chart types may have unique settings that only apply to +// this chart type. For example, ‘Exploded’ attribute on the data point +// only make sense in case of Pie and Doughnut chart types. Instead of +// adding properties that only will work with specific chart types +// CustomProperties were introduced. +// +// Custom properties are implemented using the CustomProperties property +// of both Series objects and their associated DataPoint objects. Here +// is an example of setting data point custom attribute: +// +// Chart1.Series["Default"].Points[0][CustomPropertyName.Exploded] = "true"; +// +// Custom attribute names are case-sensitive. You should be mindful of +// this fact when formatting custom properties in code-behind. Further, +// if the CustomProperty value contains a comma, then each comma must +// be preceded by a '\' character to escape the comma. This is useful +// when, for example, an RGB color value is set in your application. +// In such cases, the setting of custom properties that contain commas +// can either be done at runtime, or design-time. +// +// Reviewed: AG - Microsoft 5, 2007 +// +//=================================================================== + + +#region Used Namespaces + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +#else +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Utilities +#else // Microsoft_CONTROL + namespace System.Web.UI.DataVisualization.Charting.Utilities +#endif // Microsoft_CONTROL +{ + #region Enumerations + + + /// <summary> + /// Circular chart drawing style. + /// </summary> + internal enum PolarDrawingStyles + { + /// <summary> + /// Series are drawn as lines. + /// </summary> + Line, + /// <summary> + /// Series are drawn as markers. + /// </summary> + Marker + } + + /// <summary> + /// CircularAreaDrawingStyle + /// </summary> + internal enum CircularAreaDrawingStyles + { + /// <summary> + /// Drawn as polygon + /// </summary> + Polygon, + + /// <summary> + /// Drawn as circle + /// </summary> + Circle = 1, + } + + /// <summary> + /// Marker Style + /// </summary> + internal enum ErrorBarMarkerStyles + { + /// <summary> + /// Marker disabled + /// </summary> + None = 0, + + /// <summary> + /// The marker style is Square + /// </summary> + Square = 1, + + /// <summary> + /// The marker style is Circle + /// </summary> + Circle = 2, + + /// <summary> + /// The marker style is Diamond + /// </summary> + Diamond = 3, + + /// <summary> + /// The marker style is Triangle + /// </summary> + Triangle = 4, + + /// <summary> + /// The marker style is Cross + /// </summary> + Cross = 5, + + /// <summary> + /// The marker style is 4 corner star + /// </summary> + Star4 = 6, + + /// <summary> + /// The marker style is 5 corner star + /// </summary> + Star5 = 7, + + /// <summary> + /// The marker style is 6 corner star + /// </summary> + Star6 = 8, + + /// <summary> + /// The marker style is 10 corner star + /// </summary> + Star10 = 9, + + /// <summary> + /// Line marker + /// </summary> + Line = 10 + + }; + + /// <summary> + /// AxisName of stock chart markers + /// </summary> + internal enum StockShowOpenCloseTypes + { + /// <summary> + /// Open and Close markers are shown. + /// </summary> + Both, + + /// <summary> + /// Only Open markers are shown. + /// </summary> + Open, + + /// <summary> + /// Only Close markers are shown. + /// </summary> + Close, + } + + + /// <summary> + /// IsEmpty point value attribute + /// </summary> + internal enum EmptyPointTypes + { + /// <summary> + /// Average of two neighbor points is used. + /// </summary> + Average, + + /// <summary> + /// Zero value is used + /// </summary> + Zero + } + + /// <summary> + /// Stock chart point labels attribute + /// </summary> + internal enum StockLabelValueTypes + { + /// <summary> + /// High Y value is used to generate point label. + /// </summary> + High, + + /// <summary> + /// Low Y value is used to generate point label. + /// </summary> + Low, + + /// <summary> + /// Open Y value is used to generate point label. + /// </summary> + Open, + + /// <summary> + /// Close Y value is used to generate point label. + /// </summary> + Close, + } + + /// <summary> + /// Data point label alignment. + /// </summary> + [Flags] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")] + internal enum LabelAlignments + { + /// <summary> + /// Automatic position. + /// </summary> + Auto = 0, + /// <summary> + /// Label aligned on the top of the marker. + /// </summary> + Top = 1, + /// <summary> + /// Label aligned on the bottom of the marker. + /// </summary> + Bottom = 2, + /// <summary> + /// Label aligned on the right of the marker. + /// </summary> + Right = 4, + /// <summary> + /// Label aligned on the left of the marker. + /// </summary> + Left = 8, + /// <summary> + /// Label aligned on the top-left of the marker. + /// </summary> + TopLeft = 16, + /// <summary> + /// Label aligned on the top-right of the marker. + /// </summary> + TopRight = 32, + /// <summary> + /// Label aligned on the bottom-left of the marker. + /// </summary> + BottomLeft = 64, + /// <summary> + /// Label aligned on the bottom-right of the marker. + /// </summary> + BottomRight = 128, + /// <summary> + /// Label aligned in the center of the marker. + /// </summary> + Center = 256, + } + + #endregion //Enumerations + + /// <summary> + /// CustomPropertyName class contains constant strings defining + /// names of all custom properties used in the chart. + /// </summary> + internal static class CustomPropertyName + { + #region Common Custom Properties Names + + internal const string DrawSideBySide = "DrawSideBySide"; + internal const string EmptyPointValue = "EmptyPointValue"; + internal const string IsXAxisQuantitative = "IsXAxisQuantitative"; + internal const string BarLabelStyle = "BarLabelStyle"; + internal const string StackedGroupName = "StackedGroupName"; + internal const string DrawingStyle = "DrawingStyle"; + internal const string PointWidth = "PointWidth"; + internal const string PixelPointWidth = "PixelPointWidth"; + internal const string MinPixelPointWidth = "MinPixelPointWidth"; + internal const string MaxPixelPointWidth = "MaxPixelPointWidth"; + internal const string PriceUpColor = "PriceUpColor"; + internal const string PriceDownColor = "PriceDownColor"; + internal const string LabelValueType = "LabelValueType"; + internal const string OpenCloseStyle = "OpenCloseStyle"; + internal const string ShowOpenClose = "ShowOpenClose"; + internal const string BubbleScaleMin = "BubbleScaleMin"; + internal const string BubbleScaleMax = "BubbleScaleMax"; + internal const string BubbleMaxSize = "BubbleMaxSize"; + internal const string BubbleMinSize = "BubbleMinSize"; + internal const string BubbleUseSizeForLabel = "BubbleUseSizeForLabel"; + internal const string PieDrawingStyle = "PieDrawingStyle"; + internal const string CollectedStyle = "CollectedStyle"; + internal const string CollectedThreshold = "CollectedThreshold"; + internal const string CollectedThresholdUsePercent = "CollectedThresholdUsePercent"; + internal const string CollectedSliceExploded = "CollectedSliceExploded"; + internal const string CollectedLabel = "CollectedLabel"; + internal const string CollectedLegendText = "CollectedLegendText"; + internal const string CollectedToolTip = "CollectedToolTip"; + internal const string CollectedColor = "CollectedColor"; + internal const string CollectedChartShowLegend = "CollectedChartShowLegend"; + internal const string CollectedChartShowLabels = "CollectedChartShowLabels"; + internal const string PieStartAngle = "PieStartAngle"; + internal const string Exploded = "Exploded"; + internal const string LabelsRadialLineSize = "LabelsRadialLineSize"; + internal const string LabelsHorizontalLineSize = "LabelsHorizontalLineSize"; + internal const string PieLabelStyle = "PieLabelStyle"; + internal const string MinimumRelativePieSize = "MinimumRelativePieSize"; + internal const string _3DLabelLineSize = "3DLabelLineSize"; + internal const string PieLineColor = "PieLineColor"; + internal const string PieAutoAxisLabels = "AutoAxisLabels"; + internal const string DoughnutRadius = "DoughnutRadius"; + internal const string LabelStyle = "LabelStyle"; + internal const string ShowMarkerLines = "ShowMarkerLines"; + internal const string LineTension = "LineTension"; + internal const string PixelPointDepth = "PixelPointDepth"; + internal const string PixelPointGapDepth = "PixelPointGapDepth"; + internal const string PermittedPixelError = "PermittedPixelError"; + internal const string CircularLabelsStyle = "CircularLabelsStyle"; + internal const string PolarDrawingStyle = "PolarDrawingStyle"; + internal const string AreaDrawingStyle = "AreaDrawingStyle"; + internal const string RadarDrawingStyle = "RadarDrawingStyle"; + internal const string BoxPlotPercentile = "BoxPlotPercentile"; + internal const string BoxPlotWhiskerPercentile = "BoxPlotWhiskerPercentile"; + internal const string BoxPlotShowAverage = "BoxPlotShowAverage"; + internal const string BoxPlotShowMedian = "BoxPlotShowMedian"; + internal const string BoxPlotShowUnusualValues = "BoxPlotShowUnusualValues"; + internal const string BoxPlotSeries = "BoxPlotSeries"; + internal const string ErrorBarStyle = "ErrorBarStyle"; + internal const string ErrorBarCenterMarkerStyle = "ErrorBarCenterMarkerStyle"; + internal const string ErrorBarSeries = "ErrorBarSeries"; + internal const string ErrorBarType = "ErrorBarType"; + internal const string UsedYValueHigh = "UsedYValueHigh"; + internal const string UsedYValueLow = "UsedYValueLow"; + internal const string BoxSize = "BoxSize"; + internal const string ProportionalSymbols = "ProportionalSymbols"; + internal const string ReversalAmount = "ReversalAmount"; + internal const string UsedYValue = "UsedYValue"; + internal const string NumberOfLinesInBreak = "NumberOfLinesInBreak"; + internal const string FunnelLabelStyle = "FunnelLabelStyle"; + internal const string FunnelNeckWidth = "FunnelNeckWidth"; + internal const string FunnelNeckHeight = "FunnelNeckHeight"; + internal const string FunnelMinPointHeight = "FunnelMinPointHeight"; + internal const string Funnel3DRotationAngle = "Funnel3DRotationAngle"; + internal const string FunnelPointGap = "FunnelPointGap"; + internal const string Funnel3DDrawingStyle = "Funnel3DDrawingStyle"; + internal const string FunnelStyle = "FunnelStyle"; + internal const string FunnelInsideLabelAlignment = "FunnelInsideLabelAlignment"; + internal const string FunnelOutsideLabelPlacement = "FunnelOutsideLabelPlacement"; + internal const string CalloutLineColor = "CalloutLineColor"; + internal const string PyramidLabelStyle = "PyramidLabelStyle"; + internal const string PyramidMinPointHeight = "PyramidMinPointHeight"; + internal const string Pyramid3DRotationAngle = "Pyramid3DRotationAngle"; + internal const string PyramidPointGap = "PyramidPointGap"; + internal const string Pyramid3DDrawingStyle = "Pyramid3DDrawingStyle"; + internal const string PyramidInsideLabelAlignment = "PyramidInsideLabelAlignment"; + internal const string PyramidOutsideLabelPlacement = "PyramidOutsideLabelPlacement"; + internal const string PyramidValueType = "PyramidValueType"; + + #endregion // Common Custom Properties Names + } + + /// <summary> + /// CustomPropertyRegistry contains information for all chart + /// custom properties. This data is exposed through the + /// ‘registeredCustomProperties’ field which is an ArrayList + /// containing CustomPropertyInfo classes. + /// </summary> + internal class CustomPropertyRegistry : IServiceProvider + { + #region Fields + + // List of registered properties + internal ArrayList registeredCustomProperties = new ArrayList(); + + // Defines maximum value which can be set to the attribute which uses pixels + internal static int MaxValueOfPixelAttribute = 10000; + + internal static System.Collections.Generic.List<SeriesChartType> IsXAxisQuantitativeChartTypes = + new System.Collections.Generic.List<SeriesChartType >( + new SeriesChartType[] { + SeriesChartType.Line, + SeriesChartType.FastLine, + SeriesChartType.Spline, + SeriesChartType.Point, + SeriesChartType.FastPoint, + SeriesChartType.Bubble, + SeriesChartType.RangeColumn, + SeriesChartType.RangeBar, + }); + #endregion + + #region Constructor and Services + + /// <summary> + /// Custom properties registry public constructor. + /// </summary> + public CustomPropertyRegistry() + { + // Register properties used in the chart + RegisterProperties(); + } + + /// <summary> + /// Returns custom properties registry service object. + /// </summary> + /// <param name="serviceType">Service type to get.</param> + /// <returns>Custom properties registry service.</returns> + [EditorBrowsableAttribute(EditorBrowsableState.Never)] + object IServiceProvider.GetService(Type serviceType) + { + if(serviceType == typeof(CustomPropertyRegistry)) + { + return this; + } + throw (new ArgumentException(SR.ExceptionCustomAttributesRegistryUnsupportedType( serviceType.ToString()) )); + } + + #endregion + + #region Properties Regestering methods + + /// <summary> + /// This method registers all standard custom properties used in + /// the chart and provides all the additional information like + /// description, value validation and scenarios where custom + /// attribute can be used. + /// </summary> + private void RegisterProperties() + { + SeriesChartType[] chartTypes = null; + CustomPropertyInfo attrInfo = null; + + //*********************************************************************** + //** DrawSideBySide properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.Bar, + SeriesChartType.Column, + + SeriesChartType.RangeColumn, + SeriesChartType.BoxPlot, + SeriesChartType.RangeBar, + SeriesChartType.ErrorBar, + + }; + // "DrawSideBySide" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.DrawSideBySide, + typeof(AxisEnabled), + "Auto", + SR.DescriptionCustomAttributeDrawSideBySide, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + //*********************************************************************** + //** IsXAxisQuantitative properties + //*********************************************************************** + registeredCustomProperties.Add(new CustomPropertyInfo( + CustomPropertyName.IsXAxisQuantitative, + typeof(bool), + "false", + SR.DescriptionCustomAttributeIsXAxisQuantitive, + IsXAxisQuantitativeChartTypes.ToArray(), + true, + false)); + + //*********************************************************************** + //** EmptyPointValue properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.Point, + SeriesChartType.Bubble, + SeriesChartType.Line, + SeriesChartType.Spline, + SeriesChartType.StepLine, + SeriesChartType.Column, + SeriesChartType.RangeColumn, + SeriesChartType.RangeBar, + SeriesChartType.Radar, + SeriesChartType.Range, + SeriesChartType.SplineRange, + SeriesChartType.Polar, + SeriesChartType.Area, + SeriesChartType.SplineArea, + SeriesChartType.Bar, + }; + registeredCustomProperties.Add( new CustomPropertyInfo( + CustomPropertyName.EmptyPointValue, + typeof(EmptyPointTypes), + "Average", + SR.DescriptionCustomAttributeEmptyPointValue, + chartTypes, + true, + false) ); + + + //*********************************************************************** + //** Bar label styles properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.StackedBar, + SeriesChartType.StackedBar100, + SeriesChartType.RangeBar, + }; + // "BarLabelStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BarLabelStyle, + typeof(BarValueLabelDrawingStyle), + "Center", + SR.DescriptionCustomAttributeBarLabelStyle, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + + + //*********************************************************************** + //** Stacked Column/Bar properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.StackedBar, + SeriesChartType.StackedBar100, + SeriesChartType.StackedColumn, + SeriesChartType.StackedColumn100, + + }; + + // "StackedGroupName" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.StackedGroupName, + typeof(string), + string.Empty, + SR.DescriptionCustomAttributeStackedGroupName, + chartTypes, + true, + false); + registeredCustomProperties.Add(attrInfo); + + + + //*********************************************************************** + //** Bar label styles properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.Bar, + }; + // "BarLabelStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BarLabelStyle, + typeof(BarValueLabelDrawingStyle), + "Outside", + SR.DescriptionCustomAttributeBarLabelStyle, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + //*********************************************************************** + //** Bar and Columnt chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.Bar, + SeriesChartType.Column, + SeriesChartType.StackedBar, + SeriesChartType.StackedBar100, + SeriesChartType.StackedColumn, + SeriesChartType.StackedColumn100, + SeriesChartType.RangeBar, + SeriesChartType.RangeColumn, + + }; + // "DrawingStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.DrawingStyle, + typeof(BarDrawingStyle), + "Default", + SR.DescriptionCustomAttributeDrawingStyle, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + //*********************************************************************** + //** Chart types point width properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.Bar, + SeriesChartType.Candlestick, + SeriesChartType.Column, + SeriesChartType.StackedBar, + SeriesChartType.StackedBar100, + SeriesChartType.StackedColumn, + SeriesChartType.StackedColumn100, + SeriesChartType.Stock, + SeriesChartType.BoxPlot, + SeriesChartType.ErrorBar, + SeriesChartType.RangeBar, + SeriesChartType.RangeColumn, + }; + // "PointWidth" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PointWidth, + typeof(float), + 0.8f, + SR.DescriptionCustomAttributePointWidth, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 2f; + registeredCustomProperties.Add( attrInfo ); + + // "PixelPointWidth" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PixelPointWidth, + typeof(int), + 0, + SR.DescriptionCustomAttributePixelPointWidth, + chartTypes, + true, + false); + attrInfo.MinValue = 0; + attrInfo.MaxValue = CustomPropertyRegistry.MaxValueOfPixelAttribute; + registeredCustomProperties.Add( attrInfo ); + + // "MinPixelPointWidth" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.MinPixelPointWidth, + typeof(int), + 0, + SR.DescriptionCustomAttributeMinPixelPointWidth, + chartTypes, + true, + false); + attrInfo.MinValue = 0; + attrInfo.MaxValue = CustomPropertyRegistry.MaxValueOfPixelAttribute; + registeredCustomProperties.Add( attrInfo ); + + // "MaxPixelPointWidth" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.MaxPixelPointWidth, + typeof(int), + 0, + SR.DescriptionCustomAttributeMaxPixelPointWidth, + chartTypes, + true, + false); + attrInfo.MinValue = 0; + attrInfo.MaxValue = CustomPropertyRegistry.MaxValueOfPixelAttribute; + registeredCustomProperties.Add( attrInfo ); + + + + //*********************************************************************** + //** CandleStick chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { SeriesChartType.Candlestick }; + + // "PriceUpColor" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PriceUpColor, + typeof(Color), + "", + SR.DescriptionCustomAttributeCandlePriceUpColor, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + // "PriceDownColor" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PriceDownColor, + typeof(Color), + "", + SR.DescriptionCustomAttributePriceDownColor, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + + //*********************************************************************** + //** Stock and CandleStick chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { SeriesChartType.Stock, SeriesChartType.Candlestick }; + + // "LabelValueType" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.LabelValueType, + typeof(StockLabelValueTypes), + "Close", + SR.DescriptionCustomAttributeLabelValueType, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + //*********************************************************************** + //** Stock chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { SeriesChartType.Stock }; + + // "OpenCloseStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.OpenCloseStyle, + typeof(StockOpenCloseMarkStyle), + "Line", + SR.DescriptionCustomAttributeOpenCloseStyle, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + // "ShowOpenClose" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.ShowOpenClose, + typeof(StockShowOpenCloseTypes), + "Both", + SR.DescriptionCustomAttributeShowOpenClose, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + + //*********************************************************************** + //** Bubble chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { SeriesChartType.Bubble }; + + // "BubbleScaleMin" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BubbleScaleMin, + typeof(float), + 0f, + SR.DescriptionCustomAttributeBubbleScaleMin, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "BubbleScaleMax" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BubbleScaleMax, + typeof(float), + 0f, + SR.DescriptionCustomAttributeBubbleScaleMax, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "BubbleMaxSize" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BubbleMaxSize, + typeof(float), + 15f, + SR.DescriptionCustomAttributeBubbleMaxSize, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 100f; + registeredCustomProperties.Add( attrInfo ); + + // "BubbleMinSize" attribute of the Bubble chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BubbleMinSize, + typeof(float), + 3f, + SR.DescriptionCustomAttributeBubbleMaxSize, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 100f; + registeredCustomProperties.Add( attrInfo ); + + // "BubbleUseSizeForLabel" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BubbleUseSizeForLabel, + typeof(bool), + false, + SR.DescriptionCustomAttributeBubbleUseSizeForLabel, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + + + //*********************************************************************** + //** Pie and Doughnut chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.Pie, + SeriesChartType.Doughnut + }; + + + // "PieDrawingStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PieDrawingStyle, + typeof(PieDrawingStyle), + "Default", + SR.DescriptionCustomAttributePieDrawingStyle, + chartTypes, + true, + false); + attrInfo.AppliesTo3D = false; + registeredCustomProperties.Add( attrInfo ); + + + // "CollectedThreshold" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.CollectedThreshold, + typeof(double), + 0.0, + SR.DescriptionCustomAttributeCollectedThreshold, + chartTypes, + true, + false); + attrInfo.MinValue = 0.0; + attrInfo.MaxValue = double.MaxValue; + registeredCustomProperties.Add( attrInfo ); + + // "CollectedThresholdUsePercent" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.CollectedThresholdUsePercent, + typeof(bool), + true, + SR.DescriptionCustomAttributeCollectedThresholdUsePercent, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "CollectedSliceExploded" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.CollectedSliceExploded, + typeof(bool), + false, + SR.DescriptionCustomAttributeCollectedSliceExploded, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "CollectedLabel" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.CollectedLabel, + typeof(string), + string.Empty, + SR.DescriptionCustomAttributeCollectedLabel, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "CollectedLegendText" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.CollectedLegendText, + typeof(string), + SR.DescriptionCustomAttributeCollectedLegendDefaultText, + SR.DescriptionCustomAttributeCollectedLegendText, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "CollectedToolTip" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.CollectedToolTip, + typeof(string), + string.Empty, + SR.DescriptionCustomAttributeCollectedToolTip, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "CollectedColor" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.CollectedColor, + typeof(Color), + "", + SR.DescriptionCustomAttributeCollectedColor, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + + // "PieStartAngle" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PieStartAngle, + typeof(int), + 0, + SR.DescriptionCustomAttributePieStartAngle, + chartTypes, + true, + false); + attrInfo.MinValue = 0; + attrInfo.MaxValue = 360; + registeredCustomProperties.Add( attrInfo ); + + + + + // "Exploded" attribute of the Pie chart + registeredCustomProperties.Add( new CustomPropertyInfo( + CustomPropertyName.Exploded, + typeof(bool), + false, + SR.DescriptionCustomAttributePieDonutExploded, + chartTypes, + false, + true) ); + + // "LabelsRadialLineSize" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.LabelsRadialLineSize, + typeof(float), + 1f, + SR.DescriptionCustomAttributeLabelsRadialLineSize, + chartTypes, + true, + true); + attrInfo.AppliesTo3D = false; + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 100f; + registeredCustomProperties.Add( attrInfo ); + + // "LabelsHorizontalLineSize" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.LabelsHorizontalLineSize, + typeof(float), + 1f, + SR.DescriptionCustomAttributeLabelsHorizontalLineSize, + chartTypes, + true, + true); + attrInfo.AppliesTo3D = false; + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 100f; + registeredCustomProperties.Add( attrInfo ); + + + // "PieLabelStyle" attribute of the Pie chart + registeredCustomProperties.Add( new CustomPropertyInfo( + CustomPropertyName.PieLabelStyle, + typeof(PieLabelStyle), + "Inside", + SR.DescriptionCustomAttributePieLabelStyle, + chartTypes, + true, + true) ); + + + // "MinimumRelativePieSize" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.MinimumRelativePieSize, + typeof(float), + 30f, + SR.DescriptionCustomAttributeMinimumRelativePieSize, + chartTypes, + true, + false); + attrInfo.MinValue = 10f; + attrInfo.MaxValue = 70f; + registeredCustomProperties.Add( attrInfo ); + + // "3DLabelLineSize" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName._3DLabelLineSize, + typeof(float), + 100f, + SR.DescriptionCustomAttribute_3DLabelLineSize, + chartTypes, + true, + false); + attrInfo.AppliesTo2D = false; + attrInfo.MinValue = 30f; + attrInfo.MaxValue = 200f; + registeredCustomProperties.Add( attrInfo ); + + // "PieLineColor" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PieLineColor, + typeof(Color), + "", + SR.DescriptionCustomAttributePieLineColor, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + //*********************************************************************** + //** Doughnut chart types properties + //*********************************************************************** + + // "DoughnutRadius" attribute of the Pie chart + attrInfo = new CustomPropertyInfo( + CustomPropertyName.DoughnutRadius, + typeof(float), + 60f, + SR.DescriptionCustomAttributeDoughnutRadius, + new SeriesChartType[] { SeriesChartType.Doughnut }, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 99f; + registeredCustomProperties.Add( attrInfo ); + + + //*********************************************************************** + //** Other + //*********************************************************************** + + // "LabelStyle" attribute + chartTypes = new SeriesChartType[] { + SeriesChartType.Point, + SeriesChartType.Column, + SeriesChartType.Bubble, + SeriesChartType.Line, + SeriesChartType.Spline, + SeriesChartType.StepLine, + SeriesChartType.Area, + SeriesChartType.SplineArea, + SeriesChartType.Range, + SeriesChartType.SplineRange, + SeriesChartType.Radar, + SeriesChartType.Polar, + + }; + registeredCustomProperties.Add( new CustomPropertyInfo( + CustomPropertyName.LabelStyle, + typeof(LabelAlignments), + "Auto", + SR.DescriptionCustomAttributeLabelStyle, + chartTypes, + true, + true) ); + + // "ShowMarkerLines" attribute + chartTypes = new SeriesChartType[] { + SeriesChartType.Line, + SeriesChartType.Spline, + SeriesChartType.StepLine, + SeriesChartType.Area, + SeriesChartType.SplineArea, + SeriesChartType.Range, + SeriesChartType.SplineRange + }; + attrInfo = new CustomPropertyInfo( + CustomPropertyName.ShowMarkerLines, + typeof(bool), + false, + SR.DescriptionCustomAttributeShowMarkerLines, + chartTypes, + true, + true); + attrInfo.AppliesTo2D = false; + registeredCustomProperties.Add( attrInfo ); + + // "LineTension" attribute + chartTypes = new SeriesChartType[] { + SeriesChartType.Spline, + SeriesChartType.SplineArea, + SeriesChartType.SplineRange + }; + attrInfo = new CustomPropertyInfo( + CustomPropertyName.LineTension, + typeof(float), + 0.5f, + SR.DescriptionCustomAttributeLineTension, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 2f; + registeredCustomProperties.Add( attrInfo ); + + // "PixelPointDepth" attribute + chartTypes = new SeriesChartType[] { + SeriesChartType.Area, + SeriesChartType.Bar, + SeriesChartType.Bubble, + SeriesChartType.Candlestick, + SeriesChartType.Column, + SeriesChartType.Line, + SeriesChartType.Point, + SeriesChartType.Spline, + SeriesChartType.SplineArea, + SeriesChartType.StackedArea, + SeriesChartType.StackedArea100, + SeriesChartType.StackedBar, + SeriesChartType.StackedBar100, + SeriesChartType.StackedColumn, + SeriesChartType.StackedColumn100, + SeriesChartType.StepLine, + SeriesChartType.Stock, + + SeriesChartType.ThreeLineBreak, + SeriesChartType.BoxPlot, + SeriesChartType.ErrorBar, + SeriesChartType.RangeBar, + SeriesChartType.Kagi, + SeriesChartType.PointAndFigure, + SeriesChartType.Range, + SeriesChartType.RangeColumn, + SeriesChartType.Renko, + SeriesChartType.SplineRange, + SeriesChartType.FastLine, + }; + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PixelPointDepth, + typeof(int), + 0, + SR.DescriptionCustomAttributePixelPointDepth, + chartTypes, + true, + false); + attrInfo.MinValue = 0; + attrInfo.MaxValue = CustomPropertyRegistry.MaxValueOfPixelAttribute; + attrInfo.AppliesTo2D = false; + registeredCustomProperties.Add( attrInfo ); + + // "PixelPointGapDepth" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PixelPointGapDepth, + typeof(int), + 0, + SR.DescriptionCustomAttributePixelPointGapDepth, + chartTypes, + true, + false); + attrInfo.MinValue = 0; + attrInfo.MaxValue = CustomPropertyRegistry.MaxValueOfPixelAttribute; + attrInfo.AppliesTo2D = false; + registeredCustomProperties.Add( attrInfo ); + + + + //*********************************************************************** + //** FastLine chart type properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.FastLine, + SeriesChartType.FastPoint, + }; + +/* NOTE: This is an internal attribute + * + // "PermittedPixelError" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PixelPointGapDepth, + typeof(float), + 1f, + "Gets or sets the acceptable error in pixels for the data point filtering algorithm.", + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 1f; + registeredCustomProperties.Add( attrInfo ); +*/ + //*********************************************************************** + //** Polar chart type properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.Polar + }; + // "AreaDrawingStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.AreaDrawingStyle, + typeof(CircularAreaDrawingStyles), + "Circle", + SR.DescriptionCustomAttributePolarAreaDrawingStyle, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "CircularLabelsStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.CircularLabelsStyle, + typeof(CircularAxisLabelsStyle), + "Auto", + SR.DescriptionCustomAttributePolarCircularLabelsStyle, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "PolarDrawingStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PolarDrawingStyle, + typeof(PolarDrawingStyles), + "Line", + SR.DescriptionCustomAttributePolarDrawingStyle, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + + + //*********************************************************************** + //** Radar chart type properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.Radar + }; + // "AreaDrawingStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.AreaDrawingStyle, + typeof(CircularAreaDrawingStyles), + "Circle", + SR.DescriptionCustomAttributeRadarAreaDrawingStyle, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "CircularLabelsStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.CircularLabelsStyle, + typeof(CircularAxisLabelsStyle), + "Auto", + SR.DescriptionCustomAttributeRadarCircularLabelsStyle, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "RadarDrawingStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.RadarDrawingStyle, + typeof(RadarDrawingStyle), + "Area", + SR.DescriptionCustomAttributeRadarDrawingStyle, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + + //*********************************************************************** + //** BoxPlot chart type properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.BoxPlot + }; + // "BoxPlotPercentile" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BoxPlotPercentile, + typeof(float), + 25f, + SR.DescriptionCustomAttributeBoxPlotPercentile, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 1000f; + registeredCustomProperties.Add( attrInfo ); + + // "BoxPlotWhiskerPercentile" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BoxPlotWhiskerPercentile, + typeof(float), + 10f, + SR.DescriptionCustomAttributeBoxPlotWhiskerPercentile, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 1000f; + registeredCustomProperties.Add( attrInfo ); + + // "BoxPlotShowAverage" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BoxPlotShowAverage, + typeof(bool), + true, + SR.DescriptionCustomAttributeBoxPlotShowAverage, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "BoxPlotShowMedian" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BoxPlotShowMedian, + typeof(bool), + true, + SR.DescriptionCustomAttributeBoxPlotShowMedian, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "BoxPlotShowUnusualValues" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BoxPlotShowUnusualValues, + typeof(bool), + false, + SR.DescriptionCustomAttributeBoxPlotShowUnusualValues, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "BoxPlotSeries" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BoxPlotSeries, + typeof(string), + "", + SR.DescriptionCustomAttributeBoxPlotSeries, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + //*********************************************************************** + //** ErrorBar chart type properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { + SeriesChartType.ErrorBar + }; + // "ErrorBarStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.ErrorBarStyle, + typeof(ErrorBarStyle), + "Both", + SR.DescriptionCustomAttributeErrorBarStyle, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + // "ErrorBarCenterMarkerStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.ErrorBarCenterMarkerStyle, + typeof(ErrorBarMarkerStyles), + "Line", + SR.DescriptionCustomAttributeErrorBarCenterMarkerStyle, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + // "ErrorBarSeries" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.ErrorBarSeries, + typeof(string), + "", + SR.DescriptionCustomAttributeErrorBarSeries, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "ErrorBarType" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.ErrorBarType, + typeof(string), + String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}({1:N0})", ErrorBarType.StandardError, ErrorBarChart.DefaultErrorBarTypeValue(ErrorBarType.StandardError)), + SR.DescriptionCustomAttributeErrorBarType, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + + //*********************************************************************** + //** PointAndFigure chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { SeriesChartType.PointAndFigure }; + + // "UsedYValueHigh" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.UsedYValueHigh, + typeof(int), + 0, + SR.DescriptionCustomAttributeUsedYValueHigh, + chartTypes, + true, + false); + attrInfo.MinValue = 0; + attrInfo.MaxValue = 20; + registeredCustomProperties.Add( attrInfo ); + + // "UsedYValueLow" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.UsedYValueLow, + typeof(int), + 1, + SR.DescriptionCustomAttributeUsedYValueLow, + chartTypes, + true, + false); + attrInfo.MinValue = 0; + attrInfo.MaxValue = 20; + registeredCustomProperties.Add( attrInfo ); + + // "PriceUpColor" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PriceUpColor, + typeof(Color), + "", + SR.DescriptionCustomAttributeBarsPriceUpColor, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "BoxSize" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BoxSize, + typeof(string), + "4%", + SR.DescriptionCustomAttributePointFigureBoxSize, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "ProportionalSymbols" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.ProportionalSymbols, + typeof(bool), + true, + SR.DescriptionCustomAttributeProportionalSymbols, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "ReversalAmount" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.ReversalAmount, + typeof(int), + "3", + SR.DescriptionCustomAttributeReversalAmount, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + //*********************************************************************** + //** Kagi chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { SeriesChartType.Kagi }; + + // "UsedYValue" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.UsedYValue, + typeof(int), + 0, + SR.DescriptionCustomAttributeUsedYValue, + chartTypes, + true, + false); + attrInfo.MinValue = 0; + attrInfo.MaxValue = 20; + registeredCustomProperties.Add( attrInfo ); + + // "PriceUpColor" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PriceUpColor, + typeof(Color), + "", + SR.DescriptionCustomAttributeBarsPriceUpColor, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "ReversalAmount" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.ReversalAmount, + typeof(string), + "3%", + SR.DescriptionCustomAttributeKagiReversalAmount, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + //*********************************************************************** + //** Renko chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { SeriesChartType.Renko }; + + // "UsedYValue" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.UsedYValue, + typeof(int), + 0, + SR.DescriptionCustomAttributeRenkoUsedYValue, + chartTypes, + true, + false); + attrInfo.MinValue = 0; + attrInfo.MaxValue = 20; + registeredCustomProperties.Add( attrInfo ); + + // "PriceUpColor" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PriceUpColor, + typeof(Color), + "", + SR.DescriptionCustomAttributeBarsPriceUpColor, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "BoxSize" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.BoxSize, + typeof(string), + "4%", + SR.DescriptionCustomAttributeBoxSize, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + //*********************************************************************** + //** ThreeLineBreak chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { SeriesChartType.ThreeLineBreak }; + + // "UsedYValue" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.UsedYValue, + typeof(int), + 0, + SR.DescriptionCustomAttributeThreeLineBreakUsedYValue, + chartTypes, + true, + false); + attrInfo.MinValue = 0; + attrInfo.MaxValue = 20; + registeredCustomProperties.Add( attrInfo ); + + // "PriceUpColor" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PriceUpColor, + typeof(Color), + "", + SR.DescriptionCustomAttributeBarsPriceUpColor, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "NumberOfLinesInBreak" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.NumberOfLinesInBreak, + typeof(int), + 3, + SR.DescriptionCustomAttributeNumberOfLinesInBreak, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + + + //*********************************************************************** + //** Funnel chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { SeriesChartType.Funnel }; + + + // "FunnelLabelStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.FunnelLabelStyle, + typeof(FunnelLabelStyle), + "OutsideInColumn", + SR.DescriptionCustomAttributeFunnelLabelStyle, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + + // "FunnelNeckWidth" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.FunnelNeckWidth, + typeof(float), + 5f, + SR.DescriptionCustomAttributeFunnelNeckWidth, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 100f; + registeredCustomProperties.Add( attrInfo ); + + // "FunnelNeckHeight" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.FunnelNeckHeight, + typeof(float), + 5f, + SR.DescriptionCustomAttributeFunnelNeckHeight, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 100f; + registeredCustomProperties.Add( attrInfo ); + + // "FunnelMinPointHeight" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.FunnelMinPointHeight, + typeof(float), + 0f, + SR.DescriptionCustomAttributeFunnelMinPointHeight, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 100f; + registeredCustomProperties.Add( attrInfo ); + + // "Funnel3DRotationAngle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.Funnel3DRotationAngle, + typeof(float), + 5f, + SR.DescriptionCustomAttributeFunnel3DRotationAngle, + chartTypes, + true, + false); + attrInfo.AppliesTo2D = false; + attrInfo.MinValue = -10f; + attrInfo.MaxValue = 10f; + registeredCustomProperties.Add( attrInfo ); + + // "FunnelPointGap" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.FunnelPointGap, + typeof(float), + 0f, + SR.DescriptionCustomAttributeFunnelPointGap, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 100f; + registeredCustomProperties.Add( attrInfo ); + + // "Funnel3DDrawingStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.Funnel3DDrawingStyle, + typeof(Funnel3DDrawingStyle), + "CircularBase", + SR.DescriptionCustomAttributeFunnel3DDrawingStyle, + chartTypes, + true, + false); + attrInfo.AppliesTo2D = false; + registeredCustomProperties.Add( attrInfo ); + + // "FunnelStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.FunnelStyle, + typeof(FunnelStyle), + "YIsHeight", + SR.DescriptionCustomAttributeFunnelStyle, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + // "FunnelInsideLabelAlignment" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.FunnelInsideLabelAlignment, + typeof(FunnelLabelVerticalAlignment), + "Center", + SR.DescriptionCustomAttributeFunnelInsideLabelAlignment, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + // "FunnelOutsideLabelPlacement" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.FunnelOutsideLabelPlacement, + typeof(FunnelLabelPlacement), + "Right", + SR.DescriptionCustomAttributeFunnelOutsideLabelPlacement, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + // "CalloutLineColor" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.CalloutLineColor, + typeof(Color), + "Black", + SR.DescriptionCustomAttributeCalloutLineColor, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + //*********************************************************************** + //** Pyramid chart types properties + //*********************************************************************** + chartTypes = new SeriesChartType[] { SeriesChartType.Pyramid }; + + + // "PyramidLabelStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PyramidLabelStyle, + typeof(FunnelLabelStyle), + "OutsideInColumn", + SR.DescriptionCustomAttributePyramidLabelStyle, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + + // "PyramidMinPointHeight" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PyramidMinPointHeight, + typeof(float), + 0f, + SR.DescriptionCustomAttributePyramidMinPointHeight, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 100f; + registeredCustomProperties.Add( attrInfo ); + + // "Pyramid3DRotationAngle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.Pyramid3DRotationAngle, + typeof(float), + 5f, + SR.DescriptionCustomAttributePyramid3DRotationAngle, + chartTypes, + true, + false); + attrInfo.AppliesTo2D = false; + attrInfo.MinValue = -10f; + attrInfo.MaxValue = 10f; + registeredCustomProperties.Add( attrInfo ); + + // "PyramidPointGap" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PyramidPointGap, + typeof(float), + 0f, + SR.DescriptionCustomAttributePyramidPointGap, + chartTypes, + true, + false); + attrInfo.MinValue = 0f; + attrInfo.MaxValue = 100f; + registeredCustomProperties.Add( attrInfo ); + + // "Pyramid3DDrawingStyle" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.Pyramid3DDrawingStyle, + typeof(Funnel3DDrawingStyle), + "SquareBase", + SR.DescriptionCustomAttributePyramid3DDrawingStyle, + chartTypes, + true, + false); + attrInfo.AppliesTo2D = false; + registeredCustomProperties.Add( attrInfo ); + + // "PyramidInsideLabelAlignment" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PyramidInsideLabelAlignment, + typeof(FunnelLabelVerticalAlignment), + "Center", + SR.DescriptionCustomAttributePyramidInsideLabelAlignment, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + // "PyramidOutsideLabelPlacement" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PyramidOutsideLabelPlacement, + typeof(FunnelLabelPlacement), + "Right", + SR.DescriptionCustomAttributePyramidOutsideLabelPlacement, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + // "CalloutLineColor" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.CalloutLineColor, + typeof(Color), + "Black", + SR.DescriptionCustomAttributeCalloutLineColor, + chartTypes, + true, + true); + registeredCustomProperties.Add( attrInfo ); + + // "PyramidValueType" attribute + attrInfo = new CustomPropertyInfo( + CustomPropertyName.PyramidValueType, + typeof(PyramidValueType), + "Linear", + SR.DescriptionCustomAttributePyramidValueType, + chartTypes, + true, + false); + registeredCustomProperties.Add( attrInfo ); + + + } + + #endregion // Attributes Regestering methods + + #region Registry methods + + /// <summary> + /// Adds custom attribute information into the registry. + /// </summary> + /// <param name="customPropertyInfo">Custom attribute information.</param> + public void Register(CustomPropertyInfo customPropertyInfo) + { + // Add custom attribute information to the hash table + registeredCustomProperties.Add(customPropertyInfo); + } + + #endregion + } + + /// <summary> + /// CustomPropertyInfo class stores information about single + /// custom attribute. It includes Name, Description, Default + /// Value, any restrictions and the conditions when it can + /// be used. + /// + /// Most of the custom attribute can only be used when specific + /// chart type is selected. Some of the properties only work + /// in 2D or 3D mode and some can be applied to the whole + /// series or data points only. + /// </summary> + internal class CustomPropertyInfo + { + #region Public Fields + + /// <summary> + /// Attribute name. + /// </summary> + public string Name = String.Empty; + + /// <summary> + /// Attribute value type. + /// </summary> + public Type ValueType = typeof(int); + + /// <summary> + /// Attribute default value. + /// </summary> + public object DefaultValue = null; + + /// <summary> + /// Attribute description. + /// </summary> + public string Description = String.Empty; + + /// <summary> + /// Array of chart type supported by the attribute + /// </summary> + public SeriesChartType[] AppliesToChartType = null; + + /// <summary> + /// Indicates that attribute can be applied on series. + /// </summary> + public bool AppliesToSeries = true; + + /// <summary> + /// Indicates that attribute can be applied on data point. + /// </summary> + public bool AppliesToDataPoint = true; + + /// <summary> + /// Indicates that attribute can be applied on 3D chart type. + /// </summary> + public bool AppliesTo3D = true; + + /// <summary> + /// Indicates that attribute can be applied on 2D chart type. + /// </summary> + public bool AppliesTo2D = true; + + /// <summary> + /// Attribute minimum value. + /// </summary> + public object MinValue = null; + + /// <summary> + /// Attribute maximum value. + /// </summary> + public object MaxValue = null; + + #endregion // Public Fields + + #region Constructor + + /// <summary> + /// Public constructor. + /// </summary> + /// <param name="name">Attribute name</param> + /// <param name="valueType">Attribute value type.</param> + /// <param name="defaultValue">Attribute default value.</param> + /// <param name="description">Attribute description.</param> + /// <param name="appliesToChartType">Array of chart types where attribute used.</param> + /// <param name="appliesToSeries">True if properties can be set in series.</param> + /// <param name="appliesToDataPoint">True if properties can be set in data point.</param> + public CustomPropertyInfo( + string name, + Type valueType, + object defaultValue, + string description, + SeriesChartType[] appliesToChartType, + bool appliesToSeries, + bool appliesToDataPoint) + { + this.Name = name; + this.ValueType = valueType; + this.DefaultValue = defaultValue; + this.Description = description; + this.AppliesToChartType = appliesToChartType; + this.AppliesToSeries = appliesToSeries; + this.AppliesToDataPoint = appliesToDataPoint; + } + + #endregion // Constructor + } +} diff --git a/System.Web.DataVisualization/Common/Utilities/ElementPosition.cs b/System.Web.DataVisualization/Common/Utilities/ElementPosition.cs new file mode 100644 index 000000000..2b8707df6 --- /dev/null +++ b/System.Web.DataVisualization/Common/Utilities/ElementPosition.cs @@ -0,0 +1,535 @@ +//------------------------------------------------------------- +// <copyright company=’Microsoft Corporation’> +// Copyright © Microsoft Corporation. All Rights Reserved. +// </copyright> +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ElementPosition.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting +// +// Classes: ElementPosition +// +// Purpose: Class is used to store relative position of the chart +// elements like Legend, Title and others. It uses +// relative coordinate system where top left corner is +// 0,0 and bottom right is 100,100. +// +// If Auto property is set to true, all position properties +// (X,Y,Width and Height) are ignored and they automatically +// calculated during chart rendering. +// +// Note that setting any of the position properties will +// automatically set Auto property to false. +// +// Reviewed: AG - August 7, 2002 +// AG - Microsoft 5, 2007 +// +//=================================================================== + + +#region Used Namespaces + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Data; +using System.Drawing; +using System.Drawing.Design; +using System.Drawing.Drawing2D; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.Data; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; + using System.Windows.Forms.DataVisualization.Charting.Utilities; + using System.Windows.Forms.DataVisualization.Charting.Borders3D; +#else + using System.Web; + using System.Web.UI; + using System.Web.UI.DataVisualization.Charting; + using System.Web.UI.DataVisualization.Charting.Data; +#endif + + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting +#else +namespace System.Web.UI.DataVisualization.Charting + +#endif +{ + /// <summary> + /// ElementPosition is the base class for many chart visual + /// elements like Legend, Title and ChartArea. It provides + /// the position of the chart element in relative coordinates, + /// from (0,0) to (100,100). + /// </summary> + [ + SRDescription("DescriptionAttributeElementPosition_ElementPosition"), + DefaultProperty("Data"), + ] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class ElementPosition : ChartElement + { + #region Fields + + // Private data members, which store properties values + private float _x = 0; + private float _y = 0; + private float _width = 0; + private float _height = 0; + internal bool _auto = true; + + // Indicates the auto position of all areas must be reset + internal bool resetAreaAutoPosition = false; + + #endregion + + #region Constructors + + /// <summary> + /// ElementPosition default constructor + /// </summary> + public ElementPosition() + { + } + + /// <summary> + /// ElementPosition default constructor + /// </summary> + internal ElementPosition(IChartElement parent) + : base(parent) + { + } + + + /// <summary> + /// ElementPosition constructor. + /// </summary> + /// <param name="x">X position.</param> + /// <param name="y">Y position.</param> + /// <param name="width">Width.</param> + /// <param name="height">Height.</param> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public ElementPosition(float x, float y, float width, float height) + { + this._auto = false; + this._x = x; + this._y = y; + this._width = width; + this._height = height; + } + + #endregion + + #region Methods + + /// <summary> + /// Asks the user at design-time if he wants to change the Auto position + /// of all areas at the same time. + /// </summary> + /// <param name="autoValue">Value to be set for the Auto property.</param> + private void ResetAllAreasAutoPosition(bool autoValue) + { + if(resetAreaAutoPosition) + { + // Proceed only if at design time + if(Chart != null && Chart.IsDesignMode() && !Chart.serializing && Chart.Site != null) + { + // Check if there is more than one area and Auto position set to the same value + if(Chart.ChartAreas.Count > 1) + { + bool firstAutoValue = Chart.ChartAreas[0].Position.Auto; + bool sameAutoValue = true; + foreach(ChartArea area in Chart.ChartAreas) + { + if(area.Position.Auto != firstAutoValue) + { + sameAutoValue = false; + break; + } + } + + // Proceed only all Auto values are the same + if(sameAutoValue) + { + string message = SR.MessageChangingChartAreaPositionProperty; + if (autoValue) + { + message += SR.MessageChangingChartAreaPositionConfirmAutomatic; + } + else + { + message += SR.MessageChangingChartAreaPositionConfirmCustom; + } + + + IDesignerMessageBoxDialog confirm = Chart.Site.GetService(typeof(IDesignerMessageBoxDialog)) as IDesignerMessageBoxDialog; + if (confirm != null && confirm.ShowQuestion(message)) + { + foreach (ChartArea area in Chart.ChartAreas) + { + if (autoValue) + { + this.SetPositionNoAuto(0f, 0f, 0f, 0f); + } + area.Position._auto = autoValue; + } + + } + } + } + } + } + } + + /// <summary> + /// Convert element position into RectangleF + /// </summary> + /// <returns>RectangleF structure.</returns> + public RectangleF ToRectangleF() + { + return new RectangleF(_x, _y, _width, _height); + } + + /// <summary> + /// Initializes ElementPosition from RectangleF + /// </summary> + /// <param name="rect">RectangleF structure.</param> + public void FromRectangleF(RectangleF rect) + { + if (rect == null) + throw new ArgumentNullException("rect"); + + this._x = rect.X; + this._y = rect.Y; + this._width = rect.Width; + this._height = rect.Height; + this._auto = false; + } + + /// <summary> + /// Gets the size of the ElementPosition object. + /// </summary> + /// <returns>The size of the ElementPosition object.</returns> + [Browsable(false)] + [Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)] + public SizeF Size + { + get { return new SizeF(this._width, this._height); } + } + + /// <summary> + /// Gets the bottom position in relative coordinates. + /// </summary> + /// <returns>Bottom position.</returns> + [Browsable(false)] + [Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)] + public float Bottom + { + get { return this._y + this._height; } + } + + /// <summary> + /// Gets the right position in relative coordinates. + /// </summary> + /// <returns>Right position.</returns> + [Browsable(false)] + [Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)] + public float Right + { + get{ return this._x + this._width; } + } + + /// <summary> + /// Determines whether the specified Object is equal to the current Object. + /// </summary> + /// <param name="obj">The Object to compare with the current Object.</param> + /// <returns>true if the specified Object is equal to the current Object; otherwise, false.</returns> + internal override bool EqualsInternal(object obj) + { + ElementPosition pos = obj as ElementPosition; + if(pos != null) + { + if(this._auto == true && this._auto == pos._auto) + { + return true; + } + else if(this._x == pos._x && this._y == pos._y && + this._width == pos._width && this._height == pos._height) + { + return true; + } + + } + return false; + } + + /// <summary> + /// Returns a string that represents the element position data. + /// </summary> + /// <returns>Element position data as a string.</returns> + internal override string ToStringInternal() + { + string posString = Constants.AutoValue; + if(!this._auto) + { + posString = + this._x.ToString(System.Globalization.CultureInfo.CurrentCulture)+", "+ + this._y.ToString(System.Globalization.CultureInfo.CurrentCulture)+", "+ + this._width.ToString(System.Globalization.CultureInfo.CurrentCulture)+", "+ + this._height.ToString(System.Globalization.CultureInfo.CurrentCulture); + } + return posString; + } + + /// <summary> + /// Set the element position without modifying the "Auto" property + /// </summary> + /// <param name="x">X position.</param> + /// <param name="y">Y position.</param> + /// <param name="width">Width.</param> + /// <param name="height">Height.</param> + internal void SetPositionNoAuto(float x, float y, float width, float height) + { + bool oldValue = this._auto; + this._x = x; + this._y = y; + this._width = width; + this._height = height; + this._auto = oldValue; + } + + #endregion + + #region Element Position properties + + /// <summary> + /// X position of element. + /// </summary> + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(0.0F), + SRDescription("DescriptionAttributeElementPosition_X"), + NotifyParentPropertyAttribute(true), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "X")] + public float X + { + get + { + return _x; + } + set + { + if(value < 0.0 || value > 100.0) + { + throw(new ArgumentOutOfRangeException("value", SR.ExceptionElementPositionArgumentOutOfRange)); + } + _x = value; + Auto = false; + + // Adjust width + if( (_x + Width) > 100) + { + Width = 100 - _x; + } + + this.Invalidate(); + } + } + + /// <summary> + /// Y position of element. + /// </summary> + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(0.0F), + SRDescription("DescriptionAttributeElementPosition_Y"), + NotifyParentPropertyAttribute(true), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Y")] + public float Y + { + get + { + return _y; + } + set + { + if(value < 0.0 || value > 100.0) + { + throw(new ArgumentOutOfRangeException("value", SR.ExceptionElementPositionArgumentOutOfRange)); + } + _y = value; + Auto = false; + + // Adjust heigth + if( (_y + Height) > 100) + { + Height = 100 - _y; + } + + this.Invalidate(); + } + } + + /// <summary> + /// Width of element. + /// </summary> + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(0.0F), + SRDescription("DescriptionAttributeElementPosition_Width"), + NotifyParentPropertyAttribute(true), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public float Width + { + get + { + return _width; + } + set + { + if(value < 0.0 || value > 100.0) + { + throw(new ArgumentOutOfRangeException("value", SR.ExceptionElementPositionArgumentOutOfRange)); + } + _width = value; + Auto = false; + + // Adjust x + if( (_x + Width) > 100) + { + _x = 100 - Width; + } + + this.Invalidate(); + } + } + + /// <summary> + /// Height of element. + /// </summary> + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(0.0F), + SRDescription("DescriptionAttributeElementPosition_Height"), + NotifyParentPropertyAttribute(true), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public float Height + { + get + { + return _height; + } + set + { + if(value < 0.0 || value > 100.0) + { + throw(new ArgumentOutOfRangeException("value", SR.ExceptionElementPositionArgumentOutOfRange)); + } + _height = value; + Auto = false; + + // Adjust y + if( (_y + Height) > 100) + { + _y = 100 - Height; + + } + + this.Invalidate(); + } + } + + /// <summary> + /// Gets or sets a flag which indicates whether positioning is on. + /// </summary> + [ + SRCategory("CategoryAttributeMisc"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeElementPosition_Auto"), + NotifyParentPropertyAttribute(true), + RefreshPropertiesAttribute(RefreshProperties.All), + #if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) + #endif + ] + public bool Auto + { + get + { + return _auto; + } + set + { + if(value != _auto) + { + ResetAllAreasAutoPosition(value); + + if(value) + { + this._x = 0; + this._y = 0; + this._width = 0; + this._height = 0; + } + _auto = value; + + this.Invalidate(); + } + } + } + + #endregion + } + + /// <summary> + /// Used for invoking windows forms MesageBox dialog. + /// </summary> + internal interface IDesignerMessageBoxDialog + { + /// <summary> + /// Shows Yes/No MessageBox. + /// </summary> + /// <param name="message">The message.</param> + /// <returns> + /// true if user confirms with Yes + /// </returns> + bool ShowQuestion(string message); + } +} diff --git a/System.Web.DataVisualization/Common/Utilities/ImageLoader.cs b/System.Web.DataVisualization/Common/Utilities/ImageLoader.cs new file mode 100644 index 000000000..1b07b467c --- /dev/null +++ b/System.Web.DataVisualization/Common/Utilities/ImageLoader.cs @@ -0,0 +1,421 @@ +//------------------------------------------------------------- +// <copyright company=’Microsoft Corporation’> +// Copyright © Microsoft Corporation. All Rights Reserved. +// </copyright> +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ImageLoader.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Utilities +// +// Classes: ImageLoader +// +// Purpose: ImageLoader utility class loads specified image and +// caches it in the memory for the future use. +// +// Images can be loaded from different places including +// Files, URIs, WebRequests and Control Resources. +// +// Reviewed: AG - August 7, 2002 +// AG - Microsoft 5, 2007 +// +//=================================================================== + + +#region Used Namespaces + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Reflection; +using System.Net; +using System.IO; +using System.Security; +using System.Resources; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web; + using System.Web.UI.DataVisualization.Charting; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Utilities +#else + namespace System.Web.UI.DataVisualization.Charting.Utilities +#endif +{ + /// <summary> + /// ImageLoader utility class loads and returns specified image + /// form the File, URI, Web Request or Chart Resources. + /// Loaded images are stored in the internal hashtable which + /// allows to improve performance if image need to be used + /// several times. + /// </summary> + internal class ImageLoader : IDisposable, IServiceProvider + { + #region Fields + + // Image storage + private Hashtable _imageData = null; + + // Reference to the service container + private IServiceContainer _serviceContainer = null; + + #endregion + + #region Constructors and Initialization + + /// <summary> + /// Default constructor is not accessible. + /// </summary> + private ImageLoader() + { + } + + /// <summary> + /// Default public constructor. + /// </summary> + /// <param name="container">Service container.</param> + public ImageLoader(IServiceContainer container) + { + if(container == null) + { + throw(new ArgumentNullException(SR.ExceptionImageLoaderInvalidServiceContainer)); + } + _serviceContainer = container; + } + + /// <summary> + /// Returns Image Loader service object + /// </summary> + /// <param name="serviceType">Requested service type.</param> + /// <returns>Image Loader service object.</returns> + [EditorBrowsableAttribute(EditorBrowsableState.Never)] + object IServiceProvider.GetService(Type serviceType) + { + if(serviceType == typeof(ImageLoader)) + { + return this; + } + throw (new ArgumentException( SR.ExceptionImageLoaderUnsupportedType( serviceType.ToString()))); + } + + /// <summary> + /// Dispose images in the hashtable + /// </summary> + public void Dispose() + { + if (_imageData != null) + { + foreach (DictionaryEntry entry in _imageData) + { + if (entry.Value is IDisposable) + { + ((IDisposable)entry.Value).Dispose(); + } + } + _imageData = null; + GC.SuppressFinalize(this); + } + } + + #endregion + + #region Methods + + /// <summary> + /// Loads image from URL. Checks if image already loaded (cached). + /// </summary> + /// <param name="imageURL">Image name (FileName, URL, Resource).</param> + /// <returns>Image object.</returns> + public System.Drawing.Image LoadImage(string imageURL) + { + return LoadImage(imageURL, true); + } + + /// <summary> + /// Loads image from URL. Checks if image already loaded (cached). + /// </summary> + /// <param name="imageURL">Image name (FileName, URL, Resource).</param> + /// <param name="saveImage">True if loaded image should be saved in cache.</param> + /// <returns>Image object</returns> + public System.Drawing.Image LoadImage(string imageURL, bool saveImage) + { + System.Drawing.Image image = null; + + // Check if image is defined in the chart image collection + if (_serviceContainer != null) + { + Chart chart = (Chart)_serviceContainer.GetService(typeof(Chart)); + if(chart != null) + { + foreach(NamedImage namedImage in chart.Images) + { + if(namedImage.Name == imageURL) + { + return namedImage.Image; + } + } + } + } + + // Create new hashtable + if (_imageData == null) + { + _imageData = new Hashtable(StringComparer.OrdinalIgnoreCase); + } + + // First check if image with this name already loaded + if (_imageData.Contains(imageURL)) + { + image = (System.Drawing.Image)_imageData[imageURL]; + } + +#if ! Microsoft_CONTROL + + // Try to load as relative URL using the Control object + if(image == null) + { + Chart control = (Chart)_serviceContainer.GetService(typeof(Chart)); + if (control != null && control.Page != null) + { + if (!control.IsDesignMode()) + { + image = LoadFromFile(control.Page.MapPath(imageURL)); + } + else if (control.IsDesignMode() && !String.IsNullOrEmpty(control.webFormDocumentURL)) + { + // Find current web page path and fileName + Uri pageUri = new Uri(control.webFormDocumentURL); + string path = pageUri.LocalPath; + string pageFile = pageUri.Segments[pageUri.Segments.Length-1]; + + // Find full image fileName + string imageFileRelative = control.ResolveClientUrl(imageURL); + string imageFile = path.Replace(pageFile, imageFileRelative); + + // Load image + image = LoadFromFile(imageFile); + } + } + + else if ( HttpContext.Current != null ) + { + image = LoadFromFile(HttpContext.Current.Request.MapPath(imageURL)); + } + } +#endif + + // Try to load image from resource + if(image == null) + { + try + { + + // Check if resource class type was specified + int columnIndex = imageURL.IndexOf("::", StringComparison.Ordinal); + if (columnIndex > 0) + { + string resourceRootName = imageURL.Substring(0, columnIndex); + string resourceName = imageURL.Substring(columnIndex + 2); + System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(resourceRootName, Assembly.GetExecutingAssembly()); + image = (System.Drawing.Image)(resourceManager.GetObject(resourceName)); + } +#if Microsoft_CONTROL + else if (Assembly.GetEntryAssembly() != null) + { + // Check if resource class type was specified + columnIndex = imageURL.IndexOf(':'); + if (columnIndex > 0) + { + string resourceRootName = imageURL.Substring(0, columnIndex); + string resourceName = imageURL.Substring(columnIndex + 1); + System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(resourceRootName, Assembly.GetEntryAssembly()); + image = (Image)(resourceManager.GetObject(resourceName)); + } + else + { + // Try to load resource from every type defined in entry assembly + Assembly entryAssembly = Assembly.GetEntryAssembly(); + if (entryAssembly != null) + { + foreach (Type type in entryAssembly.GetTypes()) + { + System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(type); + try + { + image = (Image)(resourceManager.GetObject(imageURL)); + } + catch (ArgumentNullException) + { + } + catch (MissingManifestResourceException) + { + } + + // Check if image was loaded + if (image != null) + { + break; + } + } + } + } + } +#endif + } + catch (MissingManifestResourceException) + { + } + } + + + // Try to load image using the Web Request + if(image == null) + { + Uri imageUri = null; + try + { + // Try to create URI directly from image URL (will work in case of absolute URL) + imageUri = new Uri(imageURL); + } + catch(UriFormatException) + {} + + + // Load image from file or web resource + if(imageUri != null) + { + try + { + WebRequest request = WebRequest.Create(imageUri); + image = System.Drawing.Image.FromStream(request.GetResponse().GetResponseStream()); + } + catch (ArgumentException) + { + } + catch (NotSupportedException) + { + } + catch (SecurityException) + { + } + } + } +#if Microsoft_CONTROL + // absolute uri(without Server.MapPath)in web is not allowed. Loading from replative uri Server[Page].MapPath is done above. + // Try to load as file + if(image == null) + { + + image = LoadFromFile(imageURL); + } +#endif + + // Error loading image + if(image == null) + { +#if ! Microsoft_CONTROL + throw(new ArgumentException( SR.ExceptionImageLoaderIncorrectImageUrl( imageURL ) ) ); +#else + throw(new ArgumentException( SR.ExceptionImageLoaderIncorrectImageLocation( imageURL ) ) ); +#endif + } + + // Save new image in cache + if(saveImage) + { + _imageData[imageURL] = image; + } + + return image; + } + + /// <summary> + /// Helper function which loads image from file. + /// </summary> + /// <param name="fileName">File name.</param> + /// <returns>Loaded image or null.</returns> + private System.Drawing.Image LoadFromFile(string fileName) + { + // Try to load image from file + try + { + return System.Drawing.Image.FromFile(fileName); + } + catch(FileNotFoundException) + { + return null; + } + } + + /// <summary> + /// Returns the image size taking the image DPI into consideration. + /// </summary> + /// <param name="name">Image name (FileName, URL, Resource).</param> + /// <param name="graphics">Graphics used to calculate the image size.</param> + /// <param name="size">Calculated size.</param> + /// <returns>false if it fails to calculate the size, otherwise true.</returns> + internal bool GetAdjustedImageSize(string name, Graphics graphics, ref SizeF size) + { + Image image = LoadImage(name); + + if (image == null) + return false; + + GetAdjustedImageSize(image, graphics, ref size); + + return true; + } + + /// <summary> + /// Returns the image size taking the image DPI into consideration. + /// </summary> + /// <param name="image">Image for whcih to calculate the size.</param> + /// <param name="graphics">Graphics used to calculate the image size.</param> + /// <param name="size">Calculated size.</param> + internal static void GetAdjustedImageSize(Image image, Graphics graphics, ref SizeF size) + { + if (graphics != null) + { + //this will work in case the image DPI is specified, otherwise the image DPI will be assumed to be same as the screen DPI + size.Width = image.Width * graphics.DpiX / image.HorizontalResolution; + size.Height = image.Height * graphics.DpiY / image.VerticalResolution; + } + else + { + size.Width = image.Width; + size.Height = image.Height; + } + } + + /// <summary> + /// Checks if the image has the same DPI as the graphics object. + /// </summary> + /// <param name="image">Image to be checked.</param> + /// <param name="graphics">Graphics object to be used.</param> + /// <returns>true if they match, otherwise false.</returns> + internal static bool DoDpisMatch(Image image, Graphics graphics) + { + return graphics.DpiX == image.HorizontalResolution && graphics.DpiY == image.VerticalResolution; + } + + internal static Image GetScaledImage(Image image, Graphics graphics) + { + Bitmap scaledImage = new Bitmap(image, new Size((int)(image.Width * graphics.DpiX / image.HorizontalResolution), + (int)(image.Height * graphics.DpiY / image.VerticalResolution))); + + return scaledImage; + } + + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Utilities/KeywordsRegistry.cs b/System.Web.DataVisualization/Common/Utilities/KeywordsRegistry.cs new file mode 100644 index 000000000..09fbdaac8 --- /dev/null +++ b/System.Web.DataVisualization/Common/Utilities/KeywordsRegistry.cs @@ -0,0 +1,495 @@ +//------------------------------------------------------------- +// <copyright company=’Microsoft Corporation’> +// Copyright © Microsoft Corporation. All Rights Reserved. +// </copyright> +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: KeywordsRegistry.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Utilities +// +// Classes: KeywordsRegistry, KeywordInfo +// +// Purpose: A registry that keeps track of all available +// keywords and name of the objects and properties +// where they can be used. +// +// Formatting Keywords Overview: +// ----------------------------- +// A Formatting Keyword is a specially formatted character sequence +// that gets replaced by an associated Chart Series value, or +// calculated value. Keywords can be used with most string properties +// of Series and DataPoint objects. +// +// Here is an example of setting series labels so that the first +// line will display the Y value and the second line displays +// the X value. +// +// Chart1.Series["Series1"].Label = "Y = #VALY\nX = #VALX"; +// +// Series label in this case will look like this: +// +// Y = 45.78 +// X = 456 +// +// An optional format string can be added after the keyword. +// For example, when you set the Format option to Percent for +// the first Y value, the resulting keyword produced is "#VALY{P}". +// You can also apply format strings in code-behind using the same +// nomenclature; you do this by following the keyword with a format +// specifier enclosed in braces. For information concerning the +// types of formatting that can be used, see the Formatting Types +// topic in the MSDN library. +// +// Reviewed: AG - Microsoft 5, 2007 +// +//=================================================================== + + +#region Used Namespaces + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +#else +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Utilities +#else // Microsoft_CONTROL + namespace System.Web.UI.DataVisualization.Charting.Utilities +#endif // Microsoft_CONTROL +{ + /// <summary> + /// KeywordName class contains constant strings defining + /// names of all keywords used in the data point and series classes. + /// </summary> + internal static class KeywordName + { + #region Keyword Names + + internal const string Index = "#INDEX"; + internal const string ValX = "#VALX"; + internal const string ValY = "#VALY"; + internal const string Val = "#VAL"; + internal const string Total = "#TOTAL"; + internal const string Percent = "#PERCENT"; + internal const string Label = "#LABEL"; + internal const string AxisLabel = "#AXISLABEL"; + internal const string LegendText = "#LEGENDTEXT"; + internal const string SeriesName = "#SERIESNAME"; + internal const string Ser = "#SER"; + internal const string Avg = "#AVG"; + internal const string Max = "#MAX"; + internal const string Min = "#MIN"; + internal const string Last = "#LAST"; + internal const string First = "#FIRST"; + internal const string CustomProperty = "#CUSTOMPROPERTY"; + + #endregion // Keyword Names + } + + /// <summary> + /// KeywordRegistry class stores information about all + /// chart formatting keywords. It automatically registers + /// all known keywords when object is constructed. This + /// data is exposed as ArrayList through the ‘registeredKeywords’ + /// field. Each item in this ArrayList is a KeywordInfo + /// object which describes a single formatting keyword. + /// </summary> + internal class KeywordsRegistry : IServiceProvider + { + #region Fields + + // List of registered keywords + internal ArrayList registeredKeywords = new ArrayList(); + + #endregion + + #region Constructor and Services + + /// <summary> + /// Keywords registry public constructor. + /// </summary> + public KeywordsRegistry() + { + // Register Keywords used in the chart + RegisterKeywords(); + } + + /// <summary> + /// Returns Keywords registry service object. + /// </summary> + /// <param name="serviceType">Service type to get.</param> + /// <returns>Custom properties registry service.</returns> + [EditorBrowsableAttribute(EditorBrowsableState.Never)] + object IServiceProvider.GetService(Type serviceType) + { + if(serviceType == typeof(KeywordsRegistry)) + { + return this; + } + throw (new ArgumentException( SR.ExceptionKeywordsRegistryUnsupportedType(serviceType.ToString()))); + } + + #endregion + + #region Keywords Registering methods + + /// <summary> + /// Registers all chart formatting keywords. + /// </summary> + private void RegisterKeywords() + { + string seriesPointSupportedProperties = "Text,Label,LabelMapAreaAttributes,ToolTip,Url,LabelToolTip,MapAreaAttributes,AxisLabel,LegendToolTip,LegendMapAreaAttributes,LegendUrl,LegendText"; + + // #INDEX keyword + this.Register( + SR.DescriptionKeyWordNameIndexDataPoint, + KeywordName.Index, + string.Empty, + SR.DescriptionKeyWordIndexDataPoint2, + "DataPoint", + seriesPointSupportedProperties, + false, + false); + + // #VALX keyword + this.Register( + SR.DescriptionKeyWordNameXValue, + KeywordName.ValX, + string.Empty, + SR.DescriptionKeyWordXValue, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + true, + false); + + // #VALY keyword + this.Register( + SR.DescriptionKeyWordNameYValue, + KeywordName.Val, + string.Empty, + SR.DescriptionKeyWordYValue, + "Series,DataPoint,Annotation,LegendCellColumn,LegendCellColumn", + seriesPointSupportedProperties, + true, + true); + + // #TOTAL keyword + this.Register( + SR.DescriptionKeyWordNameTotalYValues, + KeywordName.Total, + string.Empty, + SR.DescriptionKeyWordTotalYValues, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + true, + false); + + // #PERCENT keyword + this.Register( + SR.DescriptionKeyWordNameYValuePercentTotal, + KeywordName.Percent, + string.Empty, + SR.DescriptionKeyWordYValuePercentTotal, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + true, + true); + + // #INDEX keyword + this.Register( + SR.DescriptionKeyWordNameIndexTheDataPoint, + KeywordName.Index, + string.Empty, + SR.DescriptionKeyWordIndexDataPoint, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + false, + false); + + // #LABEL keyword + this.Register( + SR.DescriptionKeyWordNameLabelDataPoint, + KeywordName.Label, + string.Empty, + SR.DescriptionKeyWordLabelDataPoint, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + false, + false); + + // #AXISLABEL keyword + this.Register( + SR.DescriptionKeyWordNameAxisLabelDataPoint, + KeywordName.AxisLabel, + string.Empty, + SR.DescriptionKeyWordAxisLabelDataPoint, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + false, + false); + + // #LEGENDTEXT keyword + this.Register( + SR.DescriptionKeyWordNameLegendText, + KeywordName.LegendText, + string.Empty, + SR.DescriptionKeyWordLegendText, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + false, + false); + + // #SERIESNAME keyword + this.Register( + SR.DescriptionKeyWordNameSeriesName, + KeywordName.SeriesName, + KeywordName.Ser, + SR.DescriptionKeyWordSeriesName, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + false, + false); + + // *************** NEW KEYWORDS in version 5.5 *************** + + // #AVG keyword + this.Register( + SR.DescriptionKeyWordNameAverageYValues, + KeywordName.Avg, + string.Empty, + SR.DescriptionKeyWordAverageYValues, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + true, + true); + + // #MAX keyword + this.Register( + SR.DescriptionKeyWordNameMaximumYValues, + KeywordName.Max, + string.Empty, + SR.DescriptionKeyWordMaximumYValues, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + true, + true); + + // #MIN keyword + this.Register( + SR.DescriptionKeyWordNameMinimumYValues, + KeywordName.Min, + string.Empty, + SR.DescriptionKeyWordMinimumYValues, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + true, + true); + + // #LAST keyword + this.Register( + SR.DescriptionKeyWordNameLastPointYValue, + KeywordName.Last, + string.Empty, + SR.DescriptionKeyWordLastPointYValue, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + true, + true); + + // #FIRST keyword + this.Register( + SR.DescriptionKeyWordNameFirstPointYValue, + KeywordName.First, + string.Empty, + SR.DescriptionKeyWordFirstPointYValue, + "Series,DataPoint,Annotation,LegendCellColumn", + seriesPointSupportedProperties, + true, + true); + } + + #endregion // Keywords Registering methods + + #region Registry methods + + /// <summary> + /// Adds keyword information into the registry. + /// </summary> + /// <param name="name">Keyword full name.</param> + /// <param name="keyword">Keyword text.</param> + /// <param name="keywordAliases">Keyword alternative text.</param> + /// <param name="description">Keyword description.</param> + /// <param name="appliesToTypes">Comma separated list of applicable classes</param> + /// <param name="appliesToProperties">Comma separated list of applicable properties.</param> + /// <param name="supportsFormatting">True if formatting is supported.</param> + /// <param name="supportsValueIndex">True if different point Y values are supported.</param> + public void Register( + string name, + string keyword, + string keywordAliases, + string description, + string appliesToTypes, + string appliesToProperties, + bool supportsFormatting, + bool supportsValueIndex) + { + // Create new keyword information object + KeywordInfo keywordInfo = new KeywordInfo( + name, + keyword, + keywordAliases, + description, + appliesToTypes, + appliesToProperties, + supportsFormatting, + supportsValueIndex); + + // Add keyword information to the hash table + registeredKeywords.Add(keywordInfo); + } + + #endregion + } + + /// <summary> + /// KeywordInfo class stores information about a single + /// formatting keyword. This information includes Name, + /// Description, list of data types and properties it + /// applies to and other information. + /// </summary> + internal class KeywordInfo + { + #region Public Fields + + /// <summary> + /// Keyword full name. + /// </summary> + public string Name = String.Empty; + + /// <summary> + /// String that represent this keyword in the property (keyword). + /// </summary> + public string Keyword = String.Empty; + + /// <summary> + /// Comma separated strings that may alternatively represent this + /// keyword in the property. + /// </summary> + public string KeywordAliases = String.Empty; + + /// <summary> + /// Keyword description. + /// </summary> + public string Description = String.Empty; + + /// <summary> + /// Comma separated names of classes this keyword applies to. + /// </summary> + public string AppliesToTypes = String.Empty; + + /// <summary> + /// Comma separated names of properties this keyword applies to. + /// </summary> + public string AppliesToProperties = String.Empty; + + /// <summary> + /// True if keyword value can be formatted. + /// </summary> + public bool SupportsFormatting = false; + + /// <summary> + /// True if keyword can be used with different point Y values. + /// </summary> + public bool SupportsValueIndex = false; + + #endregion // Public Fields + + #region Constructor + + /// <summary> + /// Keyword information object constructor + /// </summary> + /// <param name="name">Keyword full name.</param> + /// <param name="keyword">Keyword text.</param> + /// <param name="keywordAliases">Keyword alternative text.</param> + /// <param name="description">Keyword description.</param> + /// <param name="appliesToTypes">Comma separated list of applicable classes</param> + /// <param name="appliesToProperties">Comma separated list of applicable properties.</param> + /// <param name="supportsFormatting">True if formatting is supported.</param> + /// <param name="supportsValueIndex">True if different point Y values are supported.</param> + public KeywordInfo( + string name, + string keyword, + string keywordAliases, + string description, + string appliesToTypes, + string appliesToProperties, + bool supportsFormatting, + bool supportsValueIndex) + { + this.Name = name; + this.Keyword = keyword; + this.KeywordAliases = keywordAliases; + this.Description = description; + this.AppliesToTypes = appliesToTypes; + this.AppliesToProperties = appliesToProperties; + this.SupportsFormatting = supportsFormatting; + this.SupportsValueIndex = supportsValueIndex; + } + + #endregion // Constructor + + #region Methods + + /// <summary> + /// Returns a String that represents the current keyword Information. + /// </summary> + /// <returns>Returns keyword name.</returns> + public override string ToString() + { + return this.Name; + } + /// <summary> + /// Gets an array of keywords names including the aliases. + /// </summary> + /// <returns>A string array of keyword names that represent this keyword.</returns> + public string[] GetKeywords() + { + // NOTE: Each keyword has a unique name. In addition the keyword may have an + // alternative names (aliases). + // Most common scenario for a keyword aliase is when keyword has a long and + // short form. For example, KeywordName.Ser and "#SERIES". + + // Fill array of possible names for that keyword + if(this.KeywordAliases.Length > 0) + { + string[] keywordAliases = this.KeywordAliases.Split(','); + string[] keywordNames = new string[keywordAliases.Length + 1]; + keywordNames[0] = this.Keyword; + keywordAliases.CopyTo(keywordNames, 1); + return keywordNames; + } + else + { + return new string[] { this.Keyword }; + } + } + + #endregion // Methods + } +} + diff --git a/System.Web.DataVisualization/Common/Utilities/ValueConverter.cs b/System.Web.DataVisualization/Common/Utilities/ValueConverter.cs new file mode 100644 index 000000000..24a08a055 --- /dev/null +++ b/System.Web.DataVisualization/Common/Utilities/ValueConverter.cs @@ -0,0 +1,194 @@ +//------------------------------------------------------------- +// <copyright company=’Microsoft Corporation’> +// Copyright © Microsoft Corporation. All Rights Reserved. +// </copyright> +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: ValueConverter.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Utilities +// +// Classes: ValueConverter +// +// Purpose: Helper class which converts DateTime or numeric +// values to string. It used to display data point +// values as labels, tooltips and axis labels. +// +// Reviewed: AG - August 7, 2002 +// AG - Microsoft 5, 2007 +// +//=================================================================== + + +#region Used Namespaces + +using System; +using System.Globalization; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting; +#else + using System.Web.UI.DataVisualization.Charting; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Utilities +#else + namespace System.Web.UI.DataVisualization.Charting.Utilities +#endif +{ + /// <summary> + /// ValueConverter class is used when numeric or DateTime + /// value needs to be converted to a string using specified format. + /// </summary> + internal static class ValueConverter + { + #region Methods + + /// <summary> + /// Converts value to string using specified format. + /// </summary> + /// <param name="chart">Reference to the chart object.</param> + /// <param name="obj">Reference to the object being formatted.</param> + /// <param name="objTag">Additional object tag.</param> + /// <param name="value">Value converted to string.</param> + /// <param name="format">Format string.</param> + /// <param name="valueType">Value type.</param> + /// <param name="elementType">Chart element type being formatted.</param> + public static string FormatValue( + Chart chart, + object obj, + object objTag, + double value, + string format, + ChartValueType valueType, + ChartElementType elementType) + { + format = format ?? String.Empty; + string convertionFormat = format; + string result = ""; + + // Make sure value index is part of the format + if(convertionFormat != null && convertionFormat.Length > 0) + { + int bracketIndex = convertionFormat.IndexOf('{', 0); + if(bracketIndex >= 0) + { + while(bracketIndex >= 0) + { + // If format is not followed by the value index + if(!convertionFormat.Substring(bracketIndex).StartsWith("{0:", StringComparison.Ordinal)) + { + // Check charcter prior to the bracket + if(bracketIndex >= 1 && convertionFormat.Substring(bracketIndex - 1, 1) == "{") + { + continue; + } + else + { + // Insert value index in format + convertionFormat = convertionFormat.Insert(bracketIndex + 1, "0:"); + } + } + + bracketIndex = convertionFormat.IndexOf('{', bracketIndex + 1); + } + } + else + { + convertionFormat = "{0:" + convertionFormat + "}"; + } + } + + // Date/time formating + if (valueType == ChartValueType.DateTime || + valueType == ChartValueType.DateTimeOffset || + valueType == ChartValueType.Date) + { + // Set default format + if(convertionFormat.Length == 0) + { + convertionFormat = "{0:d}"; + if (valueType == ChartValueType.DateTimeOffset) + convertionFormat += " +0"; + } + + // Convert date to string + result = String.Format(CultureInfo.CurrentCulture, convertionFormat, DateTime.FromOADate(value)); + } + else if(valueType == ChartValueType.Time) + { + // Set default format + if(convertionFormat.Length == 0) + { + convertionFormat = "{0:t}"; + } + + // Convert date to string + result = String.Format(CultureInfo.CurrentCulture, convertionFormat, DateTime.FromOADate(value)); + } + else + { + bool failedFlag = false; + + // Set default format + if(convertionFormat.Length == 0) + { + convertionFormat = "{0:G}"; + } + + try + { + // Numeric value formatting + result = String.Format(CultureInfo.CurrentCulture,convertionFormat, value); + } + catch(FormatException) + { + failedFlag = true; + } + + // If numeric formatting failed try to format using decimal number + if(failedFlag) + { + failedFlag = false; + try + { + // Decimal value formatting + result = String.Format(CultureInfo.CurrentCulture, convertionFormat, (long)value); + } + catch (ArgumentNullException) + { + failedFlag = true; + } + catch (FormatException) + { + failedFlag = true; + } + } + + // Return format string as result (literal) if all formatting methods failed + if(failedFlag) + { + result = format; + } + } + + // For the Reporting Services chart a special number formatting + // handler may be set and used for all formatting needs. + if (chart != null) + { + // Call number formatter + FormatNumberEventArgs eventArguments = new FormatNumberEventArgs(value, format, valueType, result, objTag, elementType); + chart.CallOnFormatNumber(obj, eventArguments); + result = eventArguments.LocalizedValue; + } + + return result; + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/Common/Utilities/XmlSerializer.cs b/System.Web.DataVisualization/Common/Utilities/XmlSerializer.cs new file mode 100644 index 000000000..000f56f2d --- /dev/null +++ b/System.Web.DataVisualization/Common/Utilities/XmlSerializer.cs @@ -0,0 +1,3274 @@ +//------------------------------------------------------------- +// <copyright company=’Microsoft Corporation’> +// Copyright © Microsoft Corporation. All Rights Reserved. +// </copyright> +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: XmlSerializer.cs +// +// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Utilities +// +// Classes: XmlFormatSerializer, BinaryFormatSerializer +// SerializerBase, SerializationVisibilityAttribute +// +// Purpose: +// +// Chart serializer allows persisting of all chart data and +// settings into the stream or file using XML or binary format. +// This data can be later loaded back into the chart completely +// restoring its state. Serialize can also be used to reset chart +// control state to its default values. +// +// Both XML and Binary serialization methods use reflection to +// discover class properties which need to be serialized. Only +// properties with non-default values are persisted. Full Trust +// is required to use chartserialization. +// +// SerializeBase class implements all the chart serializer +// properties and methods to reset chart content. XmlFormatSerializer +// and BinaryFormatSerializer classes derive from the SerializeBase +// class and provide saving and loading functionality for XML and +// binary format. +// +// By default, all chart content is Saved, Loaded or Reset, but +// this can be changed using serializer Content, SerializableContent +// and NonSerializableContent properties. Content property allows a +// simple way to serialize everything, appearance or just chart data. +// +// SerializableContent and NonSerializableContent properties provide +// more control over what is beign persisted and they override the +// Content property settings. Each of the properties is a string +// which is a comma-separated listing of all chart properties to be +// serialized. The syntax of this property is "Class.Property[,Class.Property]", +// and wildcards may be used (represented by an asterisk). For example, +// to serialize all chart BackColor properties set this property to +// "*.BackColor". +// +// Reviewed: AG - August 7, 2002 +// AG - Microsoft 6, 2007 +// +//=================================================================== + + +#region Used Namespaces + +using System; +using System.Xml; +using System.Reflection; +using System.Collections; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.ComponentModel; +using System.IO; +using System.Text; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; +using System.Collections.Specialized; +using System.Security; + +#if Microsoft_CONTROL + using System.Windows.Forms.DataVisualization.Charting.ChartTypes; +#else + using System.Web.UI.WebControls; + using System.Web.UI.DataVisualization.Charting.ChartTypes; +#endif + +#endregion + +#if Microsoft_CONTROL + namespace System.Windows.Forms.DataVisualization.Charting.Utilities +#else + namespace System.Web.UI.DataVisualization.Charting.Utilities +#endif +{ + #region Serialization enumerations + + /// <summary> + /// Enumeration which describes how to persist property during the serialization + /// </summary> + internal enum SerializationVisibility + { + /// <summary> + /// Do not serialize + /// </summary> + Hidden, + + /// <summary> + /// Serialize as XML attribute + /// </summary> + Attribute, + + /// <summary> + /// Serialize as XML element + /// </summary> + Element + } + + /// <summary> + /// Determines chart current serialization status. + /// </summary> + internal enum SerializationStatus + { + /// <summary> + /// Chart is not serializing + /// </summary> + None, + + /// <summary> + /// Chart is loading + /// </summary> + Loading, + + /// <summary> + /// Chart is saving + /// </summary> + Saving, + + /// <summary> + /// Chart is resetting + /// </summary> + Resetting + } + + #endregion + + /// <summary> + /// Attribute which describes how to persist property during the serialization. + /// </summary> + [AttributeUsage(AttributeTargets.All)] + internal sealed class SerializationVisibilityAttribute : System.Attribute + { + #region Fields + + // Visibility style + private SerializationVisibility _visibility = SerializationVisibility.Attribute; + + #endregion + + #region Constructor + + /// <summary> + /// Public constructor + /// </summary> + /// <param name="visibility">Serialization visibility.</param> + internal SerializationVisibilityAttribute(SerializationVisibility visibility) + { + this._visibility = visibility; + } + + #endregion + + #region Properties + + /// <summary> + /// Serialization visibility property + /// </summary> + public SerializationVisibility Visibility + { + get + { + return _visibility; + } + //set + //{ + // _visibility = value; + //} + } + + #endregion + } + + /// <summary> + /// Base class of the serializers. Common properties and methods for all serializers. + /// </summary> + internal abstract class SerializerBase + { + #region Fields + + /// <summary> + /// Indicates that unknown properties and elements are ignored + /// </summary> + private bool _isUnknownAttributeIgnored = false; + + /// <summary> + /// Indicates that serializer works in template creation mode + /// </summary> + private bool _isTemplateMode = false; + + /// <summary> + /// Indicates that object properties are reset before loading + /// </summary> + private bool _isResetWhenLoading = true; + + /// <summary> + /// Comma separated list of serializable (Save/Load/Reset) properties. "ClassName.PropertyName" + /// </summary> + private string _serializableContent = ""; + + /// <summary> + /// Comma separated list of NON serializable (Save/Load/Reset) properties. "ClassName.PropertyName" + /// </summary> + private string _nonSerializableContent = ""; + + /// <summary> + /// Font converters used while serializing/deserializing + /// </summary> + internal static FontConverter fontConverter = new FontConverter(); + + /// <summary> + /// Color converters used while serializing/deserializing + /// </summary> + internal static ColorConverter colorConverter = new ColorConverter(); + + /// <summary> + /// Hash code provider. + /// </summary> + protected static StringComparer hashCodeProvider = StringComparer.OrdinalIgnoreCase; + + /// <summary> + /// Contains chart specific converters + /// </summary> + HybridDictionary _converterDict = new HybridDictionary(); + + + #endregion + + #region Public properties + + /// <summary> + /// Indicates that unknown properties and elements will be + /// ignored without throwing an exception. + /// </summary> + internal bool IsUnknownAttributeIgnored + { + get + { + return _isUnknownAttributeIgnored; + } + set + { + _isUnknownAttributeIgnored = value; + } + } + + /// <summary> + /// Indicates that serializer works in template creation mode + /// </summary> + internal bool IsTemplateMode + { + get + { + return _isTemplateMode; + } + set + { + _isTemplateMode = value; + } + } + + /// <summary> + /// Indicates that object properties are reset to default + /// values before loading. + /// </summary> + internal bool IsResetWhenLoading + { + get + { + return _isResetWhenLoading; + } + set + { + _isResetWhenLoading = value; + } + } + + /// <summary> + /// Comma separated list of serializable (Save/Load/Reset) properties. + /// "ClassName.PropertyName,[ClassName.PropertyName]". + /// </summary> + internal string SerializableContent + { + get + { + return _serializableContent; + } + set + { + _serializableContent = value; + + // Reset list + serializableContentList = null; + } + } + + /// <summary> + /// Comma separated list of serializable (Save/Load/Reset) properties. + /// "ClassName.PropertyName,[ClassName.PropertyName]". + /// </summary> + internal string NonSerializableContent + { + get + { + return _nonSerializableContent; + } + set + { + _nonSerializableContent = value; + + // Reset list + nonSerializableContentList = null; + } + } + + #endregion + + #region Resetting methods + + /// <summary> + /// Reset properties of the object to default values. + /// </summary> + /// <param name="objectToReset">Object to be reset.</param> + virtual internal void ResetObjectProperties(object objectToReset) + { + // Reset object properties + ResetObjectProperties(objectToReset, null, GetObjectName(objectToReset)); + } + + /// <summary> + /// Reset properties of the object to default values. + /// Method is called recursively to reset child objects properties. + /// </summary> + /// <param name="objectToReset">Object to be reset.</param> + /// <param name="parent">Parent of the reset object.</param> + /// <param name="elementName">Object element name.</param> + virtual internal void ResetObjectProperties(object objectToReset, object parent, string elementName) + { + // Check input parameters + if(objectToReset == null) + { + return; + } + + IList list = objectToReset as IList; + + // Check if object is a list + if(list != null && IsSerializableContent(elementName, parent)) + { + // Reset list by clearing all the items + list.Clear(); + return; + } + + // Retrive properties list of the object + PropertyInfo[] properties = objectToReset.GetType().GetProperties(); + if(properties != null) + { + // Loop through all properties and reset public properties + foreach(PropertyInfo pi in properties) + { + // Get property descriptor + PropertyDescriptor pd = TypeDescriptor.GetProperties(objectToReset)[pi.Name]; + + // Check XmlFormatSerializerStyle attribute + if(pd != null) + { + SerializationVisibilityAttribute styleAttribute = (SerializationVisibilityAttribute)pd.Attributes[typeof(SerializationVisibilityAttribute)]; + if(styleAttribute != null) + { + // Hidden property + if(styleAttribute.Visibility == SerializationVisibility.Hidden) + { + continue; + } + } + } + + // Check if this property should be reset + bool resetProperty = IsSerializableContent(pi.Name, objectToReset); + + // Skip inherited properties from the root object + if(IsChartBaseProperty(objectToReset, parent, pi)) + { + continue; + } + + // Reset list + if(pi.CanRead && pi.PropertyType.GetInterface("IList", true) != null) + { + if(resetProperty) + { + // Check if collection has "Reset" method + bool resetComplete = false; + MethodInfo mi = objectToReset.GetType().GetMethod("Reset" + pi.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + if(mi != null) + { + mi.Invoke(objectToReset, null); + resetComplete = true; + } + + // Reset list by clearing all the items + if(!resetComplete) + { + ((IList)pi.GetValue(objectToReset, null)).Clear(); + } + } + else + { + // Reset objects of the list + foreach(object listObject in ((IList)pi.GetValue(objectToReset, null))) + { + ResetObjectProperties(listObject, objectToReset, this.GetObjectName(listObject)); + } + } + } + + // Reset public properties with Get and Set methods + else if(pi.CanRead && pi.CanWrite) + { + // Skip indexes + if(pi.Name == "Item") + { + continue; + } + + // Skip Names + if (pi.Name == "Name") + { + continue; + } + + // Reset inner properies + if(ShouldSerializeAsAttribute(pi, objectToReset)) + { + if(resetProperty) + { + // Reset the property using property descriptor + + if(pd != null) + { + // Get property object + object objectProperty = pi.GetValue(objectToReset, null); + + // Get default value of the property + DefaultValueAttribute defValueAttribute = (DefaultValueAttribute)pd.Attributes[typeof(DefaultValueAttribute)]; + if(defValueAttribute != null) + { + if(objectProperty == null) + { + if(defValueAttribute.Value != null) + { + pd.SetValue(objectToReset, defValueAttribute.Value); + } + } + else if(! objectProperty.Equals(defValueAttribute.Value)) + { + pd.SetValue(objectToReset, defValueAttribute.Value); + } + } + else + { + // Check if property has "Reset" method + MethodInfo mi = objectToReset.GetType().GetMethod("Reset" + pi.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + if(mi != null) + { + mi.Invoke(objectToReset, null); + } + } + } + } + } + else + { + // Reset inner object + ResetObjectProperties(pi.GetValue(objectToReset, null), objectToReset, pi.Name); + } + } + } + } + return; + } + + + #endregion + + #region Abstract Serialization/Deserialization methods + + /// <summary> + /// Serialize specified object into the destination object. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="destination">Destination of the serialization.</param> + internal abstract void Serialize(object objectToSerialize, object destination); + + /// <summary> + /// Deserialize specified object from the source object. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="source">Source of the deserialization.</param> + internal abstract void Deserialize(object objectToDeserialize, object source); + + #endregion + + #region Protected helper methods + + /// <summary> + /// Converts specified font object into a string. + /// </summary> + /// <param name="font">Font object to convert.</param> + /// <returns>String that contains font data.</returns> + internal static string FontToString(Font font) + { + // Save basic properties persisted by font converter + string fontData = (string)SerializerBase.fontConverter.ConvertToInvariantString(font); + + // Persist properties not serialiazed by the converter + if(font.GdiCharSet != 1) + { + fontData += ", GdiCharSet=" + font.GdiCharSet.ToString(System.Globalization.CultureInfo.InvariantCulture); + } + if(font.GdiVerticalFont) + { + fontData += ", GdiVerticalFont"; + } + + return fontData; + } + + /// <summary> + /// Converts string data into a font object. + /// </summary> + /// <param name="fontString">String with font data.</param> + /// <returns>Newly created font object.</returns> + internal static Font FontFromString(string fontString) + { + // Check if string contains non-standard values "GdiCharSet" or "GdiVerticalFont" + string standardData = fontString; + byte gdiCharSet = 1; + bool gdiVerticalFont = false; + int charIndex = fontString.IndexOf(", GdiCharSet=", StringComparison.Ordinal); + if(charIndex >= 0) + { + // Read value + string val = fontString.Substring(charIndex + 13); + int commaIndex = val.IndexOf(",", StringComparison.Ordinal); + if(commaIndex >= 0) + { + val = val.Substring(0, commaIndex); + } + + gdiCharSet = (byte)Int32.Parse(val, System.Globalization.CultureInfo.InvariantCulture); + + // Truncate standard data string + if(standardData.Length > charIndex) + { + standardData = standardData.Substring(0, charIndex); + } + } + charIndex = fontString.IndexOf(", GdiVerticalFont", StringComparison.Ordinal); + if(charIndex >= 0) + { + gdiVerticalFont = true; + + // Truncate standard data string + if(standardData.Length > charIndex) + { + standardData = standardData.Substring(0, charIndex); + } + } + + // Create Font object from standard parameters + Font font = (Font)SerializerBase.fontConverter.ConvertFromInvariantString(standardData); + + // check if non-standard parameters provided + if(gdiVerticalFont || gdiCharSet != 1) + { + Font newFont = new Font( + font.Name, + font.SizeInPoints, + font.Style, + GraphicsUnit.Point, + gdiCharSet, + gdiVerticalFont); + + font.Dispose(); + + return newFont; + } + + return font; + } + + /// <summary> + /// Returns a hash code of a specified string. + /// </summary> + /// <param name="str">String to get the hash code for.</param> + /// <returns>String hash code.</returns> + internal static short GetStringHashCode(string str) + { + return (short)(hashCodeProvider.GetHashCode(str) + str.Length * 2); + } + + /// <summary> + /// Reads hash ID from the specified binary reader. + /// </summary> + /// <param name="reader">Binary reader to get the data from.</param> + /// <returns>Property name or collection member type ID.</returns> + internal Int16 ReadHashID(BinaryReader reader) + { + // For later versions return ID without transformations + return reader.ReadInt16(); + } + + /// <summary> + /// Checks if property belongs to the base class of the chart "Control". + /// </summary> + /// <param name="objectToSerialize">Serializable object.</param> + /// <param name="parent">Object parent.</param> + /// <param name="pi">Serializable property information.</param> + /// <returns>True if property belongs to the base class.</returns> + internal bool IsChartBaseProperty(object objectToSerialize, object parent, PropertyInfo pi) + { + bool result = false; + + // Check only for the root object + if(parent == null) + { + Type currentType = objectToSerialize.GetType(); + while(currentType != null) + { + if(pi.DeclaringType == currentType) + { + result = false; + break; + } + + // Check if it's a chart class + if( currentType == typeof(Chart)) + { + result = true; + break; + } + + // Get base class type + currentType = currentType.BaseType; + } + } + + return result; + } + + + /// <summary> + /// Converts Image object into the BASE64 encoded string + /// </summary> + /// <param name="image">Image to convert.</param> + /// <returns>BASE64 encoded image data.</returns> + internal static string ImageToString(System.Drawing.Image image) + { + // Save image into the stream using BASE64 encoding + MemoryStream imageStream = new MemoryStream(); + image.Save(imageStream, ImageFormat.Png); + imageStream.Seek(0, SeekOrigin.Begin); + + // Create XmlTextWriter and save image in BASE64 + StringBuilder stringBuilder = new StringBuilder(); + XmlTextWriter textWriter = new XmlTextWriter(new StringWriter(stringBuilder, CultureInfo.InvariantCulture)); + byte[] imageByteData = imageStream.ToArray(); + textWriter.WriteBase64(imageByteData, 0, imageByteData.Length); + + // Close image stream + textWriter.Close(); + imageStream.Close(); + + return stringBuilder.ToString(); + } + + /// <summary> + /// Converts BASE64 encoded string to image. + /// </summary> + /// <param name="data">BASE64 encoded data.</param> + /// <returns>Image.</returns> + internal static System.Drawing.Image ImageFromString(string data) + { + // Create XML text reader + byte[] buffer = new byte[1000]; + MemoryStream imageStream = new MemoryStream(); + XmlTextReader textReader = new XmlTextReader(new StringReader("<base64>" + data + "</base64>")); + + // Read tags and BASE64 encoded data + textReader.Read(); + int bytesRead = 0; + while((bytesRead = textReader.ReadBase64(buffer, 0, 1000)) > 0) + { + imageStream.Write(buffer, 0, bytesRead); + } + textReader.Read(); + + // Create image from stream + imageStream.Seek(0, SeekOrigin.Begin); + System.Drawing.Image tempImage = System.Drawing.Image.FromStream(imageStream); + System.Drawing.Bitmap image = new Bitmap(tempImage); // !!! .Net bug when image source stream is closed - can create brush using the image + image.SetResolution(tempImage.HorizontalResolution, tempImage.VerticalResolution); //The bitmap created using the constructor does not copy the resolution of the image + + // Close image stream + textReader.Close(); + imageStream.Close(); + + return image; + } + + /// <summary> + /// Get the name of the object class + /// </summary> + /// <param name="obj">Object to get the name of.</param> + /// <returns>Name of the object class (without namespace).</returns> + internal string GetObjectName(object obj) + { + string name = obj.GetType().ToString(); + return name.Substring(name.LastIndexOf('.') + 1); + } + + /// <summary> + /// Create new empty item for the list. + /// AxisName of the objects is determined by the return type of the indexer. + /// </summary> + /// <param name="list">List used to detect type of the item objects.</param> + /// <param name="itemTypeName">Name of collection type.</param> + /// <param name="itemName">Optional item name to return.</param> + /// <param name="reusedObject">Indicates that object with specified name was already in the collection and it being reused.</param> + /// <returns>New list item object.</returns> + internal object GetListNewItem(IList list, string itemTypeName, ref string itemName, ref bool reusedObject) + { + // Get type of item in collection + Type itemType = null; + if(itemTypeName.Length > 0) + { + itemType = Type.GetType(typeof(Chart).Namespace + "." + itemTypeName, false, true); + } + + reusedObject = false; + PropertyInfo pi = list.GetType().GetProperty("Item", itemType, new Type[] {typeof(string)} ); + MethodInfo mi = list.GetType().GetMethod("IndexOf", new Type[] { typeof(String) }); + ConstructorInfo ci = null; + if(pi != null) + { + // Try to get object by name using the indexer + if(itemName != null && itemName.Length > 0) + { + bool itemChecked = false; + if (mi != null) + { + try + { + int index = -1; + object oindex = mi.Invoke(list, new object[] { itemName }); + if (oindex is int) + { + index = (int)oindex; + itemChecked = true; + } + if (index != -1) + { + object objByName = list[index]; + if (objByName != null) + { + // Remove found object from the list + list.Remove(objByName); + + // Return found object + reusedObject = true; + return objByName; + } + } + } + catch (ArgumentException) + { + } + catch (TargetException) + { + } + catch (TargetInvocationException) + { + } + } + if (!itemChecked) + { + object objByName = null; + try + { + objByName = pi.GetValue(list, new object[] { itemName }); + } + catch (ArgumentException) + { + objByName = null; + } + catch (TargetException) + { + objByName = null; + } + catch (TargetInvocationException) + { + objByName = null; + } + + if (objByName != null) + { + try + { + // Remove found object from the list + list.Remove(objByName); + } + catch (NotSupportedException) + { + } + + // Return found object + reusedObject = true; + return objByName; + } + } + itemName = null; + } + + } + // Get the constructor of the type returned by indexer + if (itemType != null) + { + ci = itemType.GetConstructor(Type.EmptyTypes); + } + else + { + ci = pi.PropertyType.GetConstructor(Type.EmptyTypes); + } + if (ci == null) + { + throw (new InvalidOperationException(SR.ExceptionChartSerializerDefaultConstructorUndefined(pi.PropertyType.ToString()))); + } + return ci.Invoke(null); + } + + /// <summary> + /// Returns true if the object property should be serialized as + /// parent element attribute. Otherwise as a child element. + /// </summary> + /// <param name="pi">Property information.</param> + /// <param name="parent">Object that the property belongs to.</param> + /// <returns>True if property should be serialized as attribute.</returns> + internal bool ShouldSerializeAsAttribute(PropertyInfo pi, object parent) + { + // Check if SerializationVisibilityAttribute is set + if(parent != null) + { + PropertyDescriptor pd = TypeDescriptor.GetProperties(parent)[pi.Name]; + if(pd != null) + { + SerializationVisibilityAttribute styleAttribute = (SerializationVisibilityAttribute)pd.Attributes[typeof(SerializationVisibilityAttribute)]; + if(styleAttribute != null) + { + if(styleAttribute.Visibility == SerializationVisibility.Attribute) + { + return true; + } + else if(styleAttribute.Visibility == SerializationVisibility.Element) + { + return false; + } + } + } + } + + // If a simple type - serialize as property + if(!pi.PropertyType.IsClass) + { + return true; + } + + // Some classes are serialized as properties + if(pi.PropertyType == typeof(string) || + pi.PropertyType == typeof(Font) || + pi.PropertyType == typeof(Color) || + pi.PropertyType == typeof(System.Drawing.Image)) + { + return true; + } + + return false; + } + + + /// <summary> + /// Determines if this property should be serialized as attribute + /// </summary> + /// <param name="pi">Property information.</param> + /// <param name="objectToSerialize">Object that the property belongs to.</param> + /// <returns>True if should be serialized as attribute</returns> + internal bool SerializeICollAsAtribute(PropertyInfo pi, object objectToSerialize) + { + if (objectToSerialize != null) + { + PropertyDescriptor pd = TypeDescriptor.GetProperties(objectToSerialize)[pi.Name]; + if (pd != null) + { + SerializationVisibilityAttribute styleAttribute = (SerializationVisibilityAttribute)pd.Attributes[typeof(SerializationVisibilityAttribute)]; + if (styleAttribute != null) + { + if (styleAttribute.Visibility == SerializationVisibility.Attribute) + { + return true; + } + } + } + } + return false; + } + + /// <summary> + /// Returns true if the object property is serializable. + /// </summary> + /// <param name="propertyName">Property name.</param> + /// <param name="parent">Object that the property belongs to.</param> + /// <returns>True if property is serializable.</returns> + internal bool IsSerializableContent(string propertyName, object parent) + { + bool serializable = true; + if(_serializableContent.Length > 0 || _nonSerializableContent.Length > 0) + { + int serialzableClassFitType = 0; // 0 - undefined; 1 - '*'; 2 - 'Back*'; 3 - Exact + int serialzablePropertyFitType = 0; // 0 - undefined; 1 - '*'; 2 - 'Back*'; 3 - Exact + string ownerClassName = GetObjectName(parent); + + // Check if property in this class is part of the serializable content + serializable = IsPropertyInList(GetSerializableContentList(), ownerClassName, propertyName, out serialzableClassFitType, out serialzablePropertyFitType); + + // Check if property in this class is part of the NON serializable content + if(serializable) + { + int nonSerialzableClassFitType = 0; // 0 - undefined; 1 - '*'; 2 - 'Back*'; 3 - Exact + int nonSerialzablePropertyFitType = 0; // 0 - undefined; 1 - '*'; 2 - 'Back*'; 3 - Exact + bool nonSerializable = IsPropertyInList(GetNonSerializableContentList(), ownerClassName, propertyName, out nonSerialzableClassFitType, out nonSerialzablePropertyFitType); + + // If property was found in non serializable content list - check the type priority + // Priority order: Exact match, 'Back*' mask match, '*' all mask match + if(nonSerializable) + { + // Check priority + if((nonSerialzableClassFitType + nonSerialzablePropertyFitType) > + (serialzableClassFitType + serialzablePropertyFitType)) + { + serializable = false; + } + } + } + } + + return serializable; + } + + /// <summary> + /// Checks if property belongs is defined in the mask list. + /// </summary> + /// <param name="contentList">Array list of class/property items.</param> + /// <param name="className">Class name.</param> + /// <param name="propertyName">Property name.</param> + /// <param name="classFitType">Return class mask fit type.</param> + /// <param name="propertyFitType">Return property mask fit type.</param> + /// <returns>True if property was found in the list.</returns> + private bool IsPropertyInList(ArrayList contentList, string className, string propertyName, out int classFitType, out int propertyFitType) + { + // Initialize result values + classFitType = 0; + propertyFitType = 0; + + if(contentList != null) + { + // Loop through all items in the list using step 2 + for(int itemIndex = 0; itemIndex < contentList.Count; itemIndex += 2) + { + // Initialize result values + classFitType = 0; + propertyFitType = 0; + + // Check if object class and property name match the mask + if(NameMatchMask((ItemInfo)contentList[itemIndex], className, out classFitType)) + { + if(NameMatchMask((ItemInfo)contentList[itemIndex + 1], propertyName, out propertyFitType)) + { + return true; + } + } + } + } + + return false; + } + + /// <summary> + /// Compares class/property name with the specified mask + /// </summary> + /// <param name="itemInfo">Class/Property item information.</param> + /// <param name="objectName">Class/Property name.</param> + /// <param name="type">AxisName of matching. 0-No Match; 1-'*' any wild card; 2-'Back*' contain wild card; 3-exact match</param> + /// <returns>True if name match the mask.</returns> + private bool NameMatchMask(ItemInfo itemInfo, string objectName, out int type) + { + // Initialize type + type = 0; + + // Any class mask + if(itemInfo.any) + { + type = 1; + return true; + } + + // Ends with class mask + if(itemInfo.endsWith) + { + if(itemInfo.name.Length <= objectName.Length) + { + if(objectName.Substring(0, itemInfo.name.Length) == itemInfo.name) + { + type = 2; + return true; + } + } + } + + // Starts with class mask + if(itemInfo.startsWith) + { + if(itemInfo.name.Length <= objectName.Length) + { + if(objectName.Substring(objectName.Length - itemInfo.name.Length, itemInfo.name.Length) == itemInfo.name) + { + type = 2; + return true; + } + } + } + + // Exact name is specified + if(itemInfo.name == objectName) + { + type = 3; + return true; + } + + return false; + } + + + /// <summary> + /// Finds a converter by property descriptor. + /// </summary> + /// <param name="pd">Property descriptor.</param> + /// <returns>A converter registered in TypeConverterAttribute or by property type</returns> + internal TypeConverter FindConverter(PropertyDescriptor pd) + { + TypeConverter result; + TypeConverterAttribute typeConverterAttrib = (TypeConverterAttribute)pd.Attributes[typeof(TypeConverterAttribute)]; + if (typeConverterAttrib != null && typeConverterAttrib.ConverterTypeName.Length > 0) + { + result = this.FindConverterByType(typeConverterAttrib); + if (result != null) + { + return result; + } + try + { + return pd.Converter; + } + catch (SecurityException) + { + } + catch (MethodAccessException) + { + } + } + return TypeDescriptor.GetConverter(pd.PropertyType); + } + + /// <summary> + /// Finds a converter by TypeConverterAttribute. + /// </summary> + /// <param name="attr">TypeConverterAttribute.</param> + /// <returns>TypeConvetrer or null</returns> + internal TypeConverter FindConverterByType( TypeConverterAttribute attr) + { + // In default Inranet zone (partial trust) ConsrtuctorInfo.Invoke (PropertyDescriptor.Converter) + // throws SecurityException or MethodAccessException when the converter class is internal. + // Thats why we have this giant if - elseif here - to create type converters whitout reflection. + if (_converterDict.Contains(attr.ConverterTypeName)) + { + return (TypeConverter)_converterDict[attr.ConverterTypeName]; + } + String typeStr = attr.ConverterTypeName; + + if (attr.ConverterTypeName.Contains(",") ) + { + typeStr = attr.ConverterTypeName.Split(',')[0]; + } + + TypeConverter result = null; + + if (typeStr.EndsWith(".CustomPropertiesTypeConverter", StringComparison.OrdinalIgnoreCase)) { result = new CustomPropertiesTypeConverter(); } + else if (typeStr.EndsWith(".DoubleNanValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new DoubleNanValueConverter(); } + else if (typeStr.EndsWith(".DoubleDateNanValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new DoubleDateNanValueConverter(); } +#if !Microsoft_CONTROL + else if (typeStr.EndsWith(".MapAreaCoordinatesConverter", StringComparison.OrdinalIgnoreCase)) { result = new MapAreaCoordinatesConverter(); } +#endif //Microsoft_CONTROL + else if (typeStr.EndsWith(".ElementPositionConverter", StringComparison.OrdinalIgnoreCase)) { result = new ElementPositionConverter(); } + else if (typeStr.EndsWith(".SeriesAreaNameConverter", StringComparison.OrdinalIgnoreCase)) { result = new SeriesAreaNameConverter(); } + else if (typeStr.EndsWith(".ChartDataSourceConverter", StringComparison.OrdinalIgnoreCase)) { result = new ChartDataSourceConverter(); } + else if (typeStr.EndsWith(".SeriesDataSourceMemberConverter", StringComparison.OrdinalIgnoreCase)) { result = new SeriesDataSourceMemberConverter(); } + else if (typeStr.EndsWith(".SeriesLegendNameConverter", StringComparison.OrdinalIgnoreCase)) { result = new SeriesLegendNameConverter(); } + else if (typeStr.EndsWith(".ChartTypeConverter", StringComparison.OrdinalIgnoreCase)) { result = new ChartTypeConverter(); } + else if (typeStr.EndsWith(".SeriesNameConverter", StringComparison.OrdinalIgnoreCase)) { result = new SeriesNameConverter(); } + else if (typeStr.EndsWith(".NoNameExpandableObjectConverter", StringComparison.OrdinalIgnoreCase)) { result = new NoNameExpandableObjectConverter(); } + else if (typeStr.EndsWith(".DoubleArrayConverter", StringComparison.OrdinalIgnoreCase)) { result = new DoubleArrayConverter(); } + else if (typeStr.EndsWith(".DataPointValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new DataPointValueConverter(); } + else if (typeStr.EndsWith(".SeriesYValueTypeConverter", StringComparison.OrdinalIgnoreCase)) { result = new SeriesYValueTypeConverter(typeof(ChartValueType)); } + else if (typeStr.EndsWith(".ColorArrayConverter", StringComparison.OrdinalIgnoreCase)) { result = new ColorArrayConverter(); } + else if (typeStr.EndsWith(".LegendAreaNameConverter", StringComparison.OrdinalIgnoreCase)) { result = new LegendAreaNameConverter(); } + else if (typeStr.EndsWith(".LegendConverter", StringComparison.OrdinalIgnoreCase)) { result = new LegendConverter(); } + else if (typeStr.EndsWith(".SizeEmptyValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new SizeEmptyValueConverter(); } + else if (typeStr.EndsWith(".MarginExpandableObjectConverter", StringComparison.OrdinalIgnoreCase)) { result = new MarginExpandableObjectConverter(); } + else if (typeStr.EndsWith(".IntNanValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new IntNanValueConverter(); } + else if (typeStr.EndsWith(".AxesArrayConverter", StringComparison.OrdinalIgnoreCase)) { result = new AxesArrayConverter(); } + else if (typeStr.EndsWith(".AxisLabelDateValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new AxisLabelDateValueConverter(); } + else if (typeStr.EndsWith(".AxisMinMaxValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new AxisMinMaxValueConverter(); } + else if (typeStr.EndsWith(".AxisCrossingValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new AxisCrossingValueConverter(); } + else if (typeStr.EndsWith(".AxisMinMaxAutoValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new AxisMinMaxAutoValueConverter(); } + else if (typeStr.EndsWith(".StripLineTitleAngleConverter", StringComparison.OrdinalIgnoreCase)) { result = new StripLineTitleAngleConverter(); } + else if (typeStr.EndsWith(".AxisIntervalValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new AxisIntervalValueConverter(); } + else if (typeStr.EndsWith(".AxisElementIntervalValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new AxisElementIntervalValueConverter(); } + else if (typeStr.EndsWith(".AnchorPointValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new AnchorPointValueConverter(); } + else if (typeStr.EndsWith(".AnnotationAxisValueConverter", StringComparison.OrdinalIgnoreCase)) { result = new AnnotationAxisValueConverter(); } + + if (result != null) _converterDict[attr.ConverterTypeName] = result; + + return result; + } + + #endregion + + #region Serializable content list managment fields, methods and classes + + /// <summary> + /// Stores information about content item (class or property) + /// </summary> + private class ItemInfo + { + public string name = ""; + public bool any = false; + public bool startsWith = false; + public bool endsWith = false; + } + + // Storage for serializable content items + private ArrayList serializableContentList = null; + + // Storage for non serializable content items + private ArrayList nonSerializableContentList = null; + + /// <summary> + /// Return serializable content list. + /// </summary> + /// <returns>Serializable content list.</returns> + private ArrayList GetSerializableContentList() + { + if(serializableContentList == null) + { + serializableContentList = new ArrayList(); + FillContentList( + serializableContentList, + (this.SerializableContent.Length > 0 ) ? this.SerializableContent : "*.*"); + } + + return serializableContentList; + } + + /// <summary> + /// Return non serializable content list. + /// </summary> + /// <returns>Non serializable content list.</returns> + private ArrayList GetNonSerializableContentList() + { + if(nonSerializableContentList == null) + { + nonSerializableContentList = new ArrayList(); + FillContentList(nonSerializableContentList, this.NonSerializableContent); + } + + return nonSerializableContentList; + } + + /// <summary> + /// Fill content list from the string. + /// </summary> + /// <param name="list">Array list class.</param> + /// <param name="content">Content string.</param> + private void FillContentList(ArrayList list, string content) + { + if(content.Length > 0) + { + string[] classPropertyPairs = content.Split(','); + foreach(string item in classPropertyPairs) + { + // Create two content items: one for the class and one for the property + ItemInfo classInfo = new ItemInfo(); + ItemInfo propertyInfo = new ItemInfo(); + + // Find class and property name + int pointIndex = item.IndexOf('.'); + if(pointIndex == -1) + { + throw (new ArgumentException(SR.ExceptionChartSerializerContentStringFormatInvalid)); + } + classInfo.name = item.Substring(0, pointIndex).Trim(); + propertyInfo.name = item.Substring(pointIndex + 1).Trim(); + if(classInfo.name.Length == 0) + { + throw (new ArgumentException(SR.ExceptionChartSerializerClassNameUndefined)); + } + if(propertyInfo.name.Length == 0) + { + throw (new ArgumentException(SR.ExceptionChartSerializerPropertyNameUndefined)); + } + + // Make sure property name do not have point character + if(propertyInfo.name.IndexOf('.') != -1) + { + throw (new ArgumentException(SR.ExceptionChartSerializerContentStringFormatInvalid)); + } + + // Check for wildcards in names + CheckWildCars(classInfo); + CheckWildCars(propertyInfo); + + // Add class & property items into the array + list.Add(classInfo); + list.Add(propertyInfo); + } + } + } + + /// <summary> + /// Checks wildcards in the name of the item. + /// Possible values: + /// "*" + /// "*Name" + /// "Name*" + /// </summary> + /// <param name="info">Item information class.</param> + private void CheckWildCars(ItemInfo info) + { + // Any class mask + if(info.name == "*") + { + info.any = true; + } + + // Ends with class mask + else if(info.name[info.name.Length - 1] == '*') + { + info.endsWith = true; + info.name = info.name.TrimEnd('*'); + } + + // Starts with class mask + else if(info.name[0] == '*') + { + info.startsWith = true; + info.name = info.name.TrimStart('*'); + } + } + + #endregion + } + + /// <summary> + /// Utility class which serialize object using XML format + /// </summary> + internal class XmlFormatSerializer : SerializerBase + { + #region Serialization public methods + + /// <summary> + /// Serialize specified object into the stream. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="stream">The stream used to write the XML document.</param> + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal void Serialize(object objectToSerialize, Stream stream) + { + Serialize(objectToSerialize, (object)stream); + } + + /// <summary> + /// Serialize specified object into the XML writer. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="xmlWriter">The XmlWriter used to write the XML document.</param> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal void Serialize(object objectToSerialize, XmlWriter xmlWriter) + { + Serialize(objectToSerialize, (object)xmlWriter); + } + + /// <summary> + /// Serialize specified object into the text writer. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="textWriter">The TextWriter used to write the XML document.</param> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal void Serialize(object objectToSerialize, TextWriter textWriter) + { + Serialize(objectToSerialize, (object)textWriter); + } + + /// <summary> + /// Serialize specified object into the file. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="fileName">The file name used to write the XML document.</param> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal void Serialize(object objectToSerialize, string fileName) + { + Serialize(objectToSerialize, (object)fileName); + } + + #endregion + + #region Serialization private methods + + /// <summary> + /// Serialize specified object into different types of writers using XML format. + /// Here is what is serialized in the object: + /// - all public properties with Set and Get methods + /// - all public properties with Get method which derived from ICollection + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="writer">Defines the serialization destination. Can be Stream, TextWriter, XmlWriter or String (file name).</param> + + internal override void Serialize(object objectToSerialize, object writer) + { + // the possible writer types + Stream stream = writer as Stream; + TextWriter textWriter = writer as TextWriter; + XmlWriter xmlWriter = writer as XmlWriter; + string writerStr = writer as string; + + // Check input parameters + if(objectToSerialize == null) + { + throw(new ArgumentNullException("objectToSerialize")); + } + if(writer == null) + { + throw(new ArgumentNullException("writer")); + } + if(stream == null && textWriter == null && xmlWriter == null && writerStr == null) + { + throw (new ArgumentException(SR.ExceptionChartSerializerWriterObjectInvalid, "writer")); + } + + // Create XML document + XmlDocument xmlDocument = new XmlDocument(); + + // Create document fragment + XmlDocumentFragment docFragment = xmlDocument.CreateDocumentFragment(); + + + + // Serialize object + SerializeObject(objectToSerialize, null, GetObjectName(objectToSerialize), docFragment, xmlDocument); + + + // Append document fragment + xmlDocument.AppendChild(docFragment); + + // Remove empty child nodes + RemoveEmptyChildNodes(xmlDocument); + + // Save XML document into the writer + if(stream != null) + { + xmlDocument.Save(stream); + + // Flush stream and seek to the beginning + stream.Flush(); + stream.Seek(0, SeekOrigin.Begin); + } + + if(writerStr != null) + { + xmlDocument.Save(writerStr); + } + + if(xmlWriter != null) + { + xmlDocument.Save(xmlWriter); + } + + if(textWriter != null) + { + xmlDocument.Save(textWriter); + } + } + /// <summary> + /// Serialize specified object into the XML format. + /// Method is called recursively to serialize child objects. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="parent">Parent of the serialized object.</param> + /// <param name="elementName">Object element name.</param> + /// <param name="xmlParentNode">The XmlNode of the parent object to serialize the data in.</param> + /// <param name="xmlDocument">The XmlDocument the parent node belongs to.</param> + virtual protected void SerializeObject(object objectToSerialize, object parent, string elementName, XmlNode xmlParentNode, XmlDocument xmlDocument) + { + // Check input parameters + if(objectToSerialize == null) + { + return; + } + + // Check if object should be serialized + if(parent != null) + { + PropertyDescriptor pd = TypeDescriptor.GetProperties(parent)[elementName]; + if(pd != null) + { + SerializationVisibilityAttribute styleAttribute = (SerializationVisibilityAttribute)pd.Attributes[typeof(SerializationVisibilityAttribute)]; + if(styleAttribute != null) + { + // Hidden property + if(styleAttribute.Visibility == SerializationVisibility.Hidden) + { + return; + } + } + } + } + + // Check if object is a collection + if(objectToSerialize is ICollection) + { + // Serialize collection + SerializeCollection(objectToSerialize, elementName, xmlParentNode, xmlDocument); + return; + } + + // Create object element inside the parents node + XmlNode xmlNode = xmlDocument.CreateElement(elementName); + xmlParentNode.AppendChild(xmlNode); + + // Write template data into collection items + bool templateListItem = false; + IList parentList = parent as IList; + if(this.IsTemplateMode && parentList != null) + { + // Create "_Template_" attribute + XmlAttribute attrib = xmlDocument.CreateAttribute("_Template_"); + + // Check number of items in collection + if (parentList.Count == 1) + { + // If only one iten in collection, set "All" value. + // This means that style of this object should be applied to all + // existing items of the collection. + attrib.Value = "All"; + } + else + { + // If there is more than one item, use it's index. + // When loading, style of these items will be applied to existing + // items in collection in the loop. + int itemIndex = parentList.IndexOf(objectToSerialize); + attrib.Value = itemIndex.ToString(CultureInfo.InvariantCulture); + } + + // Add "_Template_" attribute into the XML node + xmlNode.Attributes.Append(attrib); + templateListItem = true; + } + + // Retrive properties list of the object + PropertyInfo[] properties = objectToSerialize.GetType().GetProperties(); + if (properties != null) + { + // Loop through all properties and serialize public properties + foreach(PropertyInfo pi in properties) + { + + // Skip "Name" property from collection items in template mode + if(templateListItem && pi.Name == "Name") + { + continue; + } + + // Skip inherited properties from the root object + if(IsChartBaseProperty(objectToSerialize, parent, pi)) + { + continue; + } + + // Check if this property is serializable content + if (!IsSerializableContent(pi.Name, objectToSerialize)) + { + continue; + } + + // Serialize collection + + if (pi.CanRead && pi.PropertyType.GetInterface("ICollection", true) != null && !this.SerializeICollAsAtribute(pi, objectToSerialize)) + { + // Check if SerializationVisibilityAttribute is set + bool serialize = true; + if(objectToSerialize != null) + { + PropertyDescriptor pd = TypeDescriptor.GetProperties(objectToSerialize)[pi.Name]; + if(pd != null) + { + SerializationVisibilityAttribute styleAttribute = (SerializationVisibilityAttribute)pd.Attributes[typeof(SerializationVisibilityAttribute)]; + if(styleAttribute != null) + { + if(styleAttribute.Visibility == SerializationVisibility.Hidden) + { + serialize = false; + } + } + } + } + // Check if collection has "ShouldSerialize" method + MethodInfo mi = objectToSerialize.GetType().GetMethod("ShouldSerialize" + pi.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public ); + if(mi != null) + { + object result = mi.Invoke(objectToSerialize, null); + if(result is bool && ((bool)result) == false) + { + // Do not serialize collection + serialize = false; + } + } + + // Serialize collection + if(serialize) + { + SerializeCollection(pi.GetValue(objectToSerialize, null), pi.Name, xmlNode, xmlDocument); + } + } + + // Serialize public properties with Get and Set methods + else if(pi.CanRead && pi.CanWrite) + { + // Skip indexes + if(pi.Name == "Item") + { + continue; + } + + // Check if an object should be serialized as a property or as a class + if(ShouldSerializeAsAttribute(pi, objectToSerialize)) + { + // Serialize property + SerializeProperty(pi.GetValue(objectToSerialize, null), objectToSerialize, pi.Name, xmlNode, xmlDocument); + } + else + { + // Serialize inner object + SerializeObject(pi.GetValue(objectToSerialize, null), objectToSerialize, pi.Name, xmlNode, xmlDocument); + } + } + } + } + return; + } + + + /// <summary> + /// Serializes the data point. + /// </summary> + /// <param name="objectToSerialize">The object to serialize.</param> + /// <param name="xmlParentNode">The XML parent node.</param> + /// <param name="xmlDocument">The XML document.</param> + internal void SerializeDataPoint(object objectToSerialize, XmlNode xmlParentNode, XmlDocument xmlDocument) + { + // Create object element inside the parents node + XmlNode xmlNode = xmlDocument.CreateElement(GetObjectName(objectToSerialize)); + xmlParentNode.AppendChild(xmlNode); + + DataPoint dataPoint = objectToSerialize as DataPoint; + if (dataPoint.XValue != 0d && IsSerializableContent("XValue", objectToSerialize)) + { + XmlAttribute attrib = xmlDocument.CreateAttribute("XValue"); + attrib.Value = GetXmlValue(dataPoint.XValue, dataPoint, "XValue"); + xmlNode.Attributes.Append(attrib); + } + if (dataPoint.YValues.Length > 0 && IsSerializableContent("YValues", objectToSerialize)) + { + XmlAttribute attrib = xmlDocument.CreateAttribute("YValues"); + attrib.Value = GetXmlValue(dataPoint.YValues, dataPoint, "YValues"); + xmlNode.Attributes.Append(attrib); + } + if (dataPoint.IsEmpty && IsSerializableContent("IsEmpty", objectToSerialize)) + { + XmlAttribute attrib = xmlDocument.CreateAttribute("IsEmpty"); + attrib.Value = GetXmlValue(dataPoint.isEmptyPoint, dataPoint, "IsEmpty"); + xmlNode.Attributes.Append(attrib); + } + bool hasCustomProperties = false; + foreach (DictionaryEntry entry in dataPoint.properties) + { + if (entry.Key is int) + { + CommonCustomProperties propertyType = (CommonCustomProperties)((int)entry.Key); + String properyName = propertyType.ToString(); + if (IsSerializableContent(properyName, objectToSerialize)) + { + XmlAttribute attrib = xmlDocument.CreateAttribute(properyName); + attrib.Value = GetXmlValue(entry.Value, dataPoint, properyName); + xmlNode.Attributes.Append(attrib); + } + } + else + { + hasCustomProperties = true; + } + } + + if (hasCustomProperties && !String.IsNullOrEmpty(dataPoint.CustomProperties) && IsSerializableContent("CustomProperties", objectToSerialize)) + { + XmlAttribute attrib = xmlDocument.CreateAttribute("CustomProperties"); + attrib.Value = GetXmlValue(dataPoint.CustomProperties, dataPoint, "CustomProperties"); + xmlNode.Attributes.Append(attrib); + } + + } + + /// <summary> + /// Serialize specified object into the XML text writer. + /// Method is called recursively to serialize child objects. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="elementName">Object element name.</param> + /// <param name="xmlParentNode">The XmlNode of the parent object to serialize the data in.</param> + /// <param name="xmlDocument">The XmlDocument the parent node belongs to.</param> + virtual protected void SerializeCollection(object objectToSerialize, string elementName, XmlNode xmlParentNode, XmlDocument xmlDocument) + { + ICollection collection = objectToSerialize as ICollection; + if(collection != null) + { + // Create object element inside the parents node + XmlNode xmlNode = xmlDocument.CreateElement(elementName); + xmlParentNode.AppendChild(xmlNode); + // Enumerate through all objects in collection and serialize them + foreach(object obj in collection) + { + + if (obj is DataPoint) + { + SerializeDataPoint(obj, xmlNode, xmlDocument); + continue; + } + + SerializeObject(obj, objectToSerialize, GetObjectName(obj), xmlNode, xmlDocument); + } + } + } + + /// <summary> + /// Serialize specified object into the XML text writer. + /// Method is called recursively to serialize child objects. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="parent">Parent of the serialized object.</param> + /// <param name="elementName">Object element name.</param> + /// <param name="xmlParentNode">The XmlNode of the parent object to serialize the data in.</param> + /// <param name="xmlDocument">The XmlDocument the parent node belongs to.</param> + virtual protected void SerializeProperty(object objectToSerialize, object parent, string elementName, XmlNode xmlParentNode, XmlDocument xmlDocument) + { + // Check input parameters + if(objectToSerialize == null || parent == null) + { + return; + } + + // Check if property has non-default value + PropertyDescriptor pd = TypeDescriptor.GetProperties(parent)[elementName]; + if(pd != null) + { + DefaultValueAttribute defValueAttribute = (DefaultValueAttribute)pd.Attributes[typeof(DefaultValueAttribute)]; + if(defValueAttribute != null) + { + if(objectToSerialize.Equals(defValueAttribute.Value)) + { + // Do not serialize properties with default values + return; + } + } + else + { + // Check if property has "ShouldSerialize" method + MethodInfo mi = parent.GetType().GetMethod("ShouldSerialize" + elementName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + if(mi != null) + { + object result = mi.Invoke(parent, null); + if(result is bool && ((bool)result) == false) + { + // Do not serialize properties with default values + return; + } + } + } + + // Check XmlFormatSerializerStyle attribute + SerializationVisibilityAttribute styleAttribute = (SerializationVisibilityAttribute)pd.Attributes[typeof(SerializationVisibilityAttribute)]; + if(styleAttribute != null) + { + // Hidden property + if(styleAttribute.Visibility == SerializationVisibility.Hidden) + { + return; + } + } + } + + // Serialize property as a parents node attribute + XmlAttribute attrib = xmlDocument.CreateAttribute(elementName); + attrib.Value = GetXmlValue(objectToSerialize, parent, elementName); + xmlParentNode.Attributes.Append(attrib); + } + + /// <summary> + /// Converts object value into the string. + /// </summary> + /// <param name="obj">Object to convert.</param> + /// <param name="parent">Object parent.</param> + /// <param name="elementName">Object name.</param> + /// <returns>Object value as strig.</returns> + protected string GetXmlValue(object obj, object parent, string elementName) + { + string objStr = obj as string; + if(objStr != null) + { + return objStr; + } + + Font font = obj as Font; + if(font != null) + { + return SerializerBase.FontToString(font); + } + + if(obj is Color) + { + return colorConverter.ConvertToString(null, System.Globalization.CultureInfo.InvariantCulture, obj); + } + + Color[] colors = obj as Color[]; + if(colors != null) + { + return ColorArrayConverter.ColorArrayToString(colors); + } + +#if !Microsoft_CONTROL + if(obj is Unit) + { + Unit unit = (Unit)obj; + return unit.Value.ToString(System.Globalization.CultureInfo.InvariantCulture); + } +#endif + + System.Drawing.Image image = obj as System.Drawing.Image; + if(image != null) + { + return ImageToString(image); + } + + // Look for the converter set with the attibute + PropertyDescriptor pd = TypeDescriptor.GetProperties(parent)[elementName]; + if(pd != null) + { + TypeConverter converter = this.FindConverter(pd); + if (converter != null && converter.CanConvertTo(typeof(string))) + { + return converter.ConvertToString(null, System.Globalization.CultureInfo.InvariantCulture, obj); + } + } + + // Try using default string convertion + return obj.ToString(); + } + + /// <summary> + /// Removes all empty nodes from the XML document. + /// Method is called recursively to remove empty child nodes first. + /// </summary> + /// <param name="xmlNode">The node where to start the removing.</param> + private void RemoveEmptyChildNodes(XmlNode xmlNode) + { + // Loop through all child nodes + for(int nodeIndex = 0; nodeIndex < xmlNode.ChildNodes.Count; nodeIndex++) + { + // Remove empty child nodes of the child + RemoveEmptyChildNodes(xmlNode.ChildNodes[nodeIndex]); + + // Check if there are any non-empty nodes left + XmlNode currentNode = xmlNode.ChildNodes[nodeIndex]; + if( currentNode.ParentNode != null && + !(currentNode.ParentNode is XmlDocument) ) + { + if(!currentNode.HasChildNodes && + (currentNode.Attributes == null || + currentNode.Attributes.Count == 0)) + { + // Remove node + xmlNode.RemoveChild(xmlNode.ChildNodes[nodeIndex]); + --nodeIndex; + } + } + + + + // Remove node with one "_Template_" attribute + if(!currentNode.HasChildNodes && + currentNode.Attributes.Count == 1 && + currentNode.Attributes["_Template_"] != null) + { + // Remove node + xmlNode.RemoveChild(xmlNode.ChildNodes[nodeIndex]); + --nodeIndex; + } + + + + } + } + + #endregion + + #region Deserialization public methods + + /// <summary> + /// Deserialize specified object from the stream. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="stream">The stream used to read the XML document from.</param> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal void Deserialize(object objectToDeserialize, Stream stream) + { + Deserialize(objectToDeserialize, (object)stream); + } + + /// <summary> + /// Deserialize specified object from the XML reader. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="xmlReader">The XmlReader used to read the XML document from.</param> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal void Deserialize(object objectToDeserialize, XmlReader xmlReader) + { + Deserialize(objectToDeserialize, (object)xmlReader); + } + + /// <summary> + /// Deserialize specified object from the text reader. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="textReader">The TextReader used to write the XML document from.</param> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal void Deserialize(object objectToDeserialize, TextReader textReader) + { + Deserialize(objectToDeserialize, (object)textReader); + } + + /// <summary> + /// Deserialize specified object from the file. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="fileName">The file name used to read the XML document from.</param> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal void Deserialize(object objectToDeserialize, string fileName) + { + Deserialize(objectToDeserialize, (object)fileName); + } + + #endregion + + #region Deserialization private methods + + /// <summary> + /// Deserialize object from different types of readers using XML format. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="reader">Defines the deserialization data source. Can be Stream, TextReader, XmlReader or String (file name).</param> + internal override void Deserialize(object objectToDeserialize, object reader) + { + // the four possible types of readers + Stream stream = reader as Stream; + TextReader textReader = reader as TextReader; + XmlReader xmlReader = reader as XmlReader; + string readerStr = reader as string; + + // Check input parameters + if(objectToDeserialize == null) + { + throw(new ArgumentNullException("objectToDeserialize")); + } + if(reader == null) + { + throw(new ArgumentNullException("reader")); + } + if(stream == null && textReader == null && xmlReader == null && readerStr == null) + { + throw (new ArgumentException(SR.ExceptionChartSerializerReaderObjectInvalid, "reader")); + } + + // Create XML document + XmlDocument xmlDocument = new XmlDocument(); + XmlReader xmlBaseReader = null; + try + { + // process files without DTD + XmlReaderSettings settings = new XmlReaderSettings(); + // settings.ProhibitDtd is obsolete inn NetFx 4.0, the #ifdef stays for compilation under NetFx 3.5. +#if OLD_DTD + settings.ProhibitDtd = true; +#else + settings.DtdProcessing = DtdProcessing.Prohibit; //don't allow DTD +#endif + // Load XML document from the reader + if (stream != null) + { + xmlBaseReader = XmlReader.Create(stream, settings); + } + if (readerStr != null) + { + xmlBaseReader = XmlReader.Create(readerStr, settings); + } + if (xmlReader != null) + { + xmlBaseReader = XmlReader.Create(xmlReader, settings); + } + if (textReader != null) + { + xmlBaseReader = XmlReader.Create(textReader, settings); + } + + xmlDocument.Load(xmlBaseReader); + + // Reset properties of the root object + if (IsResetWhenLoading) + { + ResetObjectProperties(objectToDeserialize); + } + + // Deserialize object + DeserializeObject(objectToDeserialize, null, GetObjectName(objectToDeserialize), xmlDocument.DocumentElement, xmlDocument); + } + finally + { + if (xmlBaseReader != null) + { + ((IDisposable)xmlBaseReader).Dispose(); + } + } + } + + /// <summary> + /// Deserialize object from the XML format. + /// Method is called recursively to deserialize child objects. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="parent">Parent of the deserialized object.</param> + /// <param name="elementName">Object element name.</param> + /// <param name="xmlParentNode">The XmlNode of the parent object to deserialize the data from.</param> + /// <param name="xmlDocument">The XmlDocument the parent node belongs to.</param> + /// <returns>Number of properties set.</returns> + virtual internal int DeserializeObject(object objectToDeserialize, object parent, string elementName, XmlNode xmlParentNode, XmlDocument xmlDocument) + { + int setPropertiesNumber = 0; + + // Check input parameters + if(objectToDeserialize == null) + { + return setPropertiesNumber; + } + + // Loop through all node properties + foreach(XmlAttribute attr in xmlParentNode.Attributes) + { + // Skip template collection item attribute + if(attr.Name == "_Template_") + { + continue; + } + + // Check if this property is serializable content + if(IsSerializableContent(attr.Name, objectToDeserialize)) + { + SetXmlValue(objectToDeserialize, attr.Name, attr.Value); + ++setPropertiesNumber; + } + } + + + + // Read template data into the collection + IList list = objectToDeserialize as IList; + + if(this.IsTemplateMode && + list != null && + xmlParentNode.FirstChild.Attributes["_Template_"] != null) + { + // Loop through all items in collection + int itemIndex = 0; + foreach(object listItem in list) + { + // Find XML node appropriate for the item from the collection + XmlNode listItemNode = null; + + // Loop through all child nodes + foreach(XmlNode childNode in xmlParentNode.ChildNodes) + { + string templateString = childNode.Attributes["_Template_"].Value; + if(templateString != null && templateString.Length > 0) + { + if(templateString == "All") + { + listItemNode = childNode; + break; + } + else + { + // If there is more items in collection than XML node in template + // apply items in a loop + int loopItemIndex = itemIndex; + while(loopItemIndex > xmlParentNode.ChildNodes.Count - 1) + { + loopItemIndex -= xmlParentNode.ChildNodes.Count; + } + + // Convert attribute value to index + int nodeIndex = int.Parse(templateString, CultureInfo.InvariantCulture); + if(nodeIndex == loopItemIndex) + { + listItemNode = childNode; + break; + } + } + } + } + + // Load data from the node + if(listItemNode != null) + { + // Load object data + DeserializeObject(listItem, objectToDeserialize, "", listItemNode, xmlDocument); + } + + // Increase item index + ++itemIndex; + } + + // No futher loading required + return 0; + } + + + + // Loop through all child elements + int listItemIndex = 0; + foreach(XmlNode childNode in xmlParentNode.ChildNodes) + { + // Special handling for the collections + // Bug VSTS #235707 - The collections IsSerializableContent are already checked as a property in the else statement. + if (list != null) + { + // Create new item object + string itemName = null; + if (childNode.Attributes["Name"] != null) + { + itemName = childNode.Attributes["Name"].Value; + } + + bool reusedObject = false; + object listItem = GetListNewItem(list, childNode.Name, ref itemName, ref reusedObject); + + // Deserialize list item object + int itemSetProperties = DeserializeObject(listItem, objectToDeserialize, "", childNode, xmlDocument); + setPropertiesNumber += itemSetProperties; + + // Add item object into the list + if (itemSetProperties > 0 || reusedObject) + { + list.Insert(listItemIndex++, listItem); + } + } + + else + { + // Check if this property is serializable content + if (IsSerializableContent(childNode.Name, objectToDeserialize)) + { + // Deserialize the property using property descriptor + PropertyDescriptor pd = TypeDescriptor.GetProperties(objectToDeserialize)[childNode.Name]; + if (pd != null) + { + object innerObject = pd.GetValue(objectToDeserialize); + + // Deserialize list item object + setPropertiesNumber += DeserializeObject(innerObject, objectToDeserialize, childNode.Name, childNode, xmlDocument); + } + else if (!IsUnknownAttributeIgnored) + { + throw (new InvalidOperationException(SR.ExceptionChartSerializerPropertyNameUnknown(childNode.Name, objectToDeserialize.GetType().ToString()))); + } + } + } + } + + return setPropertiesNumber; + } + + /// <summary> + /// Sets a property of an object using name and value as string. + /// </summary> + /// <param name="obj">Object to set.</param> + /// <param name="attrName">Attribute (property) name.</param> + /// <param name="attrValue">Object value..</param> + /// <returns>Object value as strig.</returns> + private void SetXmlValue(object obj, string attrName, string attrValue) + { + PropertyInfo pi = obj.GetType().GetProperty(attrName); + if(pi != null) + { + // Convert string to object value + object objValue = attrValue; + + if(pi.PropertyType == typeof(string)) + { + objValue = attrValue; + } + + else if(pi.PropertyType == typeof(Font)) + { + objValue = SerializerBase.FontFromString(attrValue); + } + + else if(pi.PropertyType == typeof(Color)) + { + objValue = (Color)colorConverter.ConvertFromString(null, System.Globalization.CultureInfo.InvariantCulture, attrValue); + } + +#if !Microsoft_CONTROL + else if(pi.PropertyType == typeof(Unit)) + { + objValue = new Unit(Int32.Parse(attrValue, System.Globalization.CultureInfo.InvariantCulture)); + } +#endif + + else if(pi.PropertyType == typeof(System.Drawing.Image)) + { + objValue = ImageFromString(attrValue); + } + + else + { + // Look for the converter set with the attibute + PropertyDescriptor pd = TypeDescriptor.GetProperties(obj)[attrName]; + if(pd != null) + { + TypeConverter converter = this.FindConverter(pd); + if (converter != null && converter.CanConvertFrom(typeof(string))) + { + objValue = converter.ConvertFromString(null, System.Globalization.CultureInfo.InvariantCulture, attrValue); + } + } + } + + // Set object value + pi.SetValue(obj, objValue, null); + } + else if(!IsUnknownAttributeIgnored) + { + throw(new InvalidOperationException(SR.ExceptionChartSerializerPropertyNameUnknown( attrName,obj.GetType().ToString()))); + } + } + + #endregion + } + + /// <summary> + /// Utility class which serialize object using binary format + /// </summary> + internal class BinaryFormatSerializer : SerializerBase + { + #region Serialization methods + + /// <summary> + /// Serialize specified object into the destination using binary format. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="destination">Serialization destination.</param> + internal override void Serialize(object objectToSerialize, object destination) + { + // Check input parameters + if (objectToSerialize == null) + { + throw (new ArgumentNullException("objectToSerialize")); + } + if (destination == null) + { + throw (new ArgumentNullException("destination")); + } + + string destinationStr = destination as string; + if (destinationStr != null) + { + Serialize(objectToSerialize, destinationStr); + return; + } + + Stream stream = destination as Stream; + if (stream != null) + { + Serialize(objectToSerialize, stream); + return; + } + + BinaryWriter binaryWriter = destination as BinaryWriter; + if (binaryWriter != null) + { + Serialize(objectToSerialize, binaryWriter); + return; + } + + throw (new ArgumentException(SR.ExceptionChartSerializerDestinationObjectInvalid, "destination")); + } + + /// <summary> + /// Serialize specified object into the file using binary format. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="fileName">File name to serialize the data in.</param> + internal void Serialize(object objectToSerialize, string fileName) + { + FileStream stream = new FileStream(fileName, FileMode.Create); + Serialize(objectToSerialize, new BinaryWriter(stream)); + stream.Close(); + } + + + /// <summary> + /// Serialize specified object into the stream using binary format. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="stream">Defines the serialization destination.</param> + internal void Serialize(object objectToSerialize, Stream stream) + { + Serialize(objectToSerialize, new BinaryWriter(stream)); + } + + /// <summary> + /// Serialize specified object into different types of writers using binary format. + /// Here is what is serialized in the object: + /// - all public properties with Set and Get methods + /// - all public properties with Get method which derived from ICollection + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="writer">Defines the serialization destination.</param> + internal void Serialize(object objectToSerialize, BinaryWriter writer) + { + // Check input parameters + if(objectToSerialize == null) + { + throw(new ArgumentNullException("objectToSerialize")); + } + if(writer == null) + { + throw(new ArgumentNullException("writer")); + } + + // Write bnary format header into the stream, which consist of 15 characters + char[] header = new char[15] {'D', 'C', 'B', 'F', '4', '0', '0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'}; + writer.Write(header); + + + // Serialize object + SerializeObject(objectToSerialize, null, GetObjectName(objectToSerialize), writer); + + + // Flush the writer stream + writer.Flush(); + + // Reset stream position + writer.Seek(0, SeekOrigin.Begin); + } + + /// <summary> + /// Serialize specified object into the binary format. + /// Method is called recursively to serialize child objects. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="parent">Parent of the serialized object.</param> + /// <param name="elementName">Object element name.</param> + /// <param name="writer">Binary writer object.</param> + virtual internal void SerializeObject(object objectToSerialize, object parent, string elementName, BinaryWriter writer) + { + // Check input parameters + if(objectToSerialize == null) + { + return; + } + + // Check if object should be serialized + if(parent != null) + { + PropertyDescriptor pd = TypeDescriptor.GetProperties(parent)[elementName]; + if(pd != null) + { + SerializationVisibilityAttribute styleAttribute = (SerializationVisibilityAttribute)pd.Attributes[typeof(SerializationVisibilityAttribute)]; + if(styleAttribute != null) + { + // Hidden property + if(styleAttribute.Visibility == SerializationVisibility.Hidden) + { + return; + } + } + } + } + + // Check if object is a collection + if(objectToSerialize is ICollection) + { + // Serialize collection + SerializeCollection(objectToSerialize, elementName, writer); + return; + } + + // Write object ID (hash of the name) into the writer + writer.Write(SerializerBase.GetStringHashCode(elementName)); + + // Remember position where object data is started + long elementStartPosition = writer.Seek(0, SeekOrigin.Current); + + // Retrive properties list of the object + ArrayList propNamesList = new ArrayList(); + PropertyInfo[] properties = objectToSerialize.GetType().GetProperties(); + if(properties != null) + { + // Loop through all properties and serialize public properties + foreach(PropertyInfo pi in properties) + { + // Skip inherited properties from the root object + if(IsChartBaseProperty(objectToSerialize, parent, pi)) + { + continue; + } + // Serialize collection + if (pi.CanRead && pi.PropertyType.GetInterface("ICollection", true) != null && !this.SerializeICollAsAtribute(pi, objectToSerialize)) + { + bool serialize = IsSerializableContent(pi.Name, objectToSerialize); + + // fixing Axes Array Framework 2.0 side effect + // fixed by:DT + if (serialize && objectToSerialize != null) + { + PropertyDescriptor pd = TypeDescriptor.GetProperties(objectToSerialize)[pi.Name]; + if (pd != null) + { + SerializationVisibilityAttribute styleAttribute = (SerializationVisibilityAttribute)pd.Attributes[typeof(SerializationVisibilityAttribute)]; + if (styleAttribute != null) + { + if (styleAttribute.Visibility == SerializationVisibility.Hidden) + { + serialize = false; + } + } + } + } + + MethodInfo mi = objectToSerialize.GetType().GetMethod("ShouldSerialize" + pi.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + if( serialize && mi != null) + { + object result = mi.Invoke(objectToSerialize, null); + if(result is bool && ((bool)result) == false) + { + // Do not serialize collection + serialize = false; + } + } + + // Serialize collection + if(serialize) + { + propNamesList.Add(pi.Name); + SerializeCollection(pi.GetValue(objectToSerialize, null), pi.Name, writer); + } + } + + // Serialize public properties with Get and Set methods + else if(pi.CanRead && pi.CanWrite) + { + // Skip indexes + if(pi.Name == "Item") + { + continue; + } + // Check if this property is serializable content + if (IsSerializableContent(pi.Name, objectToSerialize)) + { + // Check if an object should be serialized as a property or as a class + if (ShouldSerializeAsAttribute(pi, objectToSerialize)) + { + // Serialize property + SerializeProperty(pi.GetValue(objectToSerialize, null), objectToSerialize, pi.Name, writer); + } + else + { + // Serialize inner object + SerializeObject(pi.GetValue(objectToSerialize, null), objectToSerialize, pi.Name, writer); + } + } + propNamesList.Add(pi.Name); + } + } + + // Check that all properties have unique IDs + CheckPropertiesID(propNamesList); + } + + + // If position of the writer did not change - nothing was written + if(writer.Seek(0, SeekOrigin.Current) == elementStartPosition) + { + // Remove object ID from the stream + writer.Seek(-2, SeekOrigin.Current); + writer.Write((short)0); + writer.Seek(-2, SeekOrigin.Current); + } + else + { + // Write the end objectTag + writer.Write((short)0); + } + + return; + } + + + /// <summary> + /// Serializes the data point. + /// </summary> + /// <param name="objectToSerialize">The object to serialize.</param> + /// <param name="elementName">Name of the element.</param> + /// <param name="writer">The writer.</param> + private void SerializeDataPoint(object objectToSerialize, string elementName, BinaryWriter writer) + { + + // Write object ID (hash of the name) into the writer + writer.Write(SerializerBase.GetStringHashCode(elementName)); + // Remember position where object data is started + long elementStartPosition = writer.Seek(0, SeekOrigin.Current); + + DataPoint dataPoint = objectToSerialize as DataPoint; + if (dataPoint.XValue != 0d && IsSerializableContent("XValue", objectToSerialize)) + { + SerializeProperty(dataPoint.XValue, dataPoint, "XValue", writer); + } + if (dataPoint.YValues.Length > 0 && IsSerializableContent("YValues", objectToSerialize)) + { + SerializeProperty(dataPoint.YValues, dataPoint, "YValues", writer); + } + if (dataPoint.IsEmpty && IsSerializableContent("IsEmpty", objectToSerialize)) + { + SerializeProperty(dataPoint.IsEmpty, dataPoint, "IsEmpty", writer); + } + bool hasCustomProperties = false; + foreach (DictionaryEntry entry in dataPoint.properties) + { + if (entry.Key is int) + { + CommonCustomProperties propertyType = (CommonCustomProperties)((int)entry.Key); + String properyName = propertyType.ToString(); + if (IsSerializableContent(properyName, objectToSerialize)) + { + SerializeProperty(entry.Value, dataPoint, properyName, writer); + } + } + else + { + hasCustomProperties = true; + } + } + + if (hasCustomProperties && !String.IsNullOrEmpty(dataPoint.CustomProperties) && IsSerializableContent("CustomProperties", objectToSerialize)) + { + SerializeProperty(dataPoint.CustomProperties, dataPoint, "CustomProperties", writer); + } + + // If position of the writer did not change - nothing was written + if (writer.Seek(0, SeekOrigin.Current) == elementStartPosition) + { + // Remove object ID from the stream + writer.Seek(-2, SeekOrigin.Current); + writer.Write((short)0); + writer.Seek(-2, SeekOrigin.Current); + } + else + { + // Write the end objectTag + writer.Write((short)0); + } + } + + + /// <summary> + /// Serialize specified object into the binary writer. + /// Method is called recursively to serialize child objects. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="elementName">Object element name.</param> + /// <param name="writer">Binary writer.</param> + virtual internal void SerializeCollection(object objectToSerialize, string elementName, BinaryWriter writer) + { + ICollection collection = objectToSerialize as ICollection; + if(collection != null) + { + // Write object ID (hash of the name) into the writer + writer.Write(SerializerBase.GetStringHashCode(elementName)); + + // Remember position where object data is started + long elementStartPosition = writer.Seek(0, SeekOrigin.Current); + + // Enumerate through all objects in collection and serialize them + foreach (object obj in collection) + { + + if (obj is DataPoint) + { + SerializeDataPoint(obj, GetObjectName(obj), writer); + continue; + } + + SerializeObject(obj, objectToSerialize, GetObjectName(obj), writer); + } + + // If position of the writer did not change - nothing was written + if(writer.Seek(0, SeekOrigin.Current) == elementStartPosition) + { + // Remove object ID from the stream + writer.Seek(-2, SeekOrigin.Current); + writer.Write((short)0); + writer.Seek(-2, SeekOrigin.Current); + } + else + { + // Write the end objectTag + writer.Write((short)0); + } + + } + } + + /// <summary> + /// Serialize specified object into the binary writer. + /// Method is called recursively to serialize child objects. + /// </summary> + /// <param name="objectToSerialize">Object to be serialized.</param> + /// <param name="parent">Parent of the serialized object.</param> + /// <param name="elementName">Object element name.</param> + /// <param name="writer">Binary writer.</param> + virtual internal void SerializeProperty(object objectToSerialize, object parent, string elementName, BinaryWriter writer) + { + // Check input parameters + if(objectToSerialize == null || parent == null) + { + return; + } + + // Check if property has non-default value + PropertyDescriptor pd = TypeDescriptor.GetProperties(parent)[elementName]; + if(pd != null) + { + DefaultValueAttribute defValueAttribute = (DefaultValueAttribute)pd.Attributes[typeof(DefaultValueAttribute)]; + if(defValueAttribute != null) + { + if(objectToSerialize.Equals(defValueAttribute.Value)) + { + // Do not serialize properties with default values + return; + } + } + else + { + // Check if property has "ShouldSerialize" method + MethodInfo mi = parent.GetType().GetMethod("ShouldSerialize" + elementName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public ); + if(mi != null) + { + object result = mi.Invoke(parent, null); + if(result is bool && ((bool)result) == false) + { + // Do not serialize properties with default values + return; + } + } + } + + // Check XmlFormatSerializerStyle attribute + SerializationVisibilityAttribute styleAttribute = (SerializationVisibilityAttribute)pd.Attributes[typeof(SerializationVisibilityAttribute)]; + if(styleAttribute != null) + { + // Hidden property + if(styleAttribute.Visibility == SerializationVisibility.Hidden) + { + return; + } + } + } + + // Write property + WritePropertyValue(objectToSerialize, elementName, writer); + } + + /// <summary> + /// Converts object value into the string. + /// </summary> + /// <param name="obj">Object to convert.</param> + /// <param name="elementName">Object name.</param> + /// <param name="writer">Binary writer.</param> + /// <returns>Object value as strig.</returns> + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", + Justification = "Too large of a code change to justify making this change")] + internal void WritePropertyValue(object obj, string elementName, BinaryWriter writer) + { + // Write property ID (hash of the name) into the writer + writer.Write(SerializerBase.GetStringHashCode(elementName)); + + if(obj is bool) + { + writer.Write(((bool)obj)); + } + else if(obj is double) + { + writer.Write(((double)obj)); + } + else if(obj is string) + { + writer.Write(((string)obj)); + } + else if(obj is int) + { + writer.Write(((int)obj)); + } + else if(obj is long) + { + writer.Write(((long)obj)); + } + else if(obj is float) + { + writer.Write(((float)obj)); + } + else if(obj.GetType().IsEnum) + { + // NOTE: Using 'ToString' method instead of the 'Enum.GetName' fixes + // an issue (#4314 & #4424) with flagged enumerations when there are + // more then 1 values set. + string enumValue = obj.ToString(); + writer.Write(enumValue); + } + + else if(obj is byte) + { + // Write as long + writer.Write((byte)obj); + } + +#if !Microsoft_CONTROL + else if(obj is Unit) + { + writer.Write(((Unit)obj).Value); + } +#endif + + else if(obj is Font) + { + // Write as string + writer.Write(SerializerBase.FontToString((Font)obj)); + } + + else if(obj is Color) + { + // Write as int + writer.Write(((Color)obj).ToArgb()); + } + + else if(obj is DateTime) + { + // Write as long + writer.Write(((DateTime)obj).Ticks); + } + + else if(obj is Size) + { + // Write as two integers + writer.Write(((Size)obj).Width); + writer.Write(((Size)obj).Height); + } + + else if(obj is double[]) + { + double[] arr = (double[])obj; + + // Write the size of the array (int) + writer.Write(arr.Length); + + // Write each element of the array + foreach(double d in arr) + { + writer.Write(d); + } + } + + else if(obj is Color[]) + { + Color[] arr = (Color[])obj; + + // Write the size of the array (int) + writer.Write(arr.Length); + + // Write each element of the array + foreach(Color color in arr) + { + writer.Write(color.ToArgb()); + } + } + + else if(obj is System.Drawing.Image) + { + // Save image into the memory stream + MemoryStream imageStream = new MemoryStream(); + ((System.Drawing.Image)obj).Save(imageStream, ((System.Drawing.Image)obj).RawFormat); + + // Write the size of the data + int imageSize = (int)imageStream.Seek(0, SeekOrigin.End); + imageStream.Seek(0, SeekOrigin.Begin); + writer.Write(imageSize); + + // Write the data + writer.Write(imageStream.ToArray()); + + imageStream.Close(); + } + + + + else if(obj is Margins) + { + // Write as 4 integers + writer.Write(((Margins)obj).Top); + writer.Write(((Margins)obj).Bottom); + writer.Write(((Margins)obj).Left); + writer.Write(((Margins)obj).Right); + } + + + + else + { + throw (new InvalidOperationException(SR.ExceptionChartSerializerBinaryTypeUnsupported(obj.GetType().ToString()))); + } + } + + /// <summary> + /// Checks if all properties will have a unique ID. + /// Property ID is a hash of it's name. + /// !!!USED IN DEBUG BUILD ONLY!!! + /// </summary> + /// <param name="propNames">Array of properties names.</param> + internal void CheckPropertiesID(ArrayList propNames) + { +#if DEBUG + if(propNames != null) + { + // Loop through all properties and check the hash values + foreach(string name1 in propNames) + { + foreach(string name2 in propNames) + { + if(name1 != name2) + { + if( SerializerBase.GetStringHashCode(name1) == SerializerBase.GetStringHashCode(name2) ) + { + throw (new InvalidOperationException(SR.ExceptionChartSerializerBinaryHashCodeDuplicate(name1,name2))); + } + } + } + } + } +#endif + } + #endregion + + #region Deserialization methods + + /// <summary> + /// Deserialize specified object from the source using binary format. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="source">Deserialization source.</param> + internal override void Deserialize(object objectToDeserialize, object source) + { + // Check input parameters + if (objectToDeserialize == null) + { + throw (new ArgumentNullException("objectToDeserialize")); + } + if (source == null) + { + throw (new ArgumentNullException("source")); + } + + string sourceStr = source as string; + if (sourceStr != null) + { + Deserialize(objectToDeserialize, sourceStr); + return; + } + + Stream stream = source as Stream; + if (stream != null) + { + Deserialize(objectToDeserialize, stream); + return; + } + + BinaryWriter binaryWriter = source as BinaryWriter; + if (binaryWriter != null) + { + Deserialize(objectToDeserialize, binaryWriter); + return; + } + + throw (new ArgumentException(SR.ExceptionChartSerializerSourceObjectInvalid, "source")); + } + + /// <summary> + /// Deserialize object from the file using binary format. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="fileName">File name to read the data from.</param> + public void Deserialize(object objectToDeserialize, string fileName) + { + FileStream stream = new FileStream(fileName, FileMode.Open); + Deserialize(objectToDeserialize, new BinaryReader(stream)); + stream.Close(); + } + + /// <summary> + /// Deserialize object from the stream using binary format. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="stream">Stream to read the data from.</param> + public void Deserialize(object objectToDeserialize, Stream stream) + { + Deserialize(objectToDeserialize, new BinaryReader(stream)); + } + + /// <summary> + /// Deserialize object from different types of readers using binary format. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="reader">Binary reader.</param> + public void Deserialize(object objectToDeserialize, BinaryReader reader) + { + // Check input parameters + if(objectToDeserialize == null) + { + throw(new ArgumentNullException("objectToDeserialize")); + } + if(reader == null) + { + throw(new ArgumentNullException("reader")); + } + + // Binary deserializer do not support IsUnknownAttributeIgnored property + if(base.IsUnknownAttributeIgnored) + { + throw (new InvalidOperationException(SR.ExceptionChartSerializerBinaryIgnoreUnknownAttributesUnsupported)); + } + + // Read 15 characters of file header + char[] header = reader.ReadChars(15); + if(header[0] != 'D' || header[1] != 'C' || header[2] != 'B' || header[3] != 'F') + { + throw (new InvalidOperationException(SR.ExceptionChartSerializerBinaryFromatInvalid)); + } + + // Get ID of the root object + this.ReadHashID(reader); + + // Reset properties of the root object + if(IsResetWhenLoading) + { + ResetObjectProperties(objectToDeserialize); + } + + // Deserialize object + DeserializeObject(objectToDeserialize, null, GetObjectName(objectToDeserialize), reader, false); + } + + /// <summary> + /// Deserialize object from the binary format. + /// Method is called recursively to deserialize child objects. + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="parent">Parent of the deserialized object.</param> + /// <param name="elementName">Object element name.</param> + /// <param name="reader">Binary reader object.</param> + /// <param name="skipElement">if set to <c>true</c> the element will not be set.</param> + /// <returns>Number of properties set.</returns> + virtual protected int DeserializeObject(object objectToDeserialize, object parent, string elementName, BinaryReader reader, bool skipElement) + { + int setPropertiesNumber = 0; + + // Check input parameters + if(objectToDeserialize == null) + { + return setPropertiesNumber; + } + + // Special handling for the collections + Type[] assemblyTypes = null; + int listItemIndex = 0; + + IList list = objectToDeserialize as IList; + + if(list != null) + { + // Loop through all list items + Int16 typeHash = 0; + PropertyInfo listItemPI = objectToDeserialize.GetType().GetProperty("Item", new Type[] { typeof(int) }); + while ((typeHash = this.ReadHashID(reader)) != 0) + { + // Get collection item type from hashed type name + string typeName = String.Empty; + if(listItemPI != null) + { + if ((SerializerBase.GetStringHashCode(listItemPI.PropertyType.Name)) == typeHash) + { + typeName = listItemPI.PropertyType.Name; + } + else + { + Assembly assembly = listItemPI.PropertyType.Assembly; + if (assembly != null) + { + // Find all classes derived from this type + if (assemblyTypes == null) + { + assemblyTypes = assembly.GetExportedTypes(); + } + foreach (Type type in assemblyTypes) + { + if (type.IsSubclassOf(listItemPI.PropertyType)) + { + if ((SerializerBase.GetStringHashCode(type.Name)) == typeHash) + { + typeName = type.Name; + break; + } + } + } + } + } + } + + // Create new item object + string itemName = null; + bool reusedObject = false; + object listItem = GetListNewItem(list, typeName, ref itemName, ref reusedObject); + + + // Deserialize list item object + int itemSetProperties = DeserializeObject(listItem, objectToDeserialize, "", reader, skipElement); + + // Add item object into the list + if (!skipElement && (itemSetProperties > 0 || reusedObject)) + { + list.Insert(listItemIndex++, listItem); + } + // TD: here was removed a code which doesn't work but cause heavy workload: GetListNewItem removes the reusedObject from the list. + // Add properties set for collection item + setPropertiesNumber += itemSetProperties; + } + + return setPropertiesNumber; + } + + // Get list of object's properties + PropertyInfo[] properties = objectToDeserialize.GetType().GetProperties(); + if(properties == null) + { + return setPropertiesNumber; + } + + // Get property information by reading the ID + PropertyInfo pi = null; + while ( (pi = ReadPropertyInfo(objectToDeserialize, parent, properties, reader)) != null) + { + // Read simple properties + if(ShouldSerializeAsAttribute(pi, objectToDeserialize)) + { + if(SetPropertyValue(objectToDeserialize, pi, reader, skipElement)) + { + ++setPropertiesNumber; + } + } + + else + { + // Get property descriptor + PropertyDescriptor pd = TypeDescriptor.GetProperties(objectToDeserialize)[pi.Name]; + if(pd != null) + { + object innerObject = pd.GetValue(objectToDeserialize); + + // Deserialize inner item object + setPropertiesNumber += DeserializeObject(innerObject, objectToDeserialize, pi.Name, reader, !IsSerializableContent(pi.Name, objectToDeserialize)); + } + else if(!IsUnknownAttributeIgnored) + { + throw(new InvalidOperationException(SR.ExceptionChartSerializerPropertyNameUnknown( pi.Name,objectToDeserialize.GetType().ToString()))); + } + } + } + + return setPropertiesNumber; + } + + /// <summary> + /// Reads and sets a property of an object. + /// </summary> + /// <param name="obj">Object to set.</param> + /// <param name="pi">Property information.</param> + /// <param name="reader">Binary reader.</param> + /// <param name="skipElement">if set to <c>true</c> the property will not be set.</param> + /// <returns>True if property was set.</returns> + private bool SetPropertyValue(object obj, PropertyInfo pi, BinaryReader reader, bool skipElement) + { + if(pi != null) + { + object objValue = null; + + + if(pi.PropertyType == typeof(bool)) + { + objValue = reader.ReadBoolean(); + } + else if(pi.PropertyType == typeof(double)) + { + objValue = reader.ReadDouble(); + } + else if(pi.PropertyType == typeof(string)) + { + objValue = reader.ReadString(); + } + else if(pi.PropertyType == typeof(int)) + { + objValue = reader.ReadInt32(); + } + else if(pi.PropertyType == typeof(long)) + { + objValue = reader.ReadInt64(); + } + else if(pi.PropertyType == typeof(float)) + { + objValue = reader.ReadSingle(); + } + else if(pi.PropertyType.IsEnum) + { + // Read as string + objValue = Enum.Parse(pi.PropertyType, reader.ReadString()); + } + else if(pi.PropertyType == typeof(byte)) + { + objValue = reader.ReadByte(); + } + +#if !Microsoft_CONTROL + else if(pi.PropertyType == typeof(Unit)) + { + objValue = new Unit((double)reader.ReadDouble()); + } +#endif + + else if(pi.PropertyType == typeof(Font)) + { + // Read as string + objValue = SerializerBase.FontFromString(reader.ReadString()); + } + + else if(pi.PropertyType == typeof(Color)) + { + // Read as int + objValue = Color.FromArgb(reader.ReadInt32()); + } + + else if(pi.PropertyType == typeof(DateTime)) + { + // Read as long + objValue = new DateTime(reader.ReadInt64()); + } + + else if(pi.PropertyType == typeof(Size)) + { + // Read as two integers + objValue = new Size(reader.ReadInt32(), reader.ReadInt32()); + } + + + + else if(pi.PropertyType == typeof(Margins) ) + { + // Read as 4 integers + objValue = new Margins( + reader.ReadInt32(), + reader.ReadInt32(), + reader.ReadInt32(), + reader.ReadInt32()); + } + + + + else if(pi.PropertyType == typeof(double[])) + { + // Allocate array + double[] array = new double[reader.ReadInt32()]; + + // Read each element of the array + for(int arrayIndex = 0; arrayIndex < array.Length; arrayIndex++) + { + array[arrayIndex] = reader.ReadDouble(); + } + + objValue = array; + } + + else if(pi.PropertyType == typeof(Color[])) + { + // Allocate array + Color[] array = new Color[reader.ReadInt32()]; + + // Read each element of the array + for(int arrayIndex = 0; arrayIndex < array.Length; arrayIndex++) + { + array[arrayIndex] = Color.FromArgb(reader.ReadInt32()); + } + + objValue = array; + } + + else if(pi.PropertyType == typeof(System.Drawing.Image)) + { + // Get image data size + int imageSize = reader.ReadInt32(); + + // Create image stream + MemoryStream imageStream = new MemoryStream(imageSize + 10); + + // Copy image data into separate stream + imageStream.Write(reader.ReadBytes(imageSize), 0, imageSize); + + // Create image object + objValue = new Bitmap(System.Drawing.Image.FromStream(imageStream)); // !!! .Net bug when image source stream is closed - can create brush using the image + + // Close image stream + imageStream.Close(); + } + + else + { + throw(new InvalidOperationException(SR.ExceptionChartSerializerBinaryTypeUnsupported( obj.GetType().ToString() ))); + } + + + // Check if this property is serializable content + if (!skipElement && IsSerializableContent(pi.Name, obj)) + { + // Set object value + pi.SetValue(obj, objValue, null); + + return true; + } + } + + return false; + } + + /// <summary> + /// Reads property ID and return property information + /// </summary> + /// <param name="objectToDeserialize">Object to be deserialized.</param> + /// <param name="parent">Parent of the deserialized object.</param> + /// <param name="properties">List of properties information.</param> + /// <param name="reader">Binary reader.</param> + /// <returns>Property information.</returns> + private PropertyInfo ReadPropertyInfo(object objectToDeserialize, object parent, PropertyInfo[] properties, BinaryReader reader) + { + // Read property ID + short propertyID = this.ReadHashID(reader); + + // End objectTag reached + if(propertyID == 0) + { + return null; + } + + // Loop through all properties and check properties IDs (hash code of name) + foreach(PropertyInfo pi in properties) + { + // Skip inherited properties from the root object + if(IsChartBaseProperty(objectToDeserialize, parent, pi)) + { + continue; + } + + // Check collection + if (pi.CanRead && pi.PropertyType.GetInterface("ICollection", true) != null) + { + if((SerializerBase.GetStringHashCode(pi.Name)) == propertyID) + { + return pi; + } + } + + // Check public properties with Get and Set methods + else if(pi.CanRead && pi.CanWrite) + { + // Skip indexes + if(pi.Name == "Item") + { + continue; + } + + if((SerializerBase.GetStringHashCode(pi.Name)) == propertyID) + { + return pi; + } + } + } + + // Property was not found + throw (new InvalidOperationException(SR.ExceptionChartSerializerPropertyNotFound)); + } + + #endregion + } +} diff --git a/System.Web.DataVisualization/WebForm/AssemblyInfo.cs b/System.Web.DataVisualization/WebForm/AssemblyInfo.cs new file mode 100644 index 000000000..f6efcda52 --- /dev/null +++ b/System.Web.DataVisualization/WebForm/AssemblyInfo.cs @@ -0,0 +1,27 @@ +using System; +using System.Reflection; +using System.Security; +using System.Security.Permissions; +using System.Runtime.CompilerServices; +using System.Web.UI; +using System.Runtime.InteropServices; +using System.Resources; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: InternalsVisibleTo("System.Web.DataVisualization.Design, PublicKey=" + AssemblyRef.SharedLibPublicKeyFull)] +[assembly: TagPrefix("System.Web.UI.DataVisualization.Charting", "asp")] + +#if VS_BUILD +[assembly: AssemblyVersion(ThisAssembly.Version)] +[assembly: ComVisible(false)] +[assembly: CLSCompliant(true)] +[assembly: NeutralResourcesLanguageAttribute("")] +[assembly: AllowPartiallyTrustedCallers] +#endif //VS_BUILD + +[module: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA900:AptcaAssembliesShouldBeReviewed", + Justification = "We have APTCA signoff, for details please refer to SWI Track, Project ID 7972")] \ No newline at end of file diff --git a/System.Web.DataVisualization/WebForm/ChartWebControl.cs b/System.Web.DataVisualization/WebForm/ChartWebControl.cs new file mode 100644 index 000000000..3046fcd58 --- /dev/null +++ b/System.Web.DataVisualization/WebForm/ChartWebControl.cs @@ -0,0 +1,3408 @@ +//------------------------------------------------------------- +// <copyright company=’Microsoft Corporation’> +// Copyright © Microsoft Corporation. All Rights Reserved. +// </copyright> +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: WebCustomControl1.cs +// +// Namespace: System.Web.UI.DataVisualization.Charting +// +// Classes: Chart, TraceManager +// CustomizeMapAreasEventArgs +// +// Purpose: Chart web control main class. +// +// Reviewed: +// +//=================================================================== + +#region Used namespaces + +using System; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing.Design; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Data; +using System.Web; +using System.Net; +using System.IO; +using System.Text; +using System.Reflection; +using System.Diagnostics.CodeAnalysis; + +using System.Collections; +using System.Diagnostics; +using System.Xml; +using System.Web.UI.DataVisualization.Charting; +using System.Globalization; + +using System.Web.UI.DataVisualization.Charting.Data; +using System.Web.UI.DataVisualization.Charting.Utilities; +using System.Web.UI.DataVisualization.Charting.ChartTypes; +using System.Web.UI.DataVisualization.Charting.Borders3D; + +using System.Web.UI.DataVisualization.Charting.Formulas; +using System.Security; +using System.Security.Permissions; + + + +#endregion + +namespace System.Web.UI.DataVisualization.Charting +{ + + #region Chart enumerations + + /// <summary> + /// Chart image storage mode. + /// </summary> + public enum ImageStorageMode + { + + /// <summary> + /// Images are stored using HTTP Handler. + /// </summary> + UseHttpHandler, + + /// <summary> + /// Images is saved in temp. file using ImageLocation specified. + /// </summary> + UseImageLocation + } + + /// <summary> + /// Specifies the format of the image + /// </summary> + public enum ChartImageFormat + { + /// <summary> + /// Gets the Joint Photographic Experts Group (JPEG) image format. + /// </summary> + Jpeg, + + /// <summary> + /// Gets the W3C Portable Network Graphics (PNG) image format. + /// </summary> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Png")] + Png, + + /// <summary> + /// Gets the bitmap image format (BMP). + /// </summary> + Bmp, + + /// <summary> + /// Gets the Tag Image File Format (TIFF) image format. + /// </summary> + Tiff, + + /// <summary> + /// Gets the Graphics Interchange Format (GIF) image format. + /// </summary> + Gif, + + /// <summary> + /// Gets the Enhanced Meta File (Emf) image format. + /// </summary> + Emf, + + /// <summary> + /// Gets the Enhanced Meta File (Emf+) image format. + /// </summary> + EmfPlus, + + /// <summary> + /// Gets the Enhanced Meta File (EmfDual) image format. + /// </summary> + EmfDual, + } + + /// <summary> + /// Chart image rendering type + /// </summary> + public enum RenderType + { + /// <summary> + /// Chart image is rendered as image tag. + /// </summary> + ImageTag, + + /// <summary> + /// Chart image is streamed back directly. + /// </summary> + BinaryStreaming, + + /// <summary> + /// Chart image map is rendered. + /// </summary> + ImageMap + } + + #endregion + + /// <summary> + /// Summary description for enterprize chart control. + /// </summary> + [ + ToolboxData("<{0}:Chart runat=server>" + + "<Series><{0}:Series Name=\"Series1\"></{0}:Series></Series>" + + "<ChartAreas><{0}:ChartArea Name=\"ChartArea1\"></{0}:ChartArea></ChartAreas>" + + "</{0}:Chart>"), + ToolboxBitmap(typeof(Chart), "ChartControl.ico"), + Designer(Editors.ChartWebDesigner) + ] + [SuppressMessage("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces")] + [DisplayNameAttribute("Chart")] + [SupportsEventValidation] + [DefaultEvent("Load")] +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class Chart : System.Web.UI.WebControls.DataBoundControl, IPostBackEventHandler + { + + #region Control fields + + /// <summary> + /// True if smart labels debug markings should be drawn. + /// This field is for SmartLabels related issues debugging only. + /// </summary> + internal bool ShowDebugMarkings = false; + + // Chart services components + private ChartTypeRegistry _chartTypeRegistry = null; + private BorderTypeRegistry _borderTypeRegistry = null; + private CustomPropertyRegistry _customPropertyRegistry = null; + private DataManager _dataManager = null; + internal ChartImage chartPicture = null; + private ImageLoader _imageLoader = null; + internal static ITypeDescriptorContext controlCurrentContext = null; + internal string webFormDocumentURL = ""; + internal ServiceContainer serviceContainer = null; + + // Named images collection + private NamedImagesCollection _namedImages = null; + + + private FormulaRegistry _formulaRegistry = null; + + + // Product ID + + internal static string productID = "MSC-WCE-10"; + + // Control license + private License _license = null; + + // Private data members, which store properties values + private RenderType _renderType = RenderType.ImageTag; + private string _chartImageLocation = "ChartPic_#SEQ(300,3)"; + + // Indicates that chart is serializing the data + internal bool serializing = false; + + // Detailed serialization status which allows not only to determine if serialization + // is curently in process but also check if we are saving, loading or resetting the chart. + internal SerializationStatus serializationStatus = SerializationStatus.None; + + // Chart serializer + private ChartSerializer _chartSerializer = null; + + // Chart content saved in the view state + private SerializationContents _viewStateContent = SerializationContents .Default; + + // Image URL the chart will be renderd to + private string _currentChartImageLocation = String.Empty; + + // Image Handler URL the chart will be renderd to + private string _currentChartHandlerImageLocation = String.Empty; + + // Indicates if unique GUID should be added to image file name to solve cashing issues + private bool _addGuidParam = true; + + private KeywordsRegistry _keywordsRegistry = null; + + // Indicates image storage mode. + private ImageStorageMode _imageStorageMode = ImageStorageMode.UseHttpHandler; + + + // Selection class + internal Selection selection = null; + + #endregion + + #region Constructors and initialization + + /// <summary> + /// Chart control constructor. + /// </summary> + public Chart() : base() + { + base.EnableViewState = false; + + //********************************************************* + //** Create services + //********************************************************* + serviceContainer = new ServiceContainer(); + _chartTypeRegistry = new ChartTypeRegistry(); + _borderTypeRegistry = new BorderTypeRegistry(); + _customPropertyRegistry = new CustomPropertyRegistry(); + + _keywordsRegistry = new KeywordsRegistry(); + + _dataManager = new DataManager(serviceContainer); + _imageLoader = new ImageLoader(serviceContainer); + chartPicture = new ChartImage(serviceContainer); + _chartSerializer = new ChartSerializer(serviceContainer); + + + _formulaRegistry = new FormulaRegistry(); + + // Add services to the service container + serviceContainer.AddService(typeof(Chart), this); // Chart Control + serviceContainer.AddService(_chartTypeRegistry.GetType(), _chartTypeRegistry);// Chart types registry + serviceContainer.AddService(_borderTypeRegistry.GetType(), _borderTypeRegistry);// Border types registry + serviceContainer.AddService(_customPropertyRegistry.GetType(), _customPropertyRegistry);// Custom attribute registry + serviceContainer.AddService(_dataManager.GetType(), _dataManager); // Data Manager service + serviceContainer.AddService(_imageLoader.GetType(), _imageLoader); // Image Loader service + serviceContainer.AddService(chartPicture.GetType(), chartPicture); // Chart image service + serviceContainer.AddService(_chartSerializer.GetType(), _chartSerializer); // Chart serializer service + + + serviceContainer.AddService(_formulaRegistry.GetType(), _formulaRegistry); // Formula modules service + + + + serviceContainer.AddService(_keywordsRegistry.GetType(), _keywordsRegistry); // Keywords registry + + + + // Initialize objects + _dataManager.Initialize(); + + // Register known chart types + _chartTypeRegistry.Register(ChartTypeNames.Bar, typeof(BarChart)); + _chartTypeRegistry.Register(ChartTypeNames.Column, typeof(ColumnChart)); + _chartTypeRegistry.Register(ChartTypeNames.Point, typeof(PointChart)); + _chartTypeRegistry.Register(ChartTypeNames.Bubble, typeof(BubbleChart)); + _chartTypeRegistry.Register(ChartTypeNames.Line, typeof(LineChart)); + _chartTypeRegistry.Register(ChartTypeNames.Spline, typeof(SplineChart)); + _chartTypeRegistry.Register(ChartTypeNames.StepLine, typeof(StepLineChart)); + _chartTypeRegistry.Register(ChartTypeNames.Area, typeof(AreaChart)); + _chartTypeRegistry.Register(ChartTypeNames.SplineArea, typeof(SplineAreaChart)); + _chartTypeRegistry.Register(ChartTypeNames.StackedArea, typeof(StackedAreaChart)); + _chartTypeRegistry.Register(ChartTypeNames.Pie, typeof(PieChart)); + _chartTypeRegistry.Register(ChartTypeNames.Stock, typeof(StockChart)); + _chartTypeRegistry.Register(ChartTypeNames.Candlestick, typeof(CandleStickChart)); + _chartTypeRegistry.Register(ChartTypeNames.Doughnut, typeof(DoughnutChart)); + _chartTypeRegistry.Register(ChartTypeNames.StackedBar, typeof(StackedBarChart)); + _chartTypeRegistry.Register(ChartTypeNames.StackedColumn, typeof(StackedColumnChart)); + _chartTypeRegistry.Register(ChartTypeNames.OneHundredPercentStackedColumn, typeof(HundredPercentStackedColumnChart)); + _chartTypeRegistry.Register(ChartTypeNames.OneHundredPercentStackedBar, typeof(HundredPercentStackedBarChart)); + _chartTypeRegistry.Register(ChartTypeNames.OneHundredPercentStackedArea, typeof(HundredPercentStackedAreaChart)); + + + + _chartTypeRegistry.Register(ChartTypeNames.Range, typeof(RangeChart)); + _chartTypeRegistry.Register(ChartTypeNames.SplineRange, typeof(SplineRangeChart)); + _chartTypeRegistry.Register(ChartTypeNames.RangeBar, typeof(RangeBarChart)); + _chartTypeRegistry.Register(ChartTypeNames.RangeColumn, typeof(RangeColumnChart)); + _chartTypeRegistry.Register(ChartTypeNames.ErrorBar, typeof(ErrorBarChart)); + _chartTypeRegistry.Register(ChartTypeNames.BoxPlot, typeof(BoxPlotChart)); + _chartTypeRegistry.Register(ChartTypeNames.Radar, typeof(RadarChart)); + + + + _chartTypeRegistry.Register(ChartTypeNames.Renko, typeof(RenkoChart)); + _chartTypeRegistry.Register(ChartTypeNames.ThreeLineBreak, typeof(ThreeLineBreakChart)); + _chartTypeRegistry.Register(ChartTypeNames.Kagi, typeof(KagiChart)); + _chartTypeRegistry.Register(ChartTypeNames.PointAndFigure, typeof(PointAndFigureChart)); + + + + + + _chartTypeRegistry.Register(ChartTypeNames.Polar, typeof(PolarChart)); + _chartTypeRegistry.Register(ChartTypeNames.FastLine, typeof(FastLineChart)); + _chartTypeRegistry.Register(ChartTypeNames.Funnel, typeof(FunnelChart)); + _chartTypeRegistry.Register(ChartTypeNames.Pyramid, typeof(PyramidChart)); + + + + + + _chartTypeRegistry.Register(ChartTypeNames.FastPoint, typeof(FastPointChart)); + + + + + // Register known formula modules + _formulaRegistry.Register(SR.FormulaNamePriceIndicators, typeof(PriceIndicators)); + _formulaRegistry.Register(SR.FormulaNameGeneralTechnicalIndicators, typeof(GeneralTechnicalIndicators)); + _formulaRegistry.Register(SR.FormulaNameTechnicalVolumeIndicators, typeof(VolumeIndicators)); + _formulaRegistry.Register(SR.FormulaNameOscillator, typeof(Oscillators)); + _formulaRegistry.Register(SR.FormulaNameGeneralFormulas, typeof(GeneralFormulas)); + _formulaRegistry.Register(SR.FormulaNameTimeSeriesAndForecasting, typeof(TimeSeriesAndForecasting)); + _formulaRegistry.Register(SR.FormulaNameStatisticalAnalysis, typeof(StatisticalAnalysis)); + + // Register known 3D border types + _borderTypeRegistry.Register("Emboss", typeof(EmbossBorder)); + _borderTypeRegistry.Register("Raised", typeof(RaisedBorder)); + _borderTypeRegistry.Register("Sunken", typeof(SunkenBorder)); + _borderTypeRegistry.Register("FrameThin1", typeof(FrameThin1Border)); + _borderTypeRegistry.Register("FrameThin2", typeof(FrameThin2Border)); + _borderTypeRegistry.Register("FrameThin3", typeof(FrameThin3Border)); + _borderTypeRegistry.Register("FrameThin4", typeof(FrameThin4Border)); + _borderTypeRegistry.Register("FrameThin5", typeof(FrameThin5Border)); + _borderTypeRegistry.Register("FrameThin6", typeof(FrameThin6Border)); + _borderTypeRegistry.Register("FrameTitle1", typeof(FrameTitle1Border)); + _borderTypeRegistry.Register("FrameTitle2", typeof(FrameTitle2Border)); + _borderTypeRegistry.Register("FrameTitle3", typeof(FrameTitle3Border)); + _borderTypeRegistry.Register("FrameTitle4", typeof(FrameTitle4Border)); + _borderTypeRegistry.Register("FrameTitle5", typeof(FrameTitle5Border)); + _borderTypeRegistry.Register("FrameTitle6", typeof(FrameTitle6Border)); + _borderTypeRegistry.Register("FrameTitle7", typeof(FrameTitle7Border)); + _borderTypeRegistry.Register("FrameTitle8", typeof(FrameTitle8Border)); + + // Create selection object + this.selection = new Selection(serviceContainer); + + // Create named images collection + _namedImages = new NamedImagesCollection(); + + // Hook up event handlers + ChartAreas.NameReferenceChanged += new EventHandler<NameReferenceChangedEventArgs>(Series.ChartAreaNameReferenceChanged); + ChartAreas.NameReferenceChanged += new EventHandler<NameReferenceChangedEventArgs>(Legends.ChartAreaNameReferenceChanged); + ChartAreas.NameReferenceChanged += new EventHandler<NameReferenceChangedEventArgs>(Titles.ChartAreaNameReferenceChanged); + ChartAreas.NameReferenceChanged += new EventHandler<NameReferenceChangedEventArgs>(Annotations.ChartAreaNameReferenceChanged); + Legends.NameReferenceChanged += new EventHandler<NameReferenceChangedEventArgs>(Series.LegendNameReferenceChanged); + + this.AlternateText = String.Empty; + this.DescriptionUrl = String.Empty; + } + + #endregion + + #region Chart rendering methods + + /// <summary> + /// Gets current image URL the chart control will be rendered into. + /// </summary> + /// <returns>Current chart image URL.</returns> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings")] + [ + Bindable(false), + Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SerializationVisibility(SerializationVisibility.Hidden), + ] + public string CurrentImageLocation + { + get + { + + if (this.RenderType == RenderType.ImageTag && this.GetImageStorageMode() == ImageStorageMode.UseHttpHandler) + { + return _currentChartHandlerImageLocation; + } + + // Image name is already created + if (this._currentChartImageLocation.Length > 0) + { + return this._currentChartImageLocation; + } + + // Get picture name + this._currentChartImageLocation = this.ImageLocation; + int indexUID = -1; + if (this.RenderType == RenderType.ImageTag) + { + // Make sure image URL is not empty + if (this.ImageLocation.Length == 0) + { + throw (new InvalidOperationException(SR.ExceptionImageUrlIsEmpty)); + } + // Add file extension if there is no one + char[] slashesArray = { '\\', '/' }; + int pointIndex = _currentChartImageLocation.LastIndexOf('.'); + int slashIndex = _currentChartImageLocation.LastIndexOfAny(slashesArray); + if (pointIndex < 0 || pointIndex < slashIndex) + { + switch (chartPicture.ImageType) + { + case (ChartImageType.Bmp): + _currentChartImageLocation += ".bmp"; + break; + case (ChartImageType.Jpeg): + _currentChartImageLocation += ".jpeg"; + break; + case (ChartImageType.Png): + _currentChartImageLocation += ".png"; + break; + case (ChartImageType.Emf): + _currentChartImageLocation += ".emf"; + break; + } + } + + // Double chech that #UID is not used with #SEQ + // Add GUID to the filename + indexUID = _currentChartImageLocation.IndexOf("#UID", StringComparison.Ordinal); + int indexSEQ = _currentChartImageLocation.IndexOf("#SEQ", StringComparison.Ordinal); + if (indexUID >= 0 && indexSEQ >= 0) + { + throw (new InvalidOperationException(SR.ExceptionImageUrlInvalidFormatters)); + } + + // Add GUID to the filename + if (indexUID >= 0) + { + // Replace "#UID" with GUID string + _currentChartImageLocation = _currentChartImageLocation.Replace("#UID", Guid.NewGuid().ToString()); + } + + // Add GUID to the filename + else if (indexSEQ >= 0) + { + // Replace "#SEQ(XXX,XXX)" with the sequence string number + _currentChartImageLocation = GetNewSeqImageUrl(_currentChartImageLocation); + } + + } + + // Check if GUID parameter should be added to the SRC tag + // Solves issue with image caching in IE + int indexNoGuidParam = _currentChartImageLocation.IndexOf("#NOGUIDPARAM", StringComparison.Ordinal); + if (indexNoGuidParam > 0) + { + _currentChartImageLocation = _currentChartImageLocation.Replace("#NOGUIDPARAM", ""); + } + + // Check for virtual root character + if (_currentChartImageLocation.StartsWith("~", StringComparison.Ordinal) && HttpContext.Current != null && this.Page.Request != null) + { + // NOTE: Solves issue #4771 + _currentChartImageLocation = this.Page.ResolveUrl(_currentChartImageLocation); + } + + return _currentChartImageLocation; + } + } + + + + /// <summary> + /// Determines if chart should render image maps + /// </summary> + /// <returns>True if should render image maps</returns> + private bool HasImageMaps() + { + // Render chart image map + if (this.RenderType != RenderType.BinaryStreaming && this.IsMapEnabled) + { + if (this.MapAreas.Count > 0 || this.RenderType == RenderType.ImageMap) + { + // Render image map + return true; + } + } + return false; + } + + /// <summary> + /// Caches the IsImageRendersBorder result. + /// </summary> + private static int _isImageRendersBorder; + /// <summary> + /// Checks and returns true if the image renders border. Before Fx 4.0 image control renders border if is not declared. + /// After Fx 4.0 this is not by default. + /// </summary> + /// <returns>True if image control renders border style</returns> + private static bool IsImageRendersBorder + { + get + { + if (_isImageRendersBorder == 0) + { + using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture)) + { + using (HtmlTextWriter w = new HtmlTextWriter(sw)) + { + System.Web.UI.WebControls.Image img = new System.Web.UI.WebControls.Image(); + img.RenderControl(w); + } + _isImageRendersBorder = sw.ToString().IndexOf("border", 0, StringComparison.OrdinalIgnoreCase) != -1 ? 1 : -1; + } + } + return _isImageRendersBorder == 1; + } + } + + /// <summary> + /// Custom image control for supporting miage maps. + /// </summary> + private class CustomImageControl : System.Web.UI.WebControls.Image + { + /// <summary> + /// Initializes a new instance of the <see cref="CustomImageControl"/> class. + /// </summary> + internal CustomImageControl() : base() + { + } + + /// <summary> + /// Gets or sets a value indicating whether this instance has image map. + /// </summary> + /// <value> + /// <c>true</c> if this instance has image map; otherwise, <c>false</c>. + /// </value> + internal bool HasImageMap { get; set; } + + /// <summary> + /// Adds the attributes of an <see cref="T:System.Web.UI.WebControls.Image"/> to the output stream for rendering on the client. + /// </summary> + /// <param name="writer">A <see cref="T:System.Web.UI.HtmlTextWriter"/> that contains the output stream to render on the client browser.</param> + protected override void AddAttributesToRender(HtmlTextWriter writer) + { + base.AddAttributesToRender(writer); + if (this.HasImageMap) + { + writer.AddAttribute(HtmlTextWriterAttribute.Usemap, "#"+this.ClientID+"ImageMap", false); + } + if (!this.Enabled) + { + writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled"); + } + } + } + + /// <summary> + /// Builds the image control. + /// </summary> + /// <param name="chartImageSrc">The chart image SRC.</param> + /// <param name="addGuidParameter">if set to <c>true</c> to add GUID parameter.</param> + /// <returns>A custom image control with image maps attribute</returns> + private CustomImageControl BuildImageControl(string chartImageSrc, bool addGuidParameter) + { + CustomImageControl htmlImage = new CustomImageControl(); + htmlImage.ImageUrl = chartImageSrc + (addGuidParameter ? "?" + Guid.NewGuid().ToString() : ""); + htmlImage.ToolTip = this.ToolTip; + htmlImage.CssClass = this.CssClass; + htmlImage.AlternateText = this.AlternateText; + htmlImage.DescriptionUrl = this.DescriptionUrl; + htmlImage.AccessKey = this.AccessKey; + htmlImage.TabIndex = this.TabIndex; + htmlImage.Enabled = this.IsEnabled; + htmlImage.CopyBaseAttributes(this); + if (!IsImageRendersBorder) + { + // set border 0px only if is not declared yet. + if ( String.IsNullOrEmpty(htmlImage.Style[HtmlTextWriterStyle.BorderWidth]) && + String.IsNullOrEmpty(htmlImage.Style["border"]) && + String.IsNullOrEmpty(htmlImage.Style["border-width"])) + { + htmlImage.Style.Value = "border-width:0px;" + htmlImage.Style.Value; + } + } + + htmlImage.ID = this.ClientID; + + htmlImage.GenerateEmptyAlternateText = true; + + htmlImage.Width = this.Width; + htmlImage.Height = this.Height; + htmlImage.HasImageMap = this.HasImageMaps(); + + return htmlImage; + } + + private string _designTimeChart; + /// <summary> + /// Render this control to the output parameter specified. + /// </summary> + /// <param name="writer">HTML writer.</param> + protected override void Render(HtmlTextWriter writer) + { + // If by any reason (rudimentary designer host, no designer, embeded in user control, etc) + // Render() is called in design mode ( should be handled by control designed ) + // we render the chart in temp file. + if (this.DesignMode) + { + if (String.IsNullOrEmpty(_designTimeChart)) + { + _designTimeChart = Path.GetTempFileName() + ".bmp"; + } + SaveImage(_designTimeChart, ChartImageFormat.Bmp); + using (CustomImageControl imageControl = this.BuildImageControl("file://" + _designTimeChart, false)) + { + imageControl.RenderControl(writer); + } + return; + } + + // Check if GUID parameter should be added to the SRC tag + // Solves issue with image caching in IE + _addGuidParam = true; + int indexNoGuidParam = this.ImageLocation.IndexOf("#NOGUIDPARAM", StringComparison.Ordinal); + if(indexNoGuidParam > 0) + { + _addGuidParam = false; + } + + // Get picture name + string chartImage = this.CurrentImageLocation; + + + if (this.RenderType == RenderType.ImageTag) + { + if (this.GetImageStorageMode() == ImageStorageMode.UseHttpHandler) + { + using (MemoryStream stream = new MemoryStream()) + { + this.SaveImage(stream); + chartImage = ChartHttpHandler.GetChartImageUrl(stream, this.ImageType.ToString()); + _currentChartHandlerImageLocation = chartImage; + } + _addGuidParam = false; + } + else + { + // Save chart into specified image URL + SaveImage(this.Page.MapPath(chartImage)); + } + + using (CustomImageControl imageControl = this.BuildImageControl(chartImage, _addGuidParam)) + { + imageControl.RenderControl(writer); + } + + } + + // Render chart image as image tag + image map + else if(this.RenderType == RenderType.ImageMap) + { + + // Get chart image (do not save it) + chartPicture.PaintOffScreen(); + + using (CustomImageControl imageControl = this.BuildImageControl(chartImage, _addGuidParam)) + { + imageControl.RenderControl(writer); + } + + } + // Render chart using binary data streaming + else + { + + // Set response content type + switch (chartPicture.ImageType) + { + case (ChartImageType.Bmp): + this.Page.Response.ContentType = "image/bmp"; + break; + case (ChartImageType.Jpeg): + this.Page.Response.ContentType = "image/jpeg"; + break; + case (ChartImageType.Png): + this.Page.Response.ContentType = "image/png"; + break; + } + + this.Page.Response.Charset = ""; + + // Save image into the memory stream + MemoryStream stream = new MemoryStream(); + SaveImage(stream); + this.Page.Response.BinaryWrite(stream.GetBuffer()); + } + + + // Render chart image map + if (this.HasImageMaps()) + { + // Render image map + chartPicture.WriteChartMapTag(writer, this.ClientID + "ImageMap"); + } + + // Reset image Url field + this._currentChartImageLocation = String.Empty; + + } + + + /// <summary> + /// Checks image URL sequence format. + /// </summary> + /// <param name="imageURL">Image URL to test.</param> + void CheckImageURLSeqFormat(string imageURL) + { + // Find the begginning of the "#SEQ" formatting string + int indexSEQ = imageURL.IndexOf("#SEQ", StringComparison.Ordinal); + indexSEQ += 4; + + // The "#SEQ" formatter must be followed by (MMM,TTT), where MMM - max sequence number and TTT - time to live + if(imageURL[indexSEQ] != '(') + { + throw( new ArgumentException(SR.ExceptionImageUrlInvalidFormat, "imageURL")); + } + // Find closing bracket + int indexClosing = imageURL.IndexOf(')', 1); + if(indexClosing < 0) + { + throw (new ArgumentException(SR.ExceptionImageUrlInvalidFormat, "imageURL")); + } + + // Get max sequence number and time to live + string[] values = imageURL.Substring(indexSEQ + 1, indexClosing - indexSEQ - 1).Split(','); + if(values == null || values.Length != 2) + { + throw (new ArgumentException(SR.ExceptionImageUrlInvalidFormat, "imageURL")); + } + + // Make sure all characters are digits + foreach(String str in values) + { + if (String.IsNullOrEmpty(str) || str.Length > 7) + { + throw (new ArgumentException(SR.ExceptionImageUrlInvalidFormat, "imageURL")); + } + foreach (Char c in str) + { + if(!Char.IsDigit(c)) + { + throw( new ArgumentException( SR.ExceptionImageUrlInvalidFormat, "imageURL")); + } + } + } + } + + /// <summary> + /// Helper function, which returns a new image URL + /// using the sequence numbers + /// </summary> + /// <param name="imageUrl">Image URL format.</param> + /// <returns>New image URL.</returns> + private string GetNewSeqImageUrl(string imageUrl) + { + // Initialize image URL max sequence number and image time to live values + int maxSeqNumber = 0; + int imageTimeToLive = 0; + string result = ""; + + //********************************************************* + //** Check image URL format + //********************************************************* + + // Find the begginning of the "#SEQ" formatting string + int indexSEQ = imageUrl.IndexOf("#SEQ", StringComparison.Ordinal); + if(indexSEQ < 0) + { + throw( new ArgumentException( SR.ExceptionImageUrlMissedFormatter, "imageUrl")); + } + + // Check format + CheckImageURLSeqFormat(imageUrl); + + // Copy everything till the beginning of the format in the result string + result = imageUrl.Substring(0, indexSEQ); + indexSEQ += 4; + + // Find closing bracket + int indexClosing = imageUrl.IndexOf(')', 1); + + // Add sequence position and everything after closing bracket into the result string + result += "{0:D6}"; + result += imageUrl.Substring(indexClosing + 1); + + // Get max sequence number and time to live + string[] values = imageUrl.Substring(indexSEQ + 1, indexClosing - indexSEQ - 1).Split(','); + maxSeqNumber = Int32.Parse(values[0], System.Globalization.CultureInfo.InvariantCulture); + imageTimeToLive = Int32.Parse(values[1], System.Globalization.CultureInfo.InvariantCulture); + + //********************************************************* + //** Generate new sequence number + //********************************************************* + int imageSeqNumber = 1; + + // Make sure application scope variable "ImageSeqNumber" exist + this.Page.Application.Lock(); + if(this.Page.Application[Chart.productID+"_ImageSeqNumber"] != null) + { + imageSeqNumber = (int)this.Page.Application[Chart.productID+"_ImageSeqNumber"] + 1; + if(imageSeqNumber > maxSeqNumber) + { + imageSeqNumber = 1; + } + } + // Save sequence number + this.Page.Application[Chart.productID+"_ImageSeqNumber"] = imageSeqNumber; + this.Page.Application.UnLock(); + + //********************************************************* + //** Prepare result string + //********************************************************* + + result = String.Format(CultureInfo.InvariantCulture, result, imageSeqNumber); + + //********************************************************* + //** Check if the image with this name exsists and it's + //** live time is smaller than image time-to-live specified. + //** In this case put a warning into the even log. + //********************************************************* + if(imageTimeToLive > 0) + { + CheckChartFileTime(result, imageTimeToLive); + } + + return result; + } + + /// <summary> + /// Check if the image with this name exsists and it's + /// live time is smaller than image time-to-live specified. + /// In this case put a warning into the even log. + /// </summary> + /// <param name="fileName">File name.</param> + /// <param name="imageTimeToLive">Time to live.</param> + private void CheckChartFileTime(string fileName, int imageTimeToLive) + { + //********************************************************* + //** Check if the image with this name exsists and it's + //** live time is smaller than image time-to-live specified. + //** In this case put a warning into the even log. + //********************************************************* + try + { + if (imageTimeToLive > 0) + { + fileName = this.Page.MapPath(fileName); + if (File.Exists(fileName)) + { + DateTime fileTime = File.GetLastWriteTime(fileName); + if (fileTime.AddMinutes(imageTimeToLive) > DateTime.Now) + { + const string eventSource = "ChartComponent"; + + // Create the source, if it does not already exist. + if (!EventLog.SourceExists(eventSource)) + { + EventLog.CreateEventSource(eventSource, "Application"); + } + + // Create an EventLog instance and assign its source. + EventLog eventLog = new EventLog(); + eventLog.Source = eventSource; + + // Write an informational entry to the event log. + TimeSpan timeSpan = DateTime.Now - fileTime; + eventLog.WriteEntry(SR.EvenLogMessageChartImageFileTimeToLive(timeSpan.Minutes.ToString(CultureInfo.InvariantCulture)), EventLogEntryType.Warning); + } + } + } + } + catch (SecurityException) + { + } + catch (ArgumentException) + { + } + catch (InvalidOperationException) + { + } + catch (Win32Exception) + { + } + } + + #endregion + + #region Chart selection methods + + /// <summary> + /// This method performs the hit test and returns a HitTestResult objects. + /// </summary> + /// <param name="x">X coordinate</param> + /// <param name="y">Y coordinate</param> + /// <returns>Hit test result object</returns> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public HitTestResult HitTest(int x, int y) + { + return selection.HitTest(x, y); + } + + /// <summary> + /// This method performs the hit test and returns a HitTestResult object. + /// </summary> + /// <param name="x">X coordinate</param> + /// <param name="y">Y coordinate</param> + /// <param name="ignoreTransparent">Indicates that transparent elements should be ignored.</param> + /// <returns>Hit test result object</returns> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public HitTestResult HitTest(int x, int y, bool ignoreTransparent) + { + return selection.HitTest(x, y, ignoreTransparent); + } + + /// <summary> + /// This method performs the hit test and returns a HitTestResult object. + /// </summary> + /// <param name="x">X coordinate</param> + /// <param name="y">Y coordinate</param> + /// <param name="requestedElement">Only this chart element will be hit tested.</param> + /// <returns>Hit test result object</returns> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public HitTestResult HitTest(int x, int y, ChartElementType requestedElement) + { + return selection.HitTest(x, y, requestedElement); + } + + /// <summary> + /// Call this method to determine the chart element, + /// if any, that is located at a point defined by the given X and Y + /// coordinates. + /// <seealso cref="HitTestResult"/></summary> + /// <param name="x">The X coordinate for the point in question. + /// Often obtained from a parameter in an event + /// (e.g. the X parameter value in the MouseDown event).</param> + /// <param name="y">The Y coordinate for the point in question. + /// Often obtained from a parameter in an event + /// (e.g. the Y parameter value in the MouseDown event).</param> + /// <param name="ignoreTransparent">Indicates that transparent + /// elements should be ignored.</param> + /// <param name="requestedElement"> + /// An array of type which specify the types + /// to test for, on order to filter the result. If omitted checking for + /// elementTypes will be ignored and all kind of elementTypes will be + /// valid. + /// </param> + /// <returns> + /// A array of <see cref="HitTestResult"/> objects, + /// which provides information concerning the chart element + /// (if any) that is at the specified location. Result contains at least + /// one element, which could be ChartElementType.Nothing. + /// The objects in the result are sorted in from top to bottom of + /// different layers of control. </returns> + /// <remarks>Call this method to determine the gauge element + /// (if any) that is located at a specified point. Often this method is used in + /// some mouse-related event (e.g. MouseDown) + /// to determine what gauge element the end-user clicked on. + /// The X and Y mouse coordinates obtained from the + /// event parameters are then used for the X and Y parameter + /// values of this method call. The returned + /// <see cref="HitTestResult"/> object's properties + /// can then be used to determine what chart element was clicked on, + /// and also provides a reference to the actual object selected (if + /// any).</remarks> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public HitTestResult[] HitTest(int x, int y, bool ignoreTransparent, params ChartElementType[] requestedElement) + { + return this.selection.HitTest(x, y, ignoreTransparent, requestedElement); + } + + /// <summary> + /// Gets the chart element outline. + /// </summary> + /// <param name="chartElement">The chart element.</param> + /// <param name="elementType">Type of the element.</param> + /// <returns> A <see cref="ChartElementOutline"/> object which contains + /// 1) An array of points in absolute coordinates which can be used as outline markers arround this chart element. + /// 2) A GraphicsPath for drawing aouline around this chart emenent. + /// </returns> + /// <remarks> + /// If the <paramref name="chartElement"/> is not part of the chart or <paramref name="elementType"/> cannot be combined + /// with <paramref name="chartElement"/> then the result will contain empty array of marker points. + /// The marker points are sorted clockwise. + /// </remarks> + public ChartElementOutline GetChartElementOutline(object chartElement, ChartElementType elementType) + { + return this.selection.GetChartElementOutline(chartElement, elementType); + } + + #endregion + + #region Chart image saving methods + + /// <summary> + /// Draws chart on the graphics. + /// </summary> + /// <param name="graphics">Graphics.</param> + /// <param name="position">Position to draw in the graphics.</param> + public void Paint(Graphics graphics, Rectangle position) + { + // Change chart size to fit the new position + int oldWidth = this.chartPicture.Width; + int oldHeight = this.chartPicture.Height; + // Save graphics state. + GraphicsState transState = graphics.Save(); + try + { + this.chartPicture.Width = position.Width; + this.chartPicture.Height = position.Height; + // Set required transformation + graphics.TranslateTransform(position.X, position.Y); + // Set printing indicator + this.chartPicture.isPrinting = true; + // Draw chart + this.chartPicture.Paint(graphics, false); + // Clear printing indicator + this.chartPicture.isPrinting = false; + + } + finally + { + // Restore graphics state. + graphics.Restore(transState); + // Restore old chart position + this.chartPicture.Width = oldWidth; + this.chartPicture.Height = oldHeight; + + } + } + + /// <summary> + /// Saves chart image into the file. + /// </summary> + /// <param name="imageFileName">Image file name</param> + /// <param name="format">Image format.</param> + public void SaveImage(string imageFileName, ChartImageFormat format) + { + // Check arguments + if (imageFileName == null) + throw new ArgumentNullException("imageFileName"); + + // Create file stream for the specified file name + FileStream fileStream = new FileStream(imageFileName, FileMode.Create); + + // Save into stream + try + { + SaveImage(fileStream, format); + } + finally + { + // Close file stream + fileStream.Close(); + } + } + + + /// <summary> + /// Saves chart image into the stream. + /// </summary> + /// <param name="imageStream">Image stream.</param> + /// <param name="format">Image format.</param> + public void SaveImage( Stream imageStream, ChartImageFormat format) + { + // Check arguments + if (imageStream == null) + throw new ArgumentNullException("imageStream"); + + this.chartPicture.isPrinting = true; + try + { + if (format == ChartImageFormat.Emf || + format == ChartImageFormat.EmfDual || + format == ChartImageFormat.EmfPlus) + { + EmfType emfType = EmfType.EmfOnly; + if (format == ChartImageFormat.EmfDual) + { + emfType = EmfType.EmfPlusDual; + } + else if (format == ChartImageFormat.EmfPlus) + { + emfType = EmfType.EmfPlusOnly; + } + + // Save into the metafile + this.chartPicture.SaveIntoMetafile(imageStream, emfType); + } + else + { + // Get chart image + System.Drawing.Image chartImage = this.chartPicture.GetImage(); + + ImageFormat standardImageFormat = ImageFormat.Png; + + switch (format) + { + case ChartImageFormat.Bmp: + standardImageFormat = ImageFormat.Bmp; + break; + + case ChartImageFormat.Gif: + standardImageFormat = ImageFormat.Gif; + break; + + case ChartImageFormat.Tiff: + standardImageFormat = ImageFormat.Tiff; + break; + + + case ChartImageFormat.Jpeg: + standardImageFormat = ImageFormat.Jpeg; + break; + case ChartImageFormat.Png: + standardImageFormat = ImageFormat.Png; + break; + + + case ChartImageFormat.Emf: + standardImageFormat = ImageFormat.Emf; + break; + } + + // Save image into the file + chartImage.Save(imageStream, standardImageFormat); + + // Dispose image + chartImage.Dispose(); + } + } + finally + { + this.chartPicture.isPrinting = false; + } + } + + + /// <summary> + /// Saves image into the stream. ImageType, Compression and other control properties are used. + /// </summary> + /// <param name="imageStream">Image stream.</param> + public void SaveImage(Stream imageStream) + { + // Check arguments + if (imageStream == null) + throw new ArgumentNullException("imageStream"); + + //***************************************************** + //** Disable validating the license for now.... + //***************************************************** + // ValidateLicense(); + + this.chartPicture.isPrinting = true; + try + { + + // Save into the metafile + if( ImageType == ChartImageType.Emf) + { + this.chartPicture.SaveIntoMetafile(imageStream, EmfType.EmfOnly); + return; + } + + System.Drawing.Image image = chartPicture.GetImage(); + // Set image settings + ImageCodecInfo imageCodecInfo = null; + EncoderParameter encoderParameter = null; + EncoderParameters encoderParameters = new EncoderParameters(1); + + // Get image codec information + if(ImageType == ChartImageType.Bmp) + { + imageCodecInfo = GetEncoderInfo("image/bmp"); + } + else if(ImageType == ChartImageType.Jpeg) + { + imageCodecInfo = GetEncoderInfo("image/jpeg"); + } + else if(ImageType == ChartImageType.Png) + { + imageCodecInfo = GetEncoderInfo("image/png"); + } + + // Set image quality + encoderParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100-Compression); + encoderParameters.Param[0] = encoderParameter; + + // Save image into the file + if(imageCodecInfo == null) + { + ImageFormat format = (ImageFormat)new ImageFormatConverter().ConvertFromString(ImageType.ToString()); + image.Save(imageStream, format); + } + else + { + image.Save(imageStream, imageCodecInfo, encoderParameters); + } + + image.Dispose(); + } + finally + { + this.chartPicture.isPrinting = false; + } + } + + + /// <summary> + /// Saves image into the file. ImageType, Compression and other control properties are used. + /// </summary> + /// <param name="imageFileName">Image file name</param> + public void SaveImage(string imageFileName) + { + // Check arguments + if (imageFileName == null) + throw new ArgumentNullException("imageFileName"); + + // Create file stream for the specified file name + FileStream fileStream = new FileStream(imageFileName, FileMode.Create); + + // Save into stream + try + { + SaveImage(fileStream); + } + finally + { + // Close file stream + fileStream.Close(); + } + } + + + + + + /// <summary> + /// Helper function. Returns image encoder using Mime image type + /// </summary> + /// <param name="mimeType">Mime image type</param> + /// <returns>Image codec</returns> + private static ImageCodecInfo GetEncoderInfo(String mimeType) + { + int j; + ImageCodecInfo[] encoders; + encoders = ImageCodecInfo.GetImageEncoders(); + for(j = 0; j < encoders.Length; ++j) + { + if(encoders[j].MimeType == mimeType) + { + return encoders[j]; + } + } + return null; + } + +#endregion + + #region Control events + + + // Defines a key for storing the delegate for the PrePaint event + // in the Events list. + private static readonly object _prePaintEvent = new object(); + + /// <summary> + /// Fires after the chart element backround was drawn. + /// This event is fired for elements like: ChartPicture, ChartArea and Legend + /// </summary> + [ + SRDescription("DescriptionAttributeChartEvent_PrePaint") + ] + public event EventHandler<ChartPaintEventArgs> PrePaint + { + add { Events.AddHandler(_prePaintEvent, value); } + remove { Events.RemoveHandler(_prePaintEvent, value); } + } + + // Defines a key for storing the delegate for the PrePaint event + // in the Events list. + private static readonly object _postPaintEvent = new object(); + + /// <summary> + /// Fires after chart element was drawn. + /// This event is fired for elements like: ChartPicture, ChartArea and Legend + /// </summary> + [ + SRDescription("DescriptionAttributeChartEvent_PostPaint") + ] + public event EventHandler<ChartPaintEventArgs> PostPaint + { + add { Events.AddHandler(_postPaintEvent, value); } + remove { Events.RemoveHandler(_postPaintEvent, value); } + } + + // Defines a key for storing the delegate for the CustomizeMapAreas event + // in the Events list. + private static readonly object _customizeMapAreasEvent = new object(); + + /// <summary> + /// Fires just before the chart image map is rendered. Use this event to customize the map areas items. + /// </summary> + [ + SRDescription("DescriptionAttributeChartEvent_CustomizeMapAreas") + ] + public event EventHandler<CustomizeMapAreasEventArgs> CustomizeMapAreas + { + add { Events.AddHandler(_customizeMapAreasEvent, value); } + remove { Events.RemoveHandler(_customizeMapAreasEvent, value); } + } + + + + // Defines a key for storing the delegate for the CustomizeMapAreas event + // in the Events list. + private static readonly object _customizeEvent = new object(); + /// <summary> + /// Fires just before the chart image is drawn. Use this event to customize the chart picture. + /// </summary> + [ + SRDescription("DescriptionAttributeChartEvent_Customize") + ] + public event EventHandler Customize + { + add { Events.AddHandler(_customizeEvent, value); } + remove { Events.RemoveHandler(_customizeEvent, value); } + } + + // Defines a key for storing the delegate for the CustomizeMapAreas event + // in the Events list. + private static readonly object _customizeLegendEvent = new object(); + /// <summary> + /// Fires just before the chart legend is drawn. Use this event to customize the chart legend items. + /// </summary> + [ + SRDescription("DescriptionAttributeChartEvent_CustomizeLegend") + ] + public event EventHandler<CustomizeLegendEventArgs> CustomizeLegend + { + add { Events.AddHandler(_customizeLegendEvent, value); } + remove { Events.RemoveHandler(_customizeLegendEvent, value); } + } + + // Defines a key for storing the delegate for the Click event + // in the Events list. + private static readonly object _clickEvent = new object(); + /// <summary> + /// Occurs when active image map area defined by PostBackValue on Chart control is clicked. + /// </summary> + [ + SRCategory("CategoryAttributeAction"), + SRDescription(SR.Keys.DescriptionAttributeChartEvent_Click) + ] + public event ImageMapEventHandler Click + { + add { Events.AddHandler(_clickEvent, value); } + remove { Events.RemoveHandler(_clickEvent, value); } + } + + + #endregion + + #region Event Handling + + + /// <summary> + /// Invokes delegates registered with the Click event. + /// </summary> + /// <param name="e"></param> + [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] + protected virtual void OnClick(ImageMapEventArgs e) + { + ImageMapEventHandler clickEventDelegate = (ImageMapEventHandler)Events[_clickEvent]; + if (clickEventDelegate != null) + { + clickEventDelegate(this, e); + } + } + + + /// <summary> + /// Raises events for the Chart control when a form is posted back to the server. + /// </summary> + /// <param name="eventArgument">Event argument.</param> + [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")] + protected virtual void RaisePostBackEvent(string eventArgument) + { + if (!String.IsNullOrEmpty(eventArgument)) + { + this.OnClick(new ImageMapEventArgs(eventArgument)); + } + } + + /// <summary> + /// Fires when chart element backround must be drawn. + /// This event is fired for elements like: ChatPicture, ChartArea and Legend + /// </summary> + /// <param name="e">Event arguments.</param> + [ + SRDescription("DescriptionAttributeChart_OnBackPaint") + ] + [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] + protected virtual void OnPrePaint(ChartPaintEventArgs e) + { + EventHandler<ChartPaintEventArgs> prePaintEventDelegate = (EventHandler<ChartPaintEventArgs>)Events[_prePaintEvent]; + if (prePaintEventDelegate != null) + { + prePaintEventDelegate(this, e); + } + } + + /// <summary> + /// Fires when chart element backround must be drawn. + /// This event is fired for elements like: ChatPicture, ChartArea and Legend + /// </summary> + /// <param name="e">Event arguments.</param> + internal void CallOnPrePaint(ChartPaintEventArgs e) + { + this.OnPrePaint(e); + } + + /// <summary> + /// Fires when chart element must be drawn. + /// This event is fired for elements like: ChatPicture, ChartArea and Legend + /// </summary> + /// <param name="e">Event arguments.</param> + [ + SRDescription("DescriptionAttributeChart_OnPaint") + ] + [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] + protected virtual void OnPostPaint(ChartPaintEventArgs e) + { + EventHandler<ChartPaintEventArgs> postPaintEventDelegate = (EventHandler<ChartPaintEventArgs>)Events[_postPaintEvent]; + if (postPaintEventDelegate != null) + { + postPaintEventDelegate(this, e); + } + } + + /// <summary> + /// Fires when chart element must be drawn. + /// This event is fired for elements like: ChatPicture, ChartArea and Legend + /// </summary> + /// <param name="e">Event arguments.</param> + internal void CallOnPostPaint(ChartPaintEventArgs e) + { + this.OnPostPaint(e); + } + + /// <summary> + /// Fires when chart image map data is prepared to be rendered. + /// </summary> + /// <param name="e">The <see cref="System.Web.UI.DataVisualization.Charting.CustomizeMapAreasEventArgs"/> instance containing the event data.</param> + [ + SRDescription("DescriptionAttributeChart_OnCustomizeMapAreas") + ] + [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] + protected virtual void OnCustomizeMapAreas(CustomizeMapAreasEventArgs e) + { + EventHandler<CustomizeMapAreasEventArgs> customizeMapAreasEventDelegate = (EventHandler<CustomizeMapAreasEventArgs>)Events[_customizeMapAreasEvent]; + if (customizeMapAreasEventDelegate != null) + { + customizeMapAreasEventDelegate(this, e); + } + } + + /// <summary> + /// Fires when chart image map data is prepared to be rendered. + /// </summary> + internal void CallOnCustomizeMapAreas(MapAreasCollection areaItems) + { + this.OnCustomizeMapAreas(new CustomizeMapAreasEventArgs(areaItems)); + } + + /// <summary> + /// Fires when all chart data is prepared to be customized before drawing. + /// </summary> + /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> + [ + SRDescription("DescriptionAttributeChart_OnCustomize") + ] + [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] + protected virtual void OnCustomize(EventArgs e) + { + EventHandler customizeEventDelegate = (EventHandler)Events[_customizeEvent]; + if (customizeEventDelegate != null) + { + customizeEventDelegate(this, e); + } + } + + /// <summary> + /// Fires when all chart legend data is prepared to be customized before drawing. + /// </summary> + [ + SRDescription("DescriptionAttributeChart_OnCustomizeLegend") + ] + [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] + protected virtual void OnCustomizeLegend(CustomizeLegendEventArgs e) + { + EventHandler<CustomizeLegendEventArgs> customizeLegendEventDelegate = (EventHandler<CustomizeLegendEventArgs>)Events[_customizeLegendEvent]; + if (customizeLegendEventDelegate != null) + { + customizeLegendEventDelegate(this, e); + } + } + + /// <summary> + /// Event firing helper function. + /// </summary> + internal void CallOnCustomize() + { + OnCustomize(EventArgs.Empty); + } + + /// <summary> + /// Event firing helper function. + /// </summary> + internal void CallOnCustomizeLegend(LegendItemsCollection legendItems, string legendName) + { + OnCustomizeLegend(new CustomizeLegendEventArgs(legendItems, legendName)); + } + + #endregion + + #region View state properties and methods + + + /// <summary> + /// Restores view-state information from a previous page request that was saved by the SaveViewState method. + /// </summary> + /// <param name="savedState">An Object that represents the control state to be restored.</param> + protected override void LoadViewState(object savedState) + { + // Call the base class + base.LoadViewState(savedState); + + // Check if view state is enabled + if(this.EnableViewState) + { + + // Load chart's data if custom user state data was not set + if(this.ViewState["ViewStateData"] != null && + (this.ViewState["CustomUserViewStateData"] == null || + ((string)this.ViewState["CustomUserViewStateData"]) == "false")) + { + // Set serializable content + SerializationContents oldContent = this.Serializer.Content; + string oldSerializable = this.Serializer.SerializableContent; + string oldNonSerializable = this.Serializer.NonSerializableContent; + SerializationFormat oldFormat = this.Serializer.Format; + this.Serializer.Content = this.ViewStateContent; + this.Serializer.Format = SerializationFormat.Xml; + + // Load data in the chart from the view state + StringReader stringReader = new StringReader((string)this.ViewState["ViewStateData"]); + + this.Serializer.Load(stringReader); + + // Remove chart data from view state + this.ViewState.Remove("ViewStateData"); + + // Restore serializable content + this.Serializer.Format = oldFormat; + this.Serializer.Content = oldContent; + this.Serializer.SerializableContent = oldSerializable; + this.Serializer.NonSerializableContent = oldNonSerializable; + } + } + } + + /// <summary> + /// Saves any server control view-state changes that have occurred since the time the page was posted back to the server. + /// </summary> + /// <returns>Returns the server control's current view state. </returns> + protected override object SaveViewState() + { + // Check if view state is enabled + if(base.EnableViewState) + { + // Save chart's data if custom user state data was not set + if(this.ViewState["ViewStateData"] == null) + { + // Set serializable content + SerializationContents oldContent = this.Serializer.Content; + string oldSerializable = this.Serializer.SerializableContent; + string oldNonSerializable = this.Serializer.NonSerializableContent; + this.Serializer.Content = this.ViewStateContent; + + // Save data from the chart into the view state + StringBuilder stringBuilder = new StringBuilder(); + StringWriter stringWriter = new StringWriter(stringBuilder, CultureInfo.InvariantCulture); + this.Serializer.Save(stringWriter); + + // Put data in view state + this.ViewState["ViewStateData"] = (string)stringBuilder.ToString(); + + // Remove chart user custom view state flag + this.ViewState.Remove("CustomUserViewStateData"); + + // Restore serializable content + this.Serializer.Content = oldContent; + this.Serializer.SerializableContent = oldSerializable; + this.Serializer.NonSerializableContent = oldNonSerializable; + } + // Call base class + } + return base.SaveViewState(); + } + + + + /// <summary> + /// Gets or sets a value indicating whether the control persists its view state. + /// </summary> + [ + SRCategory("CategoryAttributeViewState"), + Bindable(true), + SRDescription("DescriptionAttributeChart_EnableViewState"), + PersistenceModeAttribute(PersistenceMode.Attribute), + DefaultValue(false) + ] + public override bool EnableViewState + { + get + { + return base.EnableViewState; + } + set + { + base.EnableViewState = value; + } + } + + + + /// <summary> + /// Chart content saved in the view state. + /// </summary> + [ + SRCategory("CategoryAttributeBehavior"), + Bindable(true), + DefaultValue(typeof(SerializationContents ), "Default"), + SRDescription("DescriptionAttributeChart_ViewStateContent"), + Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base) + ] + public SerializationContents ViewStateContent + { + get + { + return _viewStateContent; + } + set + { + int result = 0; + if (Int32.TryParse(value.ToString(), out result)) + { + throw new ArgumentException(SR.ExceptionEnumInvalid(value.ToString())); + } + _viewStateContent = value; + } + } + + /// <summary> + /// User defined control state data in XML format. + /// </summary> + [ + SRCategory("CategoryAttributeViewState"), + Browsable(false), + Obsolete("ViewStateData has been deprecated. Please investigate Control.ViewState instead."), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeChart_ViewStateData"), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden), + EditorBrowsable(EditorBrowsableState.Never) + ] + public string ViewStateData + { + get + { + return (string)this.ViewState["ViewStateData"]; + } + set + { + // Set state data + this.ViewState["ViewStateData"] = value; + + // Set custom user state data indicator + this.ViewState["CustomUserViewStateData"] = "true"; + } + } + + + #endregion + + #region Control properties + + + + /// <summary> + /// Indicates that non-critical chart exceptions will be suppressed. + /// </summary> + [ + SRCategory("CategoryAttributeMisc"), + DefaultValue(false), + SRDescription("DescriptionAttributeSuppressExceptions"), + ] + public bool SuppressExceptions + { + set + { + this.chartPicture.SuppressExceptions = value; + } + get + { + return this.chartPicture.SuppressExceptions; + } + } + + + + /// <summary> + /// Chart named images collection. + /// </summary> + [ + SRCategory("CategoryAttributeChart"), + Bindable(false), + SRDescription("DescriptionAttributeChart_Images"), + Browsable(false), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) + , EditorBrowsable(EditorBrowsableState.Never) + ] + public NamedImagesCollection Images + { + get + { + return _namedImages; + } + } + + /// <summary> + /// Font property is not used. + /// </summary> + [ + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public override FontInfo Font + { + get + { + return base.Font; + } + } + + /// <summary> + /// Chart rendering type. Image tag, input tag, binary data streaming and image map are the options. + /// </summary> + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + SRDescription("DescriptionAttributeChart_RenderType"), + PersistenceModeAttribute(PersistenceMode.Attribute), + DefaultValue(RenderType.ImageTag) + ] + public RenderType RenderType + { + get + { + return _renderType; + } + set + { + _renderType = value; + + if(_renderType == RenderType.ImageMap && this.IsMapEnabled == false) + { + this.IsMapEnabled = true; + } + } + } + + + + /// <summary> + /// Location where chart image is saved, when image tag is used for rendering. + /// </summary> + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + SRDescription("DescriptionAttributeChart_ImageUrl"), + PersistenceModeAttribute(PersistenceMode.Attribute), + DefaultValue("ChartPic_#SEQ(300,3)"), + Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base) + ] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")] + public string ImageLocation + { + get + { + return _chartImageLocation; + } + set + { + // Find the begginning of the "#SEQ" formatting string + int indexSEQ = value.IndexOf("#SEQ", StringComparison.Ordinal); + if(indexSEQ > 0) + { + // Check format + CheckImageURLSeqFormat(value); + } + _chartImageLocation = value; + } + } + + // VSTS 96787-Text Direction (RTL/LTR) + + /// <summary> + /// Indicates whether the control should draw right-to-left for RTL languages. + /// <seealso cref="AntiAliasing"/> + /// </summary> + /// <value> + /// One of the <see cref="System.Windows.Forms.RightToLeft"/> values. The default is + /// <b>RightToLeft.No</b>. + /// </value> + /// <remarks>This property affects the direction of legend color keys.</remarks> + [ + Category("Appearance"), + SRDescription("DescriptionAttributeRightToLeft"), + PersistenceMode(PersistenceMode.Attribute), + DefaultValue(RightToLeft.No) + ] + public RightToLeft RightToLeft + { + get + { + return this.chartPicture.RightToLeft; + } + set + { + this.chartPicture.RightToLeft = value; + } + } + + #endregion + + #region Data Manager Properties + + /// <summary> + /// Chart series collection. + /// </summary> + [ + SRCategory("CategoryAttributeChart"), + SRDescription("DescriptionAttributeChart_Series"), + PersistenceModeAttribute(PersistenceMode.InnerProperty), + Editor(Editors.SeriesCollectionEditor.Editor, Editors.SeriesCollectionEditor.Base), +#if !Microsoft_CONTROL + Themeable(false) +#endif + ] + public SeriesCollection Series + { + get + { + return _dataManager.Series; + } + } + + /// <summary> + /// Color palette to use + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + SRDescription("DescriptionAttributePalette"), + PersistenceModeAttribute(PersistenceMode.Attribute), + DefaultValue(ChartColorPalette.BrightPastel), + Editor(Editors.ColorPaletteEditor.Editor, Editors.ColorPaletteEditor.Base) + ] + public ChartColorPalette Palette + { + get + { + return _dataManager.Palette; + } + set + { + _dataManager.Palette = value; + } + } + + + + /// <summary> + /// Array of custom palette colors. + /// </summary> + /// <remarks> + /// When this custom colors array is non-empty the <b>Palette</b> property is ignored. + /// </remarks> + [ + SRCategory("CategoryAttributeAppearance"), + SerializationVisibilityAttribute(SerializationVisibility.Attribute), + SRDescription("DescriptionAttributeChart_PaletteCustomColors"), + TypeConverter(typeof(ColorArrayConverter)) + ] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public Color[] PaletteCustomColors + { + set + { + this._dataManager.PaletteCustomColors = value; + } + get + { + return this._dataManager.PaletteCustomColors; + } + } + + /// <summary> + /// Method resets custom colors array. Internal use only. + /// </summary> + [EditorBrowsable(EditorBrowsableState.Never)] + internal void ResetPaletteCustomColors() + { + this.PaletteCustomColors = new Color[0]; + } + + /// <summary> + /// Method resets custom colors array. Internal use only. + /// </summary> + [EditorBrowsable(EditorBrowsableState.Never)] + internal bool ShouldSerializePaletteCustomColors() + { + if(this.PaletteCustomColors == null || + this.PaletteCustomColors.Length == 0) + { + return false; + } + return true; + } + + + + #endregion + + #region Chart Properties + + + /// <summary> + /// "The data source used to populate series data. Series ValueMember properties must be also set." + /// </summary> + [ + SRCategory("CategoryAttributeData"), + Bindable(true), + SRDescription("DescriptionAttributeDataSource"), + PersistenceModeAttribute(PersistenceMode.Attribute), + DefaultValue(null), + TypeConverter(typeof(ChartDataSourceConverter)), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public override object DataSource + { + get + { + return base.DataSource; + } + set + { + base.DataSource = value; + chartPicture.DataSource = value; + } + } + + /// <summary> + /// Build number of the control + /// </summary> + [ + SRDescription("DescriptionAttributeChart_BuildNumber"), + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never), + DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), + DefaultValue("") + ] + public string BuildNumber + { + get + { + // Get build number from the assembly + string buildNumber = String.Empty; + Assembly assembly = Assembly.GetExecutingAssembly(); + if(assembly != null) + { + buildNumber = assembly.FullName.ToUpper(CultureInfo.InvariantCulture); + int versionIndex = buildNumber.IndexOf("VERSION=", StringComparison.Ordinal); + if(versionIndex >= 0) + { + buildNumber = buildNumber.Substring(versionIndex + 8); + } + versionIndex = buildNumber.IndexOf(",", StringComparison.Ordinal); + if(versionIndex >= 0) + { + buildNumber = buildNumber.Substring(0, versionIndex); + } + } + return buildNumber; + } + } + + /// <summary> + /// Chart serializer object. + /// </summary> + [ + SRCategory("CategoryAttributeSerializer"), + SRDescription("DescriptionAttributeChart_Serializer"), + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public ChartSerializer Serializer + { + get + { + return _chartSerializer; + } + } + + + + /// <summary> + /// Image type (Jpeg, BMP, Png, Svg, Flash) + /// </summary> + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(ChartImageType.Png), + SRDescription("DescriptionAttributeChartImageType"), + PersistenceMode(PersistenceMode.Attribute), + RefreshProperties(RefreshProperties.All) + ] + public ChartImageType ImageType + { + get + { + return chartPicture.ImageType; + } + set + { + chartPicture.ImageType = value; + } + } + + /// <summary> + /// Image compression value + /// </summary> + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(0), + SRDescription("DescriptionAttributeChart_Compression"), + PersistenceMode(PersistenceMode.Attribute) + ] + public int Compression + { + get + { + return chartPicture.Compression; + } + set + { + chartPicture.Compression = value; + } + } + + /* + * Disabled until we get responce from Microsoft + * --- Alex + * + /// <summary> + /// Gif image transparent color + /// </summary> + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(typeof(Color), ""), + Description("Gif image transparent color."), + PersistenceMode(PersistenceMode.Attribute), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color TransparentColor + { + get + { + return chartPicture.TransparentColor; + } + set + { + chartPicture.TransparentColor = value; + } + } + */ + #endregion + + #region Chart Image Properties + + /// <summary> + /// Indicates that chart image map is enabled. + /// </summary> + [ + SRCategory("CategoryAttributeMap"), + Bindable(true), + SRDescription(SR.Keys.DescriptionAttributeIsMapAreaAttributesEncoded), + PersistenceModeAttribute(PersistenceMode.Attribute), + DefaultValue(false) + ] + public bool IsMapAreaAttributesEncoded { get; set; } + + + /// <summary> + /// Indicates that chart image map is enabled. + /// </summary> + [ + SRCategory("CategoryAttributeMap"), + Bindable(true), + SRDescription("DescriptionAttributeMapEnabled"), + PersistenceModeAttribute(PersistenceMode.Attribute), + DefaultValue(true) + ] + public bool IsMapEnabled + { + get + { + return chartPicture.IsMapEnabled; + } + set + { + chartPicture.IsMapEnabled = value; + } + } + + /// <summary> + /// Chart map areas collection. + /// </summary> + [ + SRCategory("CategoryAttributeMap"), + SRDescription("DescriptionAttributeMapAreas"), + PersistenceModeAttribute(PersistenceMode.InnerProperty), + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base) + ] + public MapAreasCollection MapAreas + { + get + { + return chartPicture.MapAreas; + } + } + + /// <summary> + /// Specifies whether smoothing (antialiasing) is applied while drawing chart. + /// </summary> + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(typeof(AntiAliasingStyles), "All"), + SRDescription("DescriptionAttributeAntiAlias"), + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base) + ] + public AntiAliasingStyles AntiAliasing + { + get + { + return chartPicture.AntiAliasing; + } + set + { + chartPicture.AntiAliasing = value; + } + } + + /// <summary> + /// Specifies the quality of text antialiasing. + /// </summary> + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(typeof(TextAntiAliasingQuality), "High"), + SRDescription("DescriptionAttributeTextAntiAliasingQuality"), +#if !Microsoft_CONTROL + PersistenceMode(PersistenceMode.Attribute) +#endif + ] + public TextAntiAliasingQuality TextAntiAliasingQuality + { + get + { + return chartPicture.TextAntiAliasingQuality; + } + set + { + chartPicture.TextAntiAliasingQuality = value; + } + } + + /// <summary> + /// Specifies whether smoothing is applied while drawing shadows. + /// </summary> + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(true), + SRDescription("DescriptionAttributeChart_SoftShadows"), + PersistenceMode(PersistenceMode.Attribute) + ] + public bool IsSoftShadows + { + get + { + return chartPicture.IsSoftShadows; + } + set + { + chartPicture.IsSoftShadows = value; + } + } + + /// <summary> + /// Reference to chart area collection + /// </summary> + [ + SRCategory("CategoryAttributeChart"), + Bindable(true), + SRDescription("DescriptionAttributeChartAreas"), + PersistenceMode(PersistenceMode.InnerProperty), + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base) + ] + public ChartAreaCollection ChartAreas + { + get + { + return chartPicture.ChartAreas; + } + } + + /// <summary> + /// Back ground color for the Chart + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "White"), + SRDescription("DescriptionAttributeBackColor"), + PersistenceMode(PersistenceMode.Attribute), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public override Color BackColor + { + get + { + return chartPicture.BackColor; + } + set + { + chartPicture.BackColor = value; + } + } + + /// <summary> + /// Fore color propery (not used) + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(false), + Browsable(false), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeChart_ForeColor"), + PersistenceMode(PersistenceMode.Attribute), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public override Color ForeColor + { + get + { + return Color.Empty; + } + set + { + } + } + + /// <summary> + /// Chart width + /// </summary> + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(typeof(Unit), "300"), + SRDescription("DescriptionAttributeWidth"), + PersistenceMode(PersistenceMode.Attribute) + ] + public override Unit Width + { + get + { + return new Unit(chartPicture.Width); + } + set + { + if(value.Type != UnitType.Pixel) + { + throw (new ArgumentException(SR.ExceptionChartWidthIsNotInPixels)); + } + chartPicture.Width = (int)value.Value; + } + } + + /// <summary> + /// Chart legend collection. + /// </summary> + [ + SRCategory("CategoryAttributeChart"), + SRDescription("DescriptionAttributeLegends"), + PersistenceMode(PersistenceMode.InnerProperty), + Editor(Editors.LegendCollectionEditor.Editor, Editors.LegendCollectionEditor.Base), + ] + public LegendCollection Legends + { + get + { + return chartPicture.Legends; + } + } + + /// <summary> + /// Chart title collection. + /// </summary> + [ + SRCategory("CategoryAttributeChart"), + SRDescription("DescriptionAttributeTitles"), + Editor(Editors.ChartCollectionEditor.Editor, Editors.ChartCollectionEditor.Base), + PersistenceMode(PersistenceMode.InnerProperty), + ] + public TitleCollection Titles + { + get + { + return chartPicture.Titles; + } + } + + + /// <summary> + /// Chart annotation collection. + /// </summary> + [ + SRCategory("CategoryAttributeChart"), + SRDescription("DescriptionAttributeAnnotations3"), + Editor(Editors.AnnotationCollectionEditor.Editor, Editors.AnnotationCollectionEditor.Base), + PersistenceMode(PersistenceMode.InnerProperty), + ] + public AnnotationCollection Annotations + { + get + { + return chartPicture.Annotations; + } + } + + + /// <summary> + /// Series data manipulator + /// </summary> + [ + SRCategory("CategoryAttributeData"), + SRDescription("DescriptionAttributeDataManipulator"), + Browsable(false), + DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden), + SerializationVisibilityAttribute(SerializationVisibility.Hidden) + ] + public DataManipulator DataManipulator + { + get + { + return chartPicture.DataManipulator; + } + } + + + /// <summary> + /// Chart height + /// </summary> + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + DefaultValue(typeof(Unit), "300"), + SRDescription("DescriptionAttributeHeight3"), + PersistenceMode(PersistenceMode.Attribute) + ] + public override Unit Height + { + get + { + return new Unit(chartPicture.Height); + } + set + { + if(value.Type != UnitType.Pixel) + { + throw (new ArgumentException(SR.ExceptionChartHeightIsNotInPixels)); + } + chartPicture.Height = (int)value.Value; + } + } + + + /// <summary> + /// Back Hatch style + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartHatchStyle.None), + SRDescription("DescriptionAttributeBackHatchStyle"), + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base) + ] + public ChartHatchStyle BackHatchStyle + { + get + { + return chartPicture.BackHatchStyle; + } + set + { + chartPicture.BackHatchStyle = value; + } + } + + /// <summary> + /// Chart area background image + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(""), + SRDescription("DescriptionAttributeBackImage"), + PersistenceMode(PersistenceMode.Attribute), + NotifyParentPropertyAttribute(true), + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base) + ] + public string BackImage + { + get + { + return chartPicture.BackImage; + } + set + { + chartPicture.BackImage = value; + } + } + + /// <summary> + /// Chart area background image drawing mode. + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageWrapMode.Tile), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageWrapMode"), + PersistenceMode(PersistenceMode.Attribute) + ] + public ChartImageWrapMode BackImageWrapMode + { + get + { + return chartPicture.BackImageWrapMode; + } + set + { + chartPicture.BackImageWrapMode = value; + } + } + + /// <summary> + /// Background image transparent color. + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeImageTransparentColor"), + PersistenceMode(PersistenceMode.Attribute), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color BackImageTransparentColor + { + get + { + return chartPicture.BackImageTransparentColor; + } + set + { + chartPicture.BackImageTransparentColor = value; + } + } + + /// <summary> + /// Background image alignment used by ClampUnscale drawing mode. + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartImageAlignmentStyle.TopLeft), + NotifyParentPropertyAttribute(true), + SRDescription("DescriptionAttributeBackImageAlign"), + PersistenceMode(PersistenceMode.Attribute) + ] + public ChartImageAlignmentStyle BackImageAlignment + { + get + { + return chartPicture.BackImageAlignment; + } + set + { + chartPicture.BackImageAlignment = value; + } + } + + /// <summary> + /// A type for the background gradient + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(GradientStyle.None), + SRDescription("DescriptionAttributeBackGradientStyle"), + PersistenceMode(PersistenceMode.Attribute), + Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base) + ] + public GradientStyle BackGradientStyle + { + get + { + return chartPicture.BackGradientStyle; + } + set + { + chartPicture.BackGradientStyle = value; + } + } + + /// <summary> + /// The second color which is used for a gradient + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), ""), + SRDescription("DescriptionAttributeBackSecondaryColor"), + PersistenceMode(PersistenceMode.Attribute), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color BackSecondaryColor + { + get + { + return chartPicture.BackSecondaryColor; + } + set + { + chartPicture.BackSecondaryColor = value; + } + } + + + /// <summary> + /// Gets or sets the border color of the Chart. + /// </summary> + [ + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never) + ] + public override Color BorderColor + { + get { return base.BorderColor; } + set { base.BorderColor = value; } + } + + /// <summary> + /// Gets or sets the border width of the Chart. + /// </summary> + [ + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never) + ] + public override Unit BorderWidth + { + get { return base.BorderWidth;} + set { base.BorderWidth = value;} + } + + /// <summary> + /// Gets or sets the border style of the Chart. + /// </summary> + [ + Browsable(false), + EditorBrowsable(EditorBrowsableState.Never) + ] + public override BorderStyle BorderStyle + { + get { return base.BorderStyle; } + set { base.BorderStyle = value; } + } + + + /// <summary> + /// Border line color for the Chart + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(typeof(Color), "White"), + SRDescription("DescriptionAttributeBorderColor"), + PersistenceMode(PersistenceMode.Attribute), + TypeConverter(typeof(ColorConverter)), + Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base), + ] + public Color BorderlineColor + { + get + { + return chartPicture.BorderColor; + } + set + { + chartPicture.BorderColor = value; + } + } + + /// <summary> + /// The width of the border line + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(1), + SRDescription("DescriptionAttributeChart_BorderlineWidth"), + PersistenceMode(PersistenceMode.Attribute) + ] + public int BorderlineWidth + { + get + { + return chartPicture.BorderWidth; + } + set + { + chartPicture.BorderWidth = value; + } + } + + /// <summary> + /// The style of the border line + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(ChartDashStyle.NotSet), + SRDescription("DescriptionAttributeBorderDashStyle"), + PersistenceMode(PersistenceMode.Attribute) + ] + public ChartDashStyle BorderlineDashStyle + { + get + { + return chartPicture.BorderDashStyle; + } + set + { + chartPicture.BorderDashStyle = value; + } + } + + /// <summary> + /// Chart border skin style. + /// </summary> + [ + SRCategory("CategoryAttributeAppearance"), + Bindable(true), + DefaultValue(BorderSkinStyle.None), + SRDescription("DescriptionAttributeBorderSkin"), + PersistenceMode(PersistenceMode.InnerProperty), + NotifyParentProperty(true), + TypeConverterAttribute(typeof(LegendConverter)), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content) + ] + public BorderSkin BorderSkin + { + get + { + return chartPicture.BorderSkin; + } + set + { + chartPicture.BorderSkin = value; + } + } + + /// <summary> + /// When overridden in a derived class, gets or sets the alternate text displayed in the Chart control when the chart image is unavailable. + /// </summary> + [ + Bindable(true), + SRDescription(SR.Keys.DescriptionAttributeChartImageAlternateText), + Localizable(true), + SRCategory(SR.Keys.CategoryAttributeAppearance), + DefaultValue("") + ] + public string AlternateText { get; set; } + + /// <summary> + /// When overridden in a derived class, gets or sets the location to a detailed description for the chart. + /// </summary> + [ + Bindable(true), + SRDescription(SR.Keys.DescriptionAttributeChartImageDescriptionUrl), + Localizable(true), + SRCategory(SR.Keys.CategoryAttributeAccessibility), + DefaultValue(""), + UrlProperty, + Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base), + SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings") + ] + public string DescriptionUrl { get; set; } + + #endregion + + #region Control public methods + + /// <summary> + /// Creates the HTML text writer. + /// </summary> + /// <param name="tw">The inner text writer.</param> + /// <returns></returns> + private HtmlTextWriter CreateHtmlTextWriter(TextWriter tw) + { + if (((this.Context != null) && (this.Context.Request != null)) && (this.Context.Request.Browser != null)) + { + return this.Context.Request.Browser.CreateHtmlTextWriter(tw); + } + return new Html32TextWriter(tw); + } + + /// <summary> + /// Gets HTML image map of the currently rendered chart. + /// Save(...) method MUST be called before calling this method! + /// </summary> + /// <param name="name">Name of the image map tag.</param> + /// <returns>HTML image map.</returns> + public string GetHtmlImageMap(string name) + { + // Check arguments + if (name == null) + throw new ArgumentNullException("name"); + + using (StringWriter swriter = new StringWriter(CultureInfo.InvariantCulture)) + { + using (HtmlTextWriter writer = CreateHtmlTextWriter(swriter)) + { + this.chartPicture.WriteChartMapTag(writer, name); + return swriter.GetStringBuilder().ToString(); + } + } + } + + + /// <summary> + /// Saves the current state of the chart to an XML file. This is + /// mainly used for support purposes. The executing thread must have + /// file write permission + /// </summary> + /// <param name="name">File path and name to save.</param> + public void SaveXml(string name) + { + try + { + this.Serializer.Save(name); + } + catch(XmlException) + { } + } + + + /// <summary> + /// Loads chart appearance template from file. + /// </summary> + /// <param name="name">Template file name to load from.</param> + public void LoadTemplate(string name) + { + chartPicture.LoadTemplate(name); + } + + /// <summary> + /// Loads chart appearance template from stream. + /// </summary> + /// <param name="stream">Template stream to load from.</param> + public void LoadTemplate(Stream stream) + { + chartPicture.LoadTemplate(stream); + } + + + /// <summary> + /// Applies palette colors to series or data points. + /// </summary> + public void ApplyPaletteColors() + { + // Apply palette colors to series + this._dataManager.ApplyPaletteColors(); + + // Apply palette colors to data Points in series + foreach(Series series in this.Series) + { + // Check if palette colors should be aplied to the points + bool applyToPoints = false; + if(series.Palette != ChartColorPalette.None) + { + applyToPoints = true; + } + else + { + IChartType chartType = this._chartTypeRegistry.GetChartType(series.ChartTypeName); + applyToPoints = chartType.ApplyPaletteColorsToPoints; + } + + // Apply palette colors to the points + if(applyToPoints) + { + series.ApplyPaletteColors(); + } + } + } + + /// <summary> + /// Checks if control is in design mode. + /// </summary> + /// <returns>True if control is in design mode.</returns> + internal bool IsDesignMode() + { + return this.DesignMode; + } + + /// <summary> + /// Reset auto calculated chart properties values to "Auto". + /// </summary> + public void ResetAutoValues() + { + // Reset auto calculated series properties values + foreach(Series series in this.Series) + { + series.ResetAutoValues(); + } + + // Reset auto calculated axis properties values + foreach(ChartArea chartArea in this.ChartAreas) + { + chartArea.ResetAutoValues(); + } + + } + + #endregion + + #region Control DataBind method + + /// <summary> + /// Verifies that the object a data-bound control binds to is one it can work with. + /// </summary> + /// <param name="dataSource">The object to verify</param> + protected override void ValidateDataSource(object dataSource) + { + if (!ChartImage.IsValidDataSource(dataSource)) + { + base.ValidateDataSource(dataSource); + } + } + + /// <summary> + /// Binds the specified data source to the Chart control. + /// </summary> + /// <param name="data">An <see cref="IEnumerable"/> that represents the data source.</param> + protected override void PerformDataBinding(IEnumerable data) + { + this.chartPicture.DataBind(data, null); + this.chartPicture.boundToDataSource = true; + } + + /// <summary> + /// Aligns data points using their axis labels. + /// </summary> + public void AlignDataPointsByAxisLabel() + { + this.chartPicture.AlignDataPointsByAxisLabel(false, PointSortOrder.Ascending); + } + + /// <summary> + /// Aligns data points using their axis labels. + /// </summary> + /// <param name="series">Comma separated list of series that should be aligned by axis label.</param> + public void AlignDataPointsByAxisLabel(string series) + { + // Create list of series + ArrayList seriesList = new ArrayList(); + string[] seriesNames = series.Split(','); + foreach(string name in seriesNames) + { + seriesList.Add(this.Series[name.Trim()]); + } + + // Align series + this.chartPicture.AlignDataPointsByAxisLabel(seriesList, false, PointSortOrder.Ascending); + } + + /// <summary> + /// Aligns data points using their axis labels. + /// </summary> + /// <param name="series">Comma separated list of series that should be aligned by axis label.</param> + /// <param name="sortingOrder">Points sorting order by axis labels.</param> + public void AlignDataPointsByAxisLabel(string series, PointSortOrder sortingOrder) + { + // Create list of series + ArrayList seriesList = new ArrayList(); + string[] seriesNames = series.Split(','); + foreach(string name in seriesNames) + { + seriesList.Add(this.Series[name.Trim()]); + } + + // Align series + this.chartPicture.AlignDataPointsByAxisLabel(seriesList, true, sortingOrder); + } + + /// <summary> + /// Aligns data points using their axis labels. + /// </summary> + /// <param name="sortingOrder">Points sorting order by axis labels.</param> + public void AlignDataPointsByAxisLabel(PointSortOrder sortingOrder) + { + this.chartPicture.AlignDataPointsByAxisLabel(true, sortingOrder); + } + + + + /// <summary> + /// Automatically creates and binds series to specified data table. + /// Each column of the table becomes a Y value in a separate series. + /// Series X value field may also be provided. + /// </summary> + /// <param name="dataSource">Data source.</param> + /// <param name="xField">Name of the field for series X values.</param> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X is a cartesian coordinate and well understood")] + public void DataBindTable( + IEnumerable dataSource, + string xField) + { + this.chartPicture.DataBindTable( + dataSource, + xField); + } + + /// <summary> + /// Automatically creates and binds series to specified data table. + /// Each column of the table becomes a Y value in a separate series. + /// </summary> + /// <param name="dataSource">Data source.</param> + public void DataBindTable(IEnumerable dataSource) + { + this.chartPicture.DataBindTable( + dataSource, + String.Empty); + } + + /// <summary> + /// Data bind chart to the table. Series will be automatically added to the chart depending on + /// the number of unique values in the seriesGroupByField column of the data source. + /// Data source can be the Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow. + /// </summary> + /// <param name="dataSource">Data source.</param> + /// <param name="seriesGroupByField">Name of the field used to group data into series.</param> + /// <param name="xField">Name of the field for X values.</param> + /// <param name="yFields">Comma separated name(s) of the field(s) for Y value(s).</param> + /// <param name="otherFields">Other point properties binding rule in format: PointProperty=Field[{Format}] [,PointProperty=Field[{Format}]]. For example: "Tooltip=Price{C1},Url=WebSiteName".</param> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public void DataBindCrossTable( + IEnumerable dataSource, + string seriesGroupByField, + string xField, + string yFields, + string otherFields) + { + this.chartPicture.DataBindCrossTab( + dataSource, + seriesGroupByField, + xField, + yFields, + otherFields, + false, + PointSortOrder.Ascending); + } + + /// <summary> + /// Data bind chart to the table. Series will be automatically added to the chart depending on + /// the number of unique values in the seriesGroupByField column of the data source. + /// Data source can be the Ole(SQL)DataReader, DataView, DataSet, DataTable or DataRow. + /// </summary> + /// <param name="dataSource">Data source.</param> + /// <param name="seriesGroupByField">Name of the field used to group data into series.</param> + /// <param name="xField">Name of the field for X values.</param> + /// <param name="yFields">Comma separated name(s) of the field(s) for Y value(s).</param> + /// <param name="otherFields">Other point properties binding rule in format: PointProperty=Field[{Format}] [,PointProperty=Field[{Format}]]. For example: "Tooltip=Price{C1},Url=WebSiteName".</param> + /// <param name="sortingOrder">Series will be sorted by group field values in specified order.</param> + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", + Justification = "X and Y are cartesian coordinates and well understood")] + public void DataBindCrossTable( + IEnumerable dataSource, + string seriesGroupByField, + string xField, + string yFields, + string otherFields, + PointSortOrder sortingOrder) + { + this.chartPicture.DataBindCrossTab( + dataSource, + seriesGroupByField, + xField, + yFields, + otherFields, + true, + sortingOrder); + } + + + #endregion + + #region Special Extension Methods and Properties + + /// <summary> + /// Gets the requested chart service. + /// </summary> + /// <param name="serviceType">Type of requested chart service.</param> + /// <returns>Instance of the service or null if it can't be found.</returns> + public object GetService(Type serviceType) + { + // Check arguments + if (serviceType == null) + throw new ArgumentNullException("serviceType"); + + object service = null; + if(serviceContainer != null) + { + service = serviceContainer.GetService(serviceType); + } + + return service; + } + + /// <summary> + /// Called when a numeric value has to be converted to a string. + /// </summary> + [SRDescription("DescriptionAttributeChartEvent_PrePaint")] + public event EventHandler<FormatNumberEventArgs> FormatNumber; + + /// <summary> + /// Called when a numeric value has to be converted to a string. + /// </summary> + /// <param name="caller">Event caller. Can be ChartPicture, ChartArea or Legend objects.</param> + /// <param name="e">Event arguments.</param> + [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "1#")] + protected virtual void OnFormatNumber(object caller, FormatNumberEventArgs e) + { + if (FormatNumber != null) + { + FormatNumber(caller, e); + } + } + + /// <summary> + /// Called when a numeric value has to be converted to a string. + /// </summary> + /// <param name="caller">Event caller. Can be ChartPicture, ChartArea or Legend objects.</param> + /// <param name="e">Event arguments.</param> + internal void CallOnFormatNumber(object caller, FormatNumberEventArgs e) + { + this.OnFormatNumber(caller, e); + } + + #endregion + + #region HttpHandler Support + + /// <summary> + /// Chart rendering type. Image tag, input tag, binary data streaming and image map are the options. + /// </summary> + [ + SRCategory("CategoryAttributeImage"), + Bindable(true), + SRDescription("DescriptionAttributeChart_ImageStorageMode"), + PersistenceModeAttribute(PersistenceMode.Attribute), + DefaultValue(ImageStorageMode.UseHttpHandler) + ] + public ImageStorageMode ImageStorageMode + { + get + { + return this._imageStorageMode; + } + set + { + this._imageStorageMode = value; + } + } + + /// <summary> + /// Gets the image storage mode. + /// </summary> + /// <returns></returns> + internal ImageStorageMode GetImageStorageMode() + { + if (this.ImageStorageMode == ImageStorageMode.UseHttpHandler) + { + ChartHttpHandler.EnsureInstalled(); + } + return this.ImageStorageMode; + } + + #endregion //HttpHandler Support + + #region IPostBackEventHandler Members + + void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) + { + this.RaisePostBackEvent(eventArgument); + } + + #endregion + + #region IDisposable overrides + /// <summary> + /// Releases unmanaged and - optionally - managed resources + /// </summary> + /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (!String.IsNullOrEmpty(_designTimeChart)) + { + try + { + File.Delete(_designTimeChart); + } + catch (ArgumentException) { } + catch (DirectoryNotFoundException) { } + catch (IOException) { } + catch (NotSupportedException) { } + catch (UnauthorizedAccessException) { } + } + + // Dispose managed objects here + if (_imageLoader != null) + { + _imageLoader.Dispose(); + _imageLoader = null; + } + if (_namedImages != null) + { + _namedImages.Dispose(); + _namedImages = null; + } + if (_chartTypeRegistry != null) + { + _chartTypeRegistry.Dispose(); + _chartTypeRegistry = null; + } + if (serviceContainer != null) + { + serviceContainer.Dispose(); + serviceContainer = null; + } + if (_license != null) + { + _license.Dispose(); + _license = null; + } + } + //Base dispose + base.Dispose(); + if (disposing) + { + if (_dataManager != null) + { + _dataManager.Dispose(); + _dataManager = null; + } + if (chartPicture != null) + { + chartPicture.Dispose(); + chartPicture = null; + } + } + } + + /// <summary> + /// Disposing control resoursec + /// </summary> + public override sealed void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + + } + + /// <summary> + /// Chart map areas customize events arguments + /// </summary> +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class CustomizeMapAreasEventArgs : EventArgs + { + private MapAreasCollection _areaItems = null; + + /// <summary> + /// Default construvtor is not accessible + /// </summary> + private CustomizeMapAreasEventArgs() + { + } + + /// <summary> + /// Customize map area event arguments constructor + /// </summary> + /// <param name="areaItems">Legend items collection.</param> + public CustomizeMapAreasEventArgs(MapAreasCollection areaItems) + { + this._areaItems = areaItems; + } + + /// <summary> + /// Legend items collection. + /// </summary> + public MapAreasCollection MapAreaItems + { + get + { + return _areaItems; + } + } + + } + + + + /// <summary> + /// Chart legend customize events arguments + /// </summary> +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class CustomizeLegendEventArgs : EventArgs + { + private LegendItemsCollection _legendItems = null; + private string _legendName = ""; + + /// <summary> + /// Default construvtor is not accessible + /// </summary> + private CustomizeLegendEventArgs() + { + } + + /// <summary> + /// Customize legend event arguments constructor + /// </summary> + /// <param name="legendItems">Legend items collection.</param> + public CustomizeLegendEventArgs(LegendItemsCollection legendItems) + { + this._legendItems = legendItems; + } + + /// <summary> + /// Customize legend event arguments constructor + /// </summary> + /// <param name="legendItems">Legend items collection.</param> + /// <param name="legendName">Legend name.</param> + public CustomizeLegendEventArgs(LegendItemsCollection legendItems, string legendName) + { + this._legendItems = legendItems; + this._legendName = legendName; + } + + /// <summary> + /// Legend name. + /// </summary> + public string LegendName + { + get + { + return _legendName; + } + } + + /// <summary> + /// Legend items collection. + /// </summary> + public LegendItemsCollection LegendItems + { + get + { + return _legendItems; + } + } + + } + + /// <summary> + /// Specifies a value indicating whether the text appears from right to left, such as when using Hebrew or Arabic fonts + /// </summary> + public enum RightToLeft + { + /// <summary> + /// The text reads from left to right. This is the default. + /// </summary> + No, + /// <summary> + /// The text reads from right to left. + /// </summary> + Yes, + /// <summary> + /// Not used + /// </summary> + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + Inherit = No + } +} diff --git a/System.Web.DataVisualization/WebForm/Converters/MapAreaCoordinatesConverter.cs b/System.Web.DataVisualization/WebForm/Converters/MapAreaCoordinatesConverter.cs new file mode 100644 index 000000000..66695efaa --- /dev/null +++ b/System.Web.DataVisualization/WebForm/Converters/MapAreaCoordinatesConverter.cs @@ -0,0 +1,103 @@ +//------------------------------------------------------------- +// <copyright company=’Microsoft Corporation’> +// Copyright © Microsoft Corporation. All Rights Reserved. +// </copyright> +//------------------------------------------------------------- +// @owner=alexgor, deliant +//================================================================= +// File: MapAreaCoordinatesConverter.cs +// +// Namespace: System.Web.UI.DataVisualization.Charting +// +// Classes: MapAreaCoordinatesConverter +// +// Purpose: Design-time converter for map area coordinates +// +// Reviewed: AG - August 7, 2002 +// +//=================================================================== + +using System.ComponentModel; +using System.Globalization; + +namespace System.Web.UI.DataVisualization.Charting +{ + /// <summary> + /// Converter for the array of map area coordinates + /// </summary> + internal class MapAreaCoordinatesConverter : ArrayConverter + { + /// <summary> + /// Overrides the CanConvertFrom method of TypeConverter. + /// The ITypeDescriptorContext interface provides the context for the + /// conversion. Typically this interface is used at design time to + /// provide information about the design-time container. + /// </summary> + /// <param name="context">Descriptor context.</param> + /// <param name="sourceType">Convertion source type.</param> + /// <returns>Indicates if convertion is possible.</returns> + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + + /// <summary> + /// Overrides the ConvertFrom method of TypeConverter. + /// Convert from comma separated values in the string. + /// </summary> + /// <param name="context">Descriptor context.</param> + /// <param name="culture">Culture information.</param> + /// <param name="value">Value to convert from.</param> + /// <returns>Indicates if convertion is possible.</returns> + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + // Can convert from string where each array element is separated by comma + string stringValue = value as string; + if (stringValue != null) + { + string[] values = stringValue.Split(new char[] { ',' }); + float[] array = new float[values.Length]; + for (int index = 0; index < values.Length; index++) + { + array[index] = float.Parse(values[index], System.Globalization.CultureInfo.CurrentCulture); + } + + return array; + } + + // Call base class + return base.ConvertFrom(context, culture, value); + } + + /// <summary> + /// Overrides the ConvertTo method of TypeConverter. + /// Convert coordinates array to comma separated values in string. + /// </summary> + /// <param name="context">Descriptor context.</param> + /// <param name="culture">Culture information.</param> + /// <param name="value">Value to convert.</param> + /// <param name="destinationType">Convertion destination type.</param> + /// <returns>Converted object.</returns> + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string)) + { + float[] array = (float[])value; + string result = ""; + + foreach (float d in array) + { + result += d.ToString(System.Globalization.CultureInfo.CurrentCulture) + ","; + } + + return result.TrimEnd(','); + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } +} diff --git a/System.Web.DataVisualization/WebForm/FxCopExclusionsByDesign.cs b/System.Web.DataVisualization/WebForm/FxCopExclusionsByDesign.cs new file mode 100644 index 000000000..7bdc72f69 --- /dev/null +++ b/System.Web.DataVisualization/WebForm/FxCopExclusionsByDesign.cs @@ -0,0 +1,553 @@ +// <copyright company='Microsoft Corporation'> +// Copyright (c) Microsoft Corporation. All Rights Reserved. +// </copyright> +// @owner=krisztb + +using System.Diagnostics.CodeAnalysis; + +#region CA1501:AvoidExcessiveInheritance + +[module: SuppressMessage("Microsoft.Maintainability", "CA1501:AvoidExcessiveInheritance", Scope = "type", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.HundredPercentStackedAreaChart")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1501:AvoidExcessiveInheritance", Scope = "type", Target = "System.Web.UI.DataVisualization.Charting.EllipseAnnotation")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1501:AvoidExcessiveInheritance", Scope = "type", Target = "System.Web.UI.DataVisualization.Charting.Border3DAnnotation")] + +#endregion // CA1501:AvoidExcessiveInheritance + + +#region CA1502:AvoidExcessiveComplexity + +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BubbleChart.#ScaleBubbleSize(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Double)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BubbleChart.#AxisScaleBubbleSize(System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Double,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.HundredPercentStackedBarChart.#GetYValue(System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series,System.Web.UI.DataVisualization.Charting.DataPoint,System.Int32,System.Int32)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedColumnChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedColumnChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Boolean,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FunnelChart.#GetLabelsPosition()")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FunnelChart.#DrawFunnel3DSquareSegment(System.Web.UI.DataVisualization.Charting.DataPoint,System.Int32,System.Single,System.Single,System.Single,System.Single,System.Boolean,System.Boolean,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FunnelChart.#DrawFunnelCircularSegment(System.Web.UI.DataVisualization.Charting.DataPoint,System.Int32,System.Single,System.Single,System.Single,System.Single,System.Boolean,System.Boolean,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.ThreeLineBreakChart.#FillThreeLineBreakData(System.Web.UI.DataVisualization.Charting.Series,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.ErrorBarChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.ErrorBarChart.#CalculateErrorAmount(System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.ErrorBarChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BoxPlotChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BoxPlotChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BoxPlotChart.#CalculateBoxPlotValues(System.Web.UI.DataVisualization.Charting.DataPoint&,System.Web.UI.DataVisualization.Charting.Series,System.String)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PointChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PointChart.#DrawLabels(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Drawing.PointF,System.Int32,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.Series,System.Int32)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PointChart.#ProcessSinglePoint3D(System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.HundredPercentStackedColumnChart.#GetYValue(System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series,System.Web.UI.DataVisualization.Charting.DataPoint,System.Int32,System.Int32)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PointAndFigureChart.#FillPointAndFigureData(System.Web.UI.DataVisualization.Charting.Series,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedBarChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedBarChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Boolean,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedBarChart.#DrawLabels3D(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Drawing.RectangleF,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.Series,System.Double,System.Double,System.Double,System.Int32)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedAreaChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BarChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BarChart.#DrawLabelsAndMarkers(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Drawing.RectangleF,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.Series,System.Double,System.Double,System.Double,System.Int32,System.Int32&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BarChart.#ProcessChartType(System.Boolean,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BarChart.#DrawLabels3D(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Drawing.RectangleF,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.Series,System.Double,System.Double,System.Double,System.Int32)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StepLineChart.#Draw3DSurface(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single,System.Single,System.Collections.ArrayList,System.Int32,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Single,System.Single,System.Drawing.PointF,System.Drawing.PointF,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.ColumnChart.#ProcessChartType(System.Boolean,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.ColumnChart.#ProcessChartType3D(System.Boolean,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.RangeChart.#Draw3DSurface(System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single,System.Single,System.Collections.ArrayList,System.Int32,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Single,System.Single,System.Drawing.PointF,System.Drawing.PointF,System.Boolean,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.RangeChart.#DrawLine(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.Series,System.Drawing.PointF[],System.Int32,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#EstimateLabels(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.PointF,System.Drawing.SizeF,System.Single,System.Single,System.Web.UI.DataVisualization.Charting.DataPoint,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartArea)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#PointOrder(System.Web.UI.DataVisualization.Charting.Series,System.Web.UI.DataVisualization.Charting.ChartArea,System.Single[]&,System.Single[]&,System.Int32[]&,System.Boolean&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#DrawDoughnutCurves(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.DataPoint,System.Single,System.Single,System.Drawing.PointF[],System.Drawing.SolidBrush,System.Drawing.Pen,System.Boolean,System.Boolean,System.Int32)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#DrawLabels(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.PointF,System.Drawing.SizeF,System.Single,System.Single,System.Web.UI.DataVisualization.Charting.DataPoint,System.Single,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Int32,System.Drawing.Color)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#DrawPieCurves(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.DataPoint,System.Single,System.Single,System.Drawing.PointF[],System.Drawing.SolidBrush,System.Drawing.Pen,System.Boolean,System.Boolean,System.Int32)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart+LabelsMode)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#PrepareData(System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#Draw3DPie(System.Int32,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.ChartArea,System.Drawing.RectangleF,System.Single,System.Single,System.Single,System.Single,System.Boolean,System.Boolean,System.Int32)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.HundredPercentStackedAreaChart.#GetYValue(System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series,System.Web.UI.DataVisualization.Charting.DataPoint,System.Int32,System.Int32)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FastLineChart.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FastPointChart.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.RadarChart.#DrawLabels(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Drawing.PointF,System.Int32,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.Series,System.Int32)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.RadarChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StockChart.#DrawOpenCloseMarks(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series,System.Web.UI.DataVisualization.Charting.DataPoint,System.Single,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StockChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StockChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StockChart.#DrawOpenCloseMarks3D(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series,System.Web.UI.DataVisualization.Charting.DataPoint,System.Single,System.Single,System.Single,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#DrawLine(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.Series,System.Drawing.PointF[],System.Int32,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#ClipBottomPoints(System.Drawing.Drawing2D.GraphicsPath,System.Web.UI.DataVisualization.Charting.DataPoint3D&,System.Web.UI.DataVisualization.Charting.DataPoint3D&,System.Drawing.PointF&,System.Drawing.PointF&,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single,System.Single,System.Collections.ArrayList,System.Int32,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Single,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#ProcessLineChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#ClipTopPoints(System.Drawing.Drawing2D.GraphicsPath,System.Web.UI.DataVisualization.Charting.DataPoint3D&,System.Web.UI.DataVisualization.Charting.DataPoint3D&,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single,System.Single,System.Collections.ArrayList,System.Int32,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Single,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.KagiChart.#Draw3DSurface(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single,System.Single,System.Collections.ArrayList,System.Int32,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Single,System.Single,System.Drawing.PointF,System.Drawing.PointF,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.AreaChart.#Draw3DSurface(System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single,System.Single,System.Collections.ArrayList,System.Int32,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Single,System.Single,System.Drawing.PointF,System.Drawing.PointF,System.Boolean,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.AreaChart.#Draw3DSurface(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single,System.Single,System.Collections.ArrayList,System.Int32,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Single,System.Single,System.Drawing.PointF,System.Drawing.PointF,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.AreaChart.#DrawLine(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.Series,System.Drawing.PointF[],System.Int32,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.TimeSeriesAndForecasting.#PolynomialRegression(System.Web.UI.DataVisualization.Charting.Formulas.TimeSeriesAndForecasting+RegressionType,System.Double[][],System.Double[][]&,System.Int32,System.Int32,System.Double)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartImage.#DataBindCrossTab(System.Collections.IEnumerable,System.String,System.String,System.String,System.String,System.Boolean,System.Web.UI.DataVisualization.Charting.PointSortOrder)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartImage.#GetDataSourceMemberNames(System.Object,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartImage.#AlignDataPointsByAxisLabel(System.Collections.ArrayList,System.Boolean,System.Web.UI.DataVisualization.Charting.PointSortOrder)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartImage.#DataBind(System.Collections.IEnumerable,System.Collections.ArrayList)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.PolylineAnnotation.#Paint(System.Web.UI.DataVisualization.Charting.Chart,System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartHelper.#GetIntervalSize(System.Double,System.Double,System.Web.UI.DataVisualization.Charting.DateTimeIntervalType,System.Web.UI.DataVisualization.Charting.Series,System.Double,System.Web.UI.DataVisualization.Charting.DateTimeIntervalType,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#Draw3DPolygon(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.SurfaceNames,System.Single,System.Drawing.Color,System.Drawing.Color,System.Int32,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Web.UI.DataVisualization.Charting.SurfaceNames)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#ShouldDrawLineChartSurface(System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Web.UI.DataVisualization.Charting.SurfaceNames,System.Web.UI.DataVisualization.Charting.SurfaceNames,System.Drawing.Color,System.Collections.ArrayList,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Boolean,System.Web.UI.DataVisualization.Charting.LineSegmentType&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#AddEllipseSegment(System.Drawing.Drawing2D.GraphicsPath,System.Drawing.Drawing2D.GraphicsPath,System.Drawing.Drawing2D.GraphicsPath,System.Boolean,System.Single,System.Drawing.PointF&,System.Drawing.PointF&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#DrawRectangleBarStyle(System.Web.UI.DataVisualization.Charting.BarDrawingStyle,System.Boolean,System.Drawing.RectangleF)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#DrawLabelStringRel(System.Web.UI.DataVisualization.Charting.Axis,System.Int32,System.Web.UI.DataVisualization.Charting.LabelMarkStyle,System.Drawing.Color,System.String,System.String,System.Drawing.Color,System.Drawing.Font,System.Drawing.Brush,System.Drawing.RectangleF,System.Drawing.StringFormat,System.Int32,System.Drawing.RectangleF,System.Web.UI.DataVisualization.Charting.CustomLabel,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#FillRectangleRel(System.Drawing.RectangleF,System.Drawing.Color,System.Web.UI.DataVisualization.Charting.ChartHatchStyle,System.String,System.Web.UI.DataVisualization.Charting.ChartImageWrapMode,System.Drawing.Color,System.Web.UI.DataVisualization.Charting.ChartImageAlignmentStyle,System.Web.UI.DataVisualization.Charting.GradientStyle,System.Drawing.Color,System.Drawing.Color,System.Int32,System.Web.UI.DataVisualization.Charting.ChartDashStyle,System.Drawing.Color,System.Int32,System.Drawing.Drawing2D.PenAlignment,System.Boolean,System.Int32,System.Boolean,System.Web.UI.DataVisualization.Charting.BarDrawingStyle,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#FillRectangleAbs(System.Drawing.RectangleF,System.Drawing.Color,System.Web.UI.DataVisualization.Charting.ChartHatchStyle,System.String,System.Web.UI.DataVisualization.Charting.ChartImageWrapMode,System.Drawing.Color,System.Web.UI.DataVisualization.Charting.ChartImageAlignmentStyle,System.Web.UI.DataVisualization.Charting.GradientStyle,System.Drawing.Color,System.Drawing.Color,System.Int32,System.Web.UI.DataVisualization.Charting.ChartDashStyle,System.Drawing.Drawing2D.PenAlignment)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#Draw3DSurface(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.SurfaceNames,System.Single,System.Single,System.Drawing.Color,System.Drawing.Color,System.Int32,System.Web.UI.DataVisualization.Charting.ChartDashStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Collections.ArrayList,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Int32,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#FillPieSides(System.Web.UI.DataVisualization.Charting.ChartArea,System.Single,System.Single,System.Single,System.Drawing.PointF[],System.Drawing.SolidBrush,System.Drawing.Pen,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#Fill3DRectangle(System.Drawing.RectangleF,System.Single,System.Single,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Drawing.Color,System.Single,System.Single,System.Drawing.Color,System.Int32,System.Web.UI.DataVisualization.Charting.ChartDashStyle,System.Web.UI.DataVisualization.Charting.BarDrawingStyle,System.Boolean,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#DrawMarker3D(System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Single,System.Drawing.PointF,System.Web.UI.DataVisualization.Charting.MarkerStyle,System.Int32,System.Drawing.Color,System.Drawing.Color,System.Int32,System.String,System.Drawing.Color,System.Int32,System.Drawing.Color,System.Drawing.RectangleF,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#DrawBarStyleGradients(System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.BarDrawingStyle,System.Drawing.RectangleF,System.Single,System.Single,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#DrawMarkerAbs(System.Drawing.PointF,System.Web.UI.DataVisualization.Charting.MarkerStyle,System.Int32,System.Drawing.Color,System.Drawing.Color,System.Int32,System.String,System.Drawing.Color,System.Int32,System.Drawing.Color,System.Drawing.RectangleF,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#DrawPathAbs(System.Drawing.Drawing2D.GraphicsPath,System.Drawing.Color,System.Web.UI.DataVisualization.Charting.ChartHatchStyle,System.String,System.Web.UI.DataVisualization.Charting.ChartImageWrapMode,System.Drawing.Color,System.Web.UI.DataVisualization.Charting.ChartImageAlignmentStyle,System.Web.UI.DataVisualization.Charting.GradientStyle,System.Drawing.Color,System.Drawing.Color,System.Int32,System.Web.UI.DataVisualization.Charting.ChartDashStyle,System.Drawing.Drawing2D.PenAlignment)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#Fill3DRectangleAsCylinder(System.Drawing.RectangleF,System.Single,System.Single,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Drawing.Color,System.Single,System.Single,System.Drawing.Color,System.Int32,System.Web.UI.DataVisualization.Charting.ChartDashStyle,System.Boolean,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPointCustomProperties.#SetDefault(System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AxisScaleBreakStyle.#FillAxisSegmentCollection(System.Web.UI.DataVisualization.Charting.AxisScaleSegmentCollection)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Selection.#HitTest(System.Int32,System.Int32,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartElementType[])")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Selection.#GetHitTestResult(System.String,System.Int32,System.Web.UI.DataVisualization.Charting.ChartElementType,System.Object,System.Object)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Selection.#GetHotRegions(System.Object,System.Web.UI.DataVisualization.Charting.ChartElementType)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#Resize(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ElementPosition,System.Drawing.RectangleF,System.Single,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#CheckLabelsFit(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Single,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Collections.ArrayList)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#DrawAxis3DTitle(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#GetRequiredLabelSize(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Single,System.Single&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#ReduceLabelInterval(System.Double,System.Double,System.Web.UI.DataVisualization.Charting.DateTimeIntervalType&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#DrawAxisTitle(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#AdjustLabelFontAtSecondPass(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#CalcInterval(System.Double,System.Double,System.Boolean,System.Web.UI.DataVisualization.Charting.DateTimeIntervalType&,System.Web.UI.DataVisualization.Charting.ChartValueType)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#DrawAxisLine(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#EstimateNumberAxis(System.Double&,System.Double&,System.Boolean,System.Int32,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#AdjustIntervalToFitLabels(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Boolean,System.Web.UI.DataVisualization.Charting.AxisScaleSegment,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#FillLabels(System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#Draw3DAxisLine(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.PointF,System.Drawing.PointF,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Annotation.#SetPositionRelative(System.Drawing.RectangleF,System.Drawing.PointF,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Annotation.#PaintSelectionHandles(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.RectangleF,System.Drawing.Drawing2D.GraphicsPath)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Annotation.#GetRelativePosition(System.Drawing.PointF&,System.Drawing.SizeF&,System.Drawing.PointF&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPoint.#SetValueY(System.Object[])")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPointCollection.#ConvertEnumerationItem(System.Object,System.String)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPointCollection.#DataBindXY(System.Collections.IEnumerable,System.String,System.Collections.IEnumerable,System.String)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPointCollection.#DataBindXY(System.Collections.IEnumerable,System.Collections.IEnumerable[])")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPointCollection.#GetValueType(System.Collections.IEnumerator,System.String)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LabelStyle.#Paint3D(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LabelStyle.#PaintCircular(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LabelStyle.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.SmartLabel.#IsSmartLabelCollide(System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.SmartLabelStyle,System.Drawing.PointF,System.Drawing.SizeF,System.Drawing.PointF,System.Drawing.StringFormat,System.Web.UI.DataVisualization.Charting.LabelAlignmentStyles,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.SmartLabel.#LineIntersectRectangle(System.Drawing.RectangleF,System.Drawing.PointF,System.Drawing.PointF)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#FillLegendItemsCollection()")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#CheckLegendItemsFit(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.Size,System.Int32,System.Int32,System.Int32,System.Int32[],System.Int32[,]&,System.Int32[,]&,System.Int32&,System.Int32&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#RecalcLegendInfo(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#GetOptimalSize(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.SizeF)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#GetNumberOfRowsAndColumns(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.Size,System.Int32,System.Int32[]&,System.Int32&,System.Int32&,System.Int32&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#DrawLegendHeader(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.TextAnnotation.#DrawText(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.RectangleF,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator.#GroupByAxisLabel(System.String,System.Web.UI.DataVisualization.Charting.Series[],System.Web.UI.DataVisualization.Charting.Series[])")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator.#ExportSeriesValues(System.Web.UI.DataVisualization.Charting.Series[])")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator.#Group(System.String,System.Double,System.Web.UI.DataVisualization.Charting.IntervalType,System.Double,System.Web.UI.DataVisualization.Charting.IntervalType,System.Web.UI.DataVisualization.Charting.Series[],System.Web.UI.DataVisualization.Charting.Series[])")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator.#ProcessPointValues(System.Web.UI.DataVisualization.Charting.DataManipulator+GroupingFunctionInfo[],System.Double[],System.Web.UI.DataVisualization.Charting.Series,System.Web.UI.DataVisualization.Charting.DataPoint,System.Int32,System.Int32,System.Int32,System.Boolean,System.Int32&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#GetValuesFromData(System.Web.UI.DataVisualization.Charting.Axis,System.Double&,System.Double&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#GetPointsInterval(System.Collections.Generic.List`1<System.String>,System.Boolean,System.Double,System.Boolean,System.Boolean&,System.Web.UI.DataVisualization.Charting.Series&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#Resize(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#GetArea3DSceneDepth()")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#SeriesDateTimeType(System.Web.UI.DataVisualization.Charting.AxisName,System.String)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#SeriesIntegerType(System.Web.UI.DataVisualization.Charting.AxisName,System.String)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#SetDefaultFromData(System.Web.UI.DataVisualization.Charting.Axis)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#SetData(System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#SetData(System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#PreventTopBottomAxesLabelsOverlapping(System.Web.UI.DataVisualization.Charting.Axis)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Series.#PrepareData(System.ComponentModel.ISite,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Grid.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LegendCell.#PaintCellSeriesSymbol(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.SizeF)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.TickMark.#Draw3DTickLine(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.PointF,System.Drawing.PointF,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.TickMark.#PaintCustom(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.TickMark.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.StripLine.#PaintTitle(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.RectangleF)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.StripLine.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Title.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LegendAreaNameConverter.#GetStandardValues(System.ComponentModel.ITypeDescriptorContext)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartPicture.#Paint(System.Drawing.Graphics,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.BinaryFormatSerializer.#SerializeObject(System.Object,System.Object,System.String,System.IO.BinaryWriter)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#ResetObjectProperties(System.Object,System.Object,System.String)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.XmlFormatSerializer.#DeserializeObject(System.Object,System.Object,System.String,System.Xml.XmlNode,System.Xml.XmlDocument)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.XmlFormatSerializer.#SerializeObject(System.Object,System.Object,System.String,System.Xml.XmlNode,System.Xml.XmlDocument)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.ImageLoader.#LoadImage(System.String,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#FindConverterByType(System.ComponentModel.TypeConverterAttribute)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Series.#PrepareData(System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPointCollection.#DataBind(System.Collections.IEnumerable,System.String,System.String,System.String)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.KagiChart.#DrawLine(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.Series,System.Drawing.PointF[],System.Int32,System.Single)")] + + +#endregion // CA1502:AvoidExcessiveComplexity + + +#region CA1505:AvoidUnmaintainableCode + +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedColumnChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedColumnChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Boolean,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FunnelChart.#DrawFunnelCircularSegment(System.Web.UI.DataVisualization.Charting.DataPoint,System.Int32,System.Single,System.Single,System.Single,System.Single,System.Boolean,System.Boolean,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.ErrorBarChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.ErrorBarChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BoxPlotChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BoxPlotChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PointChart.#DrawLabels(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Drawing.PointF,System.Int32,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.Series,System.Int32)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedBarChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedBarChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Boolean,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedAreaChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BarChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BarChart.#DrawLabelsAndMarkers(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Drawing.RectangleF,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.Series,System.Double,System.Double,System.Double,System.Int32,System.Int32&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BarChart.#ProcessChartType(System.Boolean,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.RangeChart.#Draw3DSurface(System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single,System.Single,System.Collections.ArrayList,System.Int32,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Single,System.Single,System.Drawing.PointF,System.Drawing.PointF,System.Boolean,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.RangeChart.#DrawLine(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.Series,System.Drawing.PointF[],System.Int32,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#PointOrder(System.Web.UI.DataVisualization.Charting.Series,System.Web.UI.DataVisualization.Charting.ChartArea,System.Single[]&,System.Single[]&,System.Int32[]&,System.Boolean&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#DrawLabels(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.PointF,System.Drawing.SizeF,System.Single,System.Single,System.Web.UI.DataVisualization.Charting.DataPoint,System.Single,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Int32,System.Drawing.Color)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart+LabelsMode)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FastLineChart.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.RadarChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StockChart.#ProcessChartType3D(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StockChart.#DrawOpenCloseMarks3D(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series,System.Web.UI.DataVisualization.Charting.DataPoint,System.Single,System.Single,System.Single,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#ClipBottomPoints(System.Drawing.Drawing2D.GraphicsPath,System.Web.UI.DataVisualization.Charting.DataPoint3D&,System.Web.UI.DataVisualization.Charting.DataPoint3D&,System.Drawing.PointF&,System.Drawing.PointF&,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single,System.Single,System.Collections.ArrayList,System.Int32,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Single,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#ClipTopPoints(System.Drawing.Drawing2D.GraphicsPath,System.Web.UI.DataVisualization.Charting.DataPoint3D&,System.Web.UI.DataVisualization.Charting.DataPoint3D&,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single,System.Single,System.Collections.ArrayList,System.Int32,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Single,System.Single)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.AreaChart.#Draw3DSurface(System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Boolean,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single,System.Single,System.Collections.ArrayList,System.Int32,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Single,System.Single,System.Drawing.PointF,System.Drawing.PointF,System.Boolean,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#DrawRectangleBarStyle(System.Web.UI.DataVisualization.Charting.BarDrawingStyle,System.Boolean,System.Drawing.RectangleF)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#DrawLabelStringRel(System.Web.UI.DataVisualization.Charting.Axis,System.Int32,System.Web.UI.DataVisualization.Charting.LabelMarkStyle,System.Drawing.Color,System.String,System.String,System.Drawing.Color,System.Drawing.Font,System.Drawing.Brush,System.Drawing.RectangleF,System.Drawing.StringFormat,System.Int32,System.Drawing.RectangleF,System.Web.UI.DataVisualization.Charting.CustomLabel,System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#Draw3DSurface(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Web.UI.DataVisualization.Charting.SurfaceNames,System.Single,System.Single,System.Drawing.Color,System.Drawing.Color,System.Int32,System.Web.UI.DataVisualization.Charting.ChartDashStyle,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Collections.ArrayList,System.Int32,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Int32,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#DrawBarStyleGradients(System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.BarDrawingStyle,System.Drawing.RectangleF,System.Single,System.Single,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#DrawMarkerAbs(System.Drawing.PointF,System.Web.UI.DataVisualization.Charting.MarkerStyle,System.Int32,System.Drawing.Color,System.Drawing.Color,System.Int32,System.String,System.Drawing.Color,System.Int32,System.Drawing.Color,System.Drawing.RectangleF,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#Fill3DRectangleAsCylinder(System.Drawing.RectangleF,System.Single,System.Single,System.Web.UI.DataVisualization.Charting.Matrix3D,System.Web.UI.DataVisualization.Charting.LightStyle,System.Drawing.Color,System.Single,System.Single,System.Drawing.Color,System.Int32,System.Web.UI.DataVisualization.Charting.ChartDashStyle,System.Boolean,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#Resize(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ElementPosition,System.Drawing.RectangleF,System.Single,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#CheckLabelsFit(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Single,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Collections.ArrayList)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#FillLabels(System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Annotation.#GetRelativePosition(System.Drawing.PointF&,System.Drawing.SizeF&,System.Drawing.PointF&)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LabelStyle.#Paint3D(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LabelStyle.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#Resize(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.TickMark.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.CustomPropertyRegistry.#RegisterProperties()")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Title.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics)")] + +#endregion // CA1505:AvoidUnmaintainableCode + + +#region CA1506:AvoidExcessiveClassCoupling + +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedAreaChart.#ProcessChartType(System.Boolean,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartImage.#GetDataSourceMemberNames(System.Object,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "System.Web.UI.DataVisualization.Charting.Axis")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LabelStyle.#Paint(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Boolean)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "System.Web.UI.DataVisualization.Charting.ChartArea")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "System.Web.UI.DataVisualization.Charting.Series")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "System.Web.UI.DataVisualization.Charting.Chart")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Chart.#.ctor()")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "System.Web.UI.DataVisualization.Charting.ChartPicture")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#FindConverterByType(System.ComponentModel.TypeConverterAttribute)")] +[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "System.Web.UI.DataVisualization.Charting.ChartImage")] + +#endregion // CA1506:AvoidExcessiveClassCoupling + + +#region CA1702:CompoundWordsShouldBeCasedCorrectly + +[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartColorPalette.#SemiTransparent", MessageId = "SemiTransparent")] +[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Gridlines", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartElementType.#Gridlines", Justification = "Gridlines are popular term in charting. Refer to excel chart.")] +[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Gridline", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.GridTickTypes.#Gridline", Justification = "Gridlines are popular term in charting. Refer to excel chart.")] +[module: SuppressMessage("Microsoft.Naming", "CA1701:ResourceStringCompoundWordsShouldBeCasedCorrectly", MessageId = "Gridlines", Scope = "resource", Target = "System.Web.UI.DataVisualization.Charting.SR.resources", Justification = "Gridlines are popular term in charting. Refer to excel chart.")] + +#endregion // CA1702:CompoundWordsShouldBeCasedCorrectly + + +#region CA1703:ResourceStringsShouldBeSpelledCorrectly + +[module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "System.Web.UI.DataVisualization.Charting.SR.resources", MessageId = "rror")] +[module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "System.Web.UI.DataVisualization.Charting.SR.resources", MessageId = "Kagi")] +[module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "System.Web.UI.DataVisualization.Charting.SR.resources", MessageId = "Renko")] +[module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "System.Web.UI.DataVisualization.Charting.SR.resources", MessageId = "Polyline")] +[module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "System.Web.UI.DataVisualization.Charting.SR.resources", MessageId = "uint")] +[module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "System.Web.UI.DataVisualization.Charting.SR.resources", MessageId = "Unscaled")] +[module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "System.Web.UI.DataVisualization.Charting.SR.resources", MessageId = "deserializer")] +[module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "System.Web.UI.DataVisualization.Charting.SR.resources", MessageId = "ulong")] +[module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "System.Web.UI.DataVisualization.Charting.SR.resources", MessageId = "ushort")] +[module: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "System.Web.UI.DataVisualization.Charting.SR.resources", MessageId = "megapixels")] + +#endregion // CA1703:ResourceStringsShouldBeSpelledCorrectly + + +#region CA1805:DoNotInitializeUnnecessarily + +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BubbleChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.HundredPercentStackedBarChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart+LabelColumn.#.ctor(System.Drawing.RectangleF)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedColumnChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FunnelChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.ChartTypeRegistry.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.ErrorBarChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BoxPlotChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PointChart.#.ctor(System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PointChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PointChart+Label3DInfo.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.HundredPercentStackedColumnChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PointAndFigureChart.#.cctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedBarChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StackedAreaChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BarChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.ColumnChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.RangeChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FunnelSegmentInfo.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.HundredPercentStackedAreaChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FastLineChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FastPointChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StockChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.StockChart.#.ctor(System.Web.UI.DataVisualization.Charting.ChartTypes.StockOpenCloseMarkStyle)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.KagiChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.AreaChart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FunnelPointLabelInfo.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.NamedImage.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartImage.#.ctor(System.ComponentModel.Design.IServiceContainer)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.HotRegion.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataFormula.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CustomizeLegendEventArgs.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartHttpHandler.#.cctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CustomLabel.#.ctor(System.Double,System.Double,System.String,System.Int32,System.Web.UI.DataVisualization.Charting.LabelMarkStyle)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CustomLabel.#.ctor(System.Double,System.Double,System.String,System.Int32,System.Web.UI.DataVisualization.Charting.LabelMarkStyle,System.Web.UI.DataVisualization.Charting.GridTickTypes)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CustomLabel.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.PolylineAnnotation.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CalloutAnnotation.#.cctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator+GroupingFunctionInfo.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Point3D.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#.ctor(System.Web.UI.DataVisualization.Charting.CommonElements)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea+ChartTypeAndSeriesInfo.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea+ChartTypeAndSeriesInfo.#.ctor(System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CircularChartAreaAxis.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.FontCache+KeyInfo.#.ctor(System.Drawing.FontFamily,System.Single,System.Drawing.FontStyle)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.FontCache+KeyInfo.#.ctor(System.String,System.Single)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.FontCache+KeyInfo.#.ctor(System.Drawing.FontFamily,System.Single,System.Drawing.FontStyle,System.Drawing.GraphicsUnit)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartElement.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartElement.#.ctor(System.Web.UI.DataVisualization.Charting.IChartElement)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPointCustomProperties.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPointCustomProperties.#.ctor(System.Web.UI.DataVisualization.Charting.Series,System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AxisScaleSegmentCollection.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AxisScaleSegmentCollection.#.ctor(System.Web.UI.DataVisualization.Charting.Axis)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AxisScaleBreakStyle.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AxisScaleBreakStyle.#.ctor(System.Web.UI.DataVisualization.Charting.Axis)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Selection.#.ctor(System.ComponentModel.Design.IServiceContainer)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LegendItem.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LegendItem.#.ctor(System.String,System.Drawing.Color,System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#.ctor(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.AxisName)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartHttpHandlerSettings.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartHttpHandlerSettings.#.ctor(System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Annotation.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPoint.#.ctor(System.Web.UI.DataVisualization.Charting.Series)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.RingTimeTracker.#.ctor(System.TimeSpan,System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AnnotationPathPointCollection.#.ctor(System.Web.UI.DataVisualization.Charting.PolylineAnnotation)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.TTestResult.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.GdiGraphics.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LabelStyle.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LabelStyle.#.ctor(System.Web.UI.DataVisualization.Charting.Axis)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LegendCellColumn.#.ctor(System.String,System.Web.UI.DataVisualization.Charting.LegendCellColumnType,System.String,System.Drawing.ContentAlignment)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AxisScaleView.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AxisScaleView.#.ctor(System.Web.UI.DataVisualization.Charting.Axis)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LineAnnotation.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AnovaResult.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Margins.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Margins.#.ctor(System.Int32,System.Int32,System.Int32,System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.SmartLabel.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.SmartLabelStyle.#.ctor(System.Object)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.SmartLabelStyle.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ElementPosition.#.ctor(System.Single,System.Single,System.Single,System.Single)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ElementPosition.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ElementPosition.#.ctor(System.Web.UI.DataVisualization.Charting.IChartElement)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CommonElements.#.ctor(System.ComponentModel.Design.IServiceContainer)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CustomizeMapAreasEventArgs.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AnnotationPathPoint.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#.ctor(System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.TextAnnotation.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.HotRegionsList.#.ctor(System.Web.UI.DataVisualization.Charting.CommonElements)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#.ctor(System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartPaintEventArgs.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartPaintEventArgs.#.ctor(System.Object,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ElementPosition)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartPaintEventArgs.#.ctor(System.Object,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ElementPosition)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator+PointElementFilter.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator+PointElementFilter.#.ctor(System.Web.UI.DataVisualization.Charting.DataManipulator,System.Web.UI.DataVisualization.Charting.DateRangeType,System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.HitTestResult.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Series.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Series.#.ctor(System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Series.#.ctor(System.String,System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.FTestResult.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Grid.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Grid.#.ctor(System.Web.UI.DataVisualization.Charting.Axis,System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartSerializer.#.ctor(System.ComponentModel.Design.IServiceContainer)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartSerializer.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LegendCell.#.ctor(System.Web.UI.DataVisualization.Charting.LegendCellType,System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LegendCell.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LegendCell.#.ctor(System.Web.UI.DataVisualization.Charting.LegendCellType,System.String,System.Drawing.ContentAlignment)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LegendCell.#.ctor(System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.StripLine.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPoint3D.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AxisScaleSegment.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Title.#.ctor(System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Title.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Title.#.ctor(System.String,System.Web.UI.DataVisualization.Charting.Docking)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Title.#.ctor(System.String,System.Web.UI.DataVisualization.Charting.Docking,System.Drawing.Font,System.Drawing.Color)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Chart.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Chart.#.cctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AnnotationCollection.#.ctor(System.Web.UI.DataVisualization.Charting.IChartElement)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea3DStyle.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea3DStyle.#.ctor(System.Web.UI.DataVisualization.Charting.ChartArea)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartPicture.#.ctor(System.ComponentModel.Design.IServiceContainer)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Borders3D.SunkenBorder.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Borders3D.BorderTypeRegistry.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.CustomPropertyInfo.#.ctor(System.String,System.Type,System.Object,System.String,System.Web.UI.DataVisualization.Charting.SeriesChartType[],System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.ImageLoader.#.ctor(System.ComponentModel.Design.IServiceContainer)")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.ImageLoader.#.ctor()")] +[module: SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase+ItemInfo.#.ctor()")] + +#endregion // CA1805:DoNotInitializeUnnecessarily + + +#region CA1814:PreferJaggedArraysOverMultidimensional + +[module: SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#_subColumnSizes", MessageId = "Member")] +[module: SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#CheckLegendItemsFit(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.Size,System.Int32,System.Int32,System.Int32,System.Int32[],System.Int32[,]&,System.Int32[,]&,System.Int32&,System.Int32&)", MessageId = "Body")] +[module: SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#_cellHeights", MessageId = "Member")] + +#endregion // CA1814:PreferJaggedArraysOverMultidimensional + + +#region CA1822:MarkMembersAsStatic + +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.FunnelChart.#GetCalloutLineColor(System.Web.UI.DataVisualization.Charting.DataPointCustomProperties)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PointChart.#SetHotRegions(System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.DataPoint,System.Drawing.SizeF,System.String,System.Int32,System.Web.UI.DataVisualization.Charting.MarkerStyle,System.Drawing.PointF)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BarChart.#DrawMarkers3D(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.CommonElements,System.Drawing.RectangleF,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.Series,System.Double,System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BarChart.#SetHotRegions(System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.DataPoint,System.Drawing.SizeF,System.String,System.Int32,System.Web.UI.DataVisualization.Charting.MarkerStyle,System.Drawing.PointF)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.BarChart.#GetEmptyPointValue(System.Web.UI.DataVisualization.Charting.DataPoint,System.Int32,System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.RangeChart.#Draw3DSplinePolygon(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ChartArea,System.Single,System.Drawing.Color,System.Drawing.Color,System.Int32,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Collections.ArrayList,System.Single,System.Web.UI.DataVisualization.Charting.DrawingOperationTypes,System.Web.UI.DataVisualization.Charting.LineSegmentType,System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#GetLabelRect(System.Drawing.PointF,System.Web.UI.DataVisualization.Charting.ChartArea,System.String,System.Drawing.StringFormat,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.DataPoint,System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#GetPointLabel(System.Web.UI.DataVisualization.Charting.DataPoint)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#DrawDoughnutCurvesBigSlice(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.DataPoint,System.Single,System.Single,System.Drawing.PointF[],System.Drawing.Brush,System.Drawing.Pen,System.Boolean,System.Boolean,System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#ReduceEmptySpace(System.Double[],System.Double[],System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#CheckPaleteColors(System.Web.UI.DataVisualization.Charting.DataPointCollection)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#Map(System.Web.UI.DataVisualization.Charting.CommonElements,System.Web.UI.DataVisualization.Charting.DataPoint,System.Single,System.Single,System.Drawing.RectangleF,System.Boolean,System.Single,System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#SortIntervals(System.Double[],System.Double[],System.Int32[])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#GetLabelStyle(System.Web.UI.DataVisualization.Charting.DataPoint)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#DrawPieCurvesBigSlice(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.DataPoint,System.Single,System.Single,System.Drawing.PointF[],System.Drawing.Brush,System.Drawing.Pen,System.Boolean,System.Boolean,System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#SpreadInterval(System.Double[],System.Double[],System.Int32,System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#SwitchPoints(System.Int32,System.Web.UI.DataVisualization.Charting.DataPoint[]&,System.Single[]&,System.Single[]&,System.Int32[]&,System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.PieChart.#ShiftIntervals(System.Double[],System.Double[],System.Double,System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.RadarChart.#GetEmptyPointValue(System.Web.UI.DataVisualization.Charting.DataPoint,System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.RadarChart.#GetMiddlePoint(System.Drawing.PointF,System.Drawing.PointF)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#DrawTruncatedLine(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.Pen,System.Drawing.PointF,System.Drawing.PointF)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#DrawLine(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Web.UI.DataVisualization.Charting.DataPoint,System.Web.UI.DataVisualization.Charting.Series,System.Drawing.PointF,System.Drawing.PointF)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.LineChart.#GetCenterPointIndex(System.Collections.ArrayList)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartTypes.AreaChart.#GetAxisIntersection(System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Web.UI.DataVisualization.Charting.DataPoint3D,System.Single)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.TimeSeriesAndForecasting.#CopyDeterminant(System.Double[][])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.TimeSeriesAndForecasting.#MakeSubDeterminant(System.Double[][],System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.StatisticalAnalysis.#NormalDistributionInverse(System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.StatisticalAnalysis.#CheckNumOfPoints(System.Double[][])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.StatisticalAnalysis.#GammLn(System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.StatisticalAnalysis.#NormalDistributionFunction(System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.StatisticalAnalysis.#BetaCF(System.Double,System.Double,System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.StatisticalAnalysis.#Mean(System.Double[])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.StatisticalAnalysis.#Sort(System.Double[]&)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.PriceIndicators.#CheckNumOfValues(System.Double[][],System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.PriceIndicators.#WeightedMovingAverage(System.Double[][],System.Double[][]&,System.String[],System.String[])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.PriceIndicators.#ExponentialMovingAverage(System.Double[][],System.Double[][]&,System.String[],System.String[])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Formulas.PriceIndicators.#MovingAverage(System.Double[][],System.Double[][]&,System.String[],System.String[])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Data.DataManager.#IsPointSkipped(System.Web.UI.DataVisualization.Charting.DataPoint)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartImage.#AlignDataPointsByAxisLabel(System.Collections.ArrayList,System.Boolean,System.Web.UI.DataVisualization.Charting.PointSortOrder)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataFormula.#SplitParameters(System.String,System.String[]&)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataFormula.#DifferentNumberOfSeries(System.Double[][])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataFormula.#RemoveEmptyValues(System.Double[][],System.Double[][]&)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataFormula.#CheckXValuesAlignment(System.Web.UI.DataVisualization.Charting.Series[])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Matrix3D.#GetAngle(System.Web.UI.DataVisualization.Charting.Point3D,System.Web.UI.DataVisualization.Charting.Point3D)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Matrix3D.#GetBrightGradientColor(System.Drawing.Color,System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Matrix3D.#Set3DBarPoints(System.Single,System.Single,System.Single)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartHttpHandler.#GetHandler()")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CalloutAnnotation.#PathAddLineAsSegments(System.Drawing.Drawing2D.GraphicsPath,System.Single,System.Single,System.Single,System.Single,System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#GetBrightGradientColor(System.Drawing.Color,System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#GetPieGradientBrush(System.Drawing.RectangleF,System.Drawing.Color,System.Drawing.Color)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#CreateRoundedRectPath(System.Drawing.RectangleF,System.Single[])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#GetGradientBrush(System.Drawing.RectangleF,System.Drawing.Color,System.Drawing.Color,System.Web.UI.DataVisualization.Charting.GradientStyle)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#GetVisibleSurfacesWithPerspective(System.Web.UI.DataVisualization.Charting.Point3D[])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#Round(System.Drawing.RectangleF)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#GetHatchBrush(System.Web.UI.DataVisualization.Charting.ChartHatchStyle,System.Drawing.Color,System.Drawing.Color)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#GetPolygonCirclePath(System.Drawing.RectangleF,System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#GetPenStyle(System.Web.UI.DataVisualization.Charting.ChartDashStyle)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#AngleCorrection(System.Single,System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartGraphics.#CreateStarPolygon(System.Drawing.RectangleF,System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPointCustomProperties.#Invalidate(System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AxisScaleBreakStyle.#IsExcludedSegment(System.Collections.ArrayList,System.Int32)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AxisScaleBreakStyle.#GetLargestSequenseOfSegmentsWithNoPoints(System.Int32[],System.Int32&,System.Int32&)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Selection.#GetRegionMarkers(System.Drawing.Drawing2D.GraphicsPath)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Selection.#GetMarkers(System.Drawing.RectangleF,System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Selection.#IsChartAreaCircular(System.Web.UI.DataVisualization.Charting.ChartArea)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LegendItem.#Invalidate(System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#CalcYearInterval(System.Double)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#IsArrowInAxis(System.Web.UI.DataVisualization.Charting.ArrowOrientation,System.Web.UI.DataVisualization.Charting.AxisPosition)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#GetNumOfUnits(System.Double,System.Double,System.Web.UI.DataVisualization.Charting.DateTimeIntervalType)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Axis.#WordWrapLongestLabel(System.Web.UI.DataVisualization.Charting.CustomLabelsCollection)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Annotation.#GetAxisName(System.Web.UI.DataVisualization.Charting.Axis)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Annotation.#GetDataPointName(System.Web.UI.DataVisualization.Charting.DataPoint)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CustomPropertiesTypeConverter+CustomAttributesPropertyDescriptor.#GetStringFromValue(System.Object)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPoint.#ConvertValue(System.Object)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataPoint.#RemoveOneKeyword(System.String,System.String,System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CustomPropertiesTypeConverter.#GetSelectedSeries(System.Object)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CustomPropertiesTypeConverter.#IsDataPoint(System.Object)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.CustomPropertiesTypeConverter.#GetPropertyAttributes(System.Web.UI.DataVisualization.Charting.Utilities.CustomPropertyInfo)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LabelStyle.#GetLabelsPosition(System.Web.UI.DataVisualization.Charting.Axis)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LabelStyle.#GetAllLabelsRect(System.Web.UI.DataVisualization.Charting.ChartArea,System.Web.UI.DataVisualization.Charting.AxisPosition,System.Drawing.StringFormat)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.LabelStyle.#Invalidate()")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Margins.#Invalidate()")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.SmartLabel.#CalculatePosition(System.Web.UI.DataVisualization.Charting.LabelAlignmentStyles,System.Drawing.PointF,System.Drawing.SizeF,System.Drawing.SizeF,System.Drawing.StringFormat&)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.SmartLabel.#GetLabelPosition(System.Web.UI.DataVisualization.Charting.ChartGraphics,System.Drawing.PointF,System.Drawing.SizeF,System.Drawing.StringFormat,System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.SmartLabel.#LineIntersectRectangle(System.Drawing.RectangleF,System.Drawing.PointF,System.Drawing.PointF)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.AnnotationPathPoint.#Name")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#Invalidate(System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Legend.#GetMaximumNumberOfRows(System.Int32[])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DefaultImageHandler.#NotSupportedStorageType(System.Web.UI.DataVisualization.Charting.ChartHttpHandlerSettings)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator.#CheckFilterElementCriteria(System.Web.UI.DataVisualization.Charting.DateRangeType,System.Int32[],System.Web.UI.DataVisualization.Charting.DataPoint)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator.#ConvertIntervalType(System.Web.UI.DataVisualization.Charting.IntervalType)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator.#ConvertElementIndexesToArray(System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator.#ParseFormulaAndValueType(System.String,System.Int32&)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.DataManipulator.#CheckSeriesArrays(System.Web.UI.DataVisualization.Charting.Series[],System.Web.UI.DataVisualization.Charting.Series[])")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#IsMainSceneWallOnFront()")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#GetDateInterval(System.Double,System.Double,System.Int32&,System.Int64&)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartArea.#Activate(System.Web.UI.DataVisualization.Charting.Axis,System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ImageAnnotation.#GetImageAlignment(System.Drawing.ContentAlignment)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Series.#XSubAxisName")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Series.#YSubAxisName")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Series.#ReplaceOneKeyword(System.Web.UI.DataVisualization.Charting.Chart,System.Object,System.Object,System.Web.UI.DataVisualization.Charting.ChartElementType,System.String,System.String,System.Double,System.Web.UI.DataVisualization.Charting.ChartValueType,System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Series.#Invalidate(System.Boolean,System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Series.#CheckSupportedTypes(System.Type)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Grid.#Invalidate()")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.ChartSerializer.#GetContentString(System.Web.UI.DataVisualization.Charting.SerializationContents,System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.StripLine.#Invalidate()")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.StripLine.#Name")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Title.#Invalidate(System.Boolean)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Chart.#BeginInit()")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Chart.#RenderingDpiX")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Chart.#RenderingDpiY")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Chart.#EndInit()")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Chart.#BuildNumber")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Chart.#CheckImageURLSeqFormat(System.String)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.BinaryFormatSerializer.#WritePropertyValue(System.Object,System.String,System.IO.BinaryWriter)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.BinaryFormatSerializer.#CheckPropertiesID(System.Collections.ArrayList)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#ShouldSerializeAsAttribute(System.Reflection.PropertyInfo,System.Object)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#GetObjectName(System.Object)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#IsChartBaseProperty(System.Object,System.Object,System.Reflection.PropertyInfo)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#CheckWildCars(System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase+ItemInfo)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#SerializeICollAsAtribute(System.Reflection.PropertyInfo,System.Object)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#GetListNewItem(System.Collections.IList,System.String,System.String&,System.Boolean&)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#NameMatchMask(System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase+ItemInfo,System.String,System.Int32&)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.SerializerBase.#ReadHashID(System.IO.BinaryReader)")] +[module: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "System.Web.UI.DataVisualization.Charting.Utilities.ImageLoader.#LoadFromFile(System.String)")] + +#endregion // CA1822:MarkMembersAsStatic + +#region CA910:AlwaysSetViewStateUserKeyToUniqueValue +[module: SuppressMessage("Microsoft.MSInternal", "CA910:AlwaysSetViewStateUserKeyToUniqueValue", Scope = "type", Target = "System.Web.UI.DataVisualization.Charting.ChartHttpHandler", Justification = "This page is actually http image handler and doesn't emit any viewstate")] +#endregion //CA910:AlwaysSetViewStateUserKeyToUniqueValue \ No newline at end of file diff --git a/System.Web.DataVisualization/WebForm/General/ChartHttpHandler.cs b/System.Web.DataVisualization/WebForm/General/ChartHttpHandler.cs new file mode 100644 index 000000000..dddf8dfb3 --- /dev/null +++ b/System.Web.DataVisualization/WebForm/General/ChartHttpHandler.cs @@ -0,0 +1,2158 @@ + +//-------------------------------------------------------------------------------------------------------------------------- +// <copyright company=’Microsoft Corporation’> +// Copyright © Microsoft Corporation. All Rights Reserved. +// </copyright> +//-------------------------------------------------------------------------------------------------------------------------- +// @owner=alexgor, deliant +//========================================================================================================================== +// File: ChartHttpHandler.cs +// +// Namespace: Microsoft.Reporting.Chart.WebForms +// +// Classes: ChartHttpHandler +// +// Purpose: ChartHttpHandler is a static class which is responsible to handle with +// chart images, interactive images, scripts and other resources. +// +// +// Reviewed: DT +// Reviewed: deliant on 4/14/2011 +// MSRC#10470, VSTS#941768 http://vstfdevdiv:8080/web/wi.aspx?id=941768 +// Please review information associated with MSRC#10470 before making any changes to this file. +// - Fixes: +// - Fixed Directory Traversal/Arbitrary File Read, Delete with malformed image key. +// - Honor HttpContext.Current.Trace.IsEnabled when generate and deliver chart trace info. +// - Handle empty guid parameter ("?g=") as invalid when enforcing privacy. +// - Replaced the privacy byte array comparison with custom check (otherwise posible EOS marker can return 0 length string). +// - Added fixed string to session key to avoid direct session access. +// +// Added: deliant on 4/48/2011 fix for VSTS: 3593 - ASP.Net chart under web farm exhibit fast performace degradation +// Summary: Under large web farm setup ( ~16 processes and up) chart control image handler +// soon starts to show performace degradation up to denial of service, when a file system is used as storage. +// Issues: +// - The image files in count over 2000 in one single folder causes exponentially growing slow response, +// especially on the remote server. The fix places the Image files in separate subfolders for each process. +// - Private protection seeks and read several times in the image file istead reading the image at once +// and then check for privacy marker. Separate small network reads are expensive. +// - Due missing lock in initialization stage the chart lock files number can grow more that process max +// number which can create abandon chart image files +//========================================================================================================================== + +#region Namespaces + +using System; +using System.Collections.Generic; +using System.Text; +using System.Web; +using System.Web.UI; +using System.IO; +using System.Web.Caching; +using System.Collections; +using System.Web.Configuration; +using System.Resources; +using System.Reflection; +using System.Drawing; +using System.Drawing.Imaging; +using System.Threading; +using System.Collections.Specialized; +using System.Diagnostics; +using System.Web.Hosting; +using System.Web.SessionState; +using System.Drawing.Drawing2D; +using System.Runtime.InteropServices; +using System.Globalization; +using System.Diagnostics.CodeAnalysis; +using System.Security.Permissions; +using System.Security; +using System.Security.Cryptography; +using System.Collections.ObjectModel; +using System.Web.UI.WebControls; + +#endregion //Namespaces + +namespace System.Web.UI.DataVisualization.Charting +{ + /// <summary> + /// ChartHttpHandler processes HTTP Web requests using, handles chart images, scripts and other resources. + /// </summary> +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class ChartHttpHandler : Page, IRequiresSessionState, IHttpHandler + { + + #region Fields + + // flag that indicates whether this chart handler is installed + private static bool _installed = false; + + // flag that indicates whether this chart handler is installed + private static bool _installChecked = false; + + // storage settings + private static ChartHttpHandlerSettings _parameters = null; + + + // machine hash key which is part in chart image file name + private static string _machineHash = "_" + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture) + "_"; + + // web gadren controller file. stays locked diring process lifetime. + private static FileStream _controllerFileStream = null; + private static string _controllerDirectory = null; + private static object _initHandlerLock = new object(); + // used for storing Guid key in context; + internal static string ContextGuidKey = "{89FA5660-BD13-4f1b-8C7C-355CEC92CC7E}"; + + // web gadren controller file. stays locked diring process lifetime. + private const string handlerCheckQry = "check"; + + #endregion //Fields + + #region Consts + + internal const string ChartHttpHandlerName = "ChartImg.axd"; + internal const string ChartHttpHandlerAppSection = "ChartImageHandler"; + internal const string DefaultConfigSettings = @"storage=file;timeout=20;dir=c:\TempImageFiles\;"; + internal const string WebDevServerUseConfigSettings = "WebDevServerUseConfigSettings"; + #endregion //Consts + + #region Constructors + + /// <summary> + /// Ensures that the handler is initialized. + /// </summary> + /// <param name="hardCheck">if set to <c>true</c> then will be thrown all excepitons.</param> + private static void EnsureInitialized(bool hardCheck) + { + if (_installChecked) + { + return; + } + lock (_initHandlerLock) + { + if (_installChecked) + { + return; + } + if (HttpContext.Current != null) + { + try + { + using (TextWriter w = new StringWriter(CultureInfo.InvariantCulture)) + { + HttpContext.Current.Server.Execute(ChartHttpHandlerName + "?" + handlerCheckQry + "=0", w); + } + _installed = true; + } + catch (HttpException) + { + if (hardCheck) throw; + } + catch (SecurityException) + { + // under minimal configuration we assume that the hanlder is installed if app settings are present. + _installed = !String.IsNullOrEmpty(WebConfigurationManager.AppSettings[ChartHttpHandlerAppSection]); + } + } + if (_installed || hardCheck) + { + InitializeControllerFile(); + } + _installChecked = true; + } + } + + /// <summary> + /// Initializes the storage settings + /// </summary> + //static ChartHttpHandler() + private static ChartHttpHandlerSettings InitializeParameters() + { + + ChartHttpHandlerSettings result = new ChartHttpHandlerSettings(); + if (HttpContext.Current != null) + { + // Read settings from config; use DefaultConfigSettings in case when setting is not found + string configSettings = WebConfigurationManager.AppSettings[ChartHttpHandlerAppSection]; + if (String.IsNullOrEmpty(configSettings)) + configSettings = DefaultConfigSettings; + + result = new ChartHttpHandlerSettings(configSettings); + } + else + { + result.PrepareDesignTime(); + } + + return result; + } + + private static void ResetControllerStream() + { + if (_controllerFileStream != null) + _controllerFileStream.Dispose(); + _controllerFileStream = null; + _controllerDirectory = null; + } + + private static void InitializeControllerFile() + { + if (Settings.StorageType == ChartHttpHandlerStorageType.File && _controllerFileStream == null) + { + byte[] data = System.Text.Encoding.UTF8.GetBytes("chart io controller file"); + // 2048 processes max. + for (Int32 i = 0; i < 2048; i++) + { + try + { + ResetControllerStream(); + string controllerFileName = String.Format(CultureInfo.InvariantCulture, "{0}msc_cntr_{1}.txt", Settings.Directory, i); + _controllerDirectory = String.Format(CultureInfo.InvariantCulture, "charts_{0}", i); + _controllerFileStream = new System.IO.FileStream(controllerFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); + _controllerFileStream.Lock(0, data.Length); + _controllerFileStream.Write(data, 0, data.Length); + _machineHash = "_" + i + "_"; + if (!Directory.Exists(Settings.Directory + _controllerDirectory)) + { + Directory.CreateDirectory(Settings.Directory + _controllerDirectory); + } + else + { + TimeSpan lastWrite = DateTime.Now - Directory.GetLastWriteTime(Settings.Directory + _controllerDirectory); + if (lastWrite.Seconds < Settings.Timeout.Seconds) + { + continue; + } + } + return; + } + catch (IOException) + { + continue; + } + catch (Exception) + { + ResetControllerStream(); + throw; + } + } + ResetControllerStream(); + throw new UnauthorizedAccessException(SR.ExceptionHttpHandlerTempDirectoryUnaccesible(Settings.Directory)); + } + } + + #endregion //Constructors + + #region Methods + + #region ChartImage + + /// <summary> + /// Processes the saved image. + /// </summary> + /// <param name="context">The context.</param> + /// <returns>false if the image cannot be processed</returns> + private static bool ProcessSavedChartImage(HttpContext context) + { + // image delivery doesn't depend if handler is intitilzed or not. + String key = context.Request["i"]; + CurrentGuidKey = context.Request["g"]; + IChartStorageHandler handler = GetHandler(); + try + { + Byte[] data = handler.Load(KeyToUnc(key)); + if (data != null && data.Length > 0) + { + context.Response.Charset = ""; + context.Response.ContentType = GetMime(key); + context.Response.BinaryWrite(data); + Diagnostics.TraceWrite(SR.DiagnosticChartImageServed(key), null); + if (Settings.StorageType == ChartHttpHandlerStorageType.Session || Settings.DeleteAfterServicing) + { + handler.Delete(key); + Diagnostics.TraceWrite(SR.DiagnosticChartImageDeleted(key), null); + } + return true; + } + if (!(handler is DefaultImageHandler)) + { + // the default handler will write more detailed message + Diagnostics.TraceWrite(SR.DiagnosticChartImageServedFail(key, SR.DiagnosticChartImageServedFailNotFound), null); + } + } + catch (NullReferenceException nre) + { + Diagnostics.TraceWrite(SR.DiagnosticChartImageServedFail(key, String.Empty), nre); + throw; + } + catch (IOException ioe) + { + Diagnostics.TraceWrite(SR.DiagnosticChartImageServedFail(key, String.Empty), ioe); + throw; + } + catch (SecurityException se) + { + Diagnostics.TraceWrite(SR.DiagnosticChartImageServedFail(key, String.Empty), se); + throw; + } + return false; + } + + #endregion //ChartImage + + #region Utilities + + + /// <summary> + /// Gets or sets the current GUID key. + /// </summary> + /// <value>The current GUID key.</value> + internal static string CurrentGuidKey + { + get + { + if (HttpContext.Current != null) + { + return (string)HttpContext.Current.Items[ContextGuidKey]; + } + return String.Empty; + } + set + { + if (HttpContext.Current != null) + { + if (String.IsNullOrEmpty(value)) + { + HttpContext.Current.Items.Remove(ContextGuidKey); + } + else + { + HttpContext.Current.Items[ContextGuidKey] = value; + } + } + } + } + + /// <summary> + /// Gets the chart image handler interface reference. + /// </summary> + /// <returns></returns> + private static IChartStorageHandler GetHandler() + { + return ChartHttpHandler.Settings.GetHandler(); + } + + /// <summary> + /// Determines whether this instance is installed. + /// </summary> + internal static void EnsureInstalled() + { + EnsureInitialized(true); + EnsureSessionIsClean(); + } + + /// <summary> + /// Gets the handler URL. + /// </summary> + /// <returns></returns> + private static String GetHandlerUrl() + { + // the handler have to be executed in current cxecution path in order to get proper user identity + String appDir = Path.GetDirectoryName(HttpContext.Current.Request.CurrentExecutionFilePath ?? "").Replace("\\","/"); + if (!appDir.EndsWith("/", StringComparison.Ordinal)) + { + appDir += "/"; + } + return appDir + ChartHttpHandlerName + "?"; + } + + + /// <summary> + /// Gets the MIME type by resource url. + /// </summary> + /// <param name="resourceUrl">The resource URL.</param> + /// <returns></returns> + [SuppressMessage("Microsoft.Globalization", "CA1308", + Justification = "No security decision is being made on the ToLowerInvariant() call. It is being used to ensure the file extension is lowercase")] + private static String GetMime(String resourceUrl) + { + String ext = Path.GetExtension(resourceUrl); + + ext = ext.ToLowerInvariant(); + + if (ext == ".js") + { + return "text/javascript"; + } + else if (ext == ".htm") + { + return "text/html"; + } + else if (".css,.html,.xml".IndexOf(ext, StringComparison.Ordinal) != -1) + { + return "text/" + ext.Substring(1); + } + else if (".jpg;.jpeg;.gif;.png;.emf".IndexOf(ext, StringComparison.Ordinal) != -1) + { + string fmt = ext.Substring(1).Replace("jpg", "jpeg"); + return "image/" + fmt; + } + return "text/plain"; + } + + /// <summary> + /// Generates the chart image file name (key). + /// </summary> + /// <param name="ext">The ext.</param> + /// <param name="fileName">Name of the file.</param> + /// <returns></returns> + private static String GenerateKey(String ext) + { + String fmtKey = "chart" + _machineHash + "{0}." + ext; + RingTimeTracker rt = RingTimeTrackerFactory.GetRingTracker(fmtKey); + if (!String.IsNullOrEmpty(_controllerDirectory) && String.IsNullOrEmpty(Settings.FolderName)) + { + return _controllerDirectory + @"\" + rt.GetNextKey(); + } + return Settings.FolderName + rt.GetNextKey(); + } + + private static String KeyToUnc(String key) + { + if (!String.IsNullOrEmpty(key)) + { + return key.Replace("/", @"\"); + } + return key; + } + + private static String KeyFromUnc(String key) + { + if (!String.IsNullOrEmpty(key)) + { + return key.Replace(@"\", "/"); + } + return key; + } + + /// <summary> + /// Gets a URL by specified request query, file key. + /// </summary> + /// <param name="query">The query.</param> + /// <param name="fileKey">The file key.</param> + /// <param name="currentGuid">The current GUID.</param> + /// <returns></returns> + private static String GetUrl(String query, String fileKey, string currentGuid) + { + return GetHandlerUrl() + query + "=" + KeyFromUnc(fileKey) + "&g=" + currentGuid; + } + + /// <summary> + /// Gets the image url. + /// </summary> + /// <param name="stream">The stream.</param> + /// <param name="imageExt">The image extention.</param> + /// <returns>Generated the image source URL</returns> + [SuppressMessage("Microsoft.Globalization", "CA1308", + Justification="No security decision is being made on the ToLowerInvariant() call. It is being used to ensure the file extension is lowercase")] + internal static String GetChartImageUrl(MemoryStream stream, String imageExt) + { + EnsureInitialized(true); + // generates new guid + string guidKey = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); + // set new guid in context + CurrentGuidKey = guidKey; + + Int32 tryCounts = 10; + while (tryCounts > 0) + { + tryCounts--; + try + { + String key = GenerateKey(imageExt.ToLowerInvariant()); + IChartStorageHandler handler = Settings.GetHandler(); + handler.Save(key, stream.ToArray()); + if (!(handler is DefaultImageHandler)) + { + Diagnostics.TraceWrite(SR.DiagnosticChartImageSaved(key), null); + } + Settings.FolderName = String.Empty; + // clear guid so is not accessable out of the scope; + CurrentGuidKey = String.Empty; + return ChartHttpHandler.GetUrl("i", key, guidKey); + } + catch (IOException) { } + catch { throw;} + } + throw new IOException(SR.ExceptionHttpHandlerCanNotSave); + } + + /// <summary> + /// Ensures the session is clean. + /// </summary> + private static void EnsureSessionIsClean() + { + if (!_installed) return; + if (Settings.StorageType == ChartHttpHandlerStorageType.Session) + { + IChartStorageHandler handler = ChartHttpHandler.Settings.GetHandler(); + foreach (RingTimeTracker tracker in RingTimeTrackerFactory.OpenedRingTimeTrackers()) + { + tracker.ForEach(true, delegate(RingItem item) + { + if (item.InUse && String.CompareOrdinal(Settings.ReadSessionKey(), item.SessionID) == 0) + { + handler.Delete(tracker.GetKey(item)); + Diagnostics.TraceWrite(SR.DiagnosticChartImageDeleted(tracker.GetKey(item)), null); + item.InUse = false; + } + } + ); + } + } + } + #endregion //Utilities + + #region Diagnostics + + private static void DiagnosticWriteAll(HttpContext context) + { + HtmlTextWriter writer; + using (TextWriter w = new StringWriter(CultureInfo.CurrentCulture)) + { + + if (context.Request.Browser != null) + writer = context.Request.Browser.CreateHtmlTextWriter(w); + else + writer = new Html32TextWriter(w); + writer.Write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n\r<html xmlns=\"http://www.w3.org/1999/xhtml\" >\n\r"); + writer.Write("<head>\r\n"); + writer.Write("<style type=\"text/css\">\r\n body, span, table, td, th, div, caption {font-family: Tahoma, Arial, Helvetica, sans-serif;font-size: 10pt;} caption {background-color:Black; color: White; font-weight:bold; padding: 4px; text-align:left; } \r\n</style>\r\n"); + writer.Write("</head>\r\n<body style=\"width:978px\">\r\n"); + writer.Write("<h2>" + SR.DiagnosticHeader + "</h2>\r\n<hr/><br/>\n\r"); + DiagnosticWriteSettings(writer); + writer.Write("<hr/>"); + DiagnosticWriteActivity(writer); + writer.Write("<br/><hr/>\n\r<span>"); + try + { + writer.Write(typeof(Chart).AssemblyQualifiedName); + } + catch ( SecurityException ) {} + writer.Write("</span></body>\r\n</html>\r\n"); + context.Response.Write(w.ToString()); + } + } + + private static void DiagnosticWriteSettings(HtmlTextWriter writer) + { + writer.Write("<h4>" + SR.DiagnosticSettingsConfig(WebConfigurationManager.AppSettings[ChartHttpHandlerAppSection]) + "</h4>"); + GridView grid = CreateGridView( true); + grid.Caption = SR.DiagnosticSettingsHeader; + BoundField field = new BoundField(); + field.DataField = "Key"; + field.HeaderText = SR.DiagnosticSettingsKey; + field.HeaderStyle.HorizontalAlign = HorizontalAlign.Left; + grid.Columns.Add(field); + + field = new BoundField(); + field.DataField = "Value"; + field.HeaderText = SR.DiagnosticSettingsValue; + field.HeaderStyle.HorizontalAlign = HorizontalAlign.Left; + + grid.Columns.Add(field); + Dictionary<String, String> settings = new Dictionary<String, String>(); + + settings.Add("StorageType", Settings.StorageType.ToString()); + settings.Add("TimeOut", Settings.Timeout.ToString()); + if (Settings.StorageType == ChartHttpHandlerStorageType.File) + { + settings.Add("Directory", Settings.Directory); + } + settings.Add("DeleteAfterServicing", Settings.DeleteAfterServicing.ToString()); + settings.Add("PrivateImages", Settings.PrivateImages.ToString()); + settings.Add("ImageOwnerKey", Settings.ImageOwnerKey.ToString()); + settings.Add("CustomHandlerName", Settings.CustomHandlerName); + settings.Add(ChartHttpHandler.WebDevServerUseConfigSettings, String.Equals(Settings[ChartHttpHandler.WebDevServerUseConfigSettings], "true", StringComparison.OrdinalIgnoreCase).ToString()); + + grid.DataSource = settings; + grid.DataBind(); + + grid.RenderControl(writer); + + } + + private static void DiagnosticWriteActivity(HtmlTextWriter writer) + { + GridView grid = CreateGridView( true); + grid.Caption = SR.DiagnosticActivityHeader; + BoundField field = new BoundField(); + field.DataField = "DateStamp"; + field.ItemStyle.VerticalAlign = VerticalAlign.Top; + field.HeaderText = SR.DiagnosticActivityTime; + field.HeaderStyle.HorizontalAlign = HorizontalAlign.Left; + field.HeaderStyle.Width = 150; + grid.Columns.Add(field); + + field = new BoundField(); + field.DataField = "Url"; + field.HeaderText = SR.DiagnosticActivityMessage; + field.HeaderStyle.HorizontalAlign = HorizontalAlign.Left; + + grid.Columns.Add(field); + + grid.RowDataBound += new GridViewRowEventHandler(DiagnosticActivityGrid_RowDataBound); + + grid.DataSource = Diagnostics.Messages; + grid.DataBind(); + grid.RenderControl(writer); + + } + + static void DiagnosticActivityGrid_RowDataBound(object sender, GridViewRowEventArgs e) + { + if (e.Row.RowType == DataControlRowType.DataRow) + { + Diagnostics.HandlerPageTraceInfo currentInfo = (Diagnostics.HandlerPageTraceInfo)e.Row.DataItem; + TableCell cell = e.Row.Cells[1]; + + cell.Controls.Add(new Label() { Text = currentInfo.Verb + "," + currentInfo.Url }); + + GridView grid = CreateGridView(false); + grid.Style[HtmlTextWriterStyle.MarginLeft] = "20px"; + + grid.ShowHeader = false; + + BoundField field = new BoundField(); + field.DataField = "Text"; + field.HeaderStyle.HorizontalAlign = HorizontalAlign.Left; + grid.Columns.Add(field); + + grid.DataSource = currentInfo.Events; + grid.DataBind(); + cell.Controls.Add(grid); + } + } + + private static GridView CreateGridView(bool withAlternateStyle) + { + GridView result = new GridView(); + + result.AutoGenerateColumns = false; + result.CellPadding = 4; + result.Font.Names = new string[] { "Tahoma", "Ariel" }; + result.Font.Size = new FontUnit(10, UnitType.Point); + result.BorderWidth = 0; + result.GridLines = GridLines.None; + result.Width = new Unit(100, UnitType.Percentage); + + if (withAlternateStyle) + { + result.AlternatingRowStyle.BackColor = Color.White; + result.RowStyle.BackColor = ColorTranslator.FromHtml("#efefef"); + result.RowStyle.ForeColor = Color.Black; + result.AlternatingRowStyle.ForeColor = Color.Black; + } + + result.HeaderStyle.BackColor = Color.Gray; + result.HeaderStyle.ForeColor = Color.White; + result.HeaderStyle.Font.Bold = true; + return result; + } + + #endregion //Diagnostics + + #endregion //Methods + + #region Properties + + /// <summary> + /// Gets the chart image storage settings registred in web.config file under ChartHttpHandler key. + /// </summary> + /// <value>The settings.</value> + public static ChartHttpHandlerSettings Settings + { + get + { + if (_parameters == null) + { + _parameters = InitializeParameters(); + } + return _parameters; + } + } + + #endregion //Properties + + #region IHttpHandler Members + + /// <summary> + /// Gets a value indicating whether the <see cref="T:System.Web.UI.Page"/> object can be reused. + /// </summary> + /// <value></value> + /// <returns>false in all cases. </returns> + bool IHttpHandler.IsReusable + { + get { return true; } + } + + /// <summary> + /// Enables processing of HTTP Web requests by a custom HttpHandler that implements the <see cref="T:System.Web.IHttpHandler"></see> interface. + /// </summary> + /// <param name="context">An <see cref="T:System.Web.HttpContext"></see> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.</param> + void IHttpHandler.ProcessRequest(HttpContext context) + { + if (context.Request["i"] != null && ProcessSavedChartImage(context)) + { + return; + } + else if (context.Request["trace"] != null && Diagnostics.IsTraceEnabled) + { + DiagnosticWriteAll(context); + return; + } + else if (context.Request[handlerCheckQry] != null) + { + // handler execute test - returns no errors. + return; + } + context.Response.StatusCode = 404; + context.Response.StatusDescription = SR.ExceptionHttpHandlerImageNotFound; + } + + #endregion + + } + + #region Enumerations + + /// <summary> + /// Determines chart image storage medium + /// </summary> + public enum ChartHttpHandlerStorageType + { + /// <summary> + /// Static into application memory + /// </summary> + InProcess, + + /// <summary> + /// File system + /// </summary> + File, + /// <summary> + /// Using session as storage + /// </summary> + Session + + } + /// <summary> + /// Determines the image owner key for privacy protection. + /// </summary> + internal enum ImageOwnerKeyType + { + /// <summary> + /// No privacy protection. + /// </summary> + None, + /// <summary> + /// The key will be automatically determined. + /// </summary> + Auto, + /// <summary> + /// The user name will be used as key. + /// </summary> + UserID, + /// <summary> + /// The AnonymousID will be used as key. + /// </summary> + AnonymousID, + /// <summary> + /// The SessionID will be used as key. + /// </summary> + SessionID + } + + #endregion + + #region IChartStorageHandler interface + + /// <summary> + /// Defines methods to manage rendered chart images in a storage. + /// </summary> + public interface IChartStorageHandler + { + /// <summary> + /// Saves the data into external medium. + /// </summary> + /// <param name="key">Index key.</param> + /// <param name="data">Image data.</param> + void Save(String key, Byte[] data); + + + /// <summary> + /// Loads the data from external medium. + /// </summary> + /// <param name="key">Index key.</param> + /// <returns>A byte array with image data</returns> + Byte[] Load(String key); + + + /// <summary> + /// Deletes the data from external medium. + /// </summary> + /// <param name="key">Index key.</param> + void Delete(String key); + + /// <summary> + /// Checks for existence of data under specified key. + /// </summary> + /// <param name="key">Index key.</param> + /// <returns>True if data exists under specified key</returns> + bool Exists(String key); + } + + #endregion + + #region ChartHttpHandlerSettings Class + + /// <summary> + /// Enables access to the chart image storage settings. + /// </summary> +#if ASPPERM_35 + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] + [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] +#endif + public class ChartHttpHandlerSettings + { + #region Fields + + private StorageSettingsCollection _ssCollection = new StorageSettingsCollection(); + + private string _sesionKey = "chartKey-" + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); + + #endregion //Fields + + #region Properties + + private ChartHttpHandlerStorageType _chartImageStorage = ChartHttpHandlerStorageType.File; + + /// <summary> + /// Gets or sets the chart image storage type. + /// </summary> + /// <value>The chart image storage.</value> + public ChartHttpHandlerStorageType StorageType + { + get { return _chartImageStorage; } + set { _chartImageStorage = value; } + } + + private TimeSpan _timeout = TimeSpan.FromSeconds(30); + + /// <summary> + /// Gets or sets the timeout. + /// </summary> + /// <value>The timeout.</value> + public TimeSpan Timeout + { + get { return _timeout; } + set { _timeout = value; } + } + + private String _url = "~/"; + /// <summary> + /// Gets or sets the URL. + /// </summary> + /// <value>The URL.</value> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")] + public String Url + { + get { return _url; } + set { _url = value; } + } + + private String _directory = String.Empty; + /// <summary> + /// Gets or sets the directory. + /// </summary> + /// <value>The directory.</value> + public String Directory + { + get { return _directory; } + set { _directory = value; } + } + + private const String _folderKeyName = "{5FF3B636-70BA-4180-B7C5-FDD77D8FA525}"; + /// <summary> + /// Gets or sets the folder which will be used for storing images under <see cref="Directory"/>. + /// </summary> + /// <value>The folder name.</value> + public String FolderName + { + get + { + if (HttpContext.Current != null && HttpContext.Current.Items.Contains(_folderKeyName)) + { + return (string)HttpContext.Current.Items[_folderKeyName]; + } + return String.Empty; + } + set + { + if (!String.IsNullOrEmpty(value)) + { + if (!(value.EndsWith("/", StringComparison.Ordinal) || value.EndsWith("\\", StringComparison.Ordinal))) + { + value += "\\"; + } + this.ValidateUri(value); + } + if (HttpContext.Current != null) + { + HttpContext.Current.Items[_folderKeyName] = value; + } + } + } + + internal void ValidateUri(string key) + { + if (this.StorageType == ChartHttpHandlerStorageType.File) + { + FileInfo fi = new FileInfo(this.Directory + key); + Uri directory = new Uri(this.Directory); + Uri combinedDirectory = new Uri(fi.FullName); + if (directory.IsBaseOf(combinedDirectory)) + { + // it is fine. + return; + } + throw new UnauthorizedAccessException(SR.ExceptionHttpHandlerInvalidLocation); + } + } + + private String _customHandlerName = typeof(DefaultImageHandler).FullName; + /// <summary> + /// Gets or sets the name of the custom handler. + /// </summary> + /// <value>The name of the custom handler.</value> + public String CustomHandlerName + { + get { return _customHandlerName; } + set { _customHandlerName = value; } + } + + + private Type _customHandlerType = null; + /// <summary> + /// Gets the type of the custom handler. + /// </summary> + /// <value>The type of the custom handler.</value> + public Type HandlerType + { + get + { + if (this._customHandlerType == null) + { + this._customHandlerType = Type.GetType(this.CustomHandlerName, true); + } + return this._customHandlerType; + } + } + + /// <summary> + /// Gets a value indicating whether the handler will utilize private images. + /// </summary> + /// <value><c>true</c> if the handler will utilize private images; otherwise, <c>false</c>.</value> + /// <remarks> + /// When PrivateImages is set the handler will not return images out of session scope and + /// the client will not be able to download somebody else's images. This is default behavoiur. + /// </remarks> + public bool PrivateImages + { + get + { + return ImageOwnerKey != ImageOwnerKeyType.None; + } + } + + + + /// <summary> + /// Gets a settings parameter with the specified name registred in web.config file under ChartHttpHandler key. + /// </summary> + /// <value></value> + public string this[string name] + { + get + { + return this._ssCollection[name]; + } + } + + #endregion //Properties + + #region Constructors + /// <summary> + /// Initializes a new instance of the <see cref="T:StorageSettings"/> class. + /// </summary> + internal ChartHttpHandlerSettings() + { + ImageOwnerKey = ImageOwnerKeyType.Auto; + } + + /// <summary> + /// Initializes a new instance of the <see cref="T:ChartHttpHandlerParameters"/> class. + /// </summary> + /// <param name="parameters">The parameters.</param> + internal ChartHttpHandlerSettings(String parameters) : this() + { + this.ParseParams(parameters); + this._ssCollection.SetReadOnly(true); + } + + #endregion //Constructors + + #region Methods + + private ConstructorInfo _handlerConstructor = null; + IChartStorageHandler _storageHandler = null; + /// <summary> + /// Creates the handler instance. + /// </summary> + /// <returns></returns> + internal IChartStorageHandler GetHandler() + { + if (_storageHandler == null) + { + if (this._handlerConstructor == null) + { + this.InspectHandlerLoader(); + } + _storageHandler = this._handlerConstructor.Invoke(new object[0]) as IChartStorageHandler; + } + return _storageHandler; + } + + /// <summary> + /// Inspects the handler if it is valid. + /// </summary> + private void InspectHandlerLoader() + { + this._handlerConstructor = this.HandlerType.GetConstructor( + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, + null, + new Type[0], + new ParameterModifier[0]); + if (this._handlerConstructor == null) + { + throw new InvalidOperationException( SR.ExceptionHttpHandlerCanNotLoadType( this.HandlerType.FullName )); + } + if (this.GetHandler() == null) + { + throw new InvalidOperationException(SR.ExceptionHttpHandlerImageHandlerInterfaceUnsupported(ChartHttpHandler.Settings.HandlerType.FullName)); + } + } + + /// <summary> + /// Parses the params from web.config file key. + /// </summary> + /// <param name="parameters">The parameters.</param> + private void ParseParams(String parameters) + { + if (!String.IsNullOrEmpty(parameters)) + { + + String[] pairs = parameters.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); + for (int index = 0; index < pairs.Length; index++) + { + String item = pairs[index].Trim(); + int eqPositon = item.IndexOf('='); + if (eqPositon != -1) + { + String name = item.Substring(0, eqPositon).Trim(); + String value = item.Substring(eqPositon + 1).Trim(); + this._ssCollection.Add(name, value); + if (name.StartsWith("stor", StringComparison.OrdinalIgnoreCase)) + { + if (value.StartsWith("inproc", StringComparison.OrdinalIgnoreCase) || value.StartsWith("memory", StringComparison.OrdinalIgnoreCase)) + { + this.StorageType = ChartHttpHandlerStorageType.InProcess; + } + else if (value.StartsWith("file", StringComparison.OrdinalIgnoreCase)) + { + this.StorageType = ChartHttpHandlerStorageType.File; + } + else if (value.StartsWith("session", StringComparison.OrdinalIgnoreCase)) + { + this.StorageType = ChartHttpHandlerStorageType.Session; + } + else + { + throw new System.Configuration.SettingsPropertyWrongTypeException(SR.ExceptionHttpHandlerParameterUnknown(name, value)); + } + } + else if (name.StartsWith("url", StringComparison.OrdinalIgnoreCase)) + { + if (!value.EndsWith("/", StringComparison.Ordinal)) + { + value += "/"; + } + this.Url = value; + } + else if (name.StartsWith("dir", StringComparison.OrdinalIgnoreCase)) + { + this.Directory = value; + } + else if (name.StartsWith("time", StringComparison.OrdinalIgnoreCase)) + { + try + { + int seconds = Int32.Parse(value, CultureInfo.InvariantCulture); + if (seconds < -1) + { + throw new System.Configuration.SettingsPropertyWrongTypeException(SR.ExceptionHttpHandlerValueInvalid); + } + if (seconds == -1) + { + this.Timeout = TimeSpan.MaxValue; + } + else + { + this.Timeout = TimeSpan.FromSeconds(seconds); + } + } + catch (Exception exception) + { + throw new System.Configuration.SettingsPropertyWrongTypeException(SR.ExceptionHttpHandlerTimeoutParameterInvalid, exception); + } + } + else if (name.StartsWith("handler", StringComparison.OrdinalIgnoreCase)) + { + this.CustomHandlerName = value; + } + else if (name.StartsWith("privateImages", StringComparison.OrdinalIgnoreCase)) + { + bool privateImg = true; + if (Boolean.TryParse(value, out privateImg) && !privateImg) + { + ImageOwnerKey = ImageOwnerKeyType.None; + } + } + else if (name.StartsWith("imageOwnerKey", StringComparison.OrdinalIgnoreCase)) + { + try + { + ImageOwnerKey = (ImageOwnerKeyType)Enum.Parse(typeof(ImageOwnerKeyType), value, true); + } + catch (ArgumentException) + { + throw new System.Configuration.SettingsPropertyWrongTypeException(SR.ExceptionHttpHandlerParameterInvalid(name, value)); + } + } + + } + } + } + this.Inspect(); + } + + /// <summary> + /// Determines whether web dev server is active. + /// </summary> + /// <returns> + /// <c>true</c> if web dev server active; otherwise, <c>false</c>. + /// </returns> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "GetCurrentProcess will fail if there is no access. This is by design. ")] + // VSTS: 5176 Security annotation violations in System.Web.DataVisualization.dll + [SecuritySafeCritical] + private static bool IsWebDevActive() + { + try + { + Process process = Process.GetCurrentProcess(); + if (process.ProcessName.StartsWith("WebDev.WebServer", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + if (process.ProcessName.StartsWith("ii----press", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + catch (SecurityException) + { + } + return false; + } + /// <summary> + /// Inspects and validates this instance after loading params. + /// </summary> + internal void Inspect() + { + switch (this.StorageType) + { + case ChartHttpHandlerStorageType.InProcess: + + break; + + case ChartHttpHandlerStorageType.File: + + if (IsWebDevActive() && !( String.Compare(this[ChartHttpHandler.WebDevServerUseConfigSettings], "true", StringComparison.OrdinalIgnoreCase) == 0)) + { + this.StorageType = ChartHttpHandlerStorageType.InProcess; + break; + } + + if (String.IsNullOrEmpty(this.Url)) + { + throw new ArgumentException(SR.ExceptionHttpHandlerUrlMissing); + } + + String fileDirectory = this.Directory; + if (String.IsNullOrEmpty(fileDirectory)) + { + try + { + fileDirectory = HttpContext.Current.Server.MapPath(this.Url); + } + catch (Exception exception) + { + throw new InvalidOperationException(SR.ExceptionHttpHandlerUrlInvalid, exception); + } + } + fileDirectory = fileDirectory.Replace("/", "\\"); + if (!fileDirectory.EndsWith("\\", StringComparison.Ordinal)) + { + fileDirectory += "\\"; + } + + if (!System.IO.Directory.Exists(fileDirectory)) + { + throw new DirectoryNotFoundException(SR.ExceptionHttpHandlerTempDirectoryInvalid(fileDirectory)); + } + Exception thrown = null; + try + { + String testFileName = fileDirectory + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); + using (FileStream fileStream = File.Create(testFileName)) { } + File.Delete(testFileName); + + } + catch (DirectoryNotFoundException exception) + { + thrown = exception; + } + catch (NotSupportedException exception) + { + thrown = exception; + } + catch (PathTooLongException exception) + { + thrown = exception; + } + catch (UnauthorizedAccessException exception) + { + thrown = exception; + } + + if (thrown != null) + { + throw new UnauthorizedAccessException(SR.ExceptionHttpHandlerTempDirectoryUnaccesible(fileDirectory)); + } + + this.Directory = fileDirectory; + break; + + + } + if (!String.IsNullOrEmpty(this.CustomHandlerName)) + { + this.InspectHandlerLoader(); + } + } + + /// <summary> + /// Prepares the design time params. + /// </summary> + internal void PrepareDesignTime() + { + this.StorageType = ChartHttpHandlerStorageType.File; + this.Timeout = TimeSpan.FromSeconds(3); ; + this.Url = Path.GetTempPath(); + this.Directory = Path.GetTempPath(); + } + + internal string ReadSessionKey() + { + if (HttpContext.Current.Session != null) + { + // initialize session (if is empty any postsequent request will have different id); + if (HttpContext.Current.Session.IsNewSession) + { + if (HttpContext.Current.Session.IsReadOnly) + { + return string.Empty; + } + HttpContext.Current.Session[this._sesionKey] = 0; + } + return HttpContext.Current.Session.SessionID; + } + return String.Empty; + } + + internal string GetPrivacyKey( out ImageOwnerKeyType keyType ) + { + if (ImageOwnerKey == ImageOwnerKeyType.None) + { + keyType = ImageOwnerKeyType.None; + return String.Empty; + } + if (HttpContext.Current != null) + { + switch (ImageOwnerKey) + { + case ImageOwnerKeyType.Auto: + if (HttpContext.Current.User.Identity.IsAuthenticated) + { + keyType = ImageOwnerKeyType.UserID; + return HttpContext.Current.User.Identity.Name; + } + if (!String.IsNullOrEmpty(HttpContext.Current.Request.AnonymousID)) + { + keyType = ImageOwnerKeyType.AnonymousID; + return HttpContext.Current.Request.AnonymousID; + } + string sessionId = ReadSessionKey(); + keyType = String.IsNullOrEmpty(sessionId) ? ImageOwnerKeyType.None : ImageOwnerKeyType.SessionID; + return sessionId; + + case ImageOwnerKeyType.UserID: + if (!HttpContext.Current.User.Identity.IsAuthenticated) + { + throw new InvalidOperationException(SR.ExceptionHttpHandlerPrivacyKeyInvalid("ImageOwnerKey", ImageOwnerKey.ToString())); + } + keyType = ImageOwnerKeyType.UserID; + return HttpContext.Current.User.Identity.Name; + + case ImageOwnerKeyType.AnonymousID: + if (String.IsNullOrEmpty(HttpContext.Current.Request.AnonymousID)) + { + throw new InvalidOperationException(SR.ExceptionHttpHandlerPrivacyKeyInvalid("ImageOwnerKey", ImageOwnerKey.ToString())); + } + keyType = ImageOwnerKeyType.AnonymousID; + return HttpContext.Current.Request.AnonymousID; + + case ImageOwnerKeyType.SessionID: + if (HttpContext.Current.Session == null) + { + throw new InvalidOperationException(SR.ExceptionHttpHandlerPrivacyKeyInvalid("ImageOwnerKey", ImageOwnerKey.ToString())); + } + keyType = ImageOwnerKeyType.SessionID; + return ReadSessionKey(); + + default: + Debug.Fail("Unknown ImageOwnerKeyType."); + break; + } + } + keyType = ImageOwnerKeyType.None; + return string.Empty; + } + + internal string PrivacyKey + { + get + { + ImageOwnerKeyType keyType; + return GetPrivacyKey(out keyType); + } + } + + internal bool DeleteAfterServicing + { + get + { + // default, if is missing in config, is true. + return !(String.Compare(this["DeleteAfterServicing"], "false", StringComparison.OrdinalIgnoreCase) == 0); + } + } + + /// <summary> + /// Gets or sets the image owner key type. + /// </summary> + /// <value>The image owner key.</value> + internal ImageOwnerKeyType ImageOwnerKey { get; set; } + + #endregion //Methods + + #region SettingsCollection Class + + private class StorageSettingsCollection : NameValueCollection + { + public StorageSettingsCollection() + : base(StringComparer.OrdinalIgnoreCase) + { + } + internal void SetReadOnly(bool flag) + { + this.IsReadOnly = flag; + } + } + + #endregion //SettingsCollection Class + } + + #endregion ChartHttpHandlerParameters + + #region DefaultImageHandler Class + + /// <summary> + /// Default implementation of ChartHttpHandler.IImageHandler interface + /// </summary> + internal class DefaultImageHandler : IChartStorageHandler + { + + #region Fields + // Hashtable for storage + private static Hashtable _storageData = new Hashtable(); + // lock object + private static ReaderWriterLock _rwl = new ReaderWriterLock(); + // max access timeout + private const int accessTimeout = 10000; + + static string _privacyKeyName = "_pk"; + static byte[] _privacyMarker = (new Guid("332E3AB032904bceA82B249C25E65CB6")).ToByteArray(); + static string _sessionKeyPrefix = "chart-3ece47b3-9481-4b22-ab45-ab669972eb79"; + + #endregion //Fields + + #region Constructors + + /// <summary> + /// Initializes a new instance of the <see cref="T:DefaultImageHandler"/> class. + /// </summary> + internal DefaultImageHandler() + { + } + #endregion //Constructors + + #region Members + /// <summary> + /// Nots the type of the supported storage. + /// </summary> + /// <param name="settings">The settings.</param> + private void NotSupportedStorageType(ChartHttpHandlerSettings settings) + { + throw new NotSupportedException( SR.ExceptionHttpHandlerStorageTypeUnsupported( settings.StorageType.ToString() )); + } + + #endregion //Members + + #region Methods + + /// <summary> + /// Returns privacy hash which will be save in the file. + /// </summary> + /// <returns>A byte array of hash data</returns> + private static byte[] GetHashData() + { + string currentGuid = ChartHttpHandler.CurrentGuidKey; + string sessionID = ChartHttpHandler.Settings.PrivacyKey; + + if (String.IsNullOrEmpty(sessionID)) + { + return new byte[0]; + } + + byte[] data = Encoding.UTF8.GetBytes(sessionID + "/" + currentGuid); + + using (SHA1 sha = new SHA1CryptoServiceProvider()) + { + return sha.ComputeHash(data); + } + + } + + private static bool CompareBytes(byte[] a, byte[] b) + { + if (a.Length != b.Length) return false; + for (int i = 0; i < a.Length; i++) + { + if (a[i] != b[i]) return false; + } + return true; + } + + private static string GetSessionImageKey(string key) + { + // all session variables starts with _sessionKeyPrefix to avoid direct access to session by passing image key in Url query. + return _sessionKeyPrefix + key; + } + + #endregion //Methods + + #region ImageHandler Members + + /// <summary> + /// Stores the data into external medium. + /// </summary> + /// <param name="key">The key.</param> + /// <param name="data">The data.</param> + void IChartStorageHandler.Save(String key, Byte[] data) + { + ChartHttpHandlerSettings settings = ChartHttpHandler.Settings; + ImageOwnerKeyType imageOwnerKeyType = ImageOwnerKeyType.None; + string privacyKey = settings.GetPrivacyKey(out imageOwnerKeyType); + if (settings.StorageType == ChartHttpHandlerStorageType.InProcess) + { + _rwl.AcquireWriterLock(accessTimeout); + try + { + _storageData[key] = data; + if (settings.PrivateImages && !String.IsNullOrEmpty(privacyKey)) + { + _storageData[key + _privacyKeyName] = privacyKey; + Diagnostics.TraceWrite( SR.DiagnosticChartImageSavedPrivate(key, imageOwnerKeyType.ToString()), null); + } + else + Diagnostics.TraceWrite(SR.DiagnosticChartImageSaved(key), null); + } + finally + { + _rwl.ReleaseWriterLock(); + } + } + else if (settings.StorageType == ChartHttpHandlerStorageType.File) + { + using (FileStream stream = File.Create(settings.Directory + key)) + { + stream.Write(data, 0, data.Length); + if (settings.PrivateImages && !String.IsNullOrEmpty(privacyKey)) + { + byte[] privacyData = GetHashData(); + stream.Write(privacyData, 0, privacyData.Length); + // we will put a marker at the end of the file; + stream.Write(_privacyMarker, 0, _privacyMarker.Length); + Diagnostics.TraceWrite(SR.DiagnosticChartImageSavedPrivate(key, imageOwnerKeyType.ToString()), null); + } + else + Diagnostics.TraceWrite(SR.DiagnosticChartImageSaved(key), null); + } + } + else if (settings.StorageType == ChartHttpHandlerStorageType.Session) + { + HttpContext.Current.Session[GetSessionImageKey(key)] = data; + Diagnostics.TraceWrite(SR.DiagnosticChartImageSaved(key), null); + } + else this.NotSupportedStorageType(settings); + } + + + /// <summary> + /// Retrieves the data from external medium. + /// </summary> + /// <param name="key">The key.</param> + Byte[] IChartStorageHandler.Load( String key) + { + ChartHttpHandlerSettings settings = ChartHttpHandler.Settings; + ImageOwnerKeyType imageOwnerKeyType = ImageOwnerKeyType.None; + string privacyKey = settings.GetPrivacyKey(out imageOwnerKeyType); + Byte[] data = new Byte[0]; + if (settings.StorageType == ChartHttpHandlerStorageType.InProcess) + { + _rwl.AcquireReaderLock(accessTimeout); + try + { + if (settings.PrivateImages) + { + if (!String.IsNullOrEmpty(privacyKey)) + { + if (!String.Equals((string)_storageData[key + _privacyKeyName], privacyKey, StringComparison.Ordinal)) + { + Diagnostics.TraceWrite(SR.DiagnosticChartImageServedFail(key, SR.DiagnosticChartImageServedFailPrivacyFail(imageOwnerKeyType.ToString())), null); + return data; + } + } + else + { + if (!String.IsNullOrEmpty((string)_storageData[key + _privacyKeyName])) + { + Diagnostics.TraceWrite(SR.DiagnosticChartImageServedFail(key, SR.DiagnosticChartImageServedFailPrivacyFail(imageOwnerKeyType.ToString())), null); + return data; + } + } + } + data = (Byte[])_storageData[key]; + if (data == null) + { + Diagnostics.TraceWrite(SR.DiagnosticChartImageServedFail(key, SR.DiagnosticChartImageServedFailNotFound), null); + } + } + finally + { + _rwl.ReleaseReaderLock(); + } + } + else if (settings.StorageType == ChartHttpHandlerStorageType.File) + { + settings.ValidateUri(key); + if (File.Exists(settings.Directory + key)) + { + using (FileStream fileStream = File.OpenRead(settings.Directory + key)) + { + byte[] fileData = new byte[fileStream.Length]; + fileStream.Read(fileData, 0, fileData.Length); + using (MemoryStream stream = new MemoryStream(fileData)) + { + int streamCut = 0; + if (settings.PrivateImages) + { + // read the marker first + byte[] privacyMarkerStream = new Byte[_privacyMarker.Length]; + + streamCut += _privacyMarker.Length; + stream.Seek(stream.Length - streamCut, SeekOrigin.Begin); + stream.Read(privacyMarkerStream, 0, privacyMarkerStream.Length); + + if (!String.IsNullOrEmpty(privacyKey)) + { + byte[] privacyData = GetHashData(); + streamCut += privacyData.Length; + byte[] privacyDataFromStream = new Byte[privacyData.Length]; + stream.Seek(stream.Length - streamCut, SeekOrigin.Begin); + stream.Read(privacyDataFromStream, 0, privacyDataFromStream.Length); + + if (!CompareBytes(privacyDataFromStream, privacyData)) + { + Diagnostics.TraceWrite(SR.DiagnosticChartImageServedFail(key, SR.DiagnosticChartImageServedFailPrivacyFail(imageOwnerKeyType.ToString())), null); + return data; + } + } + else + { + // this image is marked as private - check end return null if fails + if (String.Equals( + Encoding.Unicode.GetString(privacyMarkerStream), + Encoding.Unicode.GetString(_privacyMarker), + StringComparison.Ordinal)) + { + Diagnostics.TraceWrite(SR.DiagnosticChartImageServedFail(key, SR.DiagnosticChartImageServedFailPrivacyFail(imageOwnerKeyType.ToString())), null); + return data; + } + // its fine ( no user is stored ) + streamCut = 0; + } + } + stream.Seek(0, SeekOrigin.Begin); + data = new Byte[(int)stream.Length - streamCut]; + stream.Read(data, 0, (int)data.Length); + } + } + } + else + Diagnostics.TraceWrite(SR.DiagnosticChartImageServedFail(key, SR.DiagnosticChartImageServedFailNotFound), null); + } + else if (settings.StorageType == ChartHttpHandlerStorageType.Session) + { + data = (Byte[])HttpContext.Current.Session[GetSessionImageKey(key)]; + } + else this.NotSupportedStorageType(settings); + return data; + + } + + + /// <summary> + /// Removes the data from external medium. + /// </summary> + /// <param name="key">The key.</param> + void IChartStorageHandler.Delete(String key) + { + ChartHttpHandlerSettings settings = ChartHttpHandler.Settings; + if (settings.StorageType == ChartHttpHandlerStorageType.InProcess) + { + + _rwl.AcquireWriterLock(accessTimeout); + try + { + _storageData.Remove(key); + _storageData.Remove(key + _privacyKeyName); + } + finally + { + _rwl.ReleaseWriterLock(); + } + } + else if (settings.StorageType == ChartHttpHandlerStorageType.File) + { + File.Delete(settings.Directory + key); + } + else if (settings.StorageType == ChartHttpHandlerStorageType.Session) + { + HttpContext.Current.Session.Remove(GetSessionImageKey(key)); + } + else this.NotSupportedStorageType(settings); + } + + /// <summary> + /// Checks for existence the specified key. + /// </summary> + /// <param name="key">The key.</param> + /// <returns></returns> + bool IChartStorageHandler.Exists(String key) + { + ChartHttpHandlerSettings settings = ChartHttpHandler.Settings; + if (settings.StorageType == ChartHttpHandlerStorageType.InProcess) + { + _rwl.AcquireReaderLock(accessTimeout); + try + { + return _storageData.Contains(key); + } + finally + { + _rwl.ReleaseReaderLock(); + } + } + else if (settings.StorageType == ChartHttpHandlerStorageType.File) + { + return File.Exists(settings.Directory + key); + } + else if (settings.StorageType == ChartHttpHandlerStorageType.Session) + { + return HttpContext.Current.Session[GetSessionImageKey(key)] is Byte[]; + } + else this.NotSupportedStorageType(settings); + return false; + } + + #endregion + + } + + #endregion //DefaultImageHandler Class + + #region RingTimeTracker class + + /// <summary> + /// RingItem contains time span of creation timedate and index for key generation. + /// </summary> + internal class RingItem + { + internal Int32 Index; + internal DateTime Created = DateTime.Now; + internal string SessionID = String.Empty; + internal bool InUse; + /// <summary> + /// Initializes a new instance of the <see cref="T:RingItem"/> class. + /// </summary> + /// <param name="index">The index.</param> + internal RingItem( int index) + { + this.Index = index; + } + } + /// <summary> + /// RingTimeTracker is a helper class for generating keys and tracking RingItem. + /// Contains linked list queue and tracks exprired items. + /// </summary> + internal class RingTimeTracker + { + #region Fields + // the item life span + private TimeSpan _itemLifeTime = TimeSpan.FromSeconds(360); + // last requested RingItem + private LinkedListNode<RingItem> _current; + // default key format to format names + private String _keyFormat = String.Empty; + // LinkedList with ring items + private LinkedList<RingItem> _list = new LinkedList<RingItem>(); + // Record session ID + private bool _recordSessionID = false; + + #endregion //Fields + + #region Constructors + + /// <summary> + /// Initializes a new instance of the <see cref="T:RingTimeTracker"/> class. + /// </summary> + /// <param name="itemLifeTime">The item life time.</param> + /// <param name="keyFormat">The key format.</param> + /// <param name="recordSessionID">if set to <c>true</c> the session ID will be recorded.</param> + internal RingTimeTracker(TimeSpan itemLifeTime, String keyFormat, bool recordSessionID) + { + System.Diagnostics.Debug.Assert(!String.IsNullOrEmpty(keyFormat)); + this._itemLifeTime = itemLifeTime; + this._keyFormat = keyFormat; + this._list.AddLast(new RingItem(_list.Count)); + this._current = this._list.First; + this._current.Value.Created = DateTime.Now - this._itemLifeTime - TimeSpan.FromSeconds(1); + this._recordSessionID = recordSessionID; + } + + #endregion //Constructors + + #region Methods + + + + /// <summary> + /// Determines whether the specified item is expired. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="now">The now.</param> + /// <returns> + /// <c>true</c> if the specified item is expired; otherwise, <c>false</c>. + /// </returns> + internal bool IsExpired(RingItem item, DateTime now) + { + TimeSpan elapsed = (now - item.Created); + return elapsed > this._itemLifeTime; + } + + + /// <summary> + /// Gets the next key. + /// </summary> + /// <returns></returns> + internal String GetNextKey() + { + DateTime now = DateTime.Now; + lock (this) + { + if ( !this.IsExpired(this._current.Value, now)) + { + if (this._current.Next == null) + { + if (!this.IsExpired(this._list.First.Value, now)) + { + this._list.AddLast(new RingItem(_list.Count)); + this._current = this._list.Last; + } + else + { + this._current = this._list.First; + } + } + else + { + if (!this.IsExpired(this._current.Next.Value, now)) + { + this._list.AddAfter(this._current, new RingItem(_list.Count)); + } + this._current = this._current.Next; + } + } + this._current.Value.Created = now; + if (this._recordSessionID) + { + this._current.Value.SessionID = ChartHttpHandler.Settings.ReadSessionKey(); + this._current.Value.InUse = true; + } + return this.GetCurrentKey(); + } + } + + /// <summary> + /// Gets the current key. + /// </summary> + /// <returns></returns> + internal String GetCurrentKey() + { + return String.Format( CultureInfo.InvariantCulture, this._keyFormat, this._current.Value.Index); + } + + /// <summary> + /// Gets the key. + /// </summary> + /// <param name="ringItem">The ring item.</param> + /// <returns></returns> + internal String GetKey(RingItem ringItem) + { + return String.Format(CultureInfo.InvariantCulture, this._keyFormat, ringItem.Index); + } + + /// <summary> + /// Do Action for each item. + /// </summary> + /// <param name="onlyExpired">if set to <c>true</c> do action for only expired items.</param> + /// <param name="action">The action.</param> + public void ForEach(bool onlyExpired, Action<RingItem> action) + { + if (action == null) + { + throw new ArgumentNullException("action"); + } + DateTime now = DateTime.Now; + lock (this) + { + foreach (RingItem item in this._list) + { + if (onlyExpired) + { + if (this.IsExpired(item, now)) + { + action(item); + } + } + else + { + action(item); + } + } + } + } + + #endregion //Methods + + } + #endregion //RingTracker class + + #region RingTimeTrackerFactory Class + + /// <summary> + /// RingTimeTrackerFactory contains static list of RingTimeTracker for each key formats + /// </summary> + internal static class RingTimeTrackerFactory + { + + private static ListDictionary _ringTrackers = new ListDictionary(); + private static Object _lockObject = new Object(); + + /// <summary> + /// Gets the ring tracker by specified key format. + /// </summary> + /// <param name="keyFormat">The key format.</param> + /// <returns></returns> + internal static RingTimeTracker GetRingTracker(String keyFormat) + { + if (_ringTrackers.Contains(keyFormat)) + { + return (RingTimeTracker)_ringTrackers[keyFormat]; + } + lock (_lockObject) + { + if (_ringTrackers.Contains(keyFormat)) + { + return (RingTimeTracker)_ringTrackers[keyFormat]; + } + RingTimeTracker result = new RingTimeTracker(ChartHttpHandler.Settings.Timeout, keyFormat,ChartHttpHandler.Settings.StorageType == ChartHttpHandlerStorageType.Session); + _ringTrackers.Add(keyFormat, result); + return result; + } + } + + internal static IList OpenedRingTimeTrackers() + { + lock (_lockObject) + { + return new ArrayList(_ringTrackers.Values); + } + } + + } + + #endregion //RingTimeTrackerFactory Class + + #region Diagnostics class + + /// <summary> + /// Contains helpres methods for diagnostics. + /// </summary> + internal static class Diagnostics + { + /// <summary> + /// Trace category + /// </summary> + const string ChartCategory = "chart.handler"; + /// <summary> + /// Name of context item which contain the current trace item + /// </summary> + const string ContextID = "Trace-{89FA5660-BD13-4f1b-8C7C-355CEC92CC7E}"; + /// <summary> + /// Used for syncronizing. + /// </summary> + static object _lockObject = new object(); + /// <summary> + /// Limit of trace messages in the history. + /// </summary> + const int MessageLimit = 20; + /// <summary> + /// Collection of request messages. + /// </summary> + static List<HandlerPageTraceInfo> _messages = new List<HandlerPageTraceInfo>(MessageLimit); + + /// <summary> + /// Contains request info + /// </summary> + public class HandlerPageTraceInfo + { + /// <summary> + /// Events collection in this request. + /// </summary> + private List<ChartHandlerEvents> _events = new List<ChartHandlerEvents>(); + /// <summary> + /// Initializes a new instance of the <see cref="HandlerPageTraceInfo"/> class. + /// </summary> + public HandlerPageTraceInfo() + { + if (HttpContext.Current != null) + { + DateStamp = DateTime.Now; + if (HttpContext.Current.Request != null) + { + Url = HttpContext.Current.Request.Url.ToString(); + Verb = HttpContext.Current.Request.HttpMethod; + } + } + } + /// <summary> + /// Gets or sets the date stamp. + /// </summary> + /// <value>The date stamp.</value> + public DateTime DateStamp { get; private set; } + /// <summary> + /// Gets or sets the URL. + /// </summary> + /// <value>The URL.</value> + public string Url { get; private set; } + /// <summary> + /// Gets or sets the verb. + /// </summary> + /// <value>The verb.</value> + public string Verb { get; private set; } + /// <summary> + /// Gets the events. + /// </summary> + /// <value>The events.</value> + public IList<ChartHandlerEvents> Events + { + get + { + return _events.AsReadOnly(); + } + } + /// <summary> + /// Adds a trace info item. + /// </summary> + /// <param name="message">The message.</param> + /// <param name="errorInfo">The error info.</param> + internal void AddTraceInfo(string message, string errorInfo) + { + lock (_events) + { + _events.Add(new ChartHandlerEvents() + { + Message = message, + ErrorInfo = errorInfo + } + ); + } + } + } + + /// <summary> + /// Contains an event in particural request. + /// </summary> + public class ChartHandlerEvents + { + /// <summary> + /// Gets or sets the message. + /// </summary> + /// <value>The message.</value> + public string Message { get; set; } + /// <summary> + /// Gets or sets the error info. + /// </summary> + /// <value>The error info.</value> + public string ErrorInfo { get; set; } + /// <summary> + /// Gets the text. + /// </summary> + /// <value>The text.</value> + public string Text { get { return Message + ErrorInfo; } } + } + + /// <summary> + /// Writes message in the trace. + /// </summary> + /// <param name="message">The message.</param> + /// <param name="errorInfo">The error info.</param> + internal static void TraceWrite( string message, Exception errorInfo) + { + if (IsTraceEnabled) + { + HttpContext.Current.Trace.Write(ChartCategory, message, errorInfo); + if (CurrentTraceInfo != null) + { + CurrentTraceInfo.AddTraceInfo(message, errorInfo != null ? errorInfo.ToString() : String.Empty); + } + } + } + + /// <summary> + /// Gets the current trace info. + /// </summary> + /// <value>The current trace info.</value> + private static HandlerPageTraceInfo CurrentTraceInfo + { + get + { + lock (_lockObject) + { + if (HttpContext.Current != null) + { + if (HttpContext.Current.Items[Diagnostics.ContextID] == null) + { + HandlerPageTraceInfo pageTrace = new HandlerPageTraceInfo(); + _messages.Add(pageTrace); + if (_messages.Count > MessageLimit) + { + _messages.RemoveRange(0, _messages.Count - MessageLimit); + } + HttpContext.Current.Items[Diagnostics.ContextID] = pageTrace; + } + return (HandlerPageTraceInfo)HttpContext.Current.Items[Diagnostics.ContextID]; + } + } + return null; + } + } + + /// <summary> + /// Gets a value indicating whether this instance is trace enabled. + /// </summary> + /// <value> + /// <c>true</c> if this instance is trace enabled; otherwise, <c>false</c>. + /// </value> + internal static bool IsTraceEnabled + { + get + { + return HttpContext.Current != null && HttpContext.Current.Trace.IsEnabled; + } + } + + /// <summary> + /// Gets the messages collection. + /// </summary> + /// <value>The messages.</value> + internal static ReadOnlyCollection<HandlerPageTraceInfo> Messages + { + get + { + List<HandlerPageTraceInfo> result; + lock (_lockObject) + { + result = new List<HandlerPageTraceInfo>(_messages); + } + return result.AsReadOnly(); + } + } + } + + #endregion //Diagnostics class +} diff --git a/System.Web.DynamicData/DynamicData/DynamicDataExtensions.cs b/System.Web.DynamicData/DynamicData/DynamicDataExtensions.cs index d7311de02..765abf1c5 100644 --- a/System.Web.DynamicData/DynamicData/DynamicDataExtensions.cs +++ b/System.Web.DynamicData/DynamicData/DynamicDataExtensions.cs @@ -228,7 +228,7 @@ public static Control FindFieldTemplate(this Control control, string columnName) } /// <summary> - /// Make the SelectedIndex [....] up with the PersistedSelection. Concretely, what it means is that + /// Make the SelectedIndex sync up with the PersistedSelection. Concretely, what it means is that /// if you select a row and then page away (or sort), the selection remains on that row /// even if it's not currently visible. /// </summary> diff --git a/System.Web.DynamicData/DynamicData/DynamicDataManager.cs b/System.Web.DynamicData/DynamicData/DynamicDataManager.cs index f54d6521c..2fcbbceb8 100644 --- a/System.Web.DynamicData/DynamicData/DynamicDataManager.cs +++ b/System.Web.DynamicData/DynamicData/DynamicDataManager.cs @@ -189,7 +189,7 @@ public void RegisterControl(Control control, bool setSelectionFromUrl) { internal static void EnablePersistedSelection(BaseDataBoundControl baseDataBoundControl, IMetaTable table) { Debug.Assert(baseDataBoundControl != null, "NULL!"); - // Make the persisted selection [....] up with the selected index if possible + // Make the persisted selection sync up with the selected index if possible if (!table.IsReadOnly) { DynamicDataExtensions.EnablePersistedSelectionInternal(baseDataBoundControl); } diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityConnectionStringBuilderItem.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityConnectionStringBuilderItem.cs index 5598b5c60..ba73d0268 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityConnectionStringBuilderItem.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityConnectionStringBuilderItem.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Data.EntityClient; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContext.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContext.cs index ceeca3367..24c9e3f49 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContext.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContext.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft // // Manages the properties that can be set on the first page of the wizard //------------------------------------------------------------------------------ diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContextPanel.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContextPanel.cs index fae30157a..ba12b6454 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContextPanel.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContextPanel.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContextPanel.designer.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContextPanel.designer.cs index 8b78d5d19..d0af6f070 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContextPanel.designer.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceConfigureObjectContextPanel.designer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Windows.Forms; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceContainerNameConverter.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceContainerNameConverter.cs index b92970d9e..dddf08b8a 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceContainerNameConverter.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceContainerNameConverter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceContainerNameItem.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceContainerNameItem.cs index 561dbabb7..1a470ab01 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceContainerNameItem.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceContainerNameItem.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Data.Metadata.Edm; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelection.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelection.cs index 68ca2a963..95c941121 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelection.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft // // Manages the properties that can be set on the second page of the wizard //------------------------------------------------------------------------------ diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelectionPanel.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelectionPanel.cs index a2d586e55..9deff40bb 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelectionPanel.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelectionPanel.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelectionPanel.designer.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelectionPanel.designer.cs index e5f044744..b5854bbb0 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelectionPanel.designer.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDataSelectionPanel.designer.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Windows.Forms; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDesigner.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDesigner.cs index b630b7594..babe193dc 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDesigner.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDesigner.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.ComponentModel; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDesignerHelper.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDesignerHelper.cs index 652acc587..01fe10614 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDesignerHelper.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceDesignerHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntitySetNameConverter.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntitySetNameConverter.cs index fef0dc95f..59ab452a5 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntitySetNameConverter.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntitySetNameConverter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntitySetNameItem.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntitySetNameItem.cs index 4f522e7e5..e1fcec202 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntitySetNameItem.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntitySetNameItem.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Data.Metadata.Edm; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntityTypeFilterConverter.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntityTypeFilterConverter.cs index f814d7516..9b5f5ed2d 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntityTypeFilterConverter.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntityTypeFilterConverter.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntityTypeFilterItem.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntityTypeFilterItem.cs index d5029c506..271ff0562 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntityTypeFilterItem.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceEntityTypeFilterItem.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Data.Metadata.Edm; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceState.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceState.cs index d0ab4f9f6..189826753 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceState.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceState.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft // // Temporary storage for properties set via the wizard //------------------------------------------------------------------------------ diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceStatementEditor.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceStatementEditor.cs index da4ed87c9..4d135b889 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceStatementEditor.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceStatementEditor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.ComponentModel; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceStatementEditorForm.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceStatementEditorForm.cs index 85f30115b..fd48f29e0 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceStatementEditorForm.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceStatementEditorForm.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft // // Enables a user to edit CommandText, OrderBy, Select, and // Where properties and parameters diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceWizardForm.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceWizardForm.cs index 4ae944032..83cd536ab 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceWizardForm.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDataSourceWizardForm.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft // // Containing form for the wizard panels //------------------------------------------------------------------------------ diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDesignerDataSourceView.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDesignerDataSourceView.cs index 2206efbf8..4e664aa32 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDesignerDataSourceView.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/EntityDesignerDataSourceView.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System.Collections; using System.Data; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/DesignerForm.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/DesignerForm.cs index fea3d8fac..3467d4621 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/DesignerForm.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/DesignerForm.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/RTLAwareMessageBox.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/RTLAwareMessageBox.cs index 25d42e050..fcd3e820f 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/RTLAwareMessageBox.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/RTLAwareMessageBox.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/ResourceDescriptionAttribute.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/ResourceDescriptionAttribute.cs index d61fc0f3a..f7a25c7ab 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/ResourceDescriptionAttribute.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/ResourceDescriptionAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/TaskFormBase.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/TaskFormBase.cs index fbd461cd8..0ca68d843 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/TaskFormBase.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/TaskFormBase.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/UIHelper.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/UIHelper.cs index a21300b69..ca925042f 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/UIHelper.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/UIHelper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft // // Helper methods for UI functionality like displaying dialogs //------------------------------------------------------------------------------ diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardForm.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardForm.cs index c8dadbce8..371f73057 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardForm.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardForm.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardPanel.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardPanel.cs index 4374823c0..6aecc439a 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardPanel.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardPanel.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardPanelChangingEventArgs.cs b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardPanelChangingEventArgs.cs index a77f7e065..4e30056bf 100644 --- a/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardPanelChangingEventArgs.cs +++ b/System.Web.Entity.Design/System/Data/WebControls/Design/Util/WizardPanelChangingEventArgs.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSource.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSource.cs index f0971e34d..3114cbef7 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSource.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSource.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceChangedEventArgs.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceChangedEventArgs.cs index c3ff8c1e1..b56607912 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceChangedEventArgs.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceChangedEventArgs.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] +// @owner Microsoft // @backupOwner objsdev //--------------------------------------------------------------------- diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceChangingEventArgs.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceChangingEventArgs.cs index c19dbcb82..c0fbdfb66 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceChangingEventArgs.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceChangingEventArgs.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] +// @owner Microsoft // @backupOwner objsdev //--------------------------------------------------------------------- diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceColumn.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceColumn.cs index c89ec893d..09edc5e62 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceColumn.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceColumn.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextCreatedEventArgs.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextCreatedEventArgs.cs index 2e639d2c1..f92ab5ee5 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextCreatedEventArgs.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextCreatedEventArgs.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] +// @owner Microsoft // @backupOwner objsdev //--------------------------------------------------------------------- using System; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextCreatingEventArgs.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextCreatingEventArgs.cs index a39034e81..d0a9eb119 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextCreatingEventArgs.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextCreatingEventArgs.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] +// @owner Microsoft // @backupOwner objsdev //--------------------------------------------------------------------- using System; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextDisposingEventArgs.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextDisposingEventArgs.cs index e53faa0c2..913b15800 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextDisposingEventArgs.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceContextDisposingEventArgs.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] +// @owner Microsoft // @backupOwner objsdev //--------------------------------------------------------------------- using System; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceMemberPath.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceMemberPath.cs index a1f0cbc1e..c02df2400 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceMemberPath.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceMemberPath.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceQueryBuilder.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceQueryBuilder.cs index 21cecb804..ebca39ae4 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceQueryBuilder.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceQueryBuilder.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Web.UI.WebControls diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceReferenceGroup.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceReferenceGroup.cs index 065d0f803..90033972d 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceReferenceGroup.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceReferenceGroup.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceSelectedEventArgs.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceSelectedEventArgs.cs index 1b1f06ab3..132dc52f0 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceSelectedEventArgs.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceSelectedEventArgs.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] +// @owner Microsoft // @backupOwner objsdev //--------------------------------------------------------------------- diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceSelectingEventArgs.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceSelectingEventArgs.cs index 2e5c16561..781a35ec0 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceSelectingEventArgs.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceSelectingEventArgs.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] +// @owner Microsoft // @backupOwner objsdev //--------------------------------------------------------------------- using System; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceUtil.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceUtil.cs index 2560d5e2e..315148ec4 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceUtil.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceUtil.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections; using System.Collections.Generic; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceValidationException.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceValidationException.cs index 6b285402c..f8108d339 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceValidationException.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceValidationException.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceView.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceView.cs index 88460b1e6..a6f45854e 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceView.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceView.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System.Collections; using System.Collections.Generic; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceViewSchema.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceViewSchema.cs index 497db7302..dfb3b2515 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceViewSchema.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceViewSchema.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Web.UI.WebControls diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapper.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapper.cs index 0660a995a..00219e431 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapper.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapper.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Data; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapperCollection.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapperCollection.cs index 1d8a270c4..97ac55104 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapperCollection.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapperCollection.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Data; diff --git a/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapperPropertyDescriptor.cs b/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapperPropertyDescriptor.cs index 8cc49ef33..e66c99544 100644 --- a/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapperPropertyDescriptor.cs +++ b/System.Web.Entity/System/Data/WebControls/EntityDataSourceWrapperPropertyDescriptor.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Data; diff --git a/System.Web.Entity/System/Data/WebControls/ResourceDescriptionAttribute.cs b/System.Web.Entity/System/Data/WebControls/ResourceDescriptionAttribute.cs index 94b2b327e..218f1da60 100644 --- a/System.Web.Entity/System/Data/WebControls/ResourceDescriptionAttribute.cs +++ b/System.Web.Entity/System/Data/WebControls/ResourceDescriptionAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System; diff --git a/System.Web.Entity/System/Data/WebControls/ResourceDisplayNameAttribute.cs b/System.Web.Entity/System/Data/WebControls/ResourceDisplayNameAttribute.cs index 529367d04..ece6b3f21 100644 --- a/System.Web.Entity/System/Data/WebControls/ResourceDisplayNameAttribute.cs +++ b/System.Web.Entity/System/Data/WebControls/ResourceDisplayNameAttribute.cs @@ -3,8 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] -// @backupOwner [....] +// @owner Microsoft +// @backupOwner Microsoft //------------------------------------------------------------------------------ using System; using System.ComponentModel; diff --git a/System.Web.Entity/System/Data/WebControls/WebControlParameterProxy.cs b/System.Web.Entity/System/Data/WebControls/WebControlParameterProxy.cs index 1df13685d..cd03f842f 100644 --- a/System.Web.Entity/System/Data/WebControls/WebControlParameterProxy.cs +++ b/System.Web.Entity/System/Data/WebControls/WebControlParameterProxy.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // -// @owner [....] +// @owner Microsoft // @backupOwner objsdev //--------------------------------------------------------------------- using System; diff --git a/System.Web.Mobile/UI/MobileControls/Design/AppliedDeviceFiltersDialog.cs b/System.Web.Mobile/UI/MobileControls/Design/AppliedDeviceFiltersDialog.cs index 7ef342bd4..36cd8f563 100644 --- a/System.Web.Mobile/UI/MobileControls/Design/AppliedDeviceFiltersDialog.cs +++ b/System.Web.Mobile/UI/MobileControls/Design/AppliedDeviceFiltersDialog.cs @@ -1115,7 +1115,7 @@ internal DeviceSpecificChoice RuntimeChoice Debug.Assert( (_choicePropertyFilter == null) || (_runtimeChoice == _choicePropertyFilter.RuntimeChoice), - "Local runtime choice object out of [....]." + "Local runtime choice object out of sync." ); return _runtimeChoice; } diff --git a/System.Web.Mobile/UI/MobileControls/Design/Util/GenericUI.cs b/System.Web.Mobile/UI/MobileControls/Design/Util/GenericUI.cs index 86ee1f1ab..ca56237cd 100644 --- a/System.Web.Mobile/UI/MobileControls/Design/Util/GenericUI.cs +++ b/System.Web.Mobile/UI/MobileControls/Design/Util/GenericUI.cs @@ -168,7 +168,7 @@ internal static bool ConfirmYesNo(String title, String message) } } - // Copied from ndp\fx\src\Designer\[....]\System\[....]\Design\RTLAwareMessageBox.cs + // Copied from ndp\fx\src\Designer\Microsoft\System\Microsoft\Design\RTLAwareMessageBox.cs [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] internal sealed class RTLAwareMessageBox { diff --git a/System.Web.Mobile/UI/MobileControls/Design/Util/MSHTMLHost.cs b/System.Web.Mobile/UI/MobileControls/Design/Util/MSHTMLHost.cs index f8d091ccb..c44549c4d 100644 --- a/System.Web.Mobile/UI/MobileControls/Design/Util/MSHTMLHost.cs +++ b/System.Web.Mobile/UI/MobileControls/Design/Util/MSHTMLHost.cs @@ -6,7 +6,7 @@ // MSHTMLHost.cs // -// 12/17/98: Created: [....] +// 12/17/98: Created: Microsoft // namespace System.Web.UI.Design.MobileControls.Util { @@ -210,7 +210,7 @@ public virtual int Scroll(NativeMethods.tagSIZE scrollExtant) { } public virtual void OnUIDeactivate(int fUndoable) { - // NOTE, [....], 7/99: Don't return E_NOTIMPL. Somehow doing nothing and returning S_OK + // NOTE, Microsoft, 7/99: Don't return E_NOTIMPL. Somehow doing nothing and returning S_OK // fixes trident hosting in Win2000. } @@ -245,7 +245,7 @@ public virtual void SetBorderSpace(NativeMethods.COMRECT pborderwidths) { } public virtual void SetActiveObject(NativeMethods.IOleInPlaceActiveObject pActiveObject, string pszObjName) { - // NOTE, [....], 7/99: Don't return E_NOTIMPL. Somehow doing nothing and returning S_OK + // NOTE, Microsoft, 7/99: Don't return E_NOTIMPL. Somehow doing nothing and returning S_OK // fixes trident hosting in Win2000. // throw new COMException(String.Empty, NativeMethods.E_NOTIMPL); } diff --git a/System.Web.Mobile/UI/MobileControls/MobilePage.cs b/System.Web.Mobile/UI/MobileControls/MobilePage.cs index afa31dc95..26d2ff6dd 100644 --- a/System.Web.Mobile/UI/MobileControls/MobilePage.cs +++ b/System.Web.Mobile/UI/MobileControls/MobilePage.cs @@ -1290,7 +1290,7 @@ protected override void SavePageStateToPersistenceMedium(Object view) } } - // NOTE: Make sure this stays in [....] with Page.PageRegisteredControlsThatRequirePostBackKey + // NOTE: Make sure this stays in sync with Page.PageRegisteredControlsThatRequirePostBackKey private const string PageRegisteredControlsThatRequirePostBackKey = "__ControlsRequirePostBackKey__"; private bool CheckEmptyViewState(Object viewState) { @@ -1441,7 +1441,7 @@ protected override void RemovedControl(Control control) private byte[] GetMacKeyModifier() { - //NOTE: duplicate of the version in objectstateformatter.cs, keep in [....] + //NOTE: duplicate of the version in objectstateformatter.cs, keep in sync // Use the page's directory and class name as part of the key (ASURT 64044) // We need to make sure that the hash is case insensitive, since the file system diff --git a/System.Web.Mobile/UI/MobileControls/ObjectList.cs b/System.Web.Mobile/UI/MobileControls/ObjectList.cs index 656537ad4..d0fae603e 100644 --- a/System.Web.Mobile/UI/MobileControls/ObjectList.cs +++ b/System.Web.Mobile/UI/MobileControls/ObjectList.cs @@ -948,7 +948,7 @@ internal void OnFieldChanged(bool fieldAddedOrRemoved) if (IsTrackingViewState) { _items = null; - // avoid view state being out of [....] with fields. + // avoid view state being out of sync with fields. _ignoreFieldsItemsViewModeViewState = true; if (fieldAddedOrRemoved) { diff --git a/System.Web.Mobile/UI/MobileControls/SessionViewState.cs b/System.Web.Mobile/UI/MobileControls/SessionViewState.cs index faba8d309..da3b9fbc6 100644 --- a/System.Web.Mobile/UI/MobileControls/SessionViewState.cs +++ b/System.Web.Mobile/UI/MobileControls/SessionViewState.cs @@ -27,7 +27,7 @@ namespace System.Web.UI.MobileControls * arise. The core issue behind most of these is how to handle the user * clicking the Back button. When the user does this, there is no corresponding * notification to the server, and the client and server session state are thrown - * out of [....]. + * out of sync. * * This class attempts to alleviate this by storing a small history of view states * in session data. diff --git a/System.Web.Services/System.Web.Services.txt b/System.Web.Services/System.Web.Services.txt new file mode 100644 index 000000000..f53942118 --- /dev/null +++ b/System.Web.Services/System.Web.Services.txt @@ -0,0 +1,477 @@ +; +; Resources for System.Web.Services component +; +; Copyright (c) 2000 Microsoft Corporation +; + +; +; Exceptions messages +; +NonClsCompliantException=A non-CLS Compliant Exception (i.e. an object that does not derive from System.Exception) was thrown. + +WebConfigInvalidExtensionPriority={0} is an invalid value for the extension priority. The priority must be nonnegative. +ConfigKeyNotFoundInElementCollection=No elements matching the key {0} were found in the ConfigurationElementCollection. +ConfigKeysDoNotMatch=The key does not match the indexer key. Key on element (expected value): {0}. Key provided to indexer: {1}. +Invalid_priority_group_value=The Group attribute must be set to a valid PriorityGroup value. +WebSchemaNotFound=Schema not found. +WebReflectionError=Error reflecting {0}.{1}. +WebInvalidMethodName={0} Web Service method name is not valid. +WebInvalidMethodNameCase=Invalid method name '{0}', method names are case sensitive. The method name '{1}' with the same name but different casing was found. +WebInvalidRequestFormat=Request format is invalid. +WebInvalidRequestFormatDetails=Request format is invalid: {0}. +WebMethodStatic=Web Service methods cannot be static. +WebMethodMissingParams=The last two parameters of method {0}.{1} must be of type {2} and {3}. +WebBadOutParameter=The {0} parameter of the {1}.{2} method must be an input-only parameter. +WebInOutParameter=The {0} parameter of the {1}.{2} method must be an output-only parameter. +WebAsyncMissingEnd=Asynchronous method {0}.{1} does not have a corresponding {2} method. +WebMissingPath=Path property must be set before calling the Send method. +WebResponseKnownError=The request failed with HTTP status {0}: {1}. +WebResponseUnknownError=The request failed with the error message: +WebResponseUnknownErrorEmptyBody=The request failed with an empty response. +WebResponseContent=Client found response content type of '{0}', but expected '{1}'. +WebBadStreamState=Properties and methods of the stream can't be accessed in the BeforeSerialize stage. +WebResponseBadXml=Response is not well-formed XML. +WebCannotUnderstandHeader=SOAP header {0} was not understood. +WebMissingHeader=Missing required header '{0}'. +WebNoReturnValue=There is no return value. +WebCannotAccessValue=The value can not be accessed because there was an exception during message processing. +WebCannotAccessValueStage=The value may not be accessed in message stage {0}. +WebInvalidBindingPlacement=The Binding property of {0} may not be specified in this context. +WebInvalidBindingName=The Binding property '{0}' does not match interface binding '{1}'. +WebBothMethodAttrs=A web service method can't have both a SoapDocumentMethodAttribute and a SoapRpcMethodAttribute. Use one or the other. +WebBothServiceAttrs=A web service can't have both a SoapDocumentServiceAttribute and a SoapRpcServiceAttribute. Use one or the other. +WebOneWayOutParameters=One-way methods cannot have out or ref parameters. +WebOneWayReturnValue=One-way methods cannot have return values. +WebReflectionErrorMethod=Method {0}.{1} can not be reflected. +WebMultiDimArray=Multi-dimensional arrays are not supported. Use a jagged array instead. +WebHeaderMissing=The header property/field {0}.{1} is missing or not public. +WebHeaderStatic=The header property/field {0}.{1} cannot be static. +WebHeaderRead=The header property/field {0}.{1} could not be read. +WebHeaderWrite=The header property/field {0}.{1} could not be written to. +WebHeaderType=The header property/field {0}.{1} must be of type SoapHeader or a derived type, or an array of SoapHeader or SoapUnknownHeader. +WebHeaderOneWayOut=The header property/field {0}.{1} cannot be an out header because the method is one-way. +WebHeaderInvalidMustUnderstand='{0}' is not a valid value for the field EncodedMustUnderstand. Valid values are '0', '1', 'true', and 'false'. +WebMultiplyDeclaredHeaderTypes=An operation can have only one in or out header of a given type. {0}.{1} conflicts with another header field of the same type and direction. +WebHttpHeader=Server did not recognize the value of HTTP Header {0}: {1}. +WebRequestContent=Server found request content type to be '{0}', but expected '{1}'. +WebRequestUnableToRead=Server was unable to read request. +WebRequestUnableToProcess=Server was unable to process request. +WebMissingParameter=Missing parameter: {0}. +WebUnrecognizedRequestFormat=Request format is unrecognized. +WebUnrecognizedRequestFormatUrl=Request format is unrecognized for URL unexpectedly ending in '{0}'. +WebTimeout=The timeout period expired before the response was received. +WebMissingHelpContext=HttpContext is not available. This class can only be used in the context of an ASP.NET request. +WebMissingCustomAttribute={0} must have the {1} custom attribute. +WebMissingClientProtocol=ClientProtocol must be set first. +WebResolveMissingClientProtocol=ClientProtocol property must be set before calling Resolve. +WebPathNotFound=Path:{0} could not be found. +WebMissingResource=The document at the url {0} was not recognized as a known document type.\r\nThe error message from each known type may help you fix the problem: +WebContractReferenceName=WSDL Document +WebShemaReferenceName=XML Schema +WebDiscoveryDocumentReferenceName=DISCO Document +WebMissingDocument=Discovery document at the URL {0} could not be found. +WebInvalidContentType=The document format is not recognized (the content type is '{0}'). +WebInvalidFormat=The document format is not recognized. +WebInvalidEnvelopeNamespace=Possible SOAP version mismatch: Envelope namespace {0} was unexpected. Expecting {1}. +WebResultNotXml=Result was not XML. +WebDescriptionMissingItem=Element {0} named {1} from namespace {2} is missing. +WebDescriptionMissing=Cannot find definition for {0}. Service Description with namespace {1} is missing. +WebDescriptionPartElementRequired=Part '{0}' from message '{1}' in namespace '{2}' is missing the element attribute. The element attribute is required for headers when Use=Literal. +WebDescriptionPartTypeRequired=Part '{0}' from message '{1}' in namespace '{2}' is missing the type attribute. The type attribute is required for headers when Use=Encoded. +WebDescriptionPartElementWarning=Part '{0}' from message '{1}' in namespace '{2}' defines both the element and type attributes. Only the element attribute is used for headers when Use=Literal. +WebDescriptionPartTypeWarning=Part '{0}' from message '{1}' in namespace '{2}' defines both the element and type attributes. Only the type attribute is used for headers when Use=Encoded. +WebDescriptionMissingBodyUseAttribute=Missing required 'use' attribute on 'soap:body' element. +WebDescriptionTooManyMessages=No more than one input and one output message may be specified. +WebDescriptionHeaderAndBodyUseMismatch=The value of use defined on the soap:header element must match that defined on the soap:body element. +WebQNamePrefixUndefined=Namespace prefix '{0}' not defined +WebNegativeValue=The value for '{0}' cannot be negative. +WebEmptyRef=Invalid empty reference of type '{0}' encountered in the document at URI '{1}'. +WebNullRef=Invalid null web reference encountered in the discovery document. +WebRefInvalidAttribute=Invalid web reference encountered. Missing required '{0}' attribute. +WebRefInvalidAttribute2=Invalid empty reference of type '{0}' encountered. Missing required '{1}' attribute. +WebInvalidDocType=Invalid Document type. Expecting '{0}', got '{1}'.\r\nDocument URI is '{2}'. +WebDiscoRefReport=Report from '{0}' is '{1}'. +WebTextMatchMissingPattern=Each match element must have a pattern attribute containing a valid regular expression. +WebTextMatchIgnoredTypeWarning=Optional attribute 'type' was ignored because the match does not contain sub-matches. +WebTextMatchBadCaptureIndex={0} is not a valid capture index for match '{1}'. The highest valid capture index for this match is {2}. +WebTextMatchBadGroupIndex={0} is not a valid group index for match '{1}'. The highest valid group index for this match is {2}. +WebServiceDescriptionIgnoredOptional=The optional WSDL extension element '{0}' from namespace '{1}' was not handled. +WebServiceDescriptionIgnoredRequired=The required WSDL extension element '{0}' from namespace '{1}' was not handled. +WebDuplicateServiceDescription=More than one service description with targetNamespace '{0}' was specified. +WebDuplicateFormatExtension=More than one format extension named '{0}' was specified. Each format extension must have a unique name. +WebDuplicateOperationMessage=More than one operation message named '{0}' was specified. Each operation message must have a unique name. +WebDuplicateImport=More than one import named '{0}' was specified. Each import must have a unique name. +WebDuplicateMessage=More than one message named '{0}' was specified. Each message must have a unique name. +WebDuplicatePort=More than one port named '{0}' was specified. Each port must have a unique name. +WebDuplicatePortType=More than one port type named '{0}' was specified. Each port type must have a unique name. +WebDuplicateBinding=More than one binding named '{0}' was specified. Each binding must have a unique name. +WebDuplicateService=More than one service named '{0}' was specified. Each service must have a unique name. +WebDuplicateMessagePart=More than one message part named '{0}' was specified. Each message part must have a unique name. +WebDuplicateOperationBinding=More than one operation binding named '{0}' was specified. Each operation binding must have a unique name. +WebDuplicateFaultBinding=More than one fault binding named '{0}' was specified. Each fault binding must have a unique name. +WebDuplicateOperation=More than one operation named '{0}' was specified. Each operation must have a unique name. +WebDuplicateOperationFault=More than one operation fault named '{0}' was specified. Each operation fault must have a unique name. +WebDuplicateUnknownElement=More than one {0} named '{1}' was specified. Each {0} must have a unique name. +WebUnknownEncodingStyle=The encoding style '{0}' is not supported. +WebSoap11EncodingStyleNotSupported1=The SOAP 1.1 encoding style is not supported for operations that use SOAP 1.2. Use the URI '{0}' to refer to the SOAP 1.2 encoding style. +WebNullAsyncResultInBegin=For server-side asynchronous method calls, your Begin method must return a valid IAsyncResult. Your Begin method cannot return null. +WebNullAsyncResultInEnd=For asynchronous method calls, you must supply a non-null IAsyncResult instance when you call the End method. +WebAsyncTransaction=Transactions are not supported for asynchronous method calls. Provide a synchronous version of the method or unset the TransactionOption property of the WebMethodAttribute. +WebConfigExtensionError=There was an exception running the extensions specified in the config file. +WebExtensionError=There was an exception running the extensions specified in the config file (or via an attribute). +WebChangeTypeFailed=Cannot convert {0} to {1}. +WebBadEnum=The value '{0}' was not found in the enum type '{1}'. +WebBadHex=Invalid hex digit: '{0}'. +WebClientBindingAttributeRequired=WebServiceBindingAttribute is required on proxy classes. +WebHeaderInvalidRelay='{0}' is not a valid value for the 'relay' attribute. Valid values are '0', '1', 'true', and 'false'. +WebVirtualDisoRoot=Web Directory '{0}' must be same or below to '{1}'. +WebRefDuplicateSchema=Ignoring duplicate schema with TargetNamespace='{0}' from '{1}'. +WebRefDuplicateService=Ignoring duplicate service description with TargetNamespace='{0}' from '{1}'. +WebWsiContentTypeEncoding=Input message does not conform to Simple SOAP Binding Profile Version 1.0. Requirement R1012: A MESSAGE MUST serialize the envelope using either UTF-8 or UTF-16 character encoding. +WebWsiViolation=Service '{0}' does not conform to WS-I Basic Profile v1.1. Please examine each of the normative statement violations below. To turn off conformance check set the ConformanceClaims property on corresponding WebServiceBinding attribute to WsiClaims.None.\r\n{1} +WebNullReaderForMessage=The GetReaderForMessage method cannot return null. +WebNullWriterForMessage=The GetWriterForMessage method cannot return null. +NeedConcreteType=Cannot create an instance of an interface {0}. Please specify a concrete implementation of the interface instead. + +WebUnknownElement=The element was not expected in this context: {0}. +WebUnknownElement1=An unexpected element was encountered: {0}. No elements were expected in this scope. +WebUnknownElement2=The element was not expected in this context: {0}. Expected elements: {1}. +WebUnknownAttribute=An unexpected attribute was encountered: {0}='{1}'. +WebUnknownAttribute2=An unexpected attribute was encountered: {0}='{1}'. No attributes were expected in this scope. +WebUnknownAttribute3=The attribute was not expected in this context: {0}='{1}'. Expected attributes: {2}. +WebUnreferencedObject=Item id='{0}' was not referenced: {1}. +WebSuppressedExceptionMessage=An error occurred on the server. + +CannotRunInPartialTrustOutsideAspNet=Cannot run in partial trust outside the ASP.NET environment. + + +; DescriptionAttributes + +WebServiceContext=The ASP.NET context object for the current request. +WebServiceSession=The ASP.NET session object for the current request. +WebServiceServer=The ASP.NET utility object for the current request. +WebServiceUser=The ASP.NET user object for the current request. The object is used for authorization. +WebServiceSoapVersion=The version of the SOAP protocol used for the request. +ClientProtocolAllowAutoRedirect=Enable automatic handling of server redirects. +ClientProtocolCookieContainer=A container for all cookies received from servers in the current session. +ClientProtocolPreAuthenticate=Enables pre authentication of the request. +ClientProtocolClientCertificates=The client certificates that will be sent to the server, if the server requests them. +ClientProtocolUrl=The base URL to the server to use for requests. +ClientProtocolEncoding=The encoding to use for requests. +ClientProtocolTimeout=Sets the timeout in milliseconds to be used for synchronous calls. The default of -1 means infinite. +ClientProtocolUserAgent=Sets the user agent http header for the request. +ClientProtocolUsername=The user name to be sent for basic and digest authentication. +ClientProtocolPassword=The password to be used for basic and digest authentication. +ClientProtocolDomain=The domain to be used for basic and digest authentication. +ClientProtocolProxyName=The name of the proxy server to use for requests. +ClientProtocolProxyPort=The port number of the proxy server to use for requests. +ClientProtocolSoapVersion=The version of the SOAP protocol to use for requests. By default, SOAP 1.1 will be used. +ClientProtocolEnableDecompression=This allows user to easily leverage HTTP compression that's built into IIS 6. + +; Soap localized text + +; this constant is Code for the representation of names of languages [ISO 639]. +; some of the values are +; ar Arabic +; cs Czech +; da Danish +; de German +; el Greek +; es Spanish +; fa Persian +; fi Finnish +; fr French +; he Hebrew (formerly iw) +; hi Hindi +; hu Hungarian +; it Italian +; ja Japanese +; zh Chinese +; +; for the full list plase refer to http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt +XmlLang=en + +; DefaultWsdlHelpGenerator.aspx localized text + +HelpGeneratorHttpGetTitle=HTTP GET +HelpGeneratorHttpGetText=The following is a sample HTTP GET request and response. The <font class=value>placeholders</font> shown need to be replaced with actual values. +HelpGeneratorHttpPostTitle=HTTP POST +HelpGeneratorHttpPostText=The following is a sample HTTP POST request and response. The <font class=value>placeholders</font> shown need to be replaced with actual values. +HelpGeneratorSoapTitle=SOAP 1.1 +HelpGeneratorSoap1_2Title=SOAP 1.2 +HelpGeneratorSoapText=The following is a sample SOAP 1.1 request and response. The <font class=value>placeholders</font> shown need to be replaced with actual values. +HelpGeneratorSoap1_2Text=The following is a sample SOAP 1.2 request and response. The <font class=value>placeholders</font> shown need to be replaced with actual values. +HelpGeneratorInvokeButton=Invoke +HelpGeneratorParameter=Parameter +HelpGeneratorValue=Value +HelpGeneratorTestHeader=Test +HelpGeneratorTestText=To test the operation using the HTTP POST protocol, click the 'Invoke' button. +HelpGeneratorNoTestFormRemote=The test form is only available for requests from the local machine. +HelpGeneratorLinkBack=Click <a href=\"{0}\">here</a> for a complete list of operations. +HelpGeneratorEnableHttpPostHeader=Enabling http post protocol in configuration +HelpGeneratorEnableHttpPostInstructions=To enable the http post protocol add the following to the web.config file in your application or site root directory. +HelpGeneratorOperationsIntro=The following operations are supported. For a formal definition, please review the <a href=\"{0}\">Service Description</a>. +HelpGeneratorWebService=Web Service +HelpGeneratorNoHttpGetTest=No test form is available as this service or method does not support the HTTP GET protocol. +HelpGeneratorNoHttpPostTest=No test form is available as this service or method does not support the HTTP POST protocol. +HelpGeneratorNoTestNonPrimitive=The test form is only available for methods with primitive types as parameters. +HelpGeneratorMethodNotFound=Method Not Found +HelpGeneratorMethodNotFoundText=Method '{0}' was not found in service {1}. +HelpGeneratorStyleBODY=color: #000000; background-color: white; font-family: Verdana; margin-left: 0px; margin-top: 0px; +HelpGeneratorStylecontent=margin-left: 30px; font-size: .70em; padding-bottom: 2em; +HelpGeneratorStyleAlink=color: #336699; font-weight: bold; text-decoration: underline; +HelpGeneratorStyleAvisited=color: #6699cc; font-weight: bold; text-decoration: underline; +HelpGeneratorStyleAactive=color: #336699; font-weight: bold; text-decoration: underline; +HelpGeneratorStyleAhover=color: cc3300; font-weight: bold; text-decoration: underline; +HelpGeneratorStyleP=color: #000000; margin-top: 0px; margin-bottom: 12px; font-family: Verdana; +HelpGeneratorStylepre=background-color: #e5e5cc; padding: 5px; font-family: Courier New; font-size: x-small; margin-top: -5px; border: 1px #f0f0e0 solid; +HelpGeneratorStyletd=color: #000000; font-family: Verdana; font-size: .7em; +HelpGeneratorStyleh2=font-size: 1.5em; font-weight: bold; margin-top: 25px; margin-bottom: 10px; border-top: 1px solid #003366; margin-left: -15px; color: #003366; +HelpGeneratorStyleh3=font-size: 1.1em; color: #000000; margin-left: -15px; margin-top: 10px; margin-bottom: 10px; +HelpGeneratorStyleul=margin-top: 10px; margin-left: 20px; +HelpGeneratorStyleol=margin-top: 10px; margin-left: 20px; +HelpGeneratorStyleli=margin-top: 10px; color: #000000; +HelpGeneratorStylefontvalue=color: darkblue; font: bold; +HelpGeneratorStylefontkey=color: darkgreen; font: bold; +HelpGeneratorStylefontError=color: darkred; font: bold; +HelpGeneratorStyleheading1=color: #ffffff; font-family: Tahoma; font-size: 26px; font-weight: normal; background-color: #003366; margin-top: 0px; margin-bottom: 0px; margin-left: -30px; padding-top: 10px; padding-bottom: 3px; padding-left: 15px; width: 105%; +HelpGeneratorStylebutton=background-color: #dcdcdc; font-family: Verdana; font-size: 1em; border-top: #cccccc 1px solid; border-bottom: #666666 1px solid; border-left: #cccccc 1px solid; border-right: #666666 1px solid; +HelpGeneratorStylefrmheader=color: #000000; background: #dcdcdc; font-family: Verdana; font-size: .7em; font-weight: normal; border-bottom: 1px solid #dcdcdc; padding-top: 2px; padding-bottom: 2px; +HelpGeneratorStylefrmtext=font-family: Verdana; font-size: .7em; margin-top: 8px; margin-bottom: 0px; margin-left: 32px; +HelpGeneratorStylefrmInput=font-family: Verdana; font-size: 1em; +HelpGeneratorStyleintro=margin-left: -15px; +HelpGeneratorImplementation=implementation +HelpGeneratorDefaultNamespaceWarning1=This web service is using http://tempuri.org/ as its default namespace. +HelpGeneratorDefaultNamespaceWarning2=Recommendation: Change the default namespace before the XML Web service is made public. +HelpGeneratorDefaultNamespaceHelp1=Each XML Web service needs a unique namespace in order for client applications to distinguish it from other services on the Web. http://tempuri.org/ is available for XML Web services that are under development, but published XML Web services should use a more permanent namespace. +HelpGeneratorDefaultNamespaceHelp2=Your XML Web service should be identified by a namespace that you control. For example, you can use your company's Internet domain name as part of the namespace. Although many XML Web service namespaces look like URLs, they need not point to actual resources on the Web. (XML Web service namespaces are URIs.) +HelpGeneratorDefaultNamespaceHelp3=For XML Web services creating using ASP.NET, the default namespace can be changed using the WebService attribute's Namespace property. The WebService attribute is an attribute applied to the class that contains the XML Web service methods. Below is a code example that sets the namespace to "http://microsoft.com/webservices/": +HelpGeneratorDefaultNamespaceHelp4=For more details on XML namespaces, see the W3C recommendation on <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML</A>. +HelpGeneratorDefaultNamespaceHelp5=For more details on WSDL, see the <a href="http://www.w3.org/TR/wsdl">WSDL Specification</a>. +HelpGeneratorDefaultNamespaceHelp6=For more details on URIs, see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>. + +HelpGeneratorServiceConformance=This web service does not conform to WS-I Basic Profile v1.1. +HelpGeneratorServiceConformanceDetails=Please examine each of the normative statement violations below. Follow the recommendations to remedy it, or add setting to the <webServices> config section to turn off BP 1.1 conformance warnings for the entire vroot. +HelpGeneratorServiceConformanceConfig=To turn off BP 1.1 conformance warnings for the entire vroot remove the 'BP1.1' value from the <conformanceWarnings> section of the configuration file of your application: +HelpGeneratorRecommendation=Recommendation + +Rxxxx=SOAP 1.1 binding was not found +HelpGeneratorServiceConformanceRxxxx=WS-I's Basic Profile 1.1 consists of implementation guidelines that recommend how a set of core Web services specifications should be used together to develop interoperable Web services. For the 1.1 Profile, those specifications are SOAP 1.1, WSDL 1.1, UDDI 2.0, XML 1.0 and XML Schema. +HelpGeneratorServiceConformanceRxxxx_r=Consider changing config settings in web.config file in your application or site root directory to enable SOAP 1.1 protocol for your Web service. +HelpGeneratorServiceConformanceR2028=A DESCRIPTION using the WSDL namespace and the WSDL SOAP binding namespace MUST be valid according to the XML Schemas found at http://schemas.xmlsoap.org/wsdl/2003-02-11.xsd and http://schemas.xmlsoap.org/wsdl/soap/2003-02-11.xsd. +HelpGeneratorServiceConformanceR2026=A DESCRIPTION SHOULD NOT include extension elements with a wsdl:required attribute value of "true" on any WSDL construct (wsdl:binding, wsdl:portType, wsdl:message, wsdl:types or wsdl:import) that claims conformance to the Profile. +HelpGeneratorServiceConformanceR2705=A DESCRIPTION MUST use the same value of, either 'rpc' or 'document' for the style attribute for all of its operations in a portType, in the SOAP Binding description. +HelpGeneratorServiceConformanceR2705_r=To make binding conformant add explicit SoapRpcMethod or SoapDocumentMethod attribute to all WebMethods of this binding. +HelpGeneratorServiceConformanceR2706=A wsdl:binding in a DESCRIPTION MUST use the value of "literal" for the use attribute in all soapbind:body, soapbind:fault, soapbind:header and soapbind:headerfault elements. +HelpGeneratorServiceConformanceR2706_r=To make it conformant change the implementation of the service to use 'rpc-literal' or 'document-literal' SOAP messages. You need to add explicit <font class=value>Use=SoapBindingUse.Literal</font> property to all service and method level attributes: SoapRpcService, SoapRpcMethod, SoapDocumentService, SoapDocumentMethod. +HelpGeneratorServiceConformanceR2007=A DESCRIPTION MUST specify a non-empty location attribute on the wsdl:import element. Although the wsdl:import statement is modeled after the xsd:import statement, the location attribute is required by wsdl:import while the corresponding attribute on xsd:import, schemaLocation is optional. Consistent with location being required, its content is not intended to be empty. +HelpGeneratorServiceConformanceR2007_r=To make it conformant modify all import statements to include a non-empty location attribute. +HelpGeneratorServiceConformanceR2803=In a DESCRIPTION, the namespace attribute of the wsdl:import MUST NOT be a relative URI. +HelpGeneratorServiceConformanceR2803_r=To make it conformant modify all import statements to use an absolute URI for namespace attribute value. +HelpGeneratorServiceConformanceR2105=All xsd:schema elements contained in a wsdl:types element of a DESCRIPTION MUST have a targetNamespace attribute with a valid and non-null value, UNLESS the xsd:schema element has xsd:import and/or xsd:annotation as its only child element(s). +HelpGeneratorServiceConformanceR2105_r=Please examine your schema definitions and add explicit targetNamespace attribute. Requiring a targetNamespace on all xsd:schema elements that are children of wsdl:types is a good practice, places a minimal burden on authors of WSDL documents, and avoids the cases that are not as clearly defined as they might be. +HelpGeneratorServiceConformanceR1014=The children of the soap:Body element in a ENVELOPE MUST be namespace qualified. The use of unqualified element names may cause naming conflicts, therefore qualified names must be used for the children of soap:Body. +HelpGeneratorServiceConformanceR1014_r=To make binding conformant make sure that all response and request elements are namespace qualified. Use RequestNamespace and ResponseNamespace properties on the SoapDocumentMethod or SoapRpcMethod attribute to control the namespace. + +HelpGeneratorServiceConformanceR2201=A document-literal binding in a DESCRIPTION MUST, in each of its soapbind:body element(s), have at most one part listed in the parts attribute, if the parts attribute is specified. +HelpGeneratorServiceConformanceR2210=If a document-literal binding in a DESCRIPTION does not specify the parts attribute on a soapbind:body element, the corresponding abstract wsdl:message MUST define zero or one wsdl:parts. +HelpGeneratorServiceConformanceR2210_r=For Document-literal bindings, the Profile requires that at most one part, abstractly defined with the element attribute, be serialized into the soap:Body element. When using a Bare parameter style, a conformant method must have at most one parameter. +HelpGeneratorServiceConformanceR2306=A wsdl:message in a DESCRIPTION MUST NOT specify both type and element attributes on the same wsdl:part. +HelpGeneratorServiceConformanceR2203=An rpc-literal binding in a DESCRIPTION MUST refer, in its soapbind:body element(s), only to wsdl:part element(s) that have been defined using the type attribute. +HelpGeneratorServiceConformanceR2204=A document-literal binding in a DESCRIPTION MUST refer, in each of its soapbind:body element(s), only to wsdl:part element(s) that have been defined using the element attribute. +HelpGeneratorServiceConformanceR2205=A wsdl:binding in a DESCRIPTION MUST refer, in each of its soapbind:header, soapbind:headerfault and soapbind:fault elements, only to wsdl:part element(s) that have been defined using the element attribute. Because faults and headers do not contain parameters, soapbind:fault, soapbind:header and soapbind:headerfault assume, per WSDL 1.1, that the value of the style attribute is 'document'. R2204 requires that all wsdl:part elements with a style attribute whose value is 'document' that are bound to soapbind:body be defined using the element attribute. This requirement does the same for soapbind:fault, soapbind:header and soapbind:headerfault elements. +HelpGeneratorServiceConformanceR2303=A DESCRIPTION MUST NOT use Solicit-Response and Notification type operations in a wsdl:portType definition. Solicit-Response and Notification operations are not well defined by WSDL 1.1; furthermore, WSDL 1.1 does not define bindings for them. +HelpGeneratorServiceConformanceR2304=Operation name overloading in a wsdl:portType is disallowed by the Profile. A wsdl:portType in a DESCRIPTION MUST have operations with distinct values for their name attributes. Note that this requirement applies only to the wsdl:operations within a given wsdl:portType. A wsdl:portType may have wsdl:operations with names that are the same as those found in other wsdl:portTypes. +HelpGeneratorServiceConformanceR2304_r=To make service conformant please make sure that all web methods belonging to the same binding have unique names. +HelpGeneratorServiceConformanceR2701=The wsdl:binding element in a DESCRIPTION MUST be constructed so that its soapbind:binding child element specifies the transport attribute. +HelpGeneratorServiceConformanceR2702=A wsdl:binding element in a DESCRIPTION MUST specify the HTTP transport protocol with SOAP binding. Specifically, the transport attribute of its soapbind:binding child MUST have the value "http://schemas.xmlsoap.org/soap/http". Note that this requirement does not prohibit the use of HTTPS; See R5000. +HelpGeneratorServiceConformanceR2710=The operations in a wsdl:binding in a DESCRIPTION MUST result in wire signatures that are different from one another. An endpoint that supports multiple operations must unambiguously identify the operation being invoked based on the input message that it receives. This is only possible if all the operations specified in the wsdl:binding associated with an endpoint have a unique wire signature. +HelpGeneratorServiceConformanceR2710_r=The Profile defines the "wire signature" of an operation in a wsdl:binding to be the fully qualified name of the child element of the soap:Body of the SOAP input message it describes. For the case of an empty soap:Body this name is an empty string. In the case of rpc-literal binding, the operation name is used as a wrapper for the part accessors. In the document-literal case, since a wrapper with the operation name is not present, the message signatures must be correctly designed so that they meet this requirement. +HelpGeneratorServiceConformanceR2716=A document-literal binding in a DESCRIPTION MUST NOT have the namespace attribute specified on contained soapbind:body, soapbind:header, soapbind:headerfault and soapbind:fault elements. +HelpGeneratorServiceConformanceR2717=An rpc-literal binding in a DESCRIPTION MUST have the namespace attribute specified, the value of which MUST be an absolute URI, on contained soapbind:body elements. +HelpGeneratorServiceConformanceR2726=An rpc-literal binding in a DESCRIPTION MUST NOT have the namespace attribute specified on contained soapbind:header, soapbind:headerfault and soapbind:fault elements. +HelpGeneratorServiceConformanceR2718=A wsdl:binding in a DESCRIPTION MUST have the same set of wsdl:operations as the wsdl:portType to which it refers. +HelpGeneratorServiceConformanceR2720=A wsdl:binding in a DESCRIPTION MUST use the attribute named part with a schema type of "NMTOKEN" on all contained soapbind:header and soapbind:headerfault elements. +HelpGeneratorServiceConformanceR2749=A wsdl:binding in a DESCRIPTION MUST NOT use the attribute named parts on contained soapbind:header and soapbind:headerfault elements. +HelpGeneratorServiceConformanceR2721=A wsdl:binding in a DESCRIPTION MUST have the name attribute specified on all contained soapbind:fault elements. +HelpGeneratorServiceConformanceR2754=In a DESCRIPTION, the value of the name attribute on a soapbind:fault element MUST match the value of the name attribute on its parent wsdl:fault element. +HelpGeneratorServiceConformanceHelp=For more details on Basic Profile Version 1.1, see the <a href="http://www.ws-i.org/Profiles/BasicProfile-1.1.html"> Basic Profile Specification</a>. + +BindingMissingAttribute=Binding '{0}' from namespace '{1}' missing required '{2}' attribute. +BindingInvalidAttribute=Binding '{0}' from namespace '{1}' has invalid attribute: {2}='{3}'. +OperationFlowNotification=Operation '{0}' on portType '{1}' from namespace '{2}' defined as Notification. +OperationFlowSolicitResponse=Operation '{0}' on portType '{1}' from namespace '{2}' defined as Solicit-Response. + +PortTypeOperationMissing=Operation '{0}' on binding '{1}' from namespace '{2}' has no matching operation on portType '{3}' from namespace '{4}'. +BindingOperationMissing=Binding '{0}' from namespace '{1}' missing some operations defined on portType '{2}' from namespace '{3}'. +BindingMultipleParts=One of the extensibility elements on Binding '{0}' from namespace '{1}' has more then one part listed in the '{2}' attribute. +ElementEncodedExtension=Element '{0}' on Binding '{1}' from namespace '{2}' has invalid attribute {3}='{4}'. +InputElement=Input element {0} of operation '{1}' on portType '{2}' from namespace '{3}'. {4} +OutputElement=Output element {0} of operation '{1}' on portType '{2}' from namespace '{3}'. {4} +Fault=soapbind:fault '{0}' on operation '{1}' on portType '{2}' from namespace '{3}'. {4} +HeaderFault={0} on operation '{1}' on portType '{2}' from namespace '{3}'. {4} +Binding=Binding '{0}' from namespace '{1}'. +Operation=Operation '{0}' on portType '{1}' from namespace '{2}'. +OperationBinding=Operation '{0}' on binding '{1}' from namespace '{2}'. +FaultBinding=Fault '{0}' on operation '{1}' on binding '{2}' from namespace '{3}'. +Description=Service description with targetNamespace='{0}'. +Element={0} from service description with targetNamespace='{1}'. +Port=Port '{0}' on service {1} from namespace='{2}'. +Message=Message '{0}' from service description with targetNamespace='{1}'. +Part=Part '{0}' of message '{1}' from service description with targetNamespace='{2}'. +OperationMissingBinding=Operation '{0}' on portType '{1}' from namespace '{2}' has no matching binding. +UriValueRelative=Value '{0}' is not an absolute URI. +HelpGeneratorLanguageConfig=There is no CodeDom provider defined for the language '{0}'. +HelpGeneratorInternalError=The XML Web service help page encountered an internal error. +OperationOverload=Binding '{0}' from namespace '{1}' contains operations with matching wire signatures. Wire signature of message '{2}' matches message '{3}'. +WireSignature=Input message '{0}' from namespace '{1}' has wire signature '{2}:{3}'. +WireSignatureEmpty=Input message '{0}' from namespace '{1}' has no elements (empty wire signature) + +; wsdl validation +WsdlInstanceValidation=Warning: {0} +WsdlInstanceValidationDetails=Warning: {0} Line {1}, position {2}. + +WhenUsingAMessageStyleOfParametersAsDocument0=When using a Bare parameter style and a service RoutingStyle of RequestElement, the method must have exactly one parameter. +UnsupportedMessageStyle1=Message style {0} is not supported. +TheMethodsAndUseTheSameSoapActionWhenTheService3=The methods {0} and {1} use the same SOAPAction '{2}'. When the RoutingStyle of the XML Web service is SoapAction, SOAPAction values must be unique across methods on the XML Web service. You can change the SOAPAction with the Action parameter to the SoapDocumentMethod or SoapRpcMethod attributes, or you can specify a RoutingStyle of RequestElement on the XML Web service. +TheMethodDoesNotHaveARequestElementEither1=The method {0} does not have a request element. You can use a RoutingStyle of SoapAction on the XML Web service, use the Wrapped parameter style on the method, or add a parameter to the method. +TheMethodsAndUseTheSameRequestElementXmlns4=The methods {0} and {1} use the same request element <{2} xmlns='{3}'>. When the RoutingStyle of the XML Web service is RequestElement, request elements must be unique across methods on the XML Web service. If you are using the Rpc style, you can change the message name with the RequestElementName and RequestElementNamespace parameters to SoapRpcMethodAttribute. For document style using wrapped parameter style, use the RequestElementName and RequestElementNamespace parameters to SoapDocumentMethodAttribute. For the bare parameter style, you must change the element that represents the parameter. Alternatively, you can specify a RoutingStyle of SoapAction on the XML Web service. +TheMethodsAndUseTheSameRequestElementAndSoapActionXmlns6=The methods {0} and {1} use the same request element <{2} xmlns='{3}'> and the methods {0} and {4} use the same SOAPAction '{5}'. Each method on the XML Web service must have a unique SOAPAction or request element. If you are using the Rpc style, you can change the message name with the RequestElementName and RequestElementNamespace parameters to SoapRpcMethodAttribute. For document style using wrapped parameter style, use the RequestElementName and RequestElementNamespace parameters to SoapDocumentMethodAttribute. For the bare parameter style, you must change the element that represents the parameter. Alternatively, you can specify a unique SoapAction for each method using the Action parameter to SoapRpcMethodAttribute or SoapDocumentMethodAttribute. +TheRootElementForTheRequestCouldNotBeDetermined0=The root element for the request could not be determined. When RoutingStyle is set to RequestElement, SoapExtensions configured via an attribute on the method cannot modify the request stream before it is read. The extension must be configured via the SoapExtensionTypes element in web.config, or the request must arrive at the server as clear text. +TheRequestElementXmlnsWasNotRecognized2=The request element <{0} xmlns='{1}'> was not recognized. +ServiceDescriptionWasNotFound0=XML Web service description was not found. +internalError0=An internal error occurred. +DiscoveryIsNotPossibleBecauseTypeIsMissing1=Discovery is not possible because type '{0}' is missing a WebServiceBinding attribute. +TheBindingNamedFromNamespaceWasNotFoundIn3=The binding named '{0}' from namespace '{1}' was not found in the discovery document found at '{2}'. +Missing2=Missing {0}.{1} +MissingHttpOperationElement0=Missing http:operation element. +MessageHasNoParts1=Message '{0}' has no parts. +DuplicateInputOutputNames0=Duplicate input/output names. +MissingBinding0=The operation has no matching binding. Check if the operation, input and output names in the Binding section match with the corresponding names in the PortType section. +MissingInputBinding0=Missing input binding. +MissingOutputBinding0=Missing output binding. +UnableToImportOperation1=Unable to import operation '{0}'. +UnableToImportBindingFromNamespace2=Unable to import binding '{0}' from namespace '{1}'. +TheOperationFromNamespaceHadInvalidSyntax3=The operation '{0}' on portType '{1}' from namespace '{2}' had the following syntax error: {3} +TheOperationBindingFromNamespaceHadInvalid3=The operation binding '{0}' from namespace '{1}' had invalid syntax. {2} +IfAppSettingBaseUrlArgumentIsSpecifiedThen0=If 'appSettingBaseUrl' argument is specified then 'url' argument must also be specified. +MissingMessagePartForMessageFromNamespace3=Missing message part '{0}' for message '{1}' from namespace '{2}'. +MissingMessage2=Missing message '{0}' from namespace '{1}'. +OnlyXmlElementsOrTypesDerivingFromServiceDescriptionFormatExtension0=Only XmlElements or types deriving from ServiceDescriptionFormatExtension may be added. +OnlyOperationInputOrOperationOutputTypes=Only objects of type OperationInput or OperationOutput may be added. +ProtocolWithNameIsNotRecognized1=Protocol with name '{0}' is not recognized. +BothAndUseTheMessageNameUseTheMessageName3=Both {0} and {1} use the message name '{2}'. Use the MessageName property of the WebMethod custom attribute to specify unique message names for the methods. +MissingSoapOperationBinding0=Missing soap:operation binding. +OnlyOneWebServiceBindingAttributeMayBeSpecified1=Only one WebServiceBinding attribute may be specified on type '{0}'. +ContractOverride=Method {0} on type {1} is an implementation of the service contract interface {2}. Service Description altering attributes cannot be specified on service implementation. Please place custom attribute on the interface declaration: interface: {2}, method: {3}, attribute: {4}. +TypeIsMissingWebServiceBindingAttributeThat2=Type '{0}' is missing WebServiceBinding attribute that defines a binding named '{1}'. +MultipleBindingsWithSameName2=Type '{0}' has multiple WebServiceBinding attributes that define a binding named '{1}'. +UnknownWebServicesProtocolInConfigFile1=Unknown XML Web services protocol '{0}' in config file. +RequiredXmlFormatExtensionAttributeIsMissing1=Required XmlFormatExtension attribute is missing on class {0}. +TheSyntaxOfTypeMayNotBeExtended1=The syntax of type {0} may not be extended. +InternalConfigurationError0=Internal configuration error. +ThereIsNoSoapTransportImporterThatUnderstands1=There is no SoapTransportImporter that understands the transport '{0}'. +MissingSoapBodyInputBinding0=Missing soap:body input binding. +MissingSoapBodyOutputBinding0=Missing soap:body output binding. +TheOperationStyleRpcButBothMessagesAreNot0=The operation style=rpc but both messages are not use=encoded. +TheCombinationOfStyleRpcWithUseLiteralIsNot0=The combination of style=rpc with use=literal is not supported. +TheEncodingIsNotSupported1=The encoding '{0}' is not supported. +SpecifyingAnElementForUseEncodedMessageParts0=Specifying an element for use=encoded message parts is not supported. +EachMessagePartInAnUseEncodedMessageMustSpecify0=Each message part in an use=encoded message must specify a type. +SpecifyingATypeForUseLiteralMessagesIs0=Specifying a type for use=literal messages is not supported. +SpecifyingATypeForUseLiteralMessagesIsAny=Specifying a type for use=literal messages is not supported. Type name='{0}' from targetNamespace='{1}' cannot be used as top-level any element. +EachMessagePartInAUseLiteralMessageMustSpecify0=Each message part in a use=literal message must specify an element. +EachMessagePartInRpcUseLiteralMessageMustSpecify0=Each message part in a use=literal style=rpc message must specify a type. +NoInputMIMEFormatsWereRecognized0=No input MIME formats were recognized. +NoInputHTTPFormatsWereRecognized0=No input HTTP formats were recognized. +NoOutputMIMEFormatsWereRecognized0=No output MIME formats were recognized. +MissingMatchElement0=Missing match element. +SolicitResponseIsNotSupported0=SolicitResponse is not supported. +RequestResponseIsNotSupported0=RequestResponse is not supported. +OneWayIsNotSupported0=OneWay is not supported. +NotificationIsNotSupported0=Notification is not supported. +SyntaxErrorInWSDLDocumentMessageDoesNotHave1=Syntax error in WSDL document: Message '{0}' does not have an operation associated with it in the portType. +WebMissingBodyElement=Request format is invalid: Missing required soap:Body element. +WebMissingEnvelopeElement=Request format is invalid: Missing required soap:Envelope element. +UnableToHandleRequestActionNotRecognized1=Unable to handle request. The action '{0}' was not recognized. +UnableToHandleRequestActionRequired0=Unable to handle request without a valid action parameter. Please supply a valid soap action. +UnableToHandleRequest0=Unable to handle request. +FailedToHandleRequest0=Failed to handle request. +CodeGenSupportReferenceParameters=Declaring parameters to be 'out' or 'ref' is not supported by {0}. +CodeGenSupportParameterAttributes=Custom attributes on parameter declarations are not supported by {0}. +CodeGenSupportReturnTypeAttributes=Custom attributes on return value are not supported by {0}. + +TheBinding0FromNamespace1WasIgnored2=The binding '{0}' from namespace '{1}' was ignored. {2} +TheOperation0FromNamespace1WasIgnored2=The operation '{0}' from namespace '{1}' was ignored. {2} +TheOperationBinding0FromNamespace1WasIgnored=The operation binding '{0}' from namespace '{1}' was ignored. {2} +NoMethodsWereFoundInTheWSDLForThisProtocol=No methods were found in the WSDL for this protocol. +UnexpectedFlush=Unexpected flush +ThereWasAnErrorDuringAsyncProcessing=There was an error during async processing. +CanTCallTheEndMethodOfAnAsyncCallMoreThan=Can't call the end method of an async call more than once. +AsyncDuplicateUserState=There was an error during asynchronous processing. Unique state object is required for multiple asynchronous simultaneous operations to be outstanding. +StreamDoesNotSeek=This stream does not support seeking operations. +StreamDoesNotRead=This stream does not support read operations. +ElementTypeMustBeObjectOrSoapReflectedException=The elementType must be one of SoapReflectedExtension or Object. +ElementTypeMustBeObjectOrSoapExtensionOrSoapReflectedException=The elementType must be one of SoapExtension, SoapReflectedExtension, or Object. +ProtocolDoesNotAsyncSerialize=The protocol does not support async serialization. +ThereWasAnErrorDownloading0=There was an error downloading '{0}'. +TheHTMLDocumentDoesNotContainDiscoveryInformation=The HTML document does not contain Web service discovery information. +TheDocumentWasNotRecognizedAsAKnownDocumentType=The document was not recognized as a known document type (WSDL, XML Schema, or Discovery document) for the following reason: \n - {0} +TheDocumentWasUnderstoodButContainsErrors=The document was understood, but it could not be processed. +TheWSDLDocumentContainsLinksThatCouldNotBeResolved=The WSDL document contains links that could not be resolved. +TheSchemaDocumentContainsLinksThatCouldNotBeResolved=The XML schema document contains links that could not be resolved. +CanTSpecifyElementOnEncodedMessagePartsPart=The element attribute is not allowed on encoded message parts. The erroneous part is named '{0}' in message '{1}'. +CanTMergeMessage=Cannot add service description with targetNamespace='{0}': message with name='{1}' already present in the description collection. +CanTMergePortType=Cannot add service description with targetNamespace='{0}': portType with name='{1}' already present in the description collection. +CanTMergeBinding=Cannot add service description with targetNamespace='{0}': binding with name='{1}' already present in the description collection. +CanTMergeTypes=Cannot add service description with targetNamespace='{0}': schema with targetNamespace='{1}' already present in the description collection. +CanTMergeService=Cannot add service description with targetNamespace='{0}': service with name='{1}' already present in the description collection. +indexMustBeBetweenAnd0Inclusive=index must be between 0 and {0}, inclusive. +BPConformanceSoapEncodedMethod=WebMethod {0} on WebService {1} claims conformance, but use=encoded is non-conformant according to WS-I Basic Profile v1.1. +BPConformanceHeaderFault=WebMethod {0} on WebService {1} claims conformance. Using SOAP header with {2}={3}.{4} is not allowed on conformant methods. +WsdlGenRpcLitAnonimousType=Method {0}.{1} can not be reflected. Parameter '{2}' may not be used with Rpc\\Literal SOAP messages because it is declared using an anonymous schema type, only top-level named types can be used with rpc\\literal SOAP messages. +WsdlGenRpcLitAccessorNamespace=Method {0}.{1} can not be reflected. Parameter '{2}' has invalid accessor: If you are using the Rpc\\Literal method, you can set the part's namespace. +StackTraceEnd=--- End of inner exception stack trace --- +CodeRemarks=<remarks/> +CodegenWarningDetails=CODEGEN: {0} + +ValidationError=Error: {0} Line {1}, position {2}. +SchemaValidationError=Schema validation error: {0} +SchemaValidationWarning=Schema validation warning: {0} +SchemaSyntaxErrorDetails=Schema with targetNamespace='{0}' has invalid syntax. {1} Line {2}, position {3}. +SchemaSyntaxErrorItemDetails=Schema with targetNamespace='{0}' has invalid syntax. Check schema item '{1}' named '{2}': {3} +InitFailed=Initialization failure. Please review input options and documents for validity. + +XmlSchemaElementReference=Element reference '{0}' declared in schema type '{1}' from namespace '{2}'. +XmlSchemaAttributeReference=Attribute reference '{0}' declared in schema type '{1}' from namespace '{2}'. +XmlSchemaItem=Schema item '{1}' from namespace '{0}'. {2} +XmlSchemaNamedItem=Schema item '{1}' named '{2}' from namespace '{0}' is invalid. {3} +XmlSchemaContentDef=Check content definition of schema type '{0}' from namespace '{1}'. {2} +XmlSchema=Schema with targetNamespace='{0}' has invalid syntax. {1} + +; +; Tracing messages +; +TraceCallEnter=Calling {0}\r\n Caller: {1} +TraceCallEnterDetails=Calling {0}\r\n Method: {2}\r\n Caller: {1} +TraceCallExit=Return from {0}\r\n Caller: {1} +TraceExceptionThrown=Exception thrown in {0}.\r\n {1}: {2} +TraceExceptionCought=Exception caught in {0}.\r\n {1}: {2} +TraceExceptionIgnored=Exception ignored in {0}.\r\n {1}: {2} +TraceExceptionDetails=Exception Details:\r\n{0} +TracePostWorkItemIn=Calling WorkItem.Post({0}) +TracePostWorkItemOut=Return from WorkItem.Post({0}) + +;Caller HttpRequest info +TraceUserHostName=Request Host Name: {0} +TraceUserHostAddress=Request Host Address: {0} +TraceUrl=Request Url: [{0}] {1} +TraceUrlReferrer=Http referrer: {0} + +TraceCreateSerializer=XmlSerializer [Create XmlSerializer] +TraceWriteRequest=XmlSerializer [Write Request] +TraceWriteResponse=XmlSerializer [Write Response] +TraceWriteHeaders=XmlSerializer [Write SOAP Headers] +TraceReadRequest=XmlSerializer [Read Request] +TraceReadResponse=XmlSerializer [Read Response] +TraceReadHeaders=XmlSerializer [Read SOAP Headers] diff --git a/System.Web.Services/System/Web/Services/Description/SoapProtocolImporter.cs b/System.Web.Services/System/Web/Services/Description/SoapProtocolImporter.cs index 687a920cf..5ae945018 100644 --- a/System.Web.Services/System/Web/Services/Description/SoapProtocolImporter.cs +++ b/System.Web.Services/System/Web/Services/Description/SoapProtocolImporter.cs @@ -374,7 +374,7 @@ protected override void EndNamespace() { foreach (XmlMembersMapping member in soapMembers) soapExporter.ExportMembersMapping(member); - // NOTE, [....], we are sharing the SoapInclude and XmlInclude attributes of the + // NOTE, Microsoft, we are sharing the SoapInclude and XmlInclude attributes of the // class among ALL classes generated, This is probably OK, since doing to per // class would probably result in the same set of includes if the user // has object as a return value (meaning 'all' types are OK). @@ -1076,7 +1076,7 @@ bool CheckMessageStyles(string messageName, MessagePart[] parts, SoapBodyBinding return true; } else if (soapBindingStyle == SoapBindingStyle.Document) { - // NOTE, [....]. WSDL doesn't really let us figure out whether a document is + // NOTE, Microsoft. WSDL doesn't really let us figure out whether a document is // in fact a struct containing parameters, so we apply a little heuristic here // in order to produce the appropriate programming model. hasWrapper = (parts.Length == 1 && string.Compare(parts[0].Name, "parameters", StringComparison.Ordinal) == 0); diff --git a/System.Web.Services/System/Web/Services/Discovery/DiscoveryDocument.cs b/System.Web.Services/System/Web/Services/Discovery/DiscoveryDocument.cs index 48bfca053..30527d5c5 100644 --- a/System.Web.Services/System/Web/Services/Discovery/DiscoveryDocument.cs +++ b/System.Web.Services/System/Web/Services/Discovery/DiscoveryDocument.cs @@ -36,7 +36,7 @@ public sealed class DiscoveryDocument { public DiscoveryDocument() { } - // NOTE, [....]: This property is not really ignored by the xml serializer. Instead, + // NOTE, Microsoft: This property is not really ignored by the xml serializer. Instead, // the attributes that would go here are configured in WebServicesConfiguration's // DiscoveryDocumentSerializer property. /// <include file='doc\DiscoveryDocument.uex' path='docs/doc[@for="DiscoveryDocument.References"]/*' /> diff --git a/System.Web.Services/System/Web/Services/Discovery/DiscoveryDocumentReference.cs b/System.Web.Services/System/Web/Services/Discovery/DiscoveryDocumentReference.cs index f97304c06..097e21337 100644 --- a/System.Web.Services/System/Web/Services/Discovery/DiscoveryDocumentReference.cs +++ b/System.Web.Services/System/Web/Services/Discovery/DiscoveryDocumentReference.cs @@ -66,7 +66,7 @@ public string Ref { public override string DefaultFilename { get { string filename = FilenameFromUrl(Url); - return Path.ChangeExtension(filename, ".disco"); // [[....]] change default extension + return Path.ChangeExtension(filename, ".disco"); // [Microsoft] change default extension } } diff --git a/System.Web.Services/System/Web/Services/Discovery/DynamicVirtualDiscoSearcher.cs b/System.Web.Services/System/Web/Services/Discovery/DynamicVirtualDiscoSearcher.cs index 17f470547..863998aaf 100644 --- a/System.Web.Services/System/Web/Services/Discovery/DynamicVirtualDiscoSearcher.cs +++ b/System.Web.Services/System/Web/Services/Discovery/DynamicVirtualDiscoSearcher.cs @@ -140,7 +140,7 @@ protected override DirectoryInfo GetPhysicalDir(string dir ) { // ------------------------------------------------------------------------------- - // Calculate root ADSI virtual directory name (func by '[....]'). + // Calculate root ADSI virtual directory name (func by 'Microsoft'). private string GetWebServerForUrl(string url) { Uri uri = new Uri(url); DirectoryEntry w3Service = new DirectoryEntry("IIS://" + uri.Host + "/W3SVC"); diff --git a/System.Web.Services/System/Web/Services/Protocols/ClientProtocol.cs b/System.Web.Services/System/Web/Services/Protocols/ClientProtocol.cs index 2734fa0cb..278b35813 100644 --- a/System.Web.Services/System/Web/Services/Protocols/ClientProtocol.cs +++ b/System.Web.Services/System/Web/Services/Protocols/ClientProtocol.cs @@ -88,7 +88,7 @@ static WebClientProtocol() { /// <para>[To be supplied.]</para> /// </devdoc> protected WebClientProtocol() { - this.timeout = 100000; // should be kept in [....] with HttpWebRequest.Timeout default (see private WebRequest.DefaultTimeout) + this.timeout = 100000; // should be kept in sync with HttpWebRequest.Timeout default (see private WebRequest.DefaultTimeout) } internal WebClientProtocol(WebClientProtocol protocol) { diff --git a/System.Web.Services/System/Web/Services/Protocols/LogicalMethodInfo.cs b/System.Web.Services/System/Web/Services/Protocols/LogicalMethodInfo.cs index 1b21ea69d..1e3cb1b68 100644 --- a/System.Web.Services/System/Web/Services/Protocols/LogicalMethodInfo.cs +++ b/System.Web.Services/System/Web/Services/Protocols/LogicalMethodInfo.cs @@ -20,7 +20,7 @@ namespace System.Web.Services.Protocols { /// <para>[To be supplied.]</para> /// </devdoc> public enum LogicalMethodTypes { - /// <include file='doc\LogicalMethodInfo.uex' path='docs/doc[@for="LogicalMethodTypes.[....]"]/*' /> + /// <include file='doc\LogicalMethodInfo.uex' path='docs/doc[@for="LogicalMethodTypes.Sync"]/*' /> /// <devdoc> /// <para>[To be supplied.]</para> /// </devdoc> @@ -362,7 +362,7 @@ internal WebMethodAttribute MethodAttribute { /// <para>[To be supplied.]</para> /// </devdoc> public ICustomAttributeProvider CustomAttributeProvider { - // Custom attributes are always on the XXX ([....]) or BeginXXX (async) method. + // Custom attributes are always on the XXX (sync) or BeginXXX (async) method. get { return methodInfo; } } diff --git a/System.Web.Services/System/Web/Services/Protocols/Scalars.cs b/System.Web.Services/System/Web/Services/Protocols/Scalars.cs index 846bd630e..0d388dd5e 100644 --- a/System.Web.Services/System/Web/Services/Protocols/Scalars.cs +++ b/System.Web.Services/System/Web/Services/Protocols/Scalars.cs @@ -107,7 +107,7 @@ private static string EscapeStringInternal(string s, Encoding e, bool escapeUriS } /* - // [....]: adapted from UrlEscapeStringUnicode below + // Microsoft: adapted from UrlEscapeStringUnicode below internal static string EscapeStringUnicode(string s) { int l = s.Length; StringBuilder sb = new StringBuilder(l); @@ -126,7 +126,7 @@ internal static string EscapeStringUnicode(string s) { } */ - // [....]: copied from System.Web.HttpUtility + // Microsoft: copied from System.Web.HttpUtility internal static string UrlEscapeStringUnicode(string s) { int l = s.Length; StringBuilder sb = new StringBuilder(l); diff --git a/System.Web.Services/System/Web/Services/Protocols/SoapException.cs b/System.Web.Services/System/Web/Services/Protocols/SoapException.cs index 1e77558f9..3b88b9e16 100644 --- a/System.Web.Services/System/Web/Services/Protocols/SoapException.cs +++ b/System.Web.Services/System/Web/Services/Protocols/SoapException.cs @@ -59,7 +59,7 @@ public class SoapException : SystemException { /// <devdoc> /// <para>[To be supplied.]</para> /// </devdoc> - // NOTE, [....]: The SOAP 1.1 is unclear on whether the detail element can or should be qualified. + // NOTE, Microsoft: The SOAP 1.1 is unclear on whether the detail element can or should be qualified. // Based on consensus about the intent, we will not qualify it. public static readonly XmlQualifiedName DetailElementName = new XmlQualifiedName(Soap.Element.FaultDetail, ""); diff --git a/System.Web/AspNetEventSource.cs b/System.Web/AspNetEventSource.cs index 13648d0bf..2cfa8d059 100644 --- a/System.Web/AspNetEventSource.cs +++ b/System.Web/AspNetEventSource.cs @@ -91,7 +91,7 @@ private unsafe void RequestEnteredAspNetPipelineImpl(Guid iisActivityId, Guid as // Overload used only for deducing ETW parameters; use the public entry point instead. // // !! WARNING !! - // The logic in RequestEnteredAspNetPipelineImpl must be kept in [....] with these parameters, otherwise + // The logic in RequestEnteredAspNetPipelineImpl must be kept in sync with these parameters, otherwise // type safety violations could occur. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "ETW looks at this method using reflection.")] [Event((int)Events.RequestEnteredAspNetPipeline, Level = EventLevel.Informational, Task = (EventTask)Tasks.Request, Opcode = EventOpcode.Send, Version = 1)] @@ -118,7 +118,7 @@ private unsafe void RequestStartedImpl(IIS7WorkerRequest wr) { fixed (char* pHttpVerb = httpVerb) { // !! WARNING !! - // This logic must be kept in [....] with the ETW-deduced parameters in RequestStarted, + // This logic must be kept in sync with the ETW-deduced parameters in RequestStarted, // otherwise type safety violations could occur. const int EVENTDATA_COUNT = 3; EventData* pEventData = stackalloc EventData[EVENTDATA_COUNT]; @@ -145,7 +145,7 @@ private unsafe void RequestStartedImpl(IIS7WorkerRequest wr) { // Event attribute, but this causes a dependency between System.Web and mscorlib that breaks servicing. // // !! WARNING !! - // The logic in RequestStartedImpl must be kept in [....] with these parameters, otherwise + // The logic in RequestStartedImpl must be kept in sync with these parameters, otherwise // type safety violations could occur. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "ETW looks at this method using reflection.")] [Event((int)Events.RequestStarted, Level = EventLevel.Informational, Task = (EventTask)Tasks.Request, Opcode = EventOpcode.Start, Version = 1)] diff --git a/System.Web/Cache/CacheDependency.cs b/System.Web/Cache/CacheDependency.cs index 9e137fd5f..3bf632db8 100644 --- a/System.Web/Cache/CacheDependency.cs +++ b/System.Web/Cache/CacheDependency.cs @@ -26,10 +26,6 @@ namespace System.Web.Caching { using System.Runtime.Caching; #endif - internal interface ICacheDependencyChanged { - void DependencyChanged(Object sender, EventArgs e); - } - /// <devdoc> /// <para>The <see langword='CacheDependency'/> class tracks cache dependencies, which can be files, @@ -50,7 +46,7 @@ public class CacheDependency : IDisposable { string _uniqueID; // used by HttpCachePolicy for the ETag object _depFileInfos; // files to monitor for changes, either a DepFileInfo or array of DepFileInfos object _entries; // cache entries we are dependent on, either a string or array of strings - ICacheDependencyChanged _objNotify; // Associated object to notify when a change occurs + Action<Object, EventArgs> _objNotify; // Associated object to notify when a change occurs SafeBitVector32 _bits; // status bits for ready, used, changed, disposed DateTime _utcLastModified; // Time of last modified item #if USE_MEMORY_CACHE @@ -59,7 +55,7 @@ public class CacheDependency : IDisposable { #endif static readonly string[] s_stringsEmpty; - static readonly CacheEntry[] s_entriesEmpty; + static readonly DepCacheInfo[] s_entriesEmpty; static readonly CacheDependency s_dependencyEmpty; static readonly DepFileInfo[] s_depFileInfosEmpty; @@ -78,9 +74,14 @@ internal class DepFileInfo { internal FileAttributesData _fad; } + internal class DepCacheInfo { + internal CacheStoreProvider _cacheStore; + internal string _key; + } + static CacheDependency() { s_stringsEmpty = new string[0]; - s_entriesEmpty = new CacheEntry[0]; + s_entriesEmpty = new DepCacheInfo[0]; s_dependencyEmpty = new CacheDependency(0); s_depFileInfosEmpty = new DepFileInfo[0]; } @@ -205,7 +206,7 @@ void OnChangedCallback(object state) { void InitForMemoryCache(bool isPublic, string[] filenamesArg, string[] cachekeysArg, CacheDependency dependency, DateTime utcStart) { bool dispose = true; try { - MemCache memCache = HttpRuntime.CacheInternal as MemCache; + MemCache memCache = HttpRuntime.InternalCache as MemCache; _bits = new SafeBitVector32(0); _utcLastModified = DateTime.MinValue; IList<String> files = filenamesArg; @@ -308,9 +309,9 @@ void Init(bool isPublic, string[] filenamesArg, string[] cachekeysArg, CacheDepe } #endif DepFileInfo[] depFileInfos = s_depFileInfosEmpty; - CacheEntry[] depEntries = s_entriesEmpty; + DepCacheInfo[] depEntries = s_entriesEmpty; string [] filenames, cachekeys; - CacheInternal cacheInternal; + CacheStoreProvider cache; _bits = new SafeBitVector32(0); @@ -420,13 +421,13 @@ void Init(bool isPublic, string[] filenamesArg, string[] cachekeysArg, CacheDepe // copy cache entries if (d_entries != null) { - if (d_entries is CacheEntry) { - depEntries = new CacheEntry[1] {(CacheEntry) (d_entries)}; + if (d_entries is DepCacheInfo) { + depEntries = new DepCacheInfo[1] { (DepCacheInfo)(d_entries) }; } else { - depEntries = (CacheEntry[]) (d_entries); + depEntries = (DepCacheInfo[])(d_entries); // verify that the object was fully constructed - foreach (CacheEntry entry in depEntries) { + foreach (DepCacheInfo entry in depEntries) { if (entry == null) { _bits[CHANGED] = true; // There is nothing to dispose because we haven't started @@ -501,41 +502,32 @@ void Init(bool isPublic, string[] filenamesArg, string[] cachekeysArg, CacheDepe // Monitor other cache entries for changes int lenMyEntries = depEntries.Length + cachekeys.Length; + DateTime lastUpdated; if (lenMyEntries > 0 && !_bits[CHANGED]) { - CacheEntry[] myEntries = new CacheEntry[lenMyEntries]; + DepCacheInfo[] myEntries = new DepCacheInfo[lenMyEntries]; // Monitor entries from the existing cache dependency int i = 0; - foreach (CacheEntry entry in depEntries) { - entry.AddCacheDependencyNotify(this); + foreach (DepCacheInfo entry in depEntries) { + entry._cacheStore.AddDependent(entry._key, this, out lastUpdated); myEntries[i++] = entry; } // Monitor new entries specified for this depenedency // Entries must be added to cache, and created before the startTime - cacheInternal = HttpRuntime.CacheInternal; + cache = isPublic ? HttpRuntime.Cache.ObjectCache : HttpRuntime.Cache.InternalCache; foreach (string k in cachekeys) { - CacheEntry entry = (CacheEntry) cacheInternal.DoGet(isPublic, k, CacheGetOptions.ReturnCacheEntry); - if (entry != null) { - entry.AddCacheDependencyNotify(this); - myEntries[i++] = entry; + if (cache.AddDependent(k, this, out lastUpdated)) { + myEntries[i++] = new DepCacheInfo() { _cacheStore = cache, _key = k }; - if (entry.UtcCreated > _utcLastModified) { - _utcLastModified = entry.UtcCreated; + if (lastUpdated > _utcLastModified) { + _utcLastModified = lastUpdated; } - if ( entry.State != CacheEntry.EntryState.AddedToCache || - entry.UtcCreated > utcStart) { - + if (lastUpdated > utcStart) { // Cache item has been updated since start, consider changed #if DBG - if (entry.State != CacheEntry.EntryState.AddedToCache) { - Debug.Trace("CacheDependencyInit", "Entry is not in cache, considered changed:" + k); - } - else { - Debug.Trace("CacheDependencyInit", "Changes occurred to entry since start time:" + k); - } + Debug.Trace("CacheDependencyInit", "Changes occurred to entry since start time:" + k); #endif - _bits[CHANGED] = true; break; } @@ -583,7 +575,7 @@ public void Dispose() { // Set this bit just in case our derived ctor forgot to call FinishInit() _bits[DERIVED_INIT] = true; - if (Use()) { + if (TakeOwnership()) { // Do the dispose only if the cache has not already used us DisposeInternal(); } @@ -660,17 +652,17 @@ void DisposeOurself() { // stop monitoring cache items if (l_entries != null) { - CacheEntry oneEntry = l_entries as CacheEntry; + DepCacheInfo oneEntry = l_entries as DepCacheInfo; if (oneEntry != null) { - oneEntry.RemoveCacheDependencyNotify(this); + oneEntry._cacheStore.RemoveDependent(oneEntry._key, this); } else { - CacheEntry[] entries = (CacheEntry[]) l_entries; - foreach (CacheEntry entry in entries) { + DepCacheInfo[] entries = (DepCacheInfo[])l_entries; + foreach (DepCacheInfo entry in entries) { // ensure that we handle partially contructed // objects by checking entry for null if (entry != null) { - entry.RemoveCacheDependencyNotify(this); + entry._cacheStore.RemoveDependent(entry._key, this); } } } @@ -686,8 +678,10 @@ void DisposeOurself() { #endif } - // allow the first user to declare ownership - internal bool Use() { + /// <devdoc> + /// <para>Allow the first user to declare exclusive ownership of this dependency.</para> + /// </devdoc> + public bool TakeOwnership() { return _bits.ChangeValue(USED, true); } @@ -706,22 +700,38 @@ public DateTime UtcLastModified { } } - protected void SetUtcLastModified(DateTime utcLastModified) { _utcLastModified = utcLastModified; } - // - // Add/remove an NotifyDependencyChanged notification. - // - internal void SetCacheDependencyChanged(ICacheDependencyChanged objNotify) { + public void KeepDependenciesAlive() { + if (_entries != null) { + // update the last access time of every cache item that depends on this dependency + DepCacheInfo oneEntry = _entries as DepCacheInfo; + if (oneEntry != null) { + oneEntry._cacheStore.Get(oneEntry._key); + return; + } + + foreach (DepCacheInfo entry in (DepCacheInfo[])_entries) { + if (entry != null) { + object item = entry._cacheStore.Get(entry._key); + } + } + } + } + + /// <devdoc> + /// <para>Add an Action to handle notifying interested party in changes to this dependency.</para> + /// </devdoc> + public void SetCacheDependencyChanged(Action<Object, EventArgs> dependencyChangedAction) { Debug.Assert(_objNotify == null, "_objNotify == null"); // Set this bit just in case our derived ctor forgot to call FinishInit() _bits[DERIVED_INIT] = true; - + if (!_bits[BASE_DISPOSED]) { - _objNotify = objNotify; + _objNotify = dependencyChangedAction; } } @@ -768,23 +778,23 @@ void InitUniqueID() { // get unique id from cache entries l_entries = _entries; if (l_entries != null) { - CacheEntry oneEntry = l_entries as CacheEntry; + DepCacheInfo oneEntry = l_entries as DepCacheInfo; if (oneEntry != null) { if (sb == null) sb = new StringBuilder(); - sb.Append(oneEntry.Key); - sb.Append(oneEntry.UtcCreated.Ticks.ToString(CultureInfo.InvariantCulture)); + sb.Append(oneEntry._key); + sb.Append(oneEntry.GetHashCode().ToString(CultureInfo.InvariantCulture)); } else { - CacheEntry[] entries = (CacheEntry[]) l_entries; - foreach (CacheEntry entry in entries) { + DepCacheInfo[] entries = (DepCacheInfo[])l_entries; + foreach (DepCacheInfo entry in entries) { // ensure that we handle partially contructed // objects by checking entry for null if (entry != null) { if (sb == null) sb = new StringBuilder(); - sb.Append(entry.Key); - sb.Append(entry.UtcCreated.Ticks.ToString(CultureInfo.InvariantCulture)); + sb.Append(entry._key); + sb.Append(entry.GetHashCode().ToString(CultureInfo.InvariantCulture)); } } } @@ -805,24 +815,6 @@ public virtual string GetUniqueID() { return _uniqueID; } - // - // Return the cacheEntries monitored by this dependency - // - internal CacheEntry[] CacheEntries { - get { - if (_entries == null) { - return null; - } - - CacheEntry oneEntry = _entries as CacheEntry; - if (oneEntry != null) { - return new CacheEntry[1] {oneEntry}; - } - - return (CacheEntry[]) _entries; - } - } - // // This object has changed, so fire the NotifyDependencyChanged event. // We only allow this event to be fired once. @@ -832,20 +824,20 @@ protected void NotifyDependencyChanged(Object sender, EventArgs e) { if (_bits.ChangeValue(CHANGED, true)) { _utcLastModified = DateTime.UtcNow; - ICacheDependencyChanged objNotify = _objNotify; - if (objNotify != null && !_bits[BASE_DISPOSED]) { + Action<Object, EventArgs> action = _objNotify as Action<Object, EventArgs>; + if (action != null && !_bits[BASE_DISPOSED]) { Debug.Trace("CacheDependencyNotifyDependencyChanged", "change occurred"); - objNotify.DependencyChanged(sender, e); + action(sender, e); } DisposeInternal(); } } - // - // ItemRemoved is called when a cache entry we are monitoring has been removed. - // - internal void ItemRemoved() { + /// <devdoc> + /// <para>ItemRemoved should be called when an ICacheEntry we are monitoring has been removed.</para> + /// </devdoc> + public void ItemRemoved() { NotifyDependencyChanged(this, EventArgs.Empty); } @@ -880,12 +872,12 @@ internal virtual bool IsFileDependency() // Check and see if we are dependent on any cache entries l_entries = _entries; if (l_entries != null) { - CacheEntry oneEntry = l_entries as CacheEntry; + DepCacheInfo oneEntry = l_entries as DepCacheInfo; if (oneEntry != null) { return false; } else { - CacheEntry[] entries = (CacheEntry[]) l_entries; + DepCacheInfo[] entries = (DepCacheInfo[]) l_entries; if (entries != null && entries.Length > 0) { return false; } @@ -952,7 +944,7 @@ public virtual string[] GetFileDependencies() } } - public sealed class AggregateCacheDependency : CacheDependency, ICacheDependencyChanged { + public sealed class AggregateCacheDependency : CacheDependency { ArrayList _dependencies; bool _disposed; @@ -979,10 +971,9 @@ public void Add(params CacheDependency [] dependencies) { throw new ArgumentNullException("dependencies"); } - if (!d.Use()) { + if (!d.TakeOwnership()) { throw new InvalidOperationException(SR.GetString(SR.Cache_dependency_used_more_that_once)); - } - } + } } // add dependencies, and check if any have changed bool hasChanged = false; @@ -995,7 +986,9 @@ public void Add(params CacheDependency [] dependencies) { _dependencies.AddRange(dependencies); foreach (CacheDependency d in dependencies) { - d.SetCacheDependencyChanged(this); + d.SetCacheDependencyChanged((Object sender, EventArgs args) => { + DependencyChanged(sender, args); + }); if (d.UtcLastModified > utcLastModified) { utcLastModified = d.UtcLastModified; @@ -1041,7 +1034,7 @@ protected override void DependencyDispose() { // Forward call from the aggregate to the CacheEntry /// <internalonly/> - void ICacheDependencyChanged.DependencyChanged(Object sender, EventArgs e) { + void DependencyChanged(Object sender, EventArgs e) { NotifyDependencyChanged(sender, e); } @@ -1122,7 +1115,7 @@ internal override bool IsFileDependency() return true; } - + /// <summary> /// This method will return only the file dependencies from this dependency /// </summary> diff --git a/System.Web/Cache/CacheEntry.cs b/System.Web/Cache/CacheEntry.cs index ff86e2dec..e7c2c42c4 100644 --- a/System.Web/Cache/CacheEntry.cs +++ b/System.Web/Cache/CacheEntry.cs @@ -50,8 +50,8 @@ internal CacheKey(String key, bool isPublic) { #endif } - internal String Key { - get {return _key;} + internal String Key { + get { return _key; } } internal bool IsOutputCache { @@ -81,9 +81,7 @@ public override string ToString() { * An entry in the cache. * Overhead is 68 bytes + object header. */ - internal sealed class CacheEntry : CacheKey, ICacheDependencyChanged { - static readonly DateTime NoAbsoluteExpiration = DateTime.MaxValue; - static readonly TimeSpan NoSlidingExpiration = TimeSpan.Zero; + internal sealed class CacheEntry : CacheKey { const CacheItemPriority CacheItemPriorityMin = CacheItemPriority.Low; const CacheItemPriority CacheItemPriorityMax = CacheItemPriority.NotRemovable; static readonly TimeSpan OneYear = new TimeSpan(365, 0, 0, 0); @@ -116,12 +114,13 @@ internal enum EntryState : byte { byte _usageBucket; /* index of the usage list (== priority-1) */ UsageEntryRef _usageEntryRef; /* ref into the usage list */ DateTime _utcLastUpdate; /* time we last updated usage */ + CacheInternal _cache; // dependencies CacheDependency _dependency; /* dependencies this item has */ object _onRemovedTargets; /* targets of OnRemove notification */ - /* + /* * ctor. */ @@ -130,10 +129,11 @@ internal CacheEntry( Object value, CacheDependency dependency, CacheItemRemovedCallback onRemovedHandler, - DateTime utcAbsoluteExpiration, + DateTime utcAbsoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, - bool isPublic) : + bool isPublic, + CacheInternal cache) : base(key, isPublic) { @@ -176,6 +176,8 @@ internal CacheEntry( else { _usageBucket = (byte) (priority - 1); } + + _cache = cache; } internal Object Value { @@ -248,21 +250,23 @@ internal void MonitorDependencyChanges() { // need to protect against the item being closed CacheDependency dependency = _dependency; if (dependency != null && State == EntryState.AddedToCache) { - if (!dependency.Use()) { + if (!dependency.TakeOwnership()) { throw new InvalidOperationException( SR.GetString(SR.Cache_dependency_used_more_that_once)); } - dependency.SetCacheDependencyChanged(this); + dependency.SetCacheDependencyChanged((Object sender, EventArgs args) => { + DependencyChanged(sender, args); + }); } } /* * The entry has changed, so remove ourselves from the cache. */ - void ICacheDependencyChanged.DependencyChanged(Object sender, EventArgs e) { + void DependencyChanged(Object sender, EventArgs e) { if (State == EntryState.AddedToCache) { - HttpRuntime.CacheInternal.Remove(this, CacheItemRemovedReason.DependencyChanged); + _cache.Remove(this, CacheItemRemovedReason.DependencyChanged); } } @@ -369,7 +373,7 @@ internal void Close(CacheItemRemovedReason reason) { } #endif - internal void AddCacheDependencyNotify(CacheDependency dependency) { + internal void AddDependent(CacheDependency dependency) { lock (this) { if (_onRemovedTargets == null) { _onRemovedTargets = dependency; @@ -387,16 +391,14 @@ internal void AddCacheDependencyNotify(CacheDependency dependency) { } } - internal void RemoveCacheDependencyNotify(CacheDependency dependency) { + internal void RemoveDependent(CacheDependency dependency) { lock (this) { if (_onRemovedTargets != null) { if (_onRemovedTargets == dependency) { _onRemovedTargets = null; } - else { - // We assume the dependency must exist, so we don't need - // to test for a cast. - Hashtable h = (Hashtable) _onRemovedTargets; + else if (_onRemovedTargets is Hashtable) { + Hashtable h = (Hashtable)_onRemovedTargets; h.Remove(dependency); if (h.Count == 0) { _onRemovedTargets = null; diff --git a/System.Web/Cache/OutputCache.cs b/System.Web/Cache/OutputCache.cs index f09d460df..726f9801a 100644 --- a/System.Web/Cache/OutputCache.cs +++ b/System.Web/Cache/OutputCache.cs @@ -282,29 +282,17 @@ private static CachedRawResponse Convert(OutputCacheEntry oce) { // - // helpers for accessing CacheInternal + // helpers for accessing InternalCache // // add CachedVary private static CachedVary UtcAdd(String key, CachedVary cachedVary) { - return (CachedVary) HttpRuntime.CacheInternal.UtcAdd(key, - cachedVary, - null /*dependencies*/, - Cache.NoAbsoluteExpiration, - Cache.NoSlidingExpiration, - CacheItemPriority.Normal, - null /*callback*/); + return (CachedVary) HttpRuntime.Cache.InternalCache.Add(key, cachedVary, null); } // add ControlCachedVary private static ControlCachedVary UtcAdd(String key, ControlCachedVary cachedVary) { - return (ControlCachedVary) HttpRuntime.CacheInternal.UtcAdd(key, - cachedVary, - null /*dependencies*/, - Cache.NoAbsoluteExpiration, - Cache.NoSlidingExpiration, - CacheItemPriority.Normal, - null /*callback*/); + return (ControlCachedVary) HttpRuntime.Cache.InternalCache.Add(key, cachedVary, null); } private static bool IsSubstBlockSerializable(HttpRawResponse rawResponse) { @@ -391,7 +379,7 @@ private static void EntryRemovedCallback(string key, object value, CacheItemRemo String kernelCacheUrl = cachedRawResponse._kernelCacheUrl; // if it is kernel cached, the url will be non-null. // if the entry was re-inserted, don't remove kernel entry since it will be updated - if (kernelCacheUrl != null && HttpRuntime.CacheInternal.Get(key) == null) { + if (kernelCacheUrl != null && HttpRuntime.Cache.InternalCache.Get(key) == null) { // invalidate kernel cache entry if (HttpRuntime.UseIntegratedPipeline) { UnsafeIISMethods.MgdFlushKernelCache(kernelCacheUrl); @@ -462,7 +450,7 @@ internal static bool HasDependencyChanged(bool isFragment, string depKey, string } // is the file dependency already in the in-memory cache? - if (HttpRuntime.CacheInternal.Get(depKey) != null) { + if (HttpRuntime.Cache.InternalCache.Get(depKey) != null) { #if DBG Debug.Trace("OutputCache", "HasDependencyChanged(" + depKey + ", ..., " + oceKey + ", ...) --> false"); #endif @@ -480,9 +468,10 @@ internal static bool HasDependencyChanged(bool isFragment, string depKey, string // have the file dependencies changed? if (String.Compare(dep.GetUniqueID(), 0, depKey, idStartIndex, idLength, StringComparison.Ordinal) == 0) { // file dependencies have not changed--cache them with callback to remove OutputCacheEntry if they change - HttpRuntime.CacheInternal.UtcInsert(depKey, new DependencyCacheEntry(oceKey, kernelKey, providerName), dep, - Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, - CacheItemPriority.Normal, callback); + HttpRuntime.Cache.InternalCache.Insert(depKey, new DependencyCacheEntry(oceKey, kernelKey, providerName), new CacheInsertOptions() { + Dependencies = dep, + OnRemovedCallback = callback + }); #if DBG Debug.Trace("OutputCache", "HasDependencyChanged(" + depKey + ", ..., " + oceKey + ", ...) --> false, DEPENDENCY RE-INSERTED"); #endif @@ -545,7 +534,7 @@ internal static Object Get(String key) { } } if (result == null) { - result = HttpRuntime.CacheInternal.Get(key); + result = HttpRuntime.Cache.InternalCache.Get(key); #if DBG string typeName = (result != null) ? result.GetType().Name : "null"; Debug.Trace("OutputCache", "Get(" + key + ") --> " + typeName + ", CacheInternal"); @@ -580,7 +569,7 @@ internal static Object GetFragment(String key, String providerName) { } if (result == null) { - result = HttpRuntime.CacheInternal.Get(key); + result = HttpRuntime.Cache.InternalCache.Get(key); #if DBG string typeName = (result != null) ? result.GetType().Name : "null"; Debug.Trace("OutputCache", "GetFragment(" + key + "," + providerName + ") --> " + typeName + ", CacheInternal"); @@ -601,7 +590,7 @@ internal static void Remove(String key, HttpContext context) { // If the context is null, then we don't know which // provider and we have to check all. - HttpRuntime.CacheInternal.Remove(key); + HttpRuntime.Cache.InternalCache.Remove(key); if (context == null) { // remove from all providers since we don't know which one it's in. @@ -654,7 +643,7 @@ internal static void RemoveFragment(String key, String providerName) { if (provider != null) { provider.Remove(key); } - HttpRuntime.CacheInternal.Remove(key); + HttpRuntime.Cache.InternalCache.Remove(key); #if DBG Debug.Trace("OutputCache", "RemoveFragment(" + key + "," + providerName + ")"); #endif @@ -708,7 +697,7 @@ internal static void InsertFragment(String cachedVaryKey, ControlCachedVary cach if (!cachedVary.Equals(cachedVaryInCache)) { // overwrite existing cached vary if (!useProvider) { - HttpRuntime.CacheInternal.UtcInsert(cachedVaryKey, cachedVary); + HttpRuntime.Cache.InternalCache.Insert(cachedVaryKey, cachedVary, null); } else { provider.Set(cachedVaryKey, cachedVary, Cache.NoAbsoluteExpiration); @@ -733,11 +722,11 @@ internal static void InsertFragment(String cachedVaryKey, ControlCachedVary cach // Now insert into the cache (use cache provider if possible, otherwise use internal cache) if (!useProvider) { - HttpRuntime.CacheInternal.UtcInsert(fragmentKey, fragment, - dependencies, - absExp, slidingExp, - CacheItemPriority.Normal, - null); + HttpRuntime.Cache.InternalCache.Insert(fragmentKey, fragment, new CacheInsertOptions() { + Dependencies = dependencies, + AbsoluteExpiration = absExp, + SlidingExpiration = slidingExp + }); } else { string depKey = null; @@ -749,10 +738,12 @@ internal static void InsertFragment(String cachedVaryKey, ControlCachedVary cach provider.Set(fragmentKey, fragment, absExp); if (dependencies != null) { // use Add and dispose dependencies if there's already one in the cache - Object d = HttpRuntime.CacheInternal.UtcAdd(depKey, new DependencyCacheEntry(fragmentKey, null, provider.Name), - dependencies, - absExp, Cache.NoSlidingExpiration, - CacheItemPriority.Normal, s_dependencyRemovedCallbackForFragment); + Object d = HttpRuntime.Cache.InternalCache.Add(depKey, new DependencyCacheEntry(fragmentKey, null, provider.Name), + new CacheInsertOptions() { + Dependencies = dependencies, + AbsoluteExpiration = absExp, + OnRemovedCallback = s_dependencyRemovedCallbackForFragment + }); if (d != null) { dependencies.Dispose(); } @@ -768,7 +759,7 @@ internal static void InsertFragment(String cachedVaryKey, ControlCachedVary cach + fragmentKey + ", PartialCachingCacheEntry, ...) -->" + providerUsed); #endif - } + } // insert cached vary or output cache entry internal static void InsertResponse(String cachedVaryKey, CachedVary cachedVary, @@ -820,7 +811,7 @@ internal static void InsertResponse(String cachedVaryKey, CachedVary cachedVary, if (cachedVaryInCache != null) { if (!cachedVary.Equals(cachedVaryInCache)) { if (!useProvider) { - HttpRuntime.CacheInternal.UtcInsert(cachedVaryKey, cachedVary); + HttpRuntime.Cache.InternalCache.Insert(cachedVaryKey, cachedVary, null); } else { provider.Set(cachedVaryKey, cachedVary, Cache.NoAbsoluteExpiration); @@ -845,11 +836,12 @@ internal static void InsertResponse(String cachedVaryKey, CachedVary cachedVary, // Now insert into the cache (use cache provider if possible, otherwise use internal cache) if (!useProvider) { - HttpRuntime.CacheInternal.UtcInsert(rawResponseKey, rawResponse, - dependencies, - absExp, slidingExp, - CacheItemPriority.Normal, - s_entryRemovedCallback); + HttpRuntime.Cache.InternalCache.Insert(rawResponseKey, rawResponse, new CacheInsertOptions() { + Dependencies = dependencies, + AbsoluteExpiration = absExp, + SlidingExpiration = slidingExp, + OnRemovedCallback = s_entryRemovedCallback + }); IncrementCount(); @@ -867,10 +859,12 @@ internal static void InsertResponse(String cachedVaryKey, CachedVary cachedVary, provider.Set(rawResponseKey, oce, absExp); if (dependencies != null) { // use Add and dispose dependencies if there's already one in the cache - Object d = HttpRuntime.CacheInternal.UtcAdd(depKey, new DependencyCacheEntry(rawResponseKey, oce.KernelCacheUrl, provider.Name), - dependencies, - absExp, Cache.NoSlidingExpiration, - CacheItemPriority.Normal, s_dependencyRemovedCallback); + Object d = HttpRuntime.Cache.InternalCache.Add(depKey, new DependencyCacheEntry(rawResponseKey, oce.KernelCacheUrl, provider.Name), + new CacheInsertOptions() { + Dependencies = dependencies, + AbsoluteExpiration = absExp, + OnRemovedCallback = s_dependencyRemovedCallbackForFragment + }); if (d != null) { dependencies.Dispose(); } diff --git a/System.Web/Cache/SqlCacheDependency.cs b/System.Web/Cache/SqlCacheDependency.cs index 32b120a22..a80aba01a 100644 --- a/System.Web/Cache/SqlCacheDependency.cs +++ b/System.Web/Cache/SqlCacheDependency.cs @@ -69,7 +69,7 @@ public SqlCacheDependency(string databaseEntryName, string tableName) { Debug.Trace("SqlCacheDependency", "Depend on key=" + GetDependKey(databaseEntryName, tableName) + "; value=" + - HttpRuntime.CacheInternal[GetDependKey(databaseEntryName, tableName)]); + HttpRuntime.Cache.InternalCache.Get(GetDependKey(databaseEntryName, tableName))); // Permission checking is done in GetDependKey() @@ -77,7 +77,7 @@ public SqlCacheDependency(string databaseEntryName, string tableName) _sql7DepInfo._database = databaseEntryName; _sql7DepInfo._table = tableName; - object o = HttpRuntime.CacheInternal[GetDependKey(databaseEntryName, tableName)]; + object o = HttpRuntime.Cache.InternalCache.Get(GetDependKey(databaseEntryName, tableName)); if (o == null) { // If the cache entry can't be found, this cache dependency will be set to CHANGED already. _sql7ChangeId = -1; @@ -756,7 +756,7 @@ internal static void PollDatabaseForChanges(DatabaseNotifState dbState, bool fro SqlCommand sqlCmd = null; int changeId; string tableName; - CacheInternal cacheInternal = HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; string monitorKey; object obj; bool notifEnabled = false; @@ -864,33 +864,28 @@ internal static void PollDatabaseForChanges(DatabaseNotifState dbState, bool fro "Database=" + dbState._database+ "; tableName=" + tableName + "; changeId=" + changeId); monitorKey = GetMoniterKey(dbState._database, tableName); - obj = cacheInternal[monitorKey]; + obj = cacheInternal.Get(monitorKey); if (obj == null) { Debug.Assert(!dbState._tables.ContainsKey(tableName), - "DatabaseNotifStae._tables and internal cache keys should be in-[....]"); + "DatabaseNotifStae._tables and internal cache keys should be in-sync"); Debug.Trace("SqlCacheDependencyManagerPolling", "Add Database=" + dbState._database+ "; tableName=" + tableName + "; changeId=" + changeId); - cacheInternal.UtcAdd(monitorKey, changeId, null, - Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, - CacheItemPriority.NotRemovable, null); - + cacheInternal.Add(monitorKey, changeId, new CacheInsertOptions() { Priority = CacheItemPriority.NotRemovable }); dbState._tables.Add(tableName, null); } else if (changeId != (int)obj) { Debug.Assert(dbState._tables.ContainsKey(tableName), - "DatabaseNotifStae._tables and internal cache keys should be in-[....]"); + "DatabaseNotifStae._tables and internal cache keys should be in-sync"); Debug.Trace("SqlCacheDependencyManagerPolling", "Change Database=" + dbState._database+ "; tableName=" + tableName + "; old=" + (int)obj + "; new=" + changeId); // ChangeId is different. It means some table changes have happened. // Update local cache value - cacheInternal.UtcInsert(monitorKey, changeId, null, - Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, - CacheItemPriority.NotRemovable, null); + cacheInternal.Insert(monitorKey, changeId, new CacheInsertOptions() { Priority = CacheItemPriority.NotRemovable }); } originalTables.Remove(tableName); @@ -1001,8 +996,8 @@ static internal void EnsureTableIsRegisteredAndPolled(string database, string ta // for this table has successfully completed Debug.Trace("SqlCacheDependencyManagerCheck", "Check is called. Database=" + database+ "; table=" + table); - - if (HttpRuntime.CacheInternal[GetMoniterKey(database, table)] != null) { + + if (HttpRuntime.Cache.InternalCache.Get(GetMoniterKey(database, table)) != null) { return; } diff --git a/System.Web/Cache/cache.cs b/System.Web/Cache/cache.cs index 0dd2f027e..a597396f6 100644 --- a/System.Web/Cache/cache.cs +++ b/System.Web/Cache/cache.cs @@ -14,8 +14,10 @@ namespace System.Web.Caching { using System.Collections; using System.Collections.Specialized; using System.Configuration; + using System.Configuration.Provider; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; + using System.Reflection; using System.Runtime.InteropServices; using System.Threading; using System.Web.Util; @@ -150,12 +152,6 @@ public enum CacheItemUpdateReason { DependencyChanged } - enum CacheGetOptions { - None = 0, - ReturnCacheEntry = 0x1, - } - - /// <devdoc> /// <para>Implements the cache for a Web application. There is only one instance of /// this class per application domain, and it remains valid only as long as the @@ -165,9 +161,7 @@ enum CacheGetOptions { // // Extra notes: - // - The Cache object contains a CacheInternal object. - // - The CacheInternal object is either a CacheSingle, or a CacheMultiple which contains mulitple - // CacheSingle objects. + // - The Cache object contains a ICacheStore object and wraps it for public consumption. // public sealed class Cache : IEnumerable { @@ -187,7 +181,8 @@ public sealed class Cache : IEnumerable { /// </devdoc> public static readonly TimeSpan NoSlidingExpiration = TimeSpan.Zero; - CacheInternal _cacheInternal; + static CacheStoreProvider _objectCache = null; + static CacheStoreProvider _internalCache = null; static CacheItemRemovedCallback s_sentinelRemovedCallback = new CacheItemRemovedCallback(SentinelEntry.OnCacheItemRemovedCallback); /// <internalonly/> @@ -204,10 +199,6 @@ public Cache() { internal Cache(int dummy) { } - internal void SetCacheInternal(CacheInternal cacheInternal) { - _cacheInternal = cacheInternal; - } - /// <devdoc> /// <para>Gets the number of items stored in the cache. This value can be useful when @@ -216,14 +207,86 @@ internal void SetCacheInternal(CacheInternal cacheInternal) { /// </devdoc> public int Count { get { - return _cacheInternal.PublicCount; + return Convert.ToInt32(ObjectCache.ItemCount); + } + } + + + internal CacheStoreProvider GetInternalCache(bool createIfDoesNotExist) { + if (_internalCache == null && createIfDoesNotExist) { + lock (this) { + if (_internalCache == null) { + NameValueCollection cacheProviderSettings = HostingEnvironment.CacheStoreProviderSettings; + + if (cacheProviderSettings != null) { + string providerName = (string)cacheProviderSettings["name"]; // Grab this now, as InstantiateProvider will remove it from settings + cacheProviderSettings["isPublic"] = "false"; + _internalCache = (CacheStoreProvider)ProvidersHelper.InstantiateProvider(cacheProviderSettings, typeof(CacheStoreProvider)); + _internalCache.Initialize(providerName, cacheProviderSettings); + } + else { + if (_objectCache is AspNetCache) { + _internalCache = new AspNetCache((AspNetCache)_objectCache, isPublic: false); + } + else { + _internalCache = new AspNetCache(isPublic: false); + } + _internalCache.Initialize(null, new NameValueCollection()); + } + } + } + } + + return _internalCache; + } + + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] + [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "We carefully control this method's callers.")] + internal CacheStoreProvider GetObjectCache(bool createIfDoesNotExist) { + if (_objectCache == null && createIfDoesNotExist) { + lock (this) { + if (_objectCache == null) { + NameValueCollection cacheProviderSettings = HostingEnvironment.CacheStoreProviderSettings; + + if (cacheProviderSettings != null) { + string providerName = (string)cacheProviderSettings["name"]; // Grab this now, as InstantiateProvider will remove it from settings + cacheProviderSettings["isPublic"] = "true"; + _objectCache = (CacheStoreProvider)ProvidersHelper.InstantiateProvider(cacheProviderSettings, typeof(CacheStoreProvider)); + _objectCache.Initialize(providerName, cacheProviderSettings); + } + else { + if (_internalCache is AspNetCache) { + _objectCache = new AspNetCache((AspNetCache)_internalCache, isPublic: true); + } + else { + _objectCache = new AspNetCache(isPublic: true); + } + _objectCache.Initialize(null, new NameValueCollection()); + } + } + } } + + return _objectCache; + } + + /// <devdoc> + /// <para>Provides access to the cache store used by ASP.Net internals.</para> + /// </devdoc> + internal CacheStoreProvider InternalCache { + get { return GetInternalCache(createIfDoesNotExist: true); } } + /// <devdoc> + /// <para>Provides access to the cache store that backs HttpRuntime.Cache.</para> + /// </devdoc> + internal CacheStoreProvider ObjectCache { + get { return GetObjectCache(createIfDoesNotExist: true); } + } /// <internalonly/> IEnumerator IEnumerable.GetEnumerator() { - return ((IEnumerable)_cacheInternal).GetEnumerator(); + return ObjectCache.GetEnumerator(); } @@ -233,7 +296,7 @@ IEnumerator IEnumerable.GetEnumerator() { /// while this method is enumerating through the cache items.</para> /// </devdoc> public IDictionaryEnumerator GetEnumerator() { - return _cacheInternal.GetEnumerator(); + return ObjectCache.GetEnumerator(); } @@ -330,11 +393,7 @@ public static void OnCacheItemRemovedCallback(string key, object value, CacheIte /// <para>Retrieves an item from the cache.</para> /// </devdoc> public object Get(string key) { - return _cacheInternal.DoGet(true, key, CacheGetOptions.None); - } - - internal object Get(string key, CacheGetOptions getOptions) { - return _cacheInternal.DoGet(true, key, getOptions); + return ObjectCache.Get(key); } @@ -342,16 +401,7 @@ internal object Get(string key, CacheGetOptions getOptions) { /// <para>Inserts an item into the Cache with default values.</para> /// </devdoc> public void Insert(string key, object value) { - _cacheInternal.DoInsert( - true, - key, - value, - null, - NoAbsoluteExpiration, - NoSlidingExpiration, - CacheItemPriority.Default, - null, - true); + ObjectCache.Insert(key, value, options: null); } @@ -360,16 +410,7 @@ public void Insert(string key, object value) { /// dependencies.</para> /// </devdoc> public void Insert(string key, object value, CacheDependency dependencies) { - _cacheInternal.DoInsert( - true, - key, - value, - dependencies, - NoAbsoluteExpiration, - NoSlidingExpiration, - CacheItemPriority.Default, - null, - true); + ObjectCache.Insert(key, value, new CacheInsertOptions() { Dependencies = dependencies }); } @@ -379,16 +420,11 @@ public void Insert(string key, object value, CacheDependency dependencies) { /// </devdoc> public void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration) { DateTime utcAbsoluteExpiration = DateTimeUtil.ConvertToUniversalTime(absoluteExpiration); - _cacheInternal.DoInsert( - true, - key, - value, - dependencies, - utcAbsoluteExpiration, - slidingExpiration, - CacheItemPriority.Default, - null, - true); + ObjectCache.Insert(key, value, new CacheInsertOptions() { + Dependencies = dependencies, + AbsoluteExpiration = absoluteExpiration, + SlidingExpiration = slidingExpiration + }); } @@ -402,16 +438,13 @@ public void Insert( CacheItemRemovedCallback onRemoveCallback) { DateTime utcAbsoluteExpiration = DateTimeUtil.ConvertToUniversalTime(absoluteExpiration); - _cacheInternal.DoInsert( - true, - key, - value, - dependencies, - utcAbsoluteExpiration, - slidingExpiration, - priority, - onRemoveCallback, - true); + ObjectCache.Insert(key, value, new CacheInsertOptions() { + Dependencies = dependencies, + AbsoluteExpiration = utcAbsoluteExpiration, + SlidingExpiration = slidingExpiration, + Priority = priority, + OnRemovedCallback = onRemoveCallback + }); } // DevDiv Bugs 162763: @@ -432,16 +465,8 @@ public void Insert( } DateTime utcAbsoluteExpiration = DateTimeUtil.ConvertToUniversalTime(absoluteExpiration); // Insert updatable cache entry - _cacheInternal.DoInsert ( - true, - key, - value, - null, - Cache.NoAbsoluteExpiration, - Cache.NoSlidingExpiration, - CacheItemPriority.NotRemovable, - null, - true); + ObjectCache.Insert(key, value, new CacheInsertOptions() { Priority = CacheItemPriority.NotRemovable }); + // Ensure the sentinel depends on its updatable entry string[] cacheKeys = { key }; CacheDependency expensiveObjectDep = new CacheDependency(null, cacheKeys); @@ -453,17 +478,17 @@ public void Insert( deps.Add(dependencies, expensiveObjectDep); dependencies = deps; } - // Insert sentinel entry for the updatable cache entry - _cacheInternal.DoInsert( - false, + // Insert sentinel entry for the updatable cache entry + HttpRuntime.Cache.InternalCache.Insert( CacheInternal.PrefixValidationSentinel + key, new SentinelEntry(key, expensiveObjectDep, onUpdateCallback), - dependencies, - utcAbsoluteExpiration, - slidingExpiration, - CacheItemPriority.NotRemovable, - Cache.s_sentinelRemovedCallback, - true); + new CacheInsertOptions() { + Dependencies = dependencies, + AbsoluteExpiration = utcAbsoluteExpiration, + SlidingExpiration = slidingExpiration, + Priority = CacheItemPriority.NotRemovable, + OnRemovedCallback = Cache.s_sentinelRemovedCallback + }); } @@ -477,16 +502,13 @@ public object Add( CacheItemRemovedCallback onRemoveCallback) { DateTime utcAbsoluteExpiration = DateTimeUtil.ConvertToUniversalTime(absoluteExpiration); - return _cacheInternal.DoInsert( - true, - key, - value, - dependencies, - utcAbsoluteExpiration, - slidingExpiration, - priority, - onRemoveCallback, - false); + return ObjectCache.Add(key, value, new CacheInsertOptions() { + Dependencies = dependencies, + AbsoluteExpiration = utcAbsoluteExpiration, + SlidingExpiration = slidingExpiration, + Priority = priority, + OnRemovedCallback = onRemoveCallback + }); } @@ -494,1555 +516,21 @@ public object Add( /// <para>Removes the specified item from the cache. </para> /// </devdoc> public object Remove(string key) { - CacheKey cacheKey = new CacheKey(key, true); - return _cacheInternal.DoRemove(cacheKey, CacheItemRemovedReason.Removed); + return ObjectCache.Remove(key, CacheItemRemovedReason.Removed); } public long EffectivePrivateBytesLimit { get { - return _cacheInternal.EffectivePrivateBytesLimit; + return AspNetMemoryMonitor.ProcessPrivateBytesLimit; } } public long EffectivePercentagePhysicalMemoryLimit { get { - return _cacheInternal.EffectivePercentagePhysicalMemoryLimit; - } - } - } - - class CacheCommon { - const int MEMORYSTATUS_INTERVAL_5_SECONDS = 5 * Msec.ONE_SECOND; - const int MEMORYSTATUS_INTERVAL_30_SECONDS = 30 * Msec.ONE_SECOND; - - internal CacheInternal _cacheInternal; - internal Cache _cachePublic; - internal protected CacheMemoryStats _cacheMemoryStats; - private object _timerLock = new object(); - private DisposableGCHandleRef<Timer> _timerHandleRef; - private int _currentPollInterval = MEMORYSTATUS_INTERVAL_30_SECONDS; - internal int _inCacheManagerThread; - internal bool _enableMemoryCollection; - internal bool _enableExpiration; - internal bool _internalConfigRead; - internal SRefMultiple _srefMultiple; - private int _disposed = 0; - - internal CacheCommon() { - _cachePublic = new Cache(0); - _srefMultiple = new SRefMultiple(); - _cacheMemoryStats = new CacheMemoryStats(_srefMultiple); - _enableMemoryCollection = true; - _enableExpiration = true; - } - - internal void Dispose(bool disposing) { - if (disposing) { - // This method must be tolerant to multiple calls to Dispose on the same instance - if (Interlocked.Exchange(ref _disposed, 1) == 0) { - EnableCacheMemoryTimer(false); - _cacheMemoryStats.Dispose(); - } - } - } - - internal void AddSRefTarget(object o) { - _srefMultiple.AddSRefTarget(o); - } - - internal void SetCacheInternal(CacheInternal cacheInternal) { - _cacheInternal = cacheInternal; - _cachePublic.SetCacheInternal(cacheInternal); - } - - internal void ReadCacheInternalConfig(CacheSection cacheSection) { - if (_internalConfigRead) { - return; - } - - lock (this) { - if (_internalConfigRead) { - return; - } - - // Set it to true here so that even if we have to call ReadCacheInternalConfig - // from the code below, we won't get into an infinite loop. - _internalConfigRead = true; - - if (cacheSection != null) { - _enableMemoryCollection = (!cacheSection.DisableMemoryCollection); - _enableExpiration = (!cacheSection.DisableExpiration); - _cacheMemoryStats.ReadConfig(cacheSection); - _currentPollInterval = CacheMemorySizePressure.PollInterval; - ResetFromConfigSettings(); - } - } - } - - internal void ResetFromConfigSettings() { - EnableCacheMemoryTimer(_enableMemoryCollection); - _cacheInternal.EnableExpirationTimer(_enableExpiration); - } - - internal void EnableCacheMemoryTimer(bool enable) { - lock (_timerLock) { -#if DBG - if (Debug.IsTagPresent("Timer") && !Debug.IsTagEnabled("Timer")) { - enable = false; - } - -#endif - - if (enable) { - - if (_timerHandleRef == null) { - // <cache privateBytesPollTime> has not been read yet - Timer timer = new Timer(new TimerCallback(this.CacheManagerTimerCallback), null, _currentPollInterval, _currentPollInterval); - _timerHandleRef = new DisposableGCHandleRef<Timer>(timer); - Debug.Trace("Cache", "Started CacheMemoryTimers"); - } - else { - _timerHandleRef.Target.Change(_currentPollInterval, _currentPollInterval); - } - } - else { - var timerHandleRef = _timerHandleRef; - if (timerHandleRef != null && Interlocked.CompareExchange(ref _timerHandleRef, null, timerHandleRef) == timerHandleRef) { - timerHandleRef.Dispose(); - Debug.Trace("Cache", "Stopped CacheMemoryTimers"); - } - } - } - - if (!enable) { - // wait for CacheManagerTimerCallback to finish - while(_inCacheManagerThread != 0) { - Thread.Sleep(100); - } - } - } - - void AdjustTimer() { - lock (_timerLock) { - - if (_timerHandleRef == null) - return; - - // the order of these if statements is important - - // When above the high pressure mark, interval should be 5 seconds or less - if (_cacheMemoryStats.IsAboveHighPressure()) { - if (_currentPollInterval > MEMORYSTATUS_INTERVAL_5_SECONDS) { - _currentPollInterval = MEMORYSTATUS_INTERVAL_5_SECONDS; - _timerHandleRef.Target.Change(_currentPollInterval, _currentPollInterval); - } - return; - } - - // When above half the low pressure mark, interval should be 30 seconds or less - if ((_cacheMemoryStats.CacheSizePressure.PressureLast > _cacheMemoryStats.CacheSizePressure.PressureLow/2) - || (_cacheMemoryStats.TotalMemoryPressure.PressureLast > _cacheMemoryStats.TotalMemoryPressure.PressureLow/2)) { - // DevDivBugs 104034: allow interval to fall back down when memory pressure goes away - int newPollInterval = Math.Min(CacheMemorySizePressure.PollInterval, MEMORYSTATUS_INTERVAL_30_SECONDS); - if (_currentPollInterval != newPollInterval) { - _currentPollInterval = newPollInterval; - _timerHandleRef.Target.Change(_currentPollInterval, _currentPollInterval); - } - return; - } - - // there is no pressure, interval should be the value from config - if (_currentPollInterval != CacheMemorySizePressure.PollInterval) { - _currentPollInterval = CacheMemorySizePressure.PollInterval; - _timerHandleRef.Target.Change(_currentPollInterval, _currentPollInterval); - } - } - } - - void CacheManagerTimerCallback(object state) { - CacheManagerThread(0); - } - - internal long CacheManagerThread(int minPercent) { - if (Interlocked.Exchange(ref _inCacheManagerThread, 1) != 0) - return 0; -#if DBG - Debug.Trace("CacheMemory", "**BEG** CacheManagerThread " + HttpRuntime.AppDomainAppId + ", " + DateTime.Now.ToString("T", CultureInfo.InvariantCulture)); -#endif - try { - // Dev10 633335: if the timer has been disposed, return without doing anything - if (_timerHandleRef == null) - return 0; - - // The timer thread must always call Update so that the CacheManager - // knows the size of the cache. - _cacheMemoryStats.Update(); - AdjustTimer(); - int percent = Math.Max(minPercent, _cacheMemoryStats.GetPercentToTrim()); - long beginTotalCount = _cacheInternal.TotalCount; - Stopwatch sw = Stopwatch.StartNew(); - long trimmedOrExpired = _cacheInternal.TrimIfNecessary(percent); - sw.Stop(); - // 1) don't update stats if the trim happend because MAX_COUNT was exceeded - // 2) don't update stats unless we removed at least one entry - if (percent > 0 && trimmedOrExpired > 0) { - _cacheMemoryStats.SetTrimStats(sw.Elapsed.Ticks, beginTotalCount, trimmedOrExpired); - } - -#if DBG - Debug.Trace("CacheMemory", "**END** CacheManagerThread: " + HttpRuntime.AppDomainAppId - + ", percent=" + percent - + ", beginTotalCount=" + beginTotalCount - + ", trimmed=" + trimmedOrExpired - + ", Milliseconds=" + sw.ElapsedMilliseconds); -#endif - -#if PERF - SafeNativeMethods.OutputDebugString("CacheCommon.CacheManagerThread:" - + " minPercent= " + minPercent - + ", percent= " + percent - + ", beginTotalCount=" + beginTotalCount - + ", trimmed=" + trimmedOrExpired - + ", Milliseconds=" + sw.ElapsedMilliseconds + "\n"); -#endif - return trimmedOrExpired; - } - finally { - Interlocked.Exchange(ref _inCacheManagerThread, 0); - } - } - } - - abstract class CacheInternal : IEnumerable, IDisposable { - // cache key prefixes - they keep cache keys short and prevent conflicts - - // NOTE: Since we already used up all the lowercase letters from 'a' to 'z', - // we are now using uppercase letters from 'A' to 'Z' - internal const string PrefixFIRST = "A"; - internal const string PrefixResourceProvider = "A"; - internal const string PrefixMapPathVPPFile = "Bf"; - internal const string PrefixMapPathVPPDir = "Bd"; - - // Next prefix goes here, until we get to 'Z' - - internal const string PrefixOutputCache = "a"; - internal const string PrefixSqlCacheDependency = "b"; - internal const string PrefixMemoryBuildResult = "c"; - internal const string PrefixPathData = "d"; - internal const string PrefixHttpCapabilities = "e"; - internal const string PrefixMapPath = "f"; - internal const string PrefixHttpSys = "g"; - internal const string PrefixFileSecurity = "h"; - internal const string PrefixInProcSessionState = "j"; - internal const string PrefixStateApplication = "k"; - internal const string PrefixPartialCachingControl = "l"; - internal const string UNUSED = "m"; - internal const string PrefixAdRotator = "n"; - internal const string PrefixWebServiceDataSource = "o"; - internal const string PrefixLoadXPath = "p"; - internal const string PrefixLoadXml = "q"; - internal const string PrefixLoadTransform = "r"; - internal const string PrefixAspCompatThreading = "s"; - internal const string PrefixDataSourceControl = "u"; - internal const string PrefixValidationSentinel = "w"; - internal const string PrefixWebEventResource = "x"; - internal const string PrefixAssemblyPath = "y"; - internal const string PrefixBrowserCapsHash = "z"; - internal const string PrefixLAST = "z"; - - protected CacheCommon _cacheCommon; - private int _disposed; - - // virtual methods requiring implementation - internal abstract int PublicCount {get;} - - internal abstract long TotalCount {get;} - - internal abstract IDictionaryEnumerator CreateEnumerator(); - - internal abstract CacheEntry UpdateCache( - CacheKey cacheKey, - CacheEntry newEntry, - bool replace, - CacheItemRemovedReason removedReason, - out object valueOld); - - internal abstract long TrimIfNecessary(int percent); - - internal abstract void EnableExpirationTimer(bool enable); - - // If UseMemoryCache is true, we will direct all ASP.NET - // cache usage into System.Runtime.Caching.dll. This allows - // us to test System.Runtime.Caching.dll with all existing - // ASP.NET test cases (functional, perf, and stress). -#if USE_MEMORY_CACHE - private static bool _useMemoryCache; - private static volatile bool _useMemoryCacheInited; - internal static bool UseMemoryCache { - get { - if (!_useMemoryCacheInited) { - RegistryKey regKey = null; - try { - regKey = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\ASP.NET"); - if (regKey != null) { - if ((int)regKey.GetValue("UseMemoryCache", 0)== 1) { - _useMemoryCache = true; - } - } - } - finally { - if (regKey != null) { - regKey.Close(); - } - } - _useMemoryCacheInited = true; - } - return _useMemoryCache; - } - } -#endif - - // common implementation - static internal CacheInternal Create() { - CacheCommon cacheCommon = new CacheCommon(); - CacheInternal cacheInternal; -#if USE_MEMORY_CACHE - if (UseMemoryCache) { - cacheInternal = new MemCache(cacheCommon); - cacheCommon.AddSRefTarget(cacheInternal); - } - else { -#endif - int numSubCaches = 0; - uint numCPUs = (uint) SystemInfo.GetNumProcessCPUs(); - // the number of subcaches is the minimal power of 2 greater - // than or equal to the number of cpus - numSubCaches = 1; - numCPUs -= 1; - while (numCPUs > 0) { - numSubCaches <<= 1; - numCPUs >>= 1; - } - if (numSubCaches == 1) { - cacheInternal = new CacheSingle(cacheCommon, null, 0); - } - else { - cacheInternal = new CacheMultiple(cacheCommon, numSubCaches); - } -#if USE_MEMORY_CACHE - } -#endif - cacheCommon.SetCacheInternal(cacheInternal); - cacheCommon.ResetFromConfigSettings(); - - return cacheInternal; - } - - protected CacheInternal(CacheCommon cacheCommon) { - _cacheCommon = cacheCommon; - } - - protected virtual void Dispose(bool disposing) { - _cacheCommon.Dispose(disposing); - } - - public void Dispose() { - _disposed = 1; - Dispose(true); - // no destructor, don't need it. - // System.GC.SuppressFinalize(this); - } - - internal bool IsDisposed { get { return _disposed == 1; } } - - internal void ReadCacheInternalConfig(CacheSection cacheSection) { - _cacheCommon.ReadCacheInternalConfig(cacheSection); - } - - internal long TrimCache(int percent) { - return _cacheCommon.CacheManagerThread(percent); - } - - internal Cache CachePublic { - get {return _cacheCommon._cachePublic;} - } - - internal long EffectivePrivateBytesLimit { - get { return _cacheCommon._cacheMemoryStats.CacheSizePressure.MemoryLimit; } - } - - internal long EffectivePercentagePhysicalMemoryLimit { - get { return _cacheCommon._cacheMemoryStats.TotalMemoryPressure.MemoryLimit; } - } - - IEnumerator IEnumerable.GetEnumerator() { - return CreateEnumerator(); - } - - public IDictionaryEnumerator GetEnumerator() { - return CreateEnumerator(); - } - - internal object this[string key] { - get { - return Get(key); + return AspNetMemoryMonitor.PhysicalMemoryPercentageLimit; } } - - internal object Get(string key) { - return DoGet(false, key, CacheGetOptions.None); - } - - internal object Get(string key, CacheGetOptions getOptions) { - return DoGet(false, key, getOptions); - } - - internal object DoGet(bool isPublic, string key, CacheGetOptions getOptions) { - CacheEntry entry; - CacheKey cacheKey; - object dummy; - - cacheKey = new CacheKey(key, isPublic); - entry = UpdateCache(cacheKey, null, false, CacheItemRemovedReason.Removed, out dummy); - if (entry != null) { - if ((getOptions & CacheGetOptions.ReturnCacheEntry) != 0) { - return entry; - } - else { - return entry.Value; - } - } - else { - return null; - } - } - - internal void UtcInsert(string key, object value) { - DoInsert(false, - key, - value, - null, - Cache.NoAbsoluteExpiration, - Cache.NoSlidingExpiration, - CacheItemPriority.Default, - null, - true); - - } - - internal void UtcInsert(string key, object value, CacheDependency dependencies) { - DoInsert(false, - key, - value, - dependencies, - Cache.NoAbsoluteExpiration, - Cache.NoSlidingExpiration, - CacheItemPriority.Default, - null, - true); - } - - internal void UtcInsert( - string key, - object value, - CacheDependency dependencies, - DateTime utcAbsoluteExpiration, - TimeSpan slidingExpiration) { - - DoInsert(false, - key, - value, - dependencies, - utcAbsoluteExpiration, - slidingExpiration, - CacheItemPriority.Default, - null, - true); - } - - internal void UtcInsert( - string key, - object value, - CacheDependency dependencies, - DateTime utcAbsoluteExpiration, - TimeSpan slidingExpiration, - CacheItemPriority priority, - CacheItemRemovedCallback onRemoveCallback) { - - DoInsert(false, - key, - value, - dependencies, - utcAbsoluteExpiration, - slidingExpiration, - priority, - onRemoveCallback, - true); - } - - internal object UtcAdd( - string key, - object value, - CacheDependency dependencies, - DateTime utcAbsoluteExpiration, - TimeSpan slidingExpiration, - CacheItemPriority priority, - CacheItemRemovedCallback onRemoveCallback) { - - return DoInsert( - false, - key, - value, - dependencies, - utcAbsoluteExpiration, - slidingExpiration, - priority, - onRemoveCallback, - false); - - } - - internal object DoInsert( - bool isPublic, - string key, - object value, - CacheDependency dependencies, - DateTime utcAbsoluteExpiration, - TimeSpan slidingExpiration, - CacheItemPriority priority, - CacheItemRemovedCallback onRemoveCallback, - bool replace) { - - - /* - * If we throw an exception, prevent a leak by a user who - * writes the following: - * - * Cache.Insert(key, value, new CacheDependency(file)); - */ - using (dependencies) { - CacheEntry entry; - object dummy; - - entry = new CacheEntry( - key, - value, - dependencies, - onRemoveCallback, - utcAbsoluteExpiration, - slidingExpiration, - priority, - isPublic); - - entry = UpdateCache(entry, entry, replace, CacheItemRemovedReason.Removed, out dummy); - - /* - * N.B. A set can fail if two or more threads set the same key - * at the same time. - */ -#if DBG - if (replace) { - string yesno = (entry != null) ? "succeeded" : "failed"; - Debug.Trace("CacheAPIInsert", "Cache.Insert " + yesno + ": " + key); - } - else { - if (entry == null) { - Debug.Trace("CacheAPIAdd", "Cache.Add added new item: " + key); - } - else { - Debug.Trace("CacheAPIAdd", "Cache.Add returned existing item: " + key); - } - } -#endif - - if (entry != null) { - return entry.Value; - } - else { - return null; - } - } - } - - internal object Remove(string key) { - CacheKey cacheKey = new CacheKey(key, false); - return DoRemove(cacheKey, CacheItemRemovedReason.Removed); - } - - internal object Remove(CacheKey cacheKey, CacheItemRemovedReason reason) { - return DoRemove(cacheKey, reason); - } - - /* - * Remove an item from the cache, with a specific reason. - * This is package access so only the cache can specify - * a reason other than REMOVED. - * - * @param key The key for the item. - * @exception ArgumentException - */ - internal object DoRemove(CacheKey cacheKey, CacheItemRemovedReason reason) { - object valueOld; - - UpdateCache(cacheKey, null, true, reason, out valueOld); - -#if DBG - if (valueOld != null) { - Debug.Trace("CacheAPIRemove", "Cache.Remove succeeded, reason=" + reason + ": " + cacheKey); - } - else { - Debug.Trace("CacheAPIRemove", "Cache.Remove failed, reason=" + reason + ": " + cacheKey); - } -#endif - - return valueOld; - } } - sealed class CacheKeyComparer : IEqualityComparer { - static CacheKeyComparer s_comparerInstance; - - static internal CacheKeyComparer GetInstance() { - if (s_comparerInstance == null) { - s_comparerInstance = new CacheKeyComparer(); - } - - return s_comparerInstance; - } - - private CacheKeyComparer() - { - } - - bool IEqualityComparer.Equals(Object x, Object y) - { - return Compare(x, y) == 0; - } - - // Compares two objects. An implementation of this method must return a - // value less than zero if x is less than y, zero if x is equal to y, or a - // value greater than zero if x is greater than y. - private int Compare(Object x, Object y) { - CacheKey a, b; - - Debug.Assert(x != null && x is CacheKey); - Debug.Assert(y != null && y is CacheKey); - - a = (CacheKey) x; - b = (CacheKey) y; - - if (a.IsPublic) { - if (b.IsPublic) { - return String.Compare(a.Key, b.Key, StringComparison.Ordinal); - } - else { - return 1; - } - } - else { - if (!b.IsPublic) { - return String.Compare(a.Key, b.Key, StringComparison.Ordinal); - } - else { - return -1; - } - } - } - // Returns a hash code for the given object. - // - int IEqualityComparer.GetHashCode(Object obj) { - Debug.Assert(obj != null && obj is CacheKey); - - CacheKey cacheKey = (CacheKey) obj; - - return cacheKey.GetHashCode(); - } - } - - /* - * The cache. - */ - sealed class CacheSingle : CacheInternal { - // cache stats - static readonly TimeSpan INSERT_BLOCK_WAIT = new TimeSpan(0, 0, 10); - const int MAX_COUNT = Int32.MaxValue / 2; - const int MIN_COUNT = 10; - - - Hashtable _entries; /* lookup table of entries */ - CacheExpires _expires; /* expires tables */ - CacheUsage _usage; /* usage tables */ - object _lock; /* read/write synchronization for _entries */ - int _disposed; /* disposed */ - int _totalCount; /* count of total entries */ - int _publicCount; /* count of public entries */ - ManualResetEvent _insertBlock; /* event to block inserts during high mem usage */ - bool _useInsertBlock; /* use insert block? */ - int _insertBlockCalls; /* number of callers using insert block */ - int _iSubCache; /* index of this cache */ - CacheMultiple _cacheMultiple; /* the CacheMultiple containing this cache */ - - /* - * Constructs a new Cache. - */ - internal CacheSingle(CacheCommon cacheCommon, CacheMultiple cacheMultiple, int iSubCache) : base(cacheCommon) { - _cacheMultiple = cacheMultiple; - _iSubCache = iSubCache; - _entries = new Hashtable(CacheKeyComparer.GetInstance()); - _expires = new CacheExpires(this); - _usage = new CacheUsage(this); - _lock = new object(); - _insertBlock = new ManualResetEvent(true); - cacheCommon.AddSRefTarget(new { _entries, _expires, _usage }); - } - - /* - * Dispose the cache. - */ - protected override void Dispose(bool disposing) { - if (disposing) { - if (Interlocked.Exchange(ref _disposed, 1) == 0) { - if (_expires != null) { - _expires.EnableExpirationTimer(false); - } - - // close all items - CacheEntry[] entries = null; - - lock (_lock) { - entries = new CacheEntry[_entries.Count]; - int i = 0; - foreach (DictionaryEntry d in _entries) { - entries[i++] = (CacheEntry) d.Value; - } - } - - foreach (CacheEntry entry in entries) { - Remove(entry, CacheItemRemovedReason.Removed); - } - - // force any waiters to complete their waits. Note - // that the insert block cannot be reacquired, as UseInsertBlock - // checks the _disposed field. - _insertBlock.Set(); - - // release the block, causing it to be disposed when there - // are no more callers. - ReleaseInsertBlock(); - - Debug.Trace("CacheDispose", "Cache disposed"); - } - } - - base.Dispose(disposing); - } - - // Get the insert block manual reset event if it has not been disposed. - ManualResetEvent UseInsertBlock() { - for (;;) { - if (_disposed == 1) - return null; - - int n = _insertBlockCalls; - if (n < 0) { - return null; - } - - if (Interlocked.CompareExchange(ref _insertBlockCalls, n + 1, n) == n) { - return _insertBlock; - } - } - } - - // Release the insert block event, and dispose it if it has been released - // more times than it has been used - void ReleaseInsertBlock() { - if (Interlocked.Decrement(ref _insertBlockCalls) < 0) { - ManualResetEvent e = _insertBlock; - _insertBlock = null; - - // now close - e.Close(); - } - } - - // Set the insert block event. - void SetInsertBlock() { - ManualResetEvent e = null; - try { - e = UseInsertBlock(); - if (e != null) { - e.Set(); - } - } - finally { - if (e != null) { - ReleaseInsertBlock(); - } - } - } - - // Reset the insert block event. - void ResetInsertBlock() { - ManualResetEvent e = null; - try { - e = UseInsertBlock(); - if (e != null) { - e.Reset(); - } - } - finally { - if (e != null) { - ReleaseInsertBlock(); - } - } - } - - // Wait on the insert block event. - bool WaitInsertBlock() { - bool signaled = false; - ManualResetEvent e = null; - try { - e = UseInsertBlock(); - if (e != null) { - Debug.Trace("CacheMemoryTrimInsertBlock", "WaitInsertBlock: Cache " + _iSubCache + ": _useInsertBlock=true"); - signaled = e.WaitOne(INSERT_BLOCK_WAIT, false); - Debug.Trace("CacheMemoryTrimInsertBlock", "Done waiting"); - } - } - finally { - if (e != null) { - ReleaseInsertBlock(); - } - } - - return signaled; - } - - internal void BlockInsertIfNeeded() { - if (_cacheCommon._cacheMemoryStats.IsAboveHighPressure()) { - Debug.Trace("CacheMemoryTrimInsertBlock", "BlockInsertIfNeeded: Cache " + _iSubCache + ": _useInsertBlock=true"); - _useInsertBlock = true; - ResetInsertBlock(); - } - } - - internal void UnblockInsert() { - if (_useInsertBlock) { - _useInsertBlock = false; - SetInsertBlock(); - Debug.Trace("CacheMemoryTrimInsertBlock", "UnblockInsert: Cache " + _iSubCache + ": _useInsertBlock=false"); - } - } - - - internal override int PublicCount { - get {return _publicCount;} - } - - internal override long TotalCount { - get {return _totalCount;} - } - - internal override IDictionaryEnumerator CreateEnumerator() { - Hashtable h = new Hashtable(_publicCount); - DateTime utcNow = DateTime.UtcNow; - - lock (_lock) { - foreach (DictionaryEntry d in _entries) { - CacheEntry entry = (CacheEntry) d.Value; - - // note that ASP.NET does not use this enumerator internally, - // so we just choose public items. - if (entry.IsPublic && - entry.State == CacheEntry.EntryState.AddedToCache && - ((!_cacheCommon._enableExpiration) || (utcNow <= entry.UtcExpires))) { - h[entry.Key] = entry.Value; - } - } - } - - return h.GetEnumerator(); - } - - /* - * Performs all operations on the cache, with the - * exception of Clear. The arguments indicate the type of operation: - * - * @param key The key of the object. - * @param newItem The new entry to be added to the cache. - * @param replace Whether or not newEntry should replace an existing object in the cache. - * @return The item requested. May be null. - */ - internal override CacheEntry UpdateCache( - CacheKey cacheKey, - CacheEntry newEntry, - bool replace, - CacheItemRemovedReason removedReason, - out object valueOld) - { - CacheEntry entry = null; - CacheEntry oldEntry = null; - bool expired = false; - DateTime utcNow; - CacheDependency newEntryDependency = null; - bool isGet, isAdd; - bool removeExpired = false; - bool updateExpires = false; - DateTime utcNewExpires = DateTime.MinValue; - CacheEntry.EntryState entryState = CacheEntry.EntryState.NotInCache; - bool newEntryNeedsClose = false; - CacheItemRemovedReason newEntryRemovedReason = CacheItemRemovedReason.Removed; - - valueOld = null; - isGet = !replace && newEntry == null; - isAdd = !replace && newEntry != null; - - /* - * Perform update of cache data structures in a series to - * avoid overlapping locks. - * - * First, update the hashtable. The hashtable is the place - * that guarantees what is in or out of the cache. - * - * Loop here to remove expired items in a Get or Add, where - * we can't otherwise delete an item. - */ - for (;;) { - if (removeExpired) { - Debug.Trace("CacheUpdate", "Removing expired item found in Get: " + cacheKey); - UpdateCache(cacheKey, null, true, CacheItemRemovedReason.Expired, out valueOld); - removeExpired = false; - } - - entry = null; - utcNow = DateTime.UtcNow; - - if (_useInsertBlock && newEntry != null && newEntry.HasUsage() /* HasUsage() means it's not NonRemovable */) { - bool insertBlockReleased = WaitInsertBlock(); - -#if DBG - if (!insertBlockReleased) { - Debug.Trace("CacheUpdateWaitFailed", "WaitInsertBlock failed."); - } -#endif - } - - // the _entries hashtable supports multiple readers or one writer - bool isLockEntered = false; - if (!isGet) { - Monitor.Enter(_lock, ref isLockEntered); - } - try { - entry = (CacheEntry) _entries[cacheKey]; - Debug.Trace("CacheUpdate", "Entry " + ((entry != null) ? "found" : "not found") + "in hashtable: " + cacheKey); - - if (entry != null) { - entryState = entry.State; - - // If isGet == true, we are not hold any lock and so entryState can be anything - Debug.Assert( - isGet || - entryState == CacheEntry.EntryState.AddingToCache || - entryState == CacheEntry.EntryState.AddedToCache, - "entryState == CacheEntry.EntryState.AddingToCache || entryState == CacheEntry.EntryState.AddedToCache"); - - expired = (_cacheCommon._enableExpiration) && (entry.UtcExpires < utcNow); - if (expired) { - if (isGet) { - /* - * If the expired item is Added to the cache, remove it now before - * its expiration timer fires up to a minute in the future. - * Otherwise, just return null to indicate the item is not available. - */ - if (entryState == CacheEntry.EntryState.AddedToCache) { - removeExpired = true; - continue; - } - - entry = null; - } - else { - /* - * If it's a call to Add, replace the item - * when it has expired. - */ - replace = true; - - /* - * Change the removed reason. - */ - removedReason = CacheItemRemovedReason.Expired; - } - } - else { - updateExpires = (_cacheCommon._enableExpiration) && (entry.SlidingExpiration > TimeSpan.Zero); - } - } - - /* - * Avoid running unnecessary code in a Get request by this simple test: - */ - if (!isGet) { - /* - * Remove an item from the hashtable. - */ - if (replace && entry != null) { - bool doRemove = (entryState != CacheEntry.EntryState.AddingToCache); - if (doRemove) { - oldEntry = entry; - - oldEntry.State = CacheEntry.EntryState.RemovingFromCache; - - _entries.Remove(oldEntry); - Debug.Trace("CacheUpdate", "Entry removed from hashtable: " + cacheKey); - } - else { - /* - * If we're removing and couldn't remove the old item - * because its state was AddingToCache, return null - * to indicate failure. - */ - if (newEntry == null) { - Debug.Trace("CacheUpdate", "Removal from hashtable failed: " + cacheKey); - entry = null; - } - } - } - - /* - * Add an item to the hashtable. - */ - if (newEntry != null) { - bool doAdd = true; - - if (entry != null) { - if (oldEntry == null) { - /* - * We could not remove the existing entry, - * either because it simply exists and replace == false, - * or replace == true and it's state was AddingToCache when - * we tried to remove it. - */ - doAdd = false; - newEntryRemovedReason = CacheItemRemovedReason.Removed; - } - -#if DBG - if (!doAdd) { - Debug.Trace("CacheUpdate", "Insertion into hashtable failed because old entry was not removed: " + cacheKey); - } -#endif - } - - - if (doAdd) { - /* non-definitive check */ - newEntryDependency = newEntry.Dependency; - if (newEntryDependency != null) { - if (newEntryDependency.HasChanged) { - doAdd = false; - newEntryRemovedReason = CacheItemRemovedReason.DependencyChanged; - } - -#if DBG - if (!doAdd) { - Debug.Trace("CacheUpdate", "Insertion into hashtable failed because dependency changed: " + cacheKey); - } -#endif - } - } - - if (doAdd) { - newEntry.State = CacheEntry.EntryState.AddingToCache; - _entries.Add(newEntry, newEntry); - - /* - * If this is an Add operation, indicate success - * by returning null. - */ - if (isAdd) { - Debug.Assert(entry == null || expired, "entry == null || expired"); - entry = null; - } - else { - /* - * Indicate success by returning the inserted entry. - */ - entry = newEntry; - } - - Debug.Trace("CacheUpdate", "Entry added to hashtable: " + cacheKey); - } - else { - if (!isAdd) { - /* - * If we failed for an Insert, indicate failure by returning null. - */ - entry = null; - newEntryNeedsClose = true; - } - else { - /* - * If we failed for an Add (e.g. Dependency has changed), - * return the existing value. If existing value is null, - * we have to close the newEntry ourselves. Otherwise, we'll - * return non-null and the caller should close the item. - */ - newEntryNeedsClose = (entry == null); - } - - /* - * If newEntry cannot be inserted, and it does not need to be - * closed, set it to null so that we don't insert it later. - * Leave it non-null when it needs to be closed that that we - * can close it. - */ - if (!newEntryNeedsClose) { - newEntry = null; - } - - } - } - } - - break; - } - finally { - if (isLockEntered) { - Monitor.Exit(_lock); - } - } - } - - /* - * Since we want Get to be fast, check here for a get without - * alteration to cache. - */ - if (isGet) { - if (entry != null) { - if (updateExpires) { - utcNewExpires = utcNow + entry.SlidingExpiration; - if (utcNewExpires - entry.UtcExpires >= CacheExpires.MIN_UPDATE_DELTA || utcNewExpires < entry.UtcExpires) { - _expires.UtcUpdate(entry, utcNewExpires); - } - } - - UtcUpdateUsageRecursive(entry, utcNow); - } - - if (cacheKey.IsPublic) { - PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_RATIO_BASE); - if (entry != null) { - PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_HITS); - } - else { - PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_MISSES); - } - } - - PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_RATIO_BASE); - if (entry != null) { - PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_HITS); - } - else { - PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_MISSES); - } - -#if DBG - if (entry != null) { - Debug.Trace("CacheUpdate", "Cache hit: " + cacheKey); - } - else { - Debug.Trace("CacheUpdate", "Cache miss: " + cacheKey); - } -#endif - - } - else { - int totalDelta = 0; - int publicDelta = 0; - int totalTurnover = 0; - int publicTurnover = 0; - - if (oldEntry != null) { - if (oldEntry.InExpires()) { - _expires.Remove(oldEntry); - } - - if (oldEntry.InUsage()) { - _usage.Remove(oldEntry); - } - - Debug.Assert(oldEntry.State == CacheEntry.EntryState.RemovingFromCache, "oldEntry.State == CacheEntry.EntryState.RemovingFromCache"); - oldEntry.State = CacheEntry.EntryState.RemovedFromCache; - valueOld = oldEntry.Value; - - totalDelta--; - totalTurnover++; - if (oldEntry.IsPublic) { - publicDelta--; - publicTurnover++; - } - -#if DBG - Debug.Trace("CacheUpdate", "Entry removed from cache, reason=" + removedReason + ": " + (CacheKey) oldEntry); -#endif - } - - if (newEntry != null) { - if (newEntryNeedsClose) { - // Call close if newEntry could not be added. - newEntry.State = CacheEntry.EntryState.RemovedFromCache; - newEntry.Close(newEntryRemovedReason); - newEntry = null; - } - else { - Debug.Assert(!newEntry.InExpires()); - Debug.Assert(!newEntry.InUsage()); - - if (_cacheCommon._enableExpiration && newEntry.HasExpiration()) { - _expires.Add(newEntry); - } - - if ( _cacheCommon._enableMemoryCollection && newEntry.HasUsage() && - ( // Don't bother to set usage if it's going to expire very soon - !newEntry.HasExpiration() || - newEntry.SlidingExpiration > TimeSpan.Zero || - newEntry.UtcExpires - utcNow >= CacheUsage.MIN_LIFETIME_FOR_USAGE)) { - - _usage.Add(newEntry); - } - - newEntry.State = CacheEntry.EntryState.AddedToCache; - - Debug.Trace("CacheUpdate", "Entry added to cache: " + (CacheKey)newEntry); - - totalDelta++; - totalTurnover++; - if (newEntry.IsPublic) { - publicDelta++; - publicTurnover++; - } - } - } - - // Call close after the newEntry has been fully added to the cache, - // so the OnRemoveCallback can take a dependency on the newly inserted item. - if (oldEntry != null) { - oldEntry.Close(removedReason); - } - - // Delay monitoring change events until the oldEntry has been completely removed - // from the cache, and its OnRemoveCallback called. This way we won't call the - // OnRemoveCallback for newEntry before doing so for oldEntry. - if (newEntry != null) { - // listen to change events - newEntry.MonitorDependencyChanges(); - - /* - * NB: We have to check for dependency changes after we add the item - * to cache, because otherwise we may not remove it if it changes - * between the time we check for a dependency change and the time - * we set the AddedToCache bit. The worst that will happen is that - * a get can occur on an item that has changed, but that can happen - * anyway. The important thing is that we always remove an item that - * has changed. - */ - if (newEntryDependency != null && newEntryDependency.HasChanged) { - Remove(newEntry, CacheItemRemovedReason.DependencyChanged); - } - } - - // update counts and counters - if (totalDelta == 1) { - Interlocked.Increment(ref _totalCount); - PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_ENTRIES); - } - else if (totalDelta == -1) { - Interlocked.Decrement(ref _totalCount); - PerfCounters.DecrementCounter(AppPerfCounter.TOTAL_CACHE_ENTRIES); - } - - if (publicDelta == 1) { - Interlocked.Increment(ref _publicCount); - PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_ENTRIES); - } - else if (publicDelta == -1) { - Interlocked.Decrement(ref _publicCount); - PerfCounters.DecrementCounter(AppPerfCounter.API_CACHE_ENTRIES); - } - - if (totalTurnover > 0) { - PerfCounters.IncrementCounterEx(AppPerfCounter.TOTAL_CACHE_TURNOVER_RATE, totalTurnover); - } - - if (publicTurnover > 0) { - PerfCounters.IncrementCounterEx(AppPerfCounter.API_CACHE_TURNOVER_RATE, publicTurnover); - } - } - - return entry; - } - - void UtcUpdateUsageRecursive(CacheEntry entry, DateTime utcNow) { - CacheDependency dependency; - CacheEntry[] entries; - - // Don't update if the last update is less than 1 sec away. This way we'll - // avoid over updating the usage in the scenario where a cache makes several - // update requests. - if (utcNow - entry.UtcLastUsageUpdate > CacheUsage.CORRELATED_REQUEST_TIMEOUT || utcNow < entry.UtcLastUsageUpdate) { - entry.UtcLastUsageUpdate = utcNow; - if (entry.InUsage()) { - CacheSingle cacheSingle; - if (_cacheMultiple == null) { - cacheSingle = this; - } - else { - cacheSingle = _cacheMultiple.GetCacheSingle(entry.Key.GetHashCode()); - } - - cacheSingle._usage.Update(entry); - } - - dependency = entry.Dependency; - if (dependency != null) { - entries = dependency.CacheEntries; - if (entries != null) { - foreach (CacheEntry dependent in entries) { - UtcUpdateUsageRecursive(dependent, utcNow); - } - } - } - } - } - - internal override long TrimIfNecessary(int percent) { - Debug.Assert(_cacheCommon._inCacheManagerThread == 1, "Trim should only occur when we're updating memory statistics."); - if (!_cacheCommon._enableMemoryCollection) - return 0; - - int toTrim = 0; - // do we need to drop a percentage of entries? - if (percent > 0) { - toTrim = (int)(((long)_totalCount * (long)percent) / 100L); - } - // would this leave us above MAX_COUNT? - int minTrim = _totalCount - MAX_COUNT; - if (toTrim < minTrim) { - toTrim = minTrim; - } - // would this put us below MIN_COUNT? - int maxTrim = _totalCount - MIN_COUNT; - if (toTrim > maxTrim) { - toTrim = maxTrim; - } - // do we need to trim? - if (toTrim <= 0 || HostingEnvironment.ShutdownInitiated) { - return 0; - } - - int ocEntriesTrimmed = 0; // number of output cache entries trimmed - int publicEntriesTrimmed = 0; // number of public entries trimmed - int totalTrimmed = 0; // total number of entries trimmed - int trimmedOrExpired = 0; - int beginTotalCount = _totalCount; - - try { - trimmedOrExpired = _expires.FlushExpiredItems(true); - if (trimmedOrExpired < toTrim) { - totalTrimmed = _usage.FlushUnderUsedItems(toTrim - trimmedOrExpired, ref publicEntriesTrimmed, ref ocEntriesTrimmed); - trimmedOrExpired += totalTrimmed; - } - - if (totalTrimmed > 0) { - // Update values for perfcounters - PerfCounters.IncrementCounterEx(AppPerfCounter.CACHE_TOTAL_TRIMS, totalTrimmed); - PerfCounters.IncrementCounterEx(AppPerfCounter.CACHE_API_TRIMS, publicEntriesTrimmed); - PerfCounters.IncrementCounterEx(AppPerfCounter.CACHE_OUTPUT_TRIMS, ocEntriesTrimmed); - } - } - catch { - } - -#if DBG - Debug.Trace("CacheMemory", "TrimIfNecessary: _iSubCache= " + _iSubCache - + ", beginTotalCount=" + beginTotalCount - + ", endTotalCount=" + _totalCount - + ", percent=" + percent - + ", trimmed=" + totalTrimmed); -#endif - return trimmedOrExpired; - } - - internal override void EnableExpirationTimer(bool enable) { - if (_expires != null) { - _expires.EnableExpirationTimer(enable); - } - } - } - - class CacheMultiple : CacheInternal { - int _disposed; - DisposableGCHandleRef<CacheSingle>[] _cachesRefs; - int _cacheIndexMask; - - internal CacheMultiple(CacheCommon cacheCommon, int numSingleCaches) : base(cacheCommon) { - Debug.Assert(numSingleCaches > 1, "numSingleCaches is not greater than 1"); - Debug.Assert((numSingleCaches & (numSingleCaches - 1)) == 0, "numSingleCaches is not a power of 2"); - _cacheIndexMask = numSingleCaches - 1; - - // Each CacheSingle will have its own SRef reporting the size of the data it references. - // Objects in this CacheSingle may have refs to the root Cache and therefore reference other instances of CacheSingle. - // This leads to an unbalanced tree of SRefs and makes GC less efficient while calculating multiple SRefs on multiple cores. - // Using DisposableGCHandleRef here prevents SRefs from calculating data that does not belong to other CacheSingle instances. - _cachesRefs = new DisposableGCHandleRef<CacheSingle>[numSingleCaches]; - for (int i = 0; i < numSingleCaches; i++) { - _cachesRefs[i] = new DisposableGCHandleRef<CacheSingle>(new CacheSingle(cacheCommon, this, i)); - } - } - - protected override void Dispose(bool disposing) { - if (disposing) { - if (Interlocked.Exchange(ref _disposed, 1) == 0) { - foreach (var cacheSingleRef in _cachesRefs) { - // Unfortunately the application shutdown logic allows user to access cache even after its disposal. - // We'll keep the GCHandle inside cacheSingleRef until it gets reclaimed during appdomain shutdown. - // And we'll only dispose the Target to preserve the old behavior. - cacheSingleRef.Target.Dispose(); - } - } - } - - base.Dispose(disposing); - } - - internal override int PublicCount { - get { - int count = 0; - foreach (var cacheSingleRef in _cachesRefs) { - count += cacheSingleRef.Target.PublicCount; - } - - return count; - } - } - - internal override long TotalCount { - get { - long count = 0; - foreach (var cacheSingleRef in _cachesRefs) { - count += cacheSingleRef.Target.TotalCount; - } - - return count; - } - } - - internal override IDictionaryEnumerator CreateEnumerator() { - IDictionaryEnumerator[] enumerators = new IDictionaryEnumerator[_cachesRefs.Length]; - for (int i = 0, c = _cachesRefs.Length; i < c; i++) { - enumerators[i] = _cachesRefs[i].Target.CreateEnumerator(); - } - - return new AggregateEnumerator(enumerators); - } - - internal CacheSingle GetCacheSingle(int hashCode) { - Debug.Assert(_cachesRefs != null && _cachesRefs.Length != 0); - // Dev10 865907: Math.Abs throws OverflowException for Int32.MinValue - if (hashCode < 0) { - hashCode = (hashCode == Int32.MinValue) ? 0 : -hashCode; - } - int index = (hashCode & _cacheIndexMask); - Debug.Assert(_cachesRefs[index].Target != null); - return _cachesRefs[index].Target; - } - - internal override CacheEntry UpdateCache( - CacheKey cacheKey, - CacheEntry newEntry, - bool replace, - CacheItemRemovedReason removedReason, - out object valueOld) { - - int hashCode = cacheKey.Key.GetHashCode(); - CacheSingle cacheSingle = GetCacheSingle(hashCode); - return cacheSingle.UpdateCache(cacheKey, newEntry, replace, removedReason, out valueOld); - } - - internal override long TrimIfNecessary(int percent) { - long count = 0; - foreach (var cacheSingleRef in _cachesRefs) { - count += cacheSingleRef.Target.TrimIfNecessary(percent); - } - return count; - } - - internal override void EnableExpirationTimer(bool enable) { - foreach (var cacheSingleRef in _cachesRefs) { - cacheSingleRef.Target.EnableExpirationTimer(enable); - } - } - } - - class AggregateEnumerator : IDictionaryEnumerator { - IDictionaryEnumerator [] _enumerators; - int _iCurrent; - - internal AggregateEnumerator(IDictionaryEnumerator [] enumerators) { - _enumerators = enumerators; - } - - public bool MoveNext() { - bool more; - - for (;;) { - more = _enumerators[_iCurrent].MoveNext(); - if (more) - break; - - if (_iCurrent == _enumerators.Length - 1) - break; - - _iCurrent++; - } - - return more; - } - - public void Reset() { - for (int i = 0; i <= _iCurrent; i++) { - _enumerators[i].Reset(); - } - - _iCurrent = 0; - } - - public Object Current { - get { - return _enumerators[_iCurrent].Current; - } - } - - public Object Key { - get { - return _enumerators[_iCurrent].Key; - } - } - - public Object Value { - get { - return _enumerators[_iCurrent].Value; - } - } - - public DictionaryEntry Entry { - get { - return _enumerators[_iCurrent].Entry; - } - } - } } diff --git a/System.Web/CachedPathData.cs b/System.Web/CachedPathData.cs index ad25b2d0e..8171ee83d 100644 --- a/System.Web/CachedPathData.cs +++ b/System.Web/CachedPathData.cs @@ -196,7 +196,7 @@ static private CachedPathData GetConfigPathData(string configPath) { // the filesystem. // string key = CreateKey(configPath); - CacheInternal cacheInternal = HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; CachedPathData data = (CachedPathData) cacheInternal.Get(key); // if found, return the data @@ -272,9 +272,12 @@ static private CachedPathData GetConfigPathData(string configPath) { try { } finally { - data = (CachedPathData) cacheInternal.UtcAdd(key, dataAdd, dependency, - Cache.NoAbsoluteExpiration, slidingExpiration, - priority, s_callback); + data = (CachedPathData)cacheInternal.Add(key, dataAdd, new CacheInsertOptions() { + Dependencies = dependency, + SlidingExpiration = slidingExpiration, + Priority = priority, + OnRemovedCallback = s_callback + }); if (data == null) { isDataCreator = true; @@ -369,9 +372,11 @@ static private CachedPathData GetConfigPathData(string configPath) { } using (dependency) { - cacheInternal.UtcInsert(key, dataAdd, dependency, - DateTime.UtcNow.AddSeconds(5), Cache.NoSlidingExpiration, - CacheItemPriority.Normal, s_callback); + cacheInternal.Insert(key, dataAdd, new CacheInsertOptions() { + Dependencies = dependency, + AbsoluteExpiration = DateTime.UtcNow.AddSeconds(5), + OnRemovedCallback = s_callback + }); } } @@ -416,7 +421,7 @@ static private string GetPhysicalPath(VirtualPath virtualPath) { // virtual files. // An example of a 400 range error is "path not found". static internal void RemoveBadPathData(CachedPathData pathData) { - CacheInternal cacheInternal = HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; string configPath = pathData._configPath; string key = CreateKey(configPath); @@ -437,7 +442,7 @@ static internal void RemoveBadPathData(CachedPathData pathData) { // status outside the 400 range. We need to mark all data up the path to account for // virtual files. static internal void MarkCompleted(CachedPathData pathData) { - CacheInternal cacheInternal = HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; string configPath = pathData._configPath; do { diff --git a/System.Web/Compilation/BuildManager.cs b/System.Web/Compilation/BuildManager.cs index 65f027200..7ad0d9bd9 100644 --- a/System.Web/Compilation/BuildManager.cs +++ b/System.Web/Compilation/BuildManager.cs @@ -461,7 +461,7 @@ private void RegularAppRuntimeModeInitialize() { // // Always try the memory cache first - _memoryCache = new MemoryBuildResultCache(HttpRuntime.CacheInternal); + _memoryCache = new MemoryBuildResultCache(); // Use the standard disk cache for regular apps _codeGenCache = new StandardDiskBuildResultCache(HttpRuntime.CodegenDirInternal); @@ -479,7 +479,7 @@ private void PrecompiledAppRuntimeModeInitialize() { // // Always try the memory cache first - _memoryCache = new MemoryBuildResultCache(HttpRuntime.CacheInternal); + _memoryCache = new MemoryBuildResultCache(); // Used the precomp cache for precompiled apps BuildResultCache preCompCache = new PrecompiledSiteDiskBuildResultCache( @@ -501,7 +501,7 @@ private void PrecompilationModeInitialize() { // We are precompiling an app // Always try the memory cache first - _memoryCache = new MemoryBuildResultCache(HttpRuntime.CacheInternal); + _memoryCache = new MemoryBuildResultCache(); // Create a regular disk cache, to take advantage of the fact that the app // may already have been compiled (and to cause it to be if it wasn't) diff --git a/System.Web/Compilation/BuildResultCache.cs b/System.Web/Compilation/BuildResultCache.cs index 1e3bfd5a8..0d58da9ca 100644 --- a/System.Web/Compilation/BuildResultCache.cs +++ b/System.Web/Compilation/BuildResultCache.cs @@ -67,15 +67,13 @@ internal static string GetAssemblyCacheKeyFromName(string assemblyName) { internal class MemoryBuildResultCache: BuildResultCache { - private CacheInternal _cache; private CacheItemRemovedCallback _onRemoveCallback; // The keys are simple assembly names // The values are ArrayLists containing the simple names of assemblies that depend on it private Hashtable _dependentAssemblies = new Hashtable(); - internal MemoryBuildResultCache(CacheInternal cache) { - _cache = cache; + internal MemoryBuildResultCache() { // Register an AssemblyLoad event AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(OnAssemblyLoad); @@ -121,7 +119,7 @@ internal override BuildResult GetBuildResult(string cacheKey, VirtualPath virtua Debug.Trace("BuildResultCache", "Looking for '" + cacheKey + "' in the memory cache"); string key = GetMemoryCacheKey(cacheKey); - BuildResult result = (BuildResult) _cache.Get(key); + BuildResult result = (BuildResult) HttpRuntime.Cache.InternalCache.Get(key); // Not found in the cache if (result == null) { @@ -137,9 +135,9 @@ internal override BuildResult GetBuildResult(string cacheKey, VirtualPath virtua Debug.Trace("BuildResultCache", "'" + cacheKey + "' was found but is out of date"); // Remove it from the cache - _cache.Remove(key); + HttpRuntime.Cache.InternalCache.Remove(key); - Debug.Assert(_cache.Get(key) == null); + Debug.Assert(HttpRuntime.Cache.InternalCache.Get(key) == null); return null; } @@ -183,16 +181,11 @@ internal override void CacheBuildResult(string cacheKey, BuildResult result, // Insert a new cache entry using the assembly path as the key string assemblyKey = GetAssemblyCacheKey(compiledResult.ResultAssembly); - Assembly a = (Assembly)_cache.Get(assemblyKey); + Assembly a = (Assembly) HttpRuntime.Cache.InternalCache.Get(assemblyKey); if (a == null) { Debug.Trace("BuildResultCache", "Adding marker cache entry " + compiledResult.ResultAssembly); // VSWhidbey 500049 - add as NotRemovable to prevent the assembly from being prematurely deleted - _cache.UtcInsert(assemblyKey, compiledResult.ResultAssembly, - null, - Cache.NoAbsoluteExpiration, - Cache.NoSlidingExpiration, - CacheItemPriority.NotRemovable, - null); + HttpRuntime.Cache.InternalCache.Insert(assemblyKey, compiledResult.ResultAssembly, null); } else { Debug.Assert(a == compiledResult.ResultAssembly); @@ -237,11 +230,13 @@ internal override void CacheBuildResult(string cacheKey, BuildResult result, onRemoveCallback = _onRemoveCallback; } - _cache.UtcInsert(key, result, cacheDependency, - result.MemoryCacheExpiration, - result.MemoryCacheSlidingExpiration, - cachePriority, - onRemoveCallback); + HttpRuntime.Cache.InternalCache.Insert(key, result, new CacheInsertOptions() { + Dependencies = cacheDependency, + AbsoluteExpiration = result.MemoryCacheExpiration, + SlidingExpiration = result.MemoryCacheSlidingExpiration, + Priority = cachePriority, + OnRemovedCallback = onRemoveCallback + }); } // OnCacheItemRemoved can be invoked with user code on the stack, for example if someone @@ -338,7 +333,7 @@ private void RemoveAssemblyAndCleanupDependenciesNoLock(string assemblyName) { // If we have no cache entry for this assembly, there is nothing to do string cacheKey = GetAssemblyCacheKeyFromName(assemblyName); - Assembly assembly = (Assembly)_cache[cacheKey]; + Assembly assembly = (Assembly)HttpRuntime.Cache.InternalCache.Get(cacheKey); if (assembly == null) return; @@ -348,7 +343,7 @@ private void RemoveAssemblyAndCleanupDependenciesNoLock(string assemblyName) { Debug.Trace("BuildResultCache", "removing cacheKey for assembly " + assemblyPath + " because of dependency change"); // Remove the cache entry in order to kick out all the pages that are in that batch - _cache.Remove(cacheKey); + HttpRuntime.Cache.InternalCache.Remove(cacheKey); // Now call recursively on all the dependent assemblies (VSWhidbey 577593) ICollection dependentAssemblies = _dependentAssemblies[assemblyName] as ICollection; @@ -532,7 +527,7 @@ internal virtual void RemoveAssemblyAndRelatedFiles(string assemblyName) { // This is required otherwise new components can be compiled // with obsolete build results whose assembly has been removed. string assemblyKey = GetAssemblyCacheKey(f.FullName); - HttpRuntime.CacheInternal.Remove(assemblyKey); + HttpRuntime.Cache.InternalCache.Remove(assemblyKey); // Remove the assembly RemoveAssembly(f); diff --git a/System.Web/Compilation/CompilationLock.cs b/System.Web/Compilation/CompilationLock.cs index 5872f0ea6..6e271ae70 100644 --- a/System.Web/Compilation/CompilationLock.cs +++ b/System.Web/Compilation/CompilationLock.cs @@ -188,7 +188,7 @@ internal static void GetLock(ref bool gotLock) { // Always take the BuildManager lock *before* taking the mutex, to avoid possible // deadlock situations (VSWhidbey 530732) #pragma warning disable 0618 - //@TODO: This overload of Monitor.Enter is obsolete. Please change this to use Monitor.Enter(ref bool), and remove the pragmas -- [....] + //@TODO: This overload of Monitor.Enter is obsolete. Please change this to use Monitor.Enter(ref bool), and remove the pragmas -- Microsoft Monitor.Enter(BuildManager.TheBuildManager); #pragma warning restore 0618 _mutex.WaitOne(); diff --git a/System.Web/Compilation/ResourceExpressionBuilder.cs b/System.Web/Compilation/ResourceExpressionBuilder.cs index a0cdf9eef..162fcf096 100644 --- a/System.Web/Compilation/ResourceExpressionBuilder.cs +++ b/System.Web/Compilation/ResourceExpressionBuilder.cs @@ -271,9 +271,9 @@ private static IResourceProvider GetGlobalResourceProvider(string classKey) { "." + classKey; // If we have it cached, return it - CacheInternal cacheInternal = System.Web.HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = System.Web.HttpRuntime.Cache.InternalCache; string cacheKey = CacheInternal.PrefixResourceProvider + fullClassName; - IResourceProvider resourceProvider = cacheInternal[cacheKey] as IResourceProvider; + IResourceProvider resourceProvider = cacheInternal.Get(cacheKey) as IResourceProvider; if (resourceProvider != null) { return resourceProvider; } @@ -282,7 +282,7 @@ private static IResourceProvider GetGlobalResourceProvider(string classKey) { resourceProvider = s_resourceProviderFactory.CreateGlobalResourceProvider(classKey); // Cache it - cacheInternal.UtcInsert(cacheKey, resourceProvider); + cacheInternal.Insert(cacheKey, resourceProvider, null); return resourceProvider; } @@ -296,9 +296,9 @@ internal static IResourceProvider GetLocalResourceProvider(TemplateControl templ internal static IResourceProvider GetLocalResourceProvider(VirtualPath virtualPath) { // If we have it cached, return it (it may be null if there are no local resources) - CacheInternal cacheInternal = System.Web.HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = System.Web.HttpRuntime.Cache.InternalCache; string cacheKey = CacheInternal.PrefixResourceProvider + virtualPath.VirtualPathString; - IResourceProvider resourceProvider = cacheInternal[cacheKey] as IResourceProvider; + IResourceProvider resourceProvider = cacheInternal.Get(cacheKey) as IResourceProvider; if (resourceProvider != null) { return resourceProvider; } @@ -307,7 +307,7 @@ internal static IResourceProvider GetLocalResourceProvider(VirtualPath virtualPa resourceProvider = s_resourceProviderFactory.CreateLocalResourceProvider(virtualPath.VirtualPathString); // Cache it - cacheInternal.UtcInsert(cacheKey, resourceProvider); + cacheInternal.Insert(cacheKey, resourceProvider, null); return resourceProvider; } diff --git a/System.Web/Configuration/CacheSection.cs b/System.Web/Configuration/CacheSection.cs index b422d405b..5a3261ddf 100644 --- a/System.Web/Configuration/CacheSection.cs +++ b/System.Web/Configuration/CacheSection.cs @@ -19,14 +19,20 @@ namespace System.Web.Configuration { /* <!-- cache Attributes: + defaultProvider="name" - a name matching a provider in the provider list to use for Object and Internal cache. cacheAPIEnabled="[true|false]" - Enable or disable the user Cache API disableMemoryCollection="[true|false]" - Enable or disable the cache memory collection disableExpiration="[true|false]" - Enable or disable the expiration of items from the cache privateBytesLimit="number" - Represents maximum private bytes (in bytes) allowed. If it's zero, Cache will use an auto-generated limit. Cache will collect memory when the private bytes is near the limit. This works on top of other memory indexes monitored by Cache. percentagePhysicalMemoryUsedLimit="number" - Represents percentage of physical memory process allowed. Cache will collect memory when the private bytes is near the limit. This works on top of other memory indexes monitored by Cache. privateBytesPollTime="timespan" - How often we poll the process memory by calling NtQuerySystemInformation. Default is 2 min. + --> - <cache cacheAPIEnabled="true" /> + <cache cacheAPIEnabled="true" defaultProvider="name" > + <providers> + <add name="string" type="string" ... /> + </providers> + </cache> */ public sealed class CacheSection : ConfigurationSection { @@ -44,6 +50,9 @@ public sealed class CacheSection : ConfigurationSection { private static readonly ConfigurationProperty _propPercentagePhysicalMemoryUsedLimit; private static readonly ConfigurationProperty _propPrivateBytesPollTime; + private static readonly ConfigurationProperty _propProviders; + private static readonly ConfigurationProperty _propDefaultProvider; + static CacheSection() { // Property initialization @@ -51,6 +60,14 @@ static CacheSection() { _propCacheAPIEnabled = new ConfigurationProperty("cacheAPIEnabled", typeof(bool), true, ConfigurationPropertyOptions.None); _propDisableDependencies = new ConfigurationProperty("disableDependencies", typeof(bool), false, ConfigurationPropertyOptions.None); #endif + _propProviders = new ConfigurationProperty("providers", typeof(ProviderSettingsCollection), null, ConfigurationPropertyOptions.None); + _propDefaultProvider = + new ConfigurationProperty("defaultProvider", + typeof(string), + null, + null, + StdValidatorsAndConverters.NonEmptyStringValidator, + ConfigurationPropertyOptions.None); _propDisableMemoryCollection = new ConfigurationProperty("disableMemoryCollection", @@ -91,6 +108,8 @@ static CacheSection() { _properties.Add(_propDisableDependencies); #endif + _properties.Add(_propProviders); + _properties.Add(_propDefaultProvider); _properties.Add(_propDisableMemoryCollection); _properties.Add(_propDisableExpiration); _properties.Add(_propPrivateBytesLimit); @@ -101,6 +120,24 @@ static CacheSection() { public CacheSection() { } + [ConfigurationProperty("providers")] + public ProviderSettingsCollection Providers { + get { + return (ProviderSettingsCollection)base[_propProviders]; + } + } + + [ConfigurationProperty("defaultProvider", DefaultValue = null)] + [StringValidator(MinLength = 1)] + public string DefaultProvider { + get { + return (string)base[_propDefaultProvider]; + } + set { + base[_propDefaultProvider] = value; + } + } + #if NOT_UNTIL_LATER [ConfigurationProperty("cacheAPIEnabled", DefaultValue = true)] public bool CacheAPIEnabled diff --git a/System.Web/Configuration/HandlerFactoryCache.cs b/System.Web/Configuration/HandlerFactoryCache.cs index b6fe76106..c4a5de247 100644 --- a/System.Web/Configuration/HandlerFactoryCache.cs +++ b/System.Web/Configuration/HandlerFactoryCache.cs @@ -15,6 +15,7 @@ namespace System.Web.Configuration { using System.Web.Compilation; using System.Security; using System.Security.Permissions; + using System.Web; /* * An object to cache a factory @@ -37,6 +38,7 @@ internal HandlerFactoryCache(string type) { else { throw new HttpException(SR.GetString(SR.Type_not_factory_or_handler, instance.GetType().FullName)); } + TelemetryLogger.LogHttpHandler(instance.GetType()); } internal HandlerFactoryCache(HttpHandlerAction mapping) { @@ -54,6 +56,7 @@ internal HandlerFactoryCache(HttpHandlerAction mapping) { else { throw new HttpException(SR.GetString(SR.Type_not_factory_or_handler, instance.GetType().FullName)); } + TelemetryLogger.LogHttpHandler(instance.GetType()); } internal IHttpHandlerFactory Factory { diff --git a/System.Web/Configuration/HttpCapabilitiesEvaluator.cs b/System.Web/Configuration/HttpCapabilitiesEvaluator.cs index 16584711d..30e5d5999 100644 --- a/System.Web/Configuration/HttpCapabilitiesEvaluator.cs +++ b/System.Web/Configuration/HttpCapabilitiesEvaluator.cs @@ -211,7 +211,7 @@ internal static string GetUserAgentFromClientTarget(VirtualPath configPath, stri private void CacheBrowserCapResult(ref HttpCapabilitiesBase result) { // Use the previously cached browserCap object if an identical // browserCap is found. - CacheInternal cacheInternal = System.Web.HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = System.Web.HttpRuntime.Cache.InternalCache; if (result.Capabilities == null) { return; @@ -241,7 +241,7 @@ private void CacheBrowserCapResult(ref HttpCapabilitiesBase result) { } else { // cache it and respect cachetime - cacheInternal.UtcInsert(hashKey, result, null, Cache.NoAbsoluteExpiration, _cachetime); + cacheInternal.Insert(hashKey, result, new CacheInsertOptions() { SlidingExpiration = _cachetime }); } } @@ -255,7 +255,7 @@ public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest reque internal HttpCapabilitiesBase Evaluate(HttpRequest request) { HttpCapabilitiesBase result; - CacheInternal cacheInternal = System.Web.HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = System.Web.HttpRuntime.Cache.InternalCache; // // 1) grab UA and do optimistic cache lookup (if UA is in dependency list) @@ -298,7 +298,7 @@ internal HttpCapabilitiesBase Evaluate(HttpRequest request) { CacheBrowserCapResult(ref result); // Cache the result using the optimisicCacheKey - cacheInternal.UtcInsert(optimisticCacheKey, result, null, Cache.NoAbsoluteExpiration, _cachetime); + cacheInternal.Insert(optimisticCacheKey, result, new CacheInsertOptions() { SlidingExpiration = _cachetime }); return result; } @@ -363,9 +363,9 @@ internal HttpCapabilitiesBase Evaluate(HttpRequest request) { CacheBrowserCapResult(ref result); // cache it and respect _cachetime - cacheInternal.UtcInsert(fullCacheKey, result, null, Cache.NoAbsoluteExpiration, _cachetime); + cacheInternal.Insert(fullCacheKey, result, new CacheInsertOptions() { SlidingExpiration = _cachetime }); if(optimisticCacheKey != null) { - cacheInternal.UtcInsert(optimisticCacheKey, _disableOptimisticCachingSingleton, null, Cache.NoAbsoluteExpiration, _cachetime); + cacheInternal.Insert(optimisticCacheKey, _disableOptimisticCachingSingleton, new CacheInsertOptions() { SlidingExpiration = _cachetime }); } return result; diff --git a/System.Web/Configuration/MetabaseServerConfig.cs b/System.Web/Configuration/MetabaseServerConfig.cs index d3727195d..072e7c75c 100644 --- a/System.Web/Configuration/MetabaseServerConfig.cs +++ b/System.Web/Configuration/MetabaseServerConfig.cs @@ -226,7 +226,7 @@ private string MapPathCaching(string siteID, VirtualPath path) { else { // Check if it's in the cache String cacheKey = CacheInternal.PrefixMapPath + siteID + path.VirtualPathString; - cacheInfo = (MapPathCacheInfo)HttpRuntime.CacheInternal.Get(cacheKey); + cacheInfo = (MapPathCacheInfo)HttpRuntime.Cache.InternalCache.Get(cacheKey); // If not in cache, add it to the cache if (cacheInfo == null) { @@ -234,8 +234,7 @@ private string MapPathCaching(string siteID, VirtualPath path) { // Add to the cache. // No need to have a lock here. UtcAdd will add the entry if it doesn't exist. // If it does exist, the existing value will be returned (Dev10 Bug 755034). - object existingEntry = HttpRuntime.CacheInternal.UtcAdd( - cacheKey, cacheInfo, null, Cache.NoAbsoluteExpiration, slidingExpiration, CacheItemPriority.Default, null); + object existingEntry = HttpRuntime.Cache.InternalCache.Add(cacheKey, cacheInfo, new CacheInsertOptions() { SlidingExpiration = slidingExpiration }); if (existingEntry != null) { cacheInfo = existingEntry as MapPathCacheInfo; } diff --git a/System.Web/Configuration/ProcessHostMapPath.cs b/System.Web/Configuration/ProcessHostMapPath.cs index 39dccac1a..c5de8cbbb 100644 --- a/System.Web/Configuration/ProcessHostMapPath.cs +++ b/System.Web/Configuration/ProcessHostMapPath.cs @@ -224,7 +224,7 @@ private string MapPathCaching(string siteID, VirtualPath path) { else { // Check if it's in the cache String cacheKey = CacheInternal.PrefixMapPath + siteID + path.VirtualPathString; - cacheInfo = (MapPathCacheInfo)HttpRuntime.CacheInternal.Get(cacheKey); + cacheInfo = (MapPathCacheInfo)HttpRuntime.Cache.InternalCache.Get(cacheKey); // If not in cache, add it to the cache if (cacheInfo == null) { @@ -232,8 +232,7 @@ private string MapPathCaching(string siteID, VirtualPath path) { // Add to the cache. // No need to have a lock here. UtcAdd will add the entry if it doesn't exist. // If it does exist, the existing value will be returned (Dev10 Bug 755034). - object existingEntry = HttpRuntime.CacheInternal.UtcAdd( - cacheKey, cacheInfo, null, Cache.NoAbsoluteExpiration, slidingExpiration, CacheItemPriority.Default, null); + object existingEntry = HttpRuntime.Cache.InternalCache.Add(cacheKey, cacheInfo, new CacheInsertOptions() { SlidingExpiration = slidingExpiration }); if (existingEntry != null) { cacheInfo = existingEntry as MapPathCacheInfo; } diff --git a/System.Web/Configuration/ProvidersHelper.cs b/System.Web/Configuration/ProvidersHelper.cs index 6fdb01ed1..4a1b0f4b6 100644 --- a/System.Web/Configuration/ProvidersHelper.cs +++ b/System.Web/Configuration/ProvidersHelper.cs @@ -46,6 +46,35 @@ public static ProviderBase InstantiateProvider(ProviderSettings providerSettings return provider; } + [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)] + internal static ProviderBase InstantiateProvider(NameValueCollection providerSettings, Type providerType) { + ProviderBase provider = null; + try { + string pnName = GetAndRemoveStringValue(providerSettings, "name"); + string pnType = GetAndRemoveStringValue(providerSettings, "type"); + if (string.IsNullOrEmpty(pnType)) + throw new ArgumentException(SR.GetString(SR.Provider_no_type_name)); + Type t = ConfigUtil.GetType(pnType, "type", null, null, true, true); + + if (!providerType.IsAssignableFrom(t)) + throw new ArgumentException(SR.GetString(SR.Provider_must_implement_type, providerType.ToString())); + provider = (ProviderBase)HttpRuntime.CreatePublicInstance(t); + + // Because providers modify the parameters collection (i.e. delete stuff), pass in a clone of the collection + NameValueCollection cloneParams = new NameValueCollection(providerSettings.Count, StringComparer.Ordinal); + foreach (string key in providerSettings) + cloneParams[key] = providerSettings[key]; + provider.Initialize(pnName, cloneParams); + } + catch (Exception e) { + if (e is ConfigurationException) + throw; + throw new ConfigurationErrorsException(e.Message, e); + } + + return provider; + } + [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)] public static void InstantiateProviders(ProviderSettingsCollection configProviders, ProviderCollection providers, Type providerType) { @@ -53,5 +82,13 @@ public static void InstantiateProviders(ProviderSettingsCollection configProvide providers.Add(InstantiateProvider(ps, providerType)); } } + + private static string GetAndRemoveStringValue(NameValueCollection collection, string key) { + string strValue = collection[key] as string; + if (!string.IsNullOrEmpty(strValue)) + strValue = strValue.Trim(); + collection.Remove(key); + return strValue; + } } } diff --git a/System.Web/Configuration/SessionStateSection.cs b/System.Web/Configuration/SessionStateSection.cs index c09da8b62..03df79594 100644 --- a/System.Web/Configuration/SessionStateSection.cs +++ b/System.Web/Configuration/SessionStateSection.cs @@ -392,7 +392,7 @@ public string LockAttributes { return (string)base[_propLockAttributes]; } set { - // base.LockedAttributes.SetFromList(value); // keep the internal list in [....] + // base.LockedAttributes.SetFromList(value); // keep the internal list in sync base[_propLockAttributes] = value; } } diff --git a/System.Web/FileChangesMonitor.cs b/System.Web/FileChangesMonitor.cs index e4b03d475..f60acb0bc 100644 --- a/System.Web/FileChangesMonitor.cs +++ b/System.Web/FileChangesMonitor.cs @@ -149,7 +149,7 @@ static FileSecurity() { } [SuppressMessage("Microsoft.Interoperability", "CA1404:CallGetLastErrorImmediatelyAfterPInvoke", - Justification="[....]: Call to GetLastWin32Error() does follow P/Invoke call that is outside the if/else block.")] + Justification="Microsoft: Call to GetLastWin32Error() does follow P/Invoke call that is outside the if/else block.")] static internal byte[] GetDacl(string filename) { // DevDiv #322858 - allow skipping DACL step for perf gain if (HostingEnvironment.FcnSkipReadAndCacheDacls) { @@ -305,7 +305,7 @@ internal void AddTarget(FileChangeEventHandler callback, string alias, bool newA } else { #if DBG - // Needs the lock to [....] with DebugDescription + // Needs the lock to sync with DebugDescription lock (_targets) { #endif _targets.Add(callback.Target, new FileMonitorTarget(callback, alias)); @@ -330,7 +330,7 @@ internal int RemoveTarget(object callbackTarget) { #endif if (target != null && target.Release() == 0) { #if DBG - // Needs the lock to [....] with DebugDescription + // Needs the lock to sync with DebugDescription lock (_targets) { #endif _targets.Remove(callbackTarget); diff --git a/System.Web/Hosting/ApplicationManager.cs b/System.Web/Hosting/ApplicationManager.cs index 9a24a5b37..344b26076 100644 --- a/System.Web/Hosting/ApplicationManager.cs +++ b/System.Web/Hosting/ApplicationManager.cs @@ -9,7 +9,9 @@ namespace System.Web.Hosting { using System; using System.Collections; using System.Collections.Generic; + using System.Collections.Specialized; using System.Configuration; + using System.Configuration.Provider; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; @@ -88,9 +90,6 @@ public sealed class ApplicationManager : MarshalByRefObject { // single instance of app manager private static ApplicationManager _theAppManager; - // single instance of cache manager - private static CacheManager _cm; - // store fatal exception to assist debugging private static Exception _fatalException = null; @@ -105,52 +104,6 @@ internal ApplicationManager() { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException); } - private void InitCacheManager(long privateBytesLimit) { - if (_cm == null) { - lock (_applicationManagerStaticLock) { - if (_cm == null && !_shutdownInProgress) { - _cm = new CacheManager(this, privateBytesLimit); - } - } - } - } - - private void DisposeCacheManager() { - if (_cm != null) { - lock (_applicationManagerStaticLock) { - if (_cm != null) { - _cm.Dispose(); - _cm = null; - } - } - } - } - - // Each cache must update the total with the difference between it's current size and it's previous size. - // To reduce cross-domain costs, this also returns the updated total size. - internal long GetUpdatedTotalCacheSize(long sizeUpdate) { - CacheManager cm = _cm; - return (cm != null) ? cm.GetUpdatedTotalCacheSize(sizeUpdate) : 0; - } - - internal long TrimCaches(int percent) { - long trimmedOrExpired = 0; - Dictionary<string, LockableAppDomainContext> apps = CloneAppDomainsCollection(); - foreach (LockableAppDomainContext ac in apps.Values) { - lock (ac) { - HostingEnvironment env = ac.HostEnv; - if (_shutdownInProgress) { - break; - } - if (env == null) { - continue; - } - trimmedOrExpired += env.TrimCache(percent); - } - } - return trimmedOrExpired; - } - internal bool ShutdownInProgress { get { return _shutdownInProgress; @@ -468,6 +421,10 @@ public AppDomain GetAppDomain(IApplicationHost appHost) { return GetAppDomain(appID); } + internal AppDomain GetDefaultAppDomain() { + return AppDomain.CurrentDomain; + } + [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "This isn't a dangerous method.")] private string CreateSimpleAppID(IApplicationHost appHost) { if (appHost == null) { @@ -565,8 +522,6 @@ public void ShutdownAll() { _shutdownInProgress = true; Dictionary <string, LockableAppDomainContext> oldTable = null; - DisposeCacheManager(); - lock (this) { oldTable = _appDomains; // don't keep references to hosting environments anymore @@ -769,13 +724,8 @@ internal int GetNonRandomizedStringComparerHashCode(string s, bool ignoreCase) { // communication with hosting environments // - internal void HostingEnvironmentActivated(long privateBytesLimit) { + internal void HostingEnvironmentActivated() { int count = Interlocked.Increment(ref _activeHostingEnvCount); - - // initialize CacheManager once, without blocking - if (count == 1) { - InitCacheManager(privateBytesLimit); - } } internal void HostingEnvironmentShutdownComplete(String appId, IApplicationHost appHost) { @@ -1021,7 +971,7 @@ private HostingEnvironment CreateAppDomainWithHostingEnvironment( //Hosted by IIS, we already have an IISMap. if (appHost is ISAPIApplicationHost) { string cacheKey = System.Web.Caching.CacheInternal.PrefixMapPath + siteID + virtualPath.VirtualPathString; - MapPathCacheInfo cacheInfo = (MapPathCacheInfo)HttpRuntime.CacheInternal.Remove(cacheKey); + MapPathCacheInfo cacheInfo = (MapPathCacheInfo)HttpRuntime.Cache.InternalCache.Remove(cacheKey); appConfig = WebConfigurationManager.OpenWebConfiguration(appSegment, siteID); } // For non-IIS hosting scenarios, we need to get config map from application host in a generic way. @@ -1117,6 +1067,25 @@ private HostingEnvironment CreateAppDomainWithHostingEnvironment( } } + // Allow apps to use their own CacheStoreProvider implementations + CacheSection cacheConfig = (CacheSection)appConfig.GetSection("system.web/caching/cache"); + if (cacheConfig != null && cacheConfig.DefaultProvider != null && !String.IsNullOrWhiteSpace(cacheConfig.DefaultProvider)) { + ProviderSettingsCollection cacheProviders = cacheConfig.Providers; + if (cacheProviders == null || cacheProviders.Count < 1) { + throw new ProviderException(SR.GetString(SR.Def_provider_not_found)); + } + + ProviderSettings cacheProviderSettings = cacheProviders[cacheConfig.DefaultProvider]; + if (cacheProviderSettings == null) { + throw new ProviderException(SR.GetString(SR.Def_provider_not_found)); + } else { + NameValueCollection settings = cacheProviderSettings.Parameters; + settings["name"] = cacheProviderSettings.Name; + settings["type"] = cacheProviderSettings.Type; + appDomainAdditionalData[".defaultObjectCacheProvider"] = settings; + } + } + // If we were launched from a development environment, we might want to enable the application to do things // it otherwise wouldn't normally allow, such as enabling an administrative control panel. For security reasons, // we only do this check if <deployment retail="false" /> [the default value] is specified, since the diff --git a/System.Web/Hosting/HostingEnvironment.cs b/System.Web/Hosting/HostingEnvironment.cs index 27ce61302..8e2e7658e 100644 --- a/System.Web/Hosting/HostingEnvironment.cs +++ b/System.Web/Hosting/HostingEnvironment.cs @@ -7,7 +7,10 @@ namespace System.Web.Hosting { using System; using System.Collections; + using System.Collections.Generic; + using System.Collections.Specialized; using System.Configuration; + using System.Configuration.Provider; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; @@ -31,7 +34,6 @@ namespace System.Web.Hosting { using System.Web.Util; using System.Web.WebSockets; using Microsoft.Win32; - using System.Collections.Generic; [Flags] internal enum HostingEnvironmentFlags { @@ -126,6 +128,7 @@ public sealed class HostingEnvironment : MarshalByRefObject { private bool _shutdownInProgress; private String _shutDownStack; + private static NameValueCollection _cacheProviderSettings; private int _inTrimCache; private ObjectCacheHost _objectCacheHost; @@ -135,6 +138,7 @@ public sealed class HostingEnvironment : MarshalByRefObject { // list of registered IRegisteredObject instances, suspend listeners, and background work items private Hashtable _registeredObjects = new Hashtable(); private SuspendManager _suspendManager = new SuspendManager(); + private ApplicationMonitors _applicationMonitors; private BackgroundWorkScheduler _backgroundWorkScheduler = null; // created on demand private static readonly Task<object> _completedTask = Task.FromResult<object>(null); @@ -191,14 +195,29 @@ public HostingEnvironment() { Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(ApplicationManager.OnUnhandledException); } - internal long TrimCache(int percent) { + internal static long TrimCache(int percent) + { + if (_theHostingEnvironment != null) + return _theHostingEnvironment.TrimCacheInternal(percent); + return 0; + } + + private long TrimCacheInternal(int percent) + { if (Interlocked.Exchange(ref _inTrimCache, 1) != 0) return 0; try { long trimmedOrExpired = 0; // do nothing if we're shutting down if (!_shutdownInitiated) { - trimmedOrExpired = HttpRuntime.CacheInternal.TrimCache(percent); + var iCache = HttpRuntime.Cache.GetInternalCache(createIfDoesNotExist: false); + var oCache = HttpRuntime.Cache.GetObjectCache(createIfDoesNotExist: false); + if (oCache != null) { + trimmedOrExpired = oCache.Trim(percent); + } + if (iCache != null && !iCache.Equals(oCache)) { + trimmedOrExpired += iCache.Trim(percent); + } if (_objectCacheHost != null && !_shutdownInitiated) { trimmedOrExpired += _objectCacheHost.TrimCache(percent); } @@ -330,7 +349,7 @@ internal void Initialize(ApplicationManager appManager, IApplicationHost appHost // notify app manager if (_appManager != null) { - _appManager.HostingEnvironmentActivated(CacheMemorySizePressure.EffectiveProcessMemoryLimit); + _appManager.HostingEnvironmentActivated(); } // make sure there is always app host @@ -364,6 +383,8 @@ internal void Initialize(ApplicationManager appManager, IApplicationHost appHost // get application identity (for explicit impersonation mode) GetApplicationIdentity(); + _applicationMonitors = new ApplicationMonitors(); + // call AppInitialize, unless the flag says not to do it (e.g. CBM scenario). // Also, don't call it if HostingInit failed (VSWhidbey 210495) if(!HttpRuntime.HostingInitFailed) { @@ -1260,6 +1281,19 @@ internal IApplicationHost InternalApplicationHost { } } + /// <devdoc> + /// <para>A group of repleacable monitor objects used by ASP.Net subsystems to maintain + /// application health.</para> + /// </devdoc> + public static ApplicationMonitors ApplicationMonitors { + get { + if (_theHostingEnvironment == null) + return null; + + return _theHostingEnvironment._applicationMonitors; + } + } + internal static int BusyCount { get { if (_theHostingEnvironment == null) @@ -1414,6 +1448,42 @@ public static Cache Cache { get { return HttpRuntime.Cache; } } + internal static NameValueCollection CacheStoreProviderSettings { + get { + if (_cacheProviderSettings == null) { + if (AppDomain.CurrentDomain.IsDefaultAppDomain()) { + Configuration webConfig = WebConfigurationManager.OpenWebConfiguration(null /* root web.config */); + CacheSection cacheConfig = (CacheSection)webConfig.GetSection("system.web/caching/cache"); + if (cacheConfig != null && cacheConfig.DefaultProvider != null && !String.IsNullOrWhiteSpace(cacheConfig.DefaultProvider)) { + ProviderSettingsCollection cacheProviders = cacheConfig.Providers; + if (cacheProviders == null || cacheProviders.Count < 1) { + throw new ProviderException(SR.GetString(SR.Def_provider_not_found)); + } + + ProviderSettings cacheProviderSettings = cacheProviders[cacheConfig.DefaultProvider]; + if (cacheProviderSettings == null) { + throw new ProviderException(SR.GetString(SR.Def_provider_not_found)); + } + + NameValueCollection settings = cacheProviderSettings.Parameters; + settings["name"] = cacheProviderSettings.Name; + settings["type"] = cacheProviderSettings.Type; + _cacheProviderSettings = settings; + } + } + else { + _cacheProviderSettings = AppDomain.CurrentDomain.GetData(".defaultObjectCacheProvider") as NameValueCollection; + } + } + + // Return a copy, so the consumer can't mess with our copy of the settings + if (_cacheProviderSettings != null) + return new NameValueCollection(_cacheProviderSettings); + + return null; + } + } + // count of all app domain from app manager internal static int AppDomainsCount { get { diff --git a/System.Web/Hosting/IIS7WorkerRequest.cs b/System.Web/Hosting/IIS7WorkerRequest.cs index 11db95173..4db808472 100644 --- a/System.Web/Hosting/IIS7WorkerRequest.cs +++ b/System.Web/Hosting/IIS7WorkerRequest.cs @@ -1380,7 +1380,7 @@ private void FlushCachedResponse(bool isFinal) { } // send to unmanaged code - // sends are always [....] now since they're buffered by IIS + // sends are always sync now since they're buffered by IIS FlushCore(true, numFragments, fragments, diff --git a/System.Web/Hosting/ISAPIWorkerRequest.cs b/System.Web/Hosting/ISAPIWorkerRequest.cs index ce3d178ea..c89ea82f2 100644 --- a/System.Web/Hosting/ISAPIWorkerRequest.cs +++ b/System.Web/Hosting/ISAPIWorkerRequest.cs @@ -1649,7 +1649,7 @@ internal class ISAPIWorkerRequestInProc : ISAPIWorkerRequest { protected const int NUM_BASIC_SERVER_VARIABLES = 12; // needed on every request protected const int NUM_ADDITIONAL_SERVER_VARIABLES = 23; // needed when HttpRequest.ServerVariables is populated - // These constants must be kept in [....] with g_szServerVariables and g_szUnicodeServerVariables in ecbdirect.cxx + // These constants must be kept in sync with g_szServerVariables and g_szUnicodeServerVariables in ecbdirect.cxx protected const int LOGON_USER = 0; protected const int AUTH_TYPE = 1; @@ -2407,7 +2407,7 @@ internal override void FlushCore(byte[] status, CallEndOfRequestCallbackOnceAfterAllIoComplete(); } else if (rc != 0 && async) { - // on async failure default to [....] path + // on async failure default to sync path async = false; if (!inAsyncFlush) { diff --git a/System.Web/Hosting/MapPathBasedVirtualPathProvider.cs b/System.Web/Hosting/MapPathBasedVirtualPathProvider.cs index d05bc42b6..4cc2b6b75 100644 --- a/System.Web/Hosting/MapPathBasedVirtualPathProvider.cs +++ b/System.Web/Hosting/MapPathBasedVirtualPathProvider.cs @@ -86,7 +86,7 @@ private bool CacheLookupOrInsert(string virtualPath, bool isFile) { // * null means it's not cached // * true means it's cached and it exists // * false means it's cached and it doesn't exist - bool? cacheValue = HttpRuntime.CacheInternal[cacheKey] as bool?; + bool? cacheValue = HttpRuntime.Cache.InternalCache.Get(cacheKey) as bool?; if (cacheValue != null) { return cacheValue.Value; } @@ -108,7 +108,7 @@ private bool CacheLookupOrInsert(string virtualPath, bool isFile) { if (existingDir != null) { dep = new CacheDependency(existingDir); TimeSpan slidingExp = CachedPathData.UrlMetadataSlidingExpiration; - HttpRuntime.CacheInternal.UtcInsert(cacheKey, exists, dep, Cache.NoAbsoluteExpiration, slidingExp); + HttpRuntime.Cache.InternalCache.Insert(cacheKey, exists, new CacheInsertOptions() { Dependencies = dep, SlidingExpiration = slidingExp }); } return exists; diff --git a/System.Web/Hosting/ObjectCacheHost.cs b/System.Web/Hosting/ObjectCacheHost.cs index de6fb15cf..bb2dfdd1f 100644 --- a/System.Web/Hosting/ObjectCacheHost.cs +++ b/System.Web/Hosting/ObjectCacheHost.cs @@ -91,31 +91,20 @@ void IMemoryCacheManager.ReleaseCache(MemoryCache memoryCache) { if (memoryCache == null) { throw new ArgumentNullException("memoryCache"); } - long delta = 0; lock (_lock) { if (_cacheInfos != null) { MemoryCacheInfo info = null; if (_cacheInfos.TryGetValue(memoryCache, out info)) { - delta = 0 - info.Size; _cacheInfos.Remove(memoryCache); } } } - if (delta != 0) { - ApplicationManager appManager = HostingEnvironment.GetApplicationManager(); - if (appManager != null) { - ExecutionContextUtil.RunInNullExecutionContext(delegate { - appManager.GetUpdatedTotalCacheSize(delta); - }); - } - } } void IMemoryCacheManager.UpdateCacheSize(long size, MemoryCache memoryCache) { if (memoryCache == null) { throw new ArgumentNullException("memoryCache"); } - long delta = 0; lock (_lock) { if (_cacheInfos == null) { _cacheInfos = new Dictionary<MemoryCache, MemoryCacheInfo>(); @@ -126,15 +115,8 @@ void IMemoryCacheManager.UpdateCacheSize(long size, MemoryCache memoryCache) { info.Cache = memoryCache; _cacheInfos[memoryCache] = info; } - delta = size - info.Size; info.Size = size; } - ApplicationManager appManager = HostingEnvironment.GetApplicationManager(); - if (appManager != null) { - ExecutionContextUtil.RunInNullExecutionContext(delegate { - appManager.GetUpdatedTotalCacheSize(delta); - }); - } } internal long TrimCache(int percent) { diff --git a/System.Web/Hosting/SuspendManager.cs b/System.Web/Hosting/SuspendManager.cs index 392ff89ed..a39a682a4 100644 --- a/System.Web/Hosting/SuspendManager.cs +++ b/System.Web/Hosting/SuspendManager.cs @@ -78,9 +78,13 @@ private static SuspendState SuspendImpl(ICollection<ISuspendibleRegisteredObject HttpWriter.ReleaseAllPooledBuffers(); // Trim expired entries from the runtime cache - var cache = HttpRuntime.GetCacheInternal(createIfDoesNotExist: false); - if (cache != null) { - cache.TrimCache(0); + var iCache = HttpRuntime.Cache.GetInternalCache(createIfDoesNotExist: false); + var oCache = HttpRuntime.Cache.GetObjectCache(createIfDoesNotExist: false); + if (iCache != null) { + iCache.Trim(0); + } + if (oCache != null && !oCache.Equals(iCache)) { + oCache.Trim(0); } // Trim all pooled HttpApplication instances diff --git a/System.Web/HttpApplication.cs b/System.Web/HttpApplication.cs index 41564928c..1ec9a1266 100644 --- a/System.Web/HttpApplication.cs +++ b/System.Web/HttpApplication.cs @@ -789,7 +789,7 @@ private void RemoveSendResponseEventHookup(object key, Delegate handler) { } // - // [....] event hookup + // Sync event hookup // @@ -1727,7 +1727,7 @@ private void CreateEventExecutionSteps(Object eventIndex, ArrayList steps) { asyncHandler.CreateExecutionSteps(this, steps); } - // [....] + // sync EventHandler handler = (EventHandler)Events[eventIndex]; if (handler != null) { @@ -2418,7 +2418,7 @@ private void RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext co Debug.Trace("PipelineRuntime", "RegisterEventSubscriptionsWithIIS: name=" + CurrentModuleCollectionKey + ", type=" + httpModule.GetType().FullName + "\n"); - // make sure collections are in [....] + // make sure collections are in sync Debug.Assert(moduleInfo.Name == _currentModuleCollectionKey, "moduleInfo.Name == _currentModuleCollectionKey"); #endif @@ -2566,7 +2566,7 @@ private bool HasEventSubscription(Object eventIndex) { hasEvents = true; } - // [....] + // sync EventHandler handler = (EventHandler)Events[eventIndex]; if (handler != null) { @@ -4107,7 +4107,7 @@ internal override void ResumeSteps(Exception error) { break; } - // [....] case (we might be able to stay in managed code and execute another notification) + // sync case (we might be able to stay in managed code and execute another notification) if (needToFinishRequest || UnsafeIISMethods.MgdGetNextNotification(wr.RequestContext, RequestNotificationStatus.Continue) != 1) { isSynchronousCompletion = true; needToComplete = true; @@ -4171,14 +4171,14 @@ internal override void ResumeSteps(Exception error) { if (threadContext != null) { if (context.InIndicateCompletion) { if (isSynchronousCompletion) { - // this is a [....] completion on an IIS thread + // this is a sync completion on an IIS thread threadContext.Synchronize(); // Note for DevDiv 482614 fix: // If this threadContext is from IndicateCompletionContext (e.g. this thread called IndicateCompletion) // then we continue reusing this thread and only undo impersonation before unwinding back to IIS. // // If this threadContext was created while another thread was and still is in IndicateCompletion call - // (e.g. [....] or async flush on a background thread from native code, not managed since isReEnty==false) + // (e.g. sync or async flush on a background thread from native code, not managed since isReEnty==false) // then we can not reuse this thread and this threadContext will be cleaned before we leave ResumeSteps // (because needToDisassociateThreadContext was set to true when we created this threadContext) @@ -4210,7 +4210,7 @@ internal override void ResumeSteps(Exception error) { } else if (isSynchronousCompletion) { Debug.Assert(needToDisassociateThreadContext == true, "needToDisassociateThreadContext MUST BE true"); - // this is a [....] completion on an IIS thread + // this is a sync completion on an IIS thread threadContext.Synchronize(); // get ready to call IndicateCompletion context.IndicateCompletionContext = threadContext; diff --git a/System.Web/HttpBufferlessInputStream.cs b/System.Web/HttpBufferlessInputStream.cs index ea274006e..dc3174c8f 100644 --- a/System.Web/HttpBufferlessInputStream.cs +++ b/System.Web/HttpBufferlessInputStream.cs @@ -164,7 +164,7 @@ public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, Asy } } else { - // perform a [....] read + // perform a sync read return base.BeginRead(buffer, offset, count, callback, state); } } diff --git a/System.Web/HttpCachePolicy.cs b/System.Web/HttpCachePolicy.cs index 0e5efebd8..abb20f8eb 100644 --- a/System.Web/HttpCachePolicy.cs +++ b/System.Web/HttpCachePolicy.cs @@ -573,7 +573,9 @@ internal void ResetFromHttpCachePolicySettings( int i, n; string[] fields; - + + _utcTimestampRequest = utcTimestampRequest; + _varyByContentEncodings.SetContentEncodings(settings.VaryByContentEncodings); _varyByHeaders.SetHeaders(settings.VaryByHeaders); _varyByParams.SetParams(settings.VaryByParams); @@ -1155,7 +1157,7 @@ internal bool HasExpirationPolicy() { internal bool IsKernelCacheable(HttpRequest request, bool enableKernelCacheForVaryByStar) { return _cacheability == HttpCacheability.Public - && !_hasUserProvidedDependencies // Consider ([....]): rework dependency model to support user-provided dependencies + && !_hasUserProvidedDependencies // Consider (Microsoft): rework dependency model to support user-provided dependencies && !_hasSetCookieHeader && !_noServerCaching && HasExpirationPolicy() diff --git a/System.Web/HttpContext.cs b/System.Web/HttpContext.cs index 812c77906..d8cc4fe8e 100644 --- a/System.Web/HttpContext.cs +++ b/System.Web/HttpContext.cs @@ -731,7 +731,7 @@ public AsyncPreloadModeFlags AsyncPreloadMode { // which doesn't fit our expected patterns and where that code likely has negative side effects. // // This flag is respected only by AspNetSynchronizationContext; it has no effect when the - // legacy [....] context is in use. + // legacy sync context is in use. [EditorBrowsable(EditorBrowsableState.Advanced)] public bool AllowAsyncDuringSyncStages { get { @@ -1328,7 +1328,7 @@ internal RootedObjects RootedObjects { return _rootedObjects; } set { - // [....] the Principal between the containers + // Sync the Principal between the containers SwitchPrincipalContainer(value); _rootedObjects = value; } diff --git a/System.Web/HttpCookie.cs b/System.Web/HttpCookie.cs index 4d4fdf467..c5f127e60 100644 --- a/System.Web/HttpCookie.cs +++ b/System.Web/HttpCookie.cs @@ -106,7 +106,7 @@ internal bool Added { // DevID 251951 Cookie is getting duplicated by ASP.NET when they are added via a native module // This flag is used to remember that this cookie came from an IIS Set-Header flag, // so we don't duplicate it and send it back to IIS - internal bool FromHeader { + internal bool IsInResponseHeader { get; set; } diff --git a/System.Web/HttpCookieCollection.cs b/System.Web/HttpCookieCollection.cs index 8858577a9..7f1703173 100644 --- a/System.Web/HttpCookieCollection.cs +++ b/System.Web/HttpCookieCollection.cs @@ -53,7 +53,7 @@ public HttpCookieCollection(): base(StringComparer.OrdinalIgnoreCase) { } // This copy constructor is used by the granular request validation feature. The collections are mutable once - // created, but nobody should ever be mutating them, so it's ok for these to be out of [....]. Additionally, + // created, but nobody should ever be mutating them, so it's ok for these to be out of sync. Additionally, // we don't copy _response since this should only ever be called for the request cookies. internal HttpCookieCollection(HttpCookieCollection col) : base(StringComparer.OrdinalIgnoreCase) { @@ -84,7 +84,7 @@ internal void AddCookie(HttpCookie cookie, bool append) { if (append) { // DevID 251951 Cookie is getting duplicated by ASP.NET when they are added via a native module // Need to not double add response cookies from native modules - if (!cookie.FromHeader) { + if (!cookie.IsInResponseHeader) { // mark cookie as new cookie.Added = true; } @@ -99,6 +99,17 @@ internal void AddCookie(HttpCookie cookie, bool append) { } } + // VSO bug #289778: when copying cookie from Response to Request, there is side effect + // which changes Added property and causes dup cookie in response header + // This method is meant to append cookie from one collection without changing cookie object + internal void Append(HttpCookieCollection cookies) { + for (int i = 0; i < cookies.Count; ++i) { + //BaseGet method doesn't trigger validation, while Get method does + HttpCookie cookie = (HttpCookie) cookies.BaseGet(i); + BaseAdd(cookie.Name, cookie); + } + } + // MSRC 12038: limit the maximum number of items that can be added to the collection, // as a large number of items potentially can result in too many hash collisions that may cause DoS private void ThrowIfMaxHttpCollectionKeysExceeded() { diff --git a/System.Web/HttpRequest.cs b/System.Web/HttpRequest.cs index 9ad5bc288..16163c205 100644 --- a/System.Web/HttpRequest.cs +++ b/System.Web/HttpRequest.cs @@ -769,11 +769,8 @@ internal void FillInCookiesCollection(HttpCookieCollection cookieCollection, boo storedResponseCookies = Response.GetCookiesNoCreate(); } - if (storedResponseCookies != null && storedResponseCookies.Count > 0) { - HttpCookie[] responseCookieArray = new HttpCookie[storedResponseCookies.Count]; - storedResponseCookies.CopyTo(responseCookieArray, 0); - for (int iCookie = 0; iCookie < responseCookieArray.Length; iCookie++) - cookieCollection.AddCookie(responseCookieArray[iCookie], append: true); + if (storedResponseCookies != null) { + cookieCollection.Append(storedResponseCookies); } // release any stored reference to the response cookie collection diff --git a/System.Web/HttpResponse.cs b/System.Web/HttpResponse.cs index db4f72143..b18ee0248 100644 --- a/System.Web/HttpResponse.cs +++ b/System.Web/HttpResponse.cs @@ -279,9 +279,12 @@ internal void GenerateResponseHeadersForCookies() { cookie = _cookies[c]; if (cookie.Added) { - // if a cookie was added, we generate a Set-Cookie header for it - cookieHeader = cookie.GetSetCookieHeader(_context); - headers.SetHeader(cookieHeader.Name, cookieHeader.Value, false); + if (!cookie.IsInResponseHeader) { + // if a cookie was added, we generate a Set-Cookie header for it + cookieHeader = cookie.GetSetCookieHeader(_context); + headers.SetHeader(cookieHeader.Name, cookieHeader.Value, false); + cookie.IsInResponseHeader = true; + } cookie.Added = false; cookie.Changed = false; } @@ -308,6 +311,7 @@ internal void GenerateResponseHeadersForCookies() cookie = _cookies[c]; cookieHeader = cookie.GetSetCookieHeader(_context); headers.SetHeader(cookieHeader.Name, cookieHeader.Value, false); + cookie.IsInResponseHeader = true; cookie.Added = false; cookie.Changed = false; } @@ -726,7 +730,7 @@ public IAsyncResult BeginFlush(AsyncCallback callback, Object state) { return _wr.BeginFlush(callback, state); } - // perform a [....] flush since async is not supported + // perform a sync flush since async is not supported FlushAsyncResult ar = new FlushAsyncResult(callback, state); try { Flush(false); @@ -752,7 +756,7 @@ public void EndFlush(IAsyncResult asyncResult) { return; } - // finish [....] flush since async is not supported + // finish sync flush since async is not supported if (asyncResult == null) throw new ArgumentNullException("asyncResult"); FlushAsyncResult ar = asyncResult as FlushAsyncResult; @@ -1446,7 +1450,7 @@ internal void SynchronizeHeader(int knownHeaderIndex, string name, string value) if (value != null) { HttpCookie cookie = HttpRequest.CreateCookieFromString(value); // do not write this cookie back to IIS - cookie.FromHeader = true; + cookie.IsInResponseHeader = true; Cookies.Set(cookie); cookie.Changed = false; cookie.Added = false; diff --git a/System.Web/HttpRuntime.cs b/System.Web/HttpRuntime.cs index 23b97ec0e..8ea723590 100644 --- a/System.Web/HttpRuntime.cs +++ b/System.Web/HttpRuntime.cs @@ -185,7 +185,6 @@ private static void StaticInit() { private PolicyLevel _policyLevel; private string _hostSecurityPolicyResolverType = null; private FileChangesMonitor _fcm; - private CacheInternal _cacheInternal; private Cache _cachePublic; private bool _isOnUNCShare; private Profiler _profiler; @@ -444,7 +443,6 @@ private void HostingInit(HostingEnvironmentFlags hostingFlags, PolicyLevel polic // Note that we must do this after we start monitoring directory renames, // as reading config will cause file monitoring on the application directory // to occur. - HttpRuntime.CacheInternal.ReadCacheInternalConfig(cacheSection); // Set up the codegen directory for the app. This needs to be done before we process // the policy file, because it needs to replace the $CodeGen$ token. @@ -1744,7 +1742,7 @@ internal static void ReportAppOfflineErrorMessage(HttpResponse response, byte[] } /* - * Finish processing request, [....] or async + * Finish processing request, sync or async */ private void FinishRequest(HttpWorkerRequest wr, HttpContext context, Exception e) { HttpResponse response = context.Response; @@ -2017,8 +2015,16 @@ private void Dispose() { SqlCacheDependencyManager.Dispose((drainTimeoutSec * 1000) / 2); #endif // !FEATURE_PAL // cleanup cache (this ends all sessions) - if (_cacheInternal != null) { - _cacheInternal.Dispose(); + HealthMonitoringManager.IsCacheDisposed = true; // HMM is the only place internally where we care if the Cache is disposed or not. + if (_cachePublic != null) { + var oCache = HttpRuntime.Cache.GetObjectCache(createIfDoesNotExist: false); + var iCache = HttpRuntime.Cache.GetInternalCache(createIfDoesNotExist: false); + if (oCache != null) { + oCache.Dispose(); + } + if (iCache != null) { + iCache.Dispose(); + } } // app on end, cleanup app instances @@ -2792,53 +2798,22 @@ public static Cache Cache { throw new HttpException(SR.GetString(SR.Aspnet_not_installed, VersionInfo.SystemWebVersion)); } - // In a web app, ReadCacheInternalConfig() is called from HttpRuntime.HostingInit. - // However, if the cache is used by a non-http app, HttpRuntime.HostingInit won't - // be called and we need to find a way to call ReadCacheInternalConfig(). - // The safe and inexpensive place to call it is when the non-http app accesses the - // Cache thru HttpRuntime.Cache. - // - // ReadCacheInternalConfig() protects itself from being read multiple times. - // Cache cachePublic = _theRuntime._cachePublic; if (cachePublic == null) { - CacheInternal cacheInternal = CacheInternal; - CacheSection cacheSection = RuntimeConfig.GetAppConfig().Cache; - cacheInternal.ReadCacheInternalConfig(cacheSection); - _theRuntime._cachePublic = cacheInternal.CachePublic; - cachePublic = _theRuntime._cachePublic; + lock (_theRuntime) { + cachePublic = _theRuntime._cachePublic; + if (cachePublic == null) { + // Create the CACHE object + cachePublic = new Caching.Cache(0); + _theRuntime._cachePublic = cachePublic; + } + } } return cachePublic; } } - private void CreateCache() { - lock (this) { - if (_cacheInternal == null) { - _cacheInternal = CacheInternal.Create(); - } - } - } - - internal static CacheInternal GetCacheInternal(bool createIfDoesNotExist) { - // Note that we only create the cache on first access, - // not in HttpRuntime initialization. - // This prevents cache timers from running when - // the cache is not used. - CacheInternal cacheInternal = _theRuntime._cacheInternal; - if (cacheInternal == null && createIfDoesNotExist) { - _theRuntime.CreateCache(); - cacheInternal = _theRuntime._cacheInternal; - } - - return cacheInternal; - } - - internal static CacheInternal CacheInternal { - get { return GetCacheInternal(createIfDoesNotExist: true); } - } - /// <devdoc> /// <para>[To be supplied.]</para> /// </devdoc> diff --git a/System.Web/InternalApis/NDP_Common/inc/StrongNameHelpers.cs b/System.Web/InternalApis/NDP_Common/inc/StrongNameHelpers.cs index 262070c90..eca286141 100644 --- a/System.Web/InternalApis/NDP_Common/inc/StrongNameHelpers.cs +++ b/System.Web/InternalApis/NDP_Common/inc/StrongNameHelpers.cs @@ -20,7 +20,7 @@ internal static class StrongNameHelpers { [ThreadStatic] private static IClrStrongName s_StrongName; - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] private static IClrStrongName StrongName { [System.Security.SecurityCritical] get { @@ -33,7 +33,7 @@ private static IClrStrongName StrongName { } } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] private static IClrStrongNameUsingIntPtr StrongNameUsingIntPtr { [System.Security.SecurityCritical] get { @@ -42,20 +42,20 @@ private static IClrStrongNameUsingIntPtr StrongNameUsingIntPtr { } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static int StrongNameErrorInfo() { return ts_LastStrongNameHR; } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "Microsoft.Runtime.Hosting.IClrStrongNameUsingIntPtr.StrongNameFreeBuffer(System.IntPtr)", Justification = "StrongNameFreeBuffer returns void but the new runtime wrappers return an HRESULT.")] public static void StrongNameFreeBuffer(IntPtr pbMemory) { StrongNameUsingIntPtr.StrongNameFreeBuffer(pbMemory); } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameGetPublicKey(string pwzKeyContainer, IntPtr pbKeyBlob, int cbKeyBlob, out IntPtr ppbPublicKeyBlob, out int pcbPublicKeyBlob) { int hr = StrongNameUsingIntPtr.StrongNameGetPublicKey(pwzKeyContainer, pbKeyBlob, cbKeyBlob, out ppbPublicKeyBlob, out pcbPublicKeyBlob); if( hr < 0 ) @@ -70,7 +70,7 @@ public static bool StrongNameGetPublicKey(string pwzKeyContainer, IntPtr pbKeyBl [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameKeyDelete(string pwzKeyContainer) { int hr = StrongName.StrongNameKeyDelete(pwzKeyContainer); if( hr < 0 ) @@ -82,7 +82,7 @@ public static bool StrongNameKeyDelete(string pwzKeyContainer) { } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameKeyGen(string pwzKeyContainer, int dwFlags, out IntPtr ppbKeyBlob, out int pcbKeyBlob) { int hr = StrongName.StrongNameKeyGen(pwzKeyContainer, dwFlags, out ppbKeyBlob, out pcbKeyBlob); if( hr < 0 ) @@ -96,7 +96,7 @@ public static bool StrongNameKeyGen(string pwzKeyContainer, int dwFlags, out Int } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameKeyInstall(string pwzKeyContainer, IntPtr pbKeyBlob, int cbKeyBlob) { int hr = StrongNameUsingIntPtr.StrongNameKeyInstall(pwzKeyContainer, pbKeyBlob, cbKeyBlob); if( hr < 0 ) @@ -108,7 +108,7 @@ public static bool StrongNameKeyInstall(string pwzKeyContainer, IntPtr pbKeyBlob } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzKeyContainer, IntPtr pbKeyBlob, int cbKeyBlob) { IntPtr ppbSignatureBlob = IntPtr.Zero; int cbSignatureBlob = 0; @@ -117,7 +117,7 @@ public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzK [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzKeyContainer, IntPtr pbKeyBlob, int cbKeyBlob, ref IntPtr ppbSignatureBlob, out int pcbSignatureBlob) { int hr = StrongNameUsingIntPtr.StrongNameSignatureGeneration(pwzFilePath, pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, out pcbSignatureBlob); if( hr < 0 ) @@ -130,7 +130,7 @@ public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzK } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureSize(IntPtr pbPublicKeyBlob, int cbPublicKeyBlob, out int pcbSize) { int hr = StrongNameUsingIntPtr.StrongNameSignatureSize(pbPublicKeyBlob, cbPublicKeyBlob, out pcbSize); if( hr < 0 ) @@ -143,7 +143,7 @@ public static bool StrongNameSignatureSize(IntPtr pbPublicKeyBlob, int cbPublicK } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureVerification(string pwzFilePath, int dwInFlags, out int pdwOutFlags) { int hr = StrongName.StrongNameSignatureVerification(pwzFilePath, dwInFlags, out pdwOutFlags); if( hr < 0 ) @@ -156,7 +156,7 @@ public static bool StrongNameSignatureVerification(string pwzFilePath, int dwInF } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureVerificationEx(string pwzFilePath, bool fForceVerification, out bool pfWasVerified) { int hr = StrongName.StrongNameSignatureVerificationEx(pwzFilePath, fForceVerification, out pfWasVerified); if( hr < 0 ) @@ -169,7 +169,7 @@ public static bool StrongNameSignatureVerificationEx(string pwzFilePath, bool fF } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameTokenFromPublicKey(IntPtr pbPublicKeyBlob, int cbPublicKeyBlob, out IntPtr ppbStrongNameToken, out int pcbStrongNameToken) { int hr = StrongNameUsingIntPtr.StrongNameTokenFromPublicKey(pbPublicKeyBlob, cbPublicKeyBlob, out ppbStrongNameToken, out pcbStrongNameToken); if( hr < 0 ) @@ -183,7 +183,7 @@ public static bool StrongNameTokenFromPublicKey(IntPtr pbPublicKeyBlob, int cbPu } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureSize(byte[] bPublicKeyBlob, int cbPublicKeyBlob, out int pcbSize) { int hr = StrongName.StrongNameSignatureSize(bPublicKeyBlob, cbPublicKeyBlob, out pcbSize); if( hr < 0 ) @@ -195,7 +195,7 @@ public static bool StrongNameSignatureSize(byte[] bPublicKeyBlob, int cbPublicKe return true; } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameTokenFromPublicKey(byte[] bPublicKeyBlob, int cbPublicKeyBlob, out IntPtr ppbStrongNameToken, out int pcbStrongNameToken) { int hr = StrongName.StrongNameTokenFromPublicKey(bPublicKeyBlob, cbPublicKeyBlob, out ppbStrongNameToken, out pcbStrongNameToken); if( hr < 0 ) @@ -209,7 +209,7 @@ public static bool StrongNameTokenFromPublicKey(byte[] bPublicKeyBlob, int cbPub } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameGetPublicKey(string pwzKeyContainer, byte[] bKeyBlob, int cbKeyBlob, out IntPtr ppbPublicKeyBlob, out int pcbPublicKeyBlob) { int hr = StrongName.StrongNameGetPublicKey(pwzKeyContainer, bKeyBlob, cbKeyBlob, out ppbPublicKeyBlob, out pcbPublicKeyBlob); if( hr < 0 ) @@ -223,7 +223,7 @@ public static bool StrongNameGetPublicKey(string pwzKeyContainer, byte[] bKeyBlo } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameKeyInstall(string pwzKeyContainer, byte[] bKeyBlob, int cbKeyBlob) { int hr = StrongName.StrongNameKeyInstall(pwzKeyContainer, bKeyBlob, cbKeyBlob); if( hr < 0 ) @@ -235,7 +235,7 @@ public static bool StrongNameKeyInstall(string pwzKeyContainer, byte[] bKeyBlob, } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzKeyContainer, byte[] bKeyBlob, int cbKeyBlob) { IntPtr ppbSignatureBlob = IntPtr.Zero; int cbSignatureBlob = 0; @@ -243,7 +243,7 @@ public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzK } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzKeyContainer, byte[] bKeyBlob, int cbKeyBlob, ref IntPtr ppbSignatureBlob, out int pcbSignatureBlob) { int hr = StrongName.StrongNameSignatureGeneration(pwzFilePath, pwzKeyContainer, bKeyBlob, cbKeyBlob, ppbSignatureBlob, out pcbSignatureBlob); if( hr < 0 ) diff --git a/System.Web/LegacyAspNetSynchronizationContext.cs b/System.Web/LegacyAspNetSynchronizationContext.cs index 2bbdf1b4f..8a3517932 100644 --- a/System.Web/LegacyAspNetSynchronizationContext.cs +++ b/System.Web/LegacyAspNetSynchronizationContext.cs @@ -43,7 +43,7 @@ private void CheckForRequestStateIfRequired() { private void CallCallback(SendOrPostCallback callback, Object state) { CheckForRequestStateIfRequired(); - // don't take app lock for [....] caller to avoid deadlocks in case they poll for result + // don't take app lock for sync caller to avoid deadlocks in case they poll for result if (_syncCaller) { CallCallbackPossiblyUnderLock(callback, state); } @@ -72,7 +72,7 @@ private void CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object s } } - // this property no-ops using the legacy [....] context + // this property no-ops using the legacy sync context internal override bool AllowAsyncDuringSyncStages { get; set; diff --git a/System.Web/Management/WebEvents.cs b/System.Web/Management/WebEvents.cs index f7c17a349..6dcaca837 100644 --- a/System.Web/Management/WebEvents.cs +++ b/System.Web/Management/WebEvents.cs @@ -893,15 +893,14 @@ static string CreateWebEventResourceCacheKey(String key) { } internal static String FormatResourceStringWithCache(String key) { - CacheInternal cacheInternal = HttpRuntime.CacheInternal; - // HealthMonitoring, in some scenarios, can call into the cache hundreds of // times during shutdown, after the cache has been disposed. To improve // shutdown performance, skip the cache when it is disposed. - if (cacheInternal.IsDisposed) { + if (HealthMonitoringManager.IsCacheDisposed) { return SR.Resources.GetString(key, CultureInfo.InstalledUICulture); } + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; string s; string cacheKey = CreateWebEventResourceCacheKey(key); @@ -913,7 +912,7 @@ internal static String FormatResourceStringWithCache(String key) { s = SR.Resources.GetString(key, CultureInfo.InstalledUICulture); if (s != null) { - cacheInternal.UtcInsert(cacheKey, s); + cacheInternal.Insert(cacheKey, s, null); } return s; @@ -2330,6 +2329,7 @@ internal class HealthMonitoringManager { static bool s_inited = false; static bool s_initing = false; static object s_lockObject = new object(); + static bool s_isCacheDisposed = false; // If this method returns null, it means we failed during configuration. internal static HealthMonitoringManager Manager() { @@ -2381,6 +2381,8 @@ internal static bool Enabled { } } + internal static bool IsCacheDisposed { get { return s_isCacheDisposed; } set { s_isCacheDisposed = value; } } + internal static void StartHealthMonitoringHeartbeat() { HealthMonitoringManager manager = Manager(); if (manager == null) { diff --git a/System.Web/PipelineModuleStepContainer.cs b/System.Web/PipelineModuleStepContainer.cs index fb8effd3d..0d2b49071 100644 --- a/System.Web/PipelineModuleStepContainer.cs +++ b/System.Web/PipelineModuleStepContainer.cs @@ -130,7 +130,7 @@ internal void RemoveEvent(RequestNotification notification, bool isPostEvent, De for (int i = 0; i < stepArray.Count; i++ ) { // we don't support removing async event handlers - // but the event syntax forces us to handle [....] events + // but the event syntax forces us to handle sync events syncStep = stepArray[i] as HttpApplication.SyncEventExecutionStep; if (null != syncStep) { if (syncStep.Handler == (EventHandler)handler) { diff --git a/System.Web/Routing/Route.cs b/System.Web/Routing/Route.cs index 4e78e8ee3..04f33a9d6 100644 --- a/System.Web/Routing/Route.cs +++ b/System.Web/Routing/Route.cs @@ -80,7 +80,7 @@ public string Url { } set { // The parser will throw for invalid routes. We don't have to worry - // about _parsedRoute getting out of [....] with _url since the latter + // about _parsedRoute getting out of sync with _url since the latter // won't get set unless we can parse the route. _parsedRoute = RouteParser.Parse(value); diff --git a/System.Web/Routing/RouteCollection.cs b/System.Web/Routing/RouteCollection.cs index dc8b1d354..0b6bf9cfd 100644 --- a/System.Web/Routing/RouteCollection.cs +++ b/System.Web/Routing/RouteCollection.cs @@ -81,6 +81,12 @@ public void Add(string name, RouteBase item) { if (!String.IsNullOrEmpty(name)) { _namedMap[name] = item; } + + // RouteBase doesn't have handler info, so we only log Route.RouteHandler + var route = item as Route; + if (route != null && route.RouteHandler != null) { + TelemetryLogger.LogHttpHandler(route.RouteHandler.GetType()); + } } [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", diff --git a/System.Web/Security/ADMembershipProvider.cs b/System.Web/Security/ADMembershipProvider.cs index 6fc96d5a4..046003984 100644 --- a/System.Web/Security/ADMembershipProvider.cs +++ b/System.Web/Security/ADMembershipProvider.cs @@ -378,6 +378,7 @@ public override void Initialize(string name, NameValueCollection config) int clientSearchTimeout = SecUtility.GetIntValue(config, "clientSearchTimeout", -1, false, 0); int serverSearchTimeout = SecUtility.GetIntValue(config, "serverSearchTimeout", -1, false, 0); + TimeUnit timeoutUnit = SecUtility.GetTimeoutUnit(config, "timeoutUnit", TimeUnit.Minutes); passwordStrengthRegexTimeout = SecUtility.GetNullableIntValue(config, "passwordStrengthRegexTimeout"); enableSearchMethods = SecUtility.GetBooleanValue(config, "enableSearchMethods", false); @@ -418,7 +419,7 @@ public override void Initialize(string name, NameValueCollection config) // connectionprotection if necessary, make sure credentials are valid, container exists and the directory is // either AD or ADAM) // - directoryInfo = new DirectoryInformation(adConnectionString, credential, connProtection, clientSearchTimeout, serverSearchTimeout, enablePasswordReset); + directoryInfo = new DirectoryInformation(adConnectionString, credential, connProtection, clientSearchTimeout, serverSearchTimeout, enablePasswordReset, timeoutUnit); // // initialize the syntaxes table @@ -609,6 +610,7 @@ public override void Initialize(string name, NameValueCollection config) config.Remove("connectionPassword"); config.Remove("clientSearchTimeout"); config.Remove("serverSearchTimeout"); + config.Remove("timeoutUnit"); config.Remove("enableSearchMethods"); config.Remove("maxInvalidPasswordAttempts"); config.Remove("passwordAttemptWindow"); @@ -2021,9 +2023,9 @@ public override string GetUserNameByEmail(string email) searcher.PropertiesToLoad.Add(attributeMapUsername); if (directoryInfo.ClientSearchTimeout != -1) - searcher.ClientTimeout = new TimeSpan(0, directoryInfo.ClientSearchTimeout, 0); + searcher.ClientTimeout = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ClientSearchTimeout, directoryInfo.TimeoutUnit); if (directoryInfo.ServerSearchTimeout != -1) - searcher.ServerPageTimeLimit = new TimeSpan(0, directoryInfo.ServerSearchTimeout, 0); + searcher.ServerPageTimeLimit = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ServerSearchTimeout, directoryInfo.TimeoutUnit); resCol = searcher.FindAll(); bool userFound = false; @@ -2371,9 +2373,9 @@ private DirectoryEntry FindUserEntry(DirectoryEntry containerEntry, string filte searcher.Filter = "(&(objectCategory=person)(objectClass=user)" + filter + ")"; if (directoryInfo.ClientSearchTimeout != -1) - searcher.ClientTimeout = new TimeSpan(0, directoryInfo.ClientSearchTimeout, 0); + searcher.ClientTimeout = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ClientSearchTimeout, directoryInfo.TimeoutUnit); if (directoryInfo.ServerSearchTimeout != -1) - searcher.ServerPageTimeLimit = new TimeSpan(0, directoryInfo.ServerSearchTimeout, 0); + searcher.ServerPageTimeLimit = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ServerSearchTimeout, directoryInfo.TimeoutUnit); if (retrieveSAMAccountName) searcher.PropertiesToLoad.Add("sAMAccountName"); @@ -2413,9 +2415,9 @@ private MembershipUser FindUser(DirectoryEntry containerEntry, string filter, Sy searcher.Filter = "(&(objectCategory=person)(objectClass=user)" + filter + ")"; if (directoryInfo.ClientSearchTimeout != -1) - searcher.ClientTimeout = new TimeSpan(0, directoryInfo.ClientSearchTimeout, 0); + searcher.ClientTimeout = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ClientSearchTimeout, directoryInfo.TimeoutUnit); if (directoryInfo.ServerSearchTimeout != -1) - searcher.ServerPageTimeLimit = new TimeSpan(0, directoryInfo.ServerSearchTimeout, 0); + searcher.ServerPageTimeLimit = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ServerSearchTimeout, directoryInfo.TimeoutUnit); // // load all the attributes needed to create a MembershipUser object @@ -2483,9 +2485,9 @@ private MembershipUserCollection FindUsers(DirectoryEntry containerEntry, string searcher.Filter = "(&(objectCategory=person)(objectClass=user)" + filter + ")"; if (directoryInfo.ClientSearchTimeout != -1) - searcher.ClientTimeout = new TimeSpan(0, directoryInfo.ClientSearchTimeout, 0); + searcher.ClientTimeout = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ClientSearchTimeout, directoryInfo.TimeoutUnit); if (directoryInfo.ServerSearchTimeout != -1) - searcher.ServerPageTimeLimit = new TimeSpan(0, directoryInfo.ServerSearchTimeout, 0); + searcher.ServerPageTimeLimit = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ServerSearchTimeout, directoryInfo.TimeoutUnit); // // load all the attributes needed to create a MembershipUser object @@ -3059,9 +3061,9 @@ private bool IsUpnUnique(string username) searcher.SearchScope = System.DirectoryServices.SearchScope.Subtree; if (directoryInfo.ClientSearchTimeout != -1) - searcher.ClientTimeout = new TimeSpan(0, directoryInfo.ClientSearchTimeout, 0); + searcher.ClientTimeout = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ClientSearchTimeout, directoryInfo.TimeoutUnit); if (directoryInfo.ServerSearchTimeout != -1) - searcher.ServerPageTimeLimit = new TimeSpan(0, directoryInfo.ServerSearchTimeout, 0); + searcher.ServerPageTimeLimit = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ServerSearchTimeout, directoryInfo.TimeoutUnit); bool result; try @@ -3099,9 +3101,9 @@ private bool IsEmailUnique(DirectoryEntry containerEntry, string username, strin searcher.SearchScope = System.DirectoryServices.SearchScope.Subtree; if (directoryInfo.ClientSearchTimeout != -1) - searcher.ClientTimeout = new TimeSpan(0, directoryInfo.ClientSearchTimeout, 0); + searcher.ClientTimeout = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ClientSearchTimeout, directoryInfo.TimeoutUnit); if (directoryInfo.ServerSearchTimeout != -1) - searcher.ServerPageTimeLimit = new TimeSpan(0, directoryInfo.ServerSearchTimeout, 0); + searcher.ServerPageTimeLimit = DateTimeUtil.GetTimeoutFromTimeUnit(directoryInfo.ServerSearchTimeout, directoryInfo.TimeoutUnit); bool result; try @@ -3434,6 +3436,7 @@ internal sealed class DirectoryInformation private bool concurrentBindSupported = false; private int clientSearchTimeout = -1; private int serverSearchTimeout = -1; + private TimeUnit timeUnit = TimeUnit.Unknown; private DirectoryEntry rootdse = null; private NetworkCredential credentials = null; private AuthenticationTypes authenticationType = AuthenticationTypes.None; @@ -3471,7 +3474,8 @@ internal DirectoryInformation(string adspath, string connProtection, int clientSearchTimeout, int serverSearchTimeout, - bool enablePasswordReset) + bool enablePasswordReset, + TimeUnit timeUnit) { // @@ -3482,6 +3486,7 @@ internal DirectoryInformation(string adspath, this.credentials = credentials; this.clientSearchTimeout = clientSearchTimeout; this.serverSearchTimeout = serverSearchTimeout; + this.timeUnit = timeUnit; Debug.Assert(adspath != null); Debug.Assert(adspath.Length > 0); @@ -3880,6 +3885,11 @@ internal int ServerSearchTimeout get { return serverSearchTimeout; } } + internal TimeUnit TimeoutUnit + { + get { return timeUnit; } + } + internal string ADAMPartitionDN { get { return adamPartitionDN; } diff --git a/System.Web/Security/Cryptography/CryptoAlgorithms.cs b/System.Web/Security/Cryptography/CryptoAlgorithms.cs index a4147901f..aeb505ade 100644 --- a/System.Web/Security/Cryptography/CryptoAlgorithms.cs +++ b/System.Web/Security/Cryptography/CryptoAlgorithms.cs @@ -12,7 +12,7 @@ namespace System.Web.Security.Cryptography { // Utility class to provide the "one true way" of getting instances of // cryptographic algorithms, like SymmetricAlgorithm and HashAlgorithm. - // From discussions with [....] and the crypto board, we should prefer + // From discussions with Microsoft and the crypto board, we should prefer // the CNG implementations of algorithms, then the CAPI implementations, // then finally managed implementations if there are no CNG / CAPI // implementations. The CNG / CAPI implementations are preferred for diff --git a/System.Web/Security/FileAuthorizationModule.cs b/System.Web/Security/FileAuthorizationModule.cs index 63c2efee1..7eb437ea8 100644 --- a/System.Web/Security/FileAuthorizationModule.cs +++ b/System.Web/Security/FileAuthorizationModule.cs @@ -254,7 +254,7 @@ private static FileSecurityDescriptorWrapper GetFileSecurityDescriptorWrapper(st freeDescriptor = false; string oCacheKey = CacheInternal.PrefixFileSecurity + fileName; - FileSecurityDescriptorWrapper oSecDesc = HttpRuntime.CacheInternal.Get(oCacheKey) as FileSecurityDescriptorWrapper; + FileSecurityDescriptorWrapper oSecDesc = HttpRuntime.Cache.InternalCache.Get(oCacheKey) as FileSecurityDescriptorWrapper; // If it's not present in the cache, then create it and add to the cache if (oSecDesc == null) { @@ -267,8 +267,11 @@ private static FileSecurityDescriptorWrapper GetFileSecurityDescriptorWrapper(st Debug.Trace("FAM", "GetFileSecurityDescriptorWrapper: inserting into cache with dependency on " + cacheDependencyPath); CacheDependency dependency = new CacheDependency(0, cacheDependencyPath); TimeSpan slidingExp = CachedPathData.UrlMetadataSlidingExpiration; - HttpRuntime.CacheInternal.UtcInsert(oCacheKey, oSecDesc, dependency, Cache.NoAbsoluteExpiration, slidingExp, - CacheItemPriority.Default, new CacheItemRemovedCallback(oSecDesc.OnCacheItemRemoved)); + HttpRuntime.Cache.InternalCache.Insert(oCacheKey, oSecDesc, new CacheInsertOptions() { + Dependencies = dependency, + SlidingExpiration = slidingExp, + OnRemovedCallback = new CacheItemRemovedCallback(oSecDesc.OnCacheItemRemoved) + }); } catch (Exception e){ Debug.Trace("internal", e.ToString()); freeDescriptor = true; @@ -303,7 +306,7 @@ static internal bool RequestRequiresAuthorization(HttpContext context) { oCacheKey = CacheInternal.PrefixFileSecurity + context.Request.PhysicalPathInternal; - sec = HttpRuntime.CacheInternal.Get(oCacheKey); + sec = HttpRuntime.Cache.InternalCache.Get(oCacheKey); // If it's not present in the cache, then return true if (sec == null || !(sec is FileSecurityDescriptorWrapper)) diff --git a/System.Web/Security/Membership.cs b/System.Web/Security/Membership.cs index 13b14cad6..dfe0be3bc 100644 --- a/System.Web/Security/Membership.cs +++ b/System.Web/Security/Membership.cs @@ -412,7 +412,27 @@ private static void Initialize() if (defaultProviderInitialized) { s_InitializedDefaultProvider = true; } + // VSO #265267 log warning in event log when using clear password and encrypted password in Membership provider + // VSO #366114 Move this to only after the initialization has fully completed. + if (s_Initialized && s_InitializedDefaultProvider) { + CheckedPasswordFormat(s_Providers); + } + } + } + + // VSO #265267 we want to log a warning in the event log, whenever detect using clear password or encrypted password formats settings in Membership provider + private static void CheckedPasswordFormat(MembershipProviderCollection providers) { + //VSO #294931 Since this is an optional feature, we want to prevent any corner cases that were not able to return the password format. In those cases, we will just do nothing and not log any warnings. + try { + + foreach (MembershipProvider p in providers) { + if (p != null && (p.PasswordFormat == MembershipPasswordFormat.Clear || p.PasswordFormat == MembershipPasswordFormat.Encrypted)) { + string providerName = p.Name ?? string.Empty; + WebBaseEvent.RaiseRuntimeError(new ConfigurationErrorsException(SR.GetString(SR.MembershipPasswordFormat_Obsoleted, providerName, p.PasswordFormat)), typeof(MembershipProvider)); + } + } } + catch { } } private static bool InitializeSettings(bool initializeGeneralSettings, RuntimeConfig appConfig, MembershipSection settings) { diff --git a/System.Web/Security/RoleClaimProvider.cs b/System.Web/Security/RoleClaimProvider.cs index ad8c9dc19..03563e9dc 100644 --- a/System.Web/Security/RoleClaimProvider.cs +++ b/System.Web/Security/RoleClaimProvider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // // RoleClaimProvider.cs diff --git a/System.Web/State/InProcStateClientManager.cs b/System.Web/State/InProcStateClientManager.cs index 4e92fdfd9..dc66a9cb2 100644 --- a/System.Web/State/InProcStateClientManager.cs +++ b/System.Web/State/InProcStateClientManager.cs @@ -118,7 +118,7 @@ SessionStateStoreData DoGet(HttpContext context, // with SQL provider SessionIDManager.CheckIdLength(id, true /* throwOnFail */); - InProcSessionState state = (InProcSessionState) HttpRuntime.CacheInternal.Get(key); + InProcSessionState state = (InProcSessionState)HttpRuntime.Cache.InternalCache.Get(key); if (state != null) { bool lockedByOther; // True if the state is locked by another session int initialFlags; @@ -224,7 +224,7 @@ public override void ReleaseItemExclusive(HttpContext context, SessionIDManager.CheckIdLength(id, true /* throwOnFail */); - InProcSessionState state = (InProcSessionState) HttpRuntime.CacheInternal.Get(key); + InProcSessionState state = (InProcSessionState)HttpRuntime.Cache.InternalCache.Get(key); /* If the state isn't there, we probably took too long to run. */ if (state == null) @@ -250,7 +250,7 @@ public override void SetAndReleaseItemExclusive(HttpContext context, bool newItem) { string key = CreateSessionStateCacheKey(id); bool doInsert = true; - CacheInternal cacheInternal = HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; int lockCookieForInsert = NewLockCookie; ISessionStateItemCollection items = null; HttpStaticObjectsCollection staticObjects = null; @@ -312,7 +312,7 @@ because the expiry time has changed. Pleas note that an insert will cause the Session_End to be incorrectly raised. Please note that the item itself should not expire between now and - where we do UtcInsert below because CacheInternal.Get above have just + where we do UtcInsert below because cacheInternal.Get above have just updated its expiry time. */ stateCurrent._flags |= (int)SessionStateItemFlags.IgnoreCacheItemRemoved; @@ -346,9 +346,11 @@ when we drop the lock. } finally { // protected from ThreadAbortEx - cacheInternal.UtcInsert( - key, state, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, state._timeout, 0), - CacheItemPriority.NotRemovable, _callback); + cacheInternal.Insert(key, state, new CacheInsertOptions() { + SlidingExpiration = new TimeSpan(0, state._timeout, 0), + Priority = CacheItemPriority.NotRemovable, + OnRemovedCallback = _callback + }); PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL); PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE); @@ -383,9 +385,11 @@ public override void CreateUninitializedItem(HttpContext context, String id, int } finally { // protected from ThreadAbortEx - object existingEntry = HttpRuntime.CacheInternal.UtcAdd( - key, state, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, timeout, 0), - CacheItemPriority.NotRemovable, _callback); + object existingEntry = HttpRuntime.Cache.InternalCache.Add(key, state, new CacheInsertOptions() { + SlidingExpiration = new TimeSpan(0, timeout, 0), + Priority = CacheItemPriority.NotRemovable, + OnRemovedCallback = _callback + }); if (existingEntry == null) { PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_TOTAL); PerfCounters.IncrementCounter(AppPerfCounter.SESSIONS_ACTIVE); @@ -402,7 +406,7 @@ public override void RemoveItem(HttpContext context, Debug.Assert(lockId != null, "lockId != null"); string key = CreateSessionStateCacheKey(id); - CacheInternal cacheInternal = HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; int lockCookie = (int)lockId; SessionIDManager.CheckIdLength(id, true /* throwOnFail */); @@ -438,7 +442,7 @@ public override void ResetItemTimeout(HttpContext context, String id) string key = CreateSessionStateCacheKey(id); SessionIDManager.CheckIdLength(id, true /* throwOnFail */); - HttpRuntime.CacheInternal.Get(key); + HttpRuntime.Cache.InternalCache.Get(key); } // Create a new SessionStateStoreData. diff --git a/System.Web/State/SessionStateModule.cs b/System.Web/State/SessionStateModule.cs index 84b3d55a8..0915da99b 100644 --- a/System.Web/State/SessionStateModule.cs +++ b/System.Web/State/SessionStateModule.cs @@ -31,6 +31,8 @@ namespace System.Web.SessionState { using System.Web.Hosting; using System.Web.Management; using Microsoft.Win32; + using System.Collections.Concurrent; + using System.Collections.Generic; public delegate void SessionStateItemExpireCallback( string id, SessionStateStoreData item); @@ -153,7 +155,8 @@ public sealed class SessionStateModule : ISessionStateModule { private static bool s_PollIntervalRegLookedUp = false; private static object s_PollIntervalRegLock = new object(); - + + private static ConcurrentDictionary<string, int> s_queuedRequestsNumPerSession = new ConcurrentDictionary<string, int>(); // // Check if we can optmize for InProc case. // Optimization details: @@ -962,7 +965,7 @@ void LockSessionStateItem() { Debug.Assert(storedItem != null, "Must succeed in locking session state item."); } } - + bool GetSessionStateItem() { bool isCompleted = true; bool locked; @@ -1012,6 +1015,8 @@ bool GetSessionStateItem() { } void PollLockedSession() { + EnsureRequestTimeout(); + if (_timerCallback == null) { _timerCallback = new TimerCallback(this.PollLockedSessionCallback); } @@ -1019,6 +1024,9 @@ void PollLockedSession() { if (_timer == null) { _timerId++; + // Only call this method once when setting up timer to poll the session item. + // It should not be called in timer's callback + QueueRef(); #if DBG if (!Debug.IsTagPresent("Timer") || Debug.IsTagEnabled("Timer")) #endif @@ -1030,6 +1038,53 @@ void PollLockedSession() { } } + private void EnsureRequestTimeout() { + // Request may be blocked in acquiring state longer than execution timeout. + // In that case, it will be timeout anyway after it gets the session item. + // So it makes sense to timeout it when waiting longer than executionTimeout. + if (_rqContext.HasTimeoutExpired) { + throw new HttpException(SR.GetString(SR.Request_timed_out)); + } + } + + private static bool IsRequestQueueEnabled { + get { + return (AppSettings.RequestQueueLimitPerSession != AppSettings.UnlimitedRequestsPerSession); + } + } + + private void QueueRef() { + if (!IsRequestQueueEnabled || _rqId == null) { + return; + } + + // + // Check the limit + int count = 0; + s_queuedRequestsNumPerSession.TryGetValue(_rqId, out count); + + if (count >= AppSettings.RequestQueueLimitPerSession) { + throw new HttpException(SR.GetString(SR.Request_Queue_Limit_Per_Session_Exceeded)); + } + + // + // Add ref + s_queuedRequestsNumPerSession.AddOrUpdate(_rqId, 1, (key, value) => value + 1); + } + + private void DequeRef() { + if (!IsRequestQueueEnabled || _rqId == null) { + return; + } + + // Decrement the counter + if (s_queuedRequestsNumPerSession.AddOrUpdate(_rqId, 0, (key, value) => value - 1) == 0) { + // + // Remove the element when no more references + ((ICollection<KeyValuePair<string, int>>)s_queuedRequestsNumPerSession).Remove(new KeyValuePair<string,int>(_rqId, 0)); + } + } + [RegistryPermission(SecurityAction.Assert, Unrestricted = true)] private static void LookUpRegForPollInterval() { lock (s_PollIntervalRegLock) { @@ -1167,6 +1222,8 @@ void PollLockedSessionCallback(object state) { } if (isCompleted || error != null) { + DequeRef(); + _rqAr.Complete(false, null, error); } } diff --git a/System.Web/State/StateRuntime.cs b/System.Web/State/StateRuntime.cs index de279f206..47d08fbea 100644 --- a/System.Web/State/StateRuntime.cs +++ b/System.Web/State/StateRuntime.cs @@ -217,6 +217,7 @@ internal sealed class CachedContent { internal IntPtr _stateItem; // The pointer to the native memory that points to the psi internal bool _locked; internal DateTime _utcLockDate; + internal TimeSpan _slidingExpiration; internal int _lockCookie; internal int _extraFlags; #pragma warning disable 0649 @@ -228,6 +229,7 @@ internal CachedContent( IntPtr stateItem, bool locked, DateTime utcLockDate, + TimeSpan slidingExpiration, int lockCookie, int extraFlags) { @@ -235,6 +237,7 @@ internal CachedContent( _stateItem = stateItem; _locked = locked; _utcLockDate = utcLockDate; + _slidingExpiration = slidingExpiration; _lockCookie = lockCookie; _extraFlags = extraFlags; } @@ -413,19 +416,17 @@ bool GetOptionalInt32HeaderValue(HttpContext context, string header, out int val string exclusiveAccess; string key; CachedContent content; - CacheEntry entry; int lockCookie; int timeout; key = CreateKey(request); - entry = (CacheEntry) HttpRuntime.CacheInternal.Get(key, CacheGetOptions.ReturnCacheEntry); - if (entry == null) { + content = (CachedContent) HttpRuntime.Cache.InternalCache.Get(key); + if (content == null) { ReportNotFound(context); return; } exclusiveAccess = request.Headers[StateHeaders.EXCLUSIVE_NAME]; - content = (CachedContent) entry.Value; content._spinLock.AcquireWriterLock(); try { if (content._content == null) { @@ -483,7 +484,7 @@ bool GetOptionalInt32HeaderValue(HttpContext context, string header, out int val response.AppendHeader(StateHeaders.LOCKCOOKIE_NAME_RAW, (content._lockCookie).ToString(CultureInfo.InvariantCulture)); } - timeout = (int) (entry.SlidingExpiration.Ticks / TimeSpan.TicksPerMinute); + timeout = (int)(content._slidingExpiration.Ticks / TimeSpan.TicksPerMinute); response.AppendHeader(StateHeaders.TIMEOUT_NAME_RAW, (timeout).ToString(CultureInfo.InvariantCulture)); responseStream = response.OutputStream; buf = content._content; @@ -520,7 +521,7 @@ unsafe IntPtr FinishPut(HttpContext context) { int lockCookie; int lockCookieNew = 1; IntPtr stateItem; - CacheInternal cacheInternal = HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; /* create the content */ requestStream = request.InputStream; @@ -561,8 +562,8 @@ unsafe IntPtr FinishPut(HttpContext context) { /* lookup current value */ key = CreateKey(request); - CacheEntry entry = (CacheEntry) cacheInternal.Get(key, CacheGetOptions.ReturnCacheEntry); - if (entry != null) { + contentCurrent = (CachedContent) cacheInternal.Get(key); + if (contentCurrent != null) { // DevDivBugs 146875: Expired Session State race condition // We make sure we do not overwrite an already existing item with an uninitialized item. if (((int)SessionStateItemFlags.Uninitialized & extraFlags) == 1) { @@ -573,7 +574,6 @@ unsafe IntPtr FinishPut(HttpContext context) { return stateItem; } - contentCurrent = (CachedContent) entry.Value; contentCurrent._spinLock.AcquireWriterLock(); try { if (contentCurrent._content == null) { @@ -587,7 +587,7 @@ unsafe IntPtr FinishPut(HttpContext context) { return stateItem; } - if (entry.SlidingExpiration == timeout && contentCurrent._content != null) { + if (contentCurrent._slidingExpiration == timeout && contentCurrent._content != null) { /* delete the old state item */ IntPtr stateItemOld = contentCurrent._stateItem; @@ -619,12 +619,14 @@ Update _extraFlags to ignore the cache item removed callback (this way, } } - content = new CachedContent(buf, stateItem, false, DateTime.MinValue, lockCookieNew, extraFlags); - cacheInternal.UtcInsert( - key, content, null, Cache.NoAbsoluteExpiration, timeout, - CacheItemPriority.NotRemovable, _removedHandler); + content = new CachedContent(buf, stateItem, false, DateTime.MinValue, timeout, lockCookieNew, extraFlags); + cacheInternal.Insert(key, content, new CacheInsertOptions() { + SlidingExpiration = timeout, + Priority = CacheItemPriority.NotRemovable, + OnRemovedCallback = _removedHandler + }); - if (entry == null) { + if (contentCurrent == null) { IncrementStateServiceCounter(StateServicePerfCounter.STATE_SERVICE_SESSIONS_TOTAL); IncrementStateServiceCounter(StateServicePerfCounter.STATE_SERVICE_SESSIONS_ACTIVE); } @@ -634,7 +636,7 @@ Update _extraFlags to ignore the cache item removed callback (this way, internal /*public*/ void DoDelete(HttpContext context) { string key = CreateKey(context.Request); - CacheInternal cacheInternal = HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; CachedContent content = (CachedContent) cacheInternal.Get(key); /* If the item isn't there, we probably took too long to run. */ @@ -680,7 +682,7 @@ Update _extraFlags to ignore the cache item removed callback (this way, Object item; key = CreateKey(context.Request); - item = HttpRuntime.CacheInternal.Get(key); + item = HttpRuntime.Cache.InternalCache.Get(key); if (item == null) { ReportNotFound(context); } diff --git a/System.Web/State/StateWorkerRequest.cs b/System.Web/State/StateWorkerRequest.cs index 385d054eb..8450d6d37 100644 --- a/System.Web/State/StateWorkerRequest.cs +++ b/System.Web/State/StateWorkerRequest.cs @@ -23,7 +23,7 @@ namespace System.Web.SessionState { class StateHttpWorkerRequest : HttpWorkerRequest { - /* long enough to hold the string representation of an IPv4 or IPv6 address; keep in [....] with tracker.cxx */ + /* long enough to hold the string representation of an IPv4 or IPv6 address; keep in sync with tracker.cxx */ private const int ADDRESS_LENGTH_MAX = 64; IntPtr _tracker; diff --git a/System.Web/System.Web.txt b/System.Web/System.Web.txt index 81be1e2a6..30478ffa1 100644 --- a/System.Web/System.Web.txt +++ b/System.Web/System.Web.txt @@ -1,4 +1,4 @@ -; + ; ; ASP.NET managed resource file ; ; Copyright (c) 2000 Microsoft Corporation @@ -324,6 +324,7 @@ Invalid_value_for_CacheControl=Property value for CacheControl is not valid. Val OutputStream_NotAvail=OutputStream is not available when a custom TextWriter is used. Information_Disclosure_Warning=This error page might contain sensitive information because ASP.NET is configured to show verbose error messages using <customErrors mode="Off"/>. Consider using <customErrors mode="On"/> or <customErrors mode="RemoteOnly"/> in production environments. InvalidOffsetOrCount=The sum of {0} and {1} is greater than the length of the buffer. +Invalid_path_for_push_promise=Invalid path '{0}' for push promise. A virtual path is expected. ; Runtime @@ -392,7 +393,7 @@ Hosting_Env_IdleTimeout=Idle timeout Unhandled_Exception=An unhandled exception occurred and the process was terminated. Provider_must_implement_the_interface=The provider class '{0}' must implement the class '{1}'. Permission_set_not_found=Could not find permission set named '{0}'. -Require_stable_string_hash_codes=ASP.NET cannot operate when String hash code randomization is enabled for the current machine. Please verify that the registry key HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\UseRandomizedStringHashAlgorithm does not exist or is set to [DWORD] 0. +Require_stable_string_hash_codes=ASP.NET can operate with String hash code randomization only when enabled per application via AppSettings configuration. Registry key HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\UseRandomizedStringHashAlgorithm and <runtime/UseRandomizedStringHashAlgorithm> configuration are not supported. ; Server vars collection Server_variable_cannot_be_modified=This server variable cannot be modified during request execution. @@ -1304,7 +1305,11 @@ ModelDataSourceView_CannotCallMethodsWithOutOrRefParameters=Cannot call the meth ModelDataSourceView_DataMethodNotFound=A public method with the name '{0}' was either not found or there were multiple methods with the same name on the type '{1}'. ModelDataSourceView_DeleteNotSupported=Deleting is not supported unless the DeleteMethod is specified. ModelDataSourceView_InvalidSelectReturnType=The Select Method must return one of "IQueryable<{0}>" or "IEnumerable<{0}>" or "{0}" when ItemType is set to "{0}". +ModelDataSourceView_InvalidAsyncSelectReturnType=The Task-based Select Method must return one of "Task<IEnumerable<{0}>>" or "Task<System.Web.UI.WebControls.SelectResult>" or "Task<{0}>" when ItemType is set to "{0}". +ModelDataSourceView_UseAsyncMethodMustBeUsingAsyncPage=When using a Task-based async method, the page must be marked as asynchronous using the <%@ Page Async="true" %> directive, and the web application must be targeting .NET 4.5 or higher via <httpRuntime targetFramework="4.5" />. ModelDataSourceView_InvalidPagingParameters=When the DataBoundControl has paging enabled, either the SelectMethod should return an IQueryable<ItemType> or should have all these mandatory parameters : int startRowIndex, int maximumRows, out int totalRowCount +ModelDataSourceView_InvalidAsyncPagingParameters=When the DataBoundControl has paging enabled, the SelectMethod should return "Task<System.Web.UI.WebControls.SelectResult>" and have all these mandatory parameters : int startRowIndex, int maximumRows +ModelDataSourceView_MustUseSelectResultAsReturnType=When using custom paging with an async Select method, the Select method return type must be "Task<System.Web.UI.WebControls.SelectResult>". ModelDataSourceView_InvalidSortingParameters=When the DataBoundControl has sorting enabled, either the SelectMethod should return an IQueryable<ItemType> or should have all these mandatory parameters : string sortByExpression ModelDataSourceView_InsertNotSupported=Inserting is not supported unless the InsertMethod is specified. ModelDataSourceView_MultipleModelMethodSources=The DataMethodsType and DataMethodsObject properties cannot both be specified at the same time. @@ -1314,6 +1319,7 @@ ModelDataSourceView_SelectNotSupported=The Select operation is not supported unl ModelDataSourceView_SortNotSupportedOnIEnumerable=The SelectMethod does not support sorting with IEnumerable data. Automatic sorting is only supported when the SelectMethod returns an IQueryable type. ModelDataSourceView_ParameterCannotBeNull=A null value for parameter '{0}' of non-nullable type '{1}' for method '{2}' in '{3}'. An optional parameter must be a reference type or a nullable type. ModelDataSourceView_ParameterValueHasWrongType=An invalid value for parameter '{0}' for method '{1}' in '{2}'. The value from model binding is of type '{3}', but the parameter requires a value of type '{4}'. +ModelDataSourceView_CancellationTokenIsNotSupported=Parameters typed as CancellationToken are supported only in Task-returning methods. ObjectDataSource_Description=Connect to a middle-tier business object or DataSet in the Bin or App_Code directory for the application. ObjectDataSource_DisplayName=Object ObjectDataSourceView_DeleteNotSupported=Deleting is not supported by ObjectDataSource '{0}' unless the DeleteMethod is specified. @@ -3758,6 +3764,7 @@ AppVerifier_Subtitle=ASP.NET detected an error while invoking an asynchronous me AppVerifier_BasicInfo_URL=Current URL: {0} AppVerifier_BasicInfo_ErrorCode=Error code: {0} AppVerifier_BasicInfo_Description=Description: {0} +AppVerifier_BasicInfo_NotificationInfo=The assertion was triggered after processing notification {0}, isPostNotification = {1}, isReentry = {2} AppVerifier_BasicInfo_ThreadInfo=The assertion was triggered on thread {0} at {1} with the following stack trace: AppVerifier_BeginMethodInfo_EntryMethod=Entry point which triggered failure: {0} AppVerifier_BeginMethodInfo_RequestNotification_Integrated=Request notification at time of entry: {0} [IsPostNotification = {1}] @@ -3781,4 +3788,15 @@ AppVerifier_Errors_BeginHandlerReturnedNull=The entry point returned a null valu AppVerifier_Errors_BeginHandlerReturnedAsyncResultMarkedCompletedSynchronouslyButWhichWasNotCompleted=The entry point returned an IAsyncResult instance that was marked 'CompletedSynchronously = true' and 'IsCompleted = false'. If the operation is completed, it must be marked 'IsCompleted = true'. AppVerifier_Errors_BeginHandlerReturnedAsyncResultMarkedCompletedSynchronouslyButAsyncCallbackNeverCalled=The entry point returned an IAsyncResult instance that was marked 'CompletedSynchronously = true', but AsyncCallback was never invoked synchronously. If an operation completes synchronously and AsyncCallback is non-null, the callback must be invoked synchronously before the entry point returns to its caller. AppVerifier_Errors_BeginHandlerReturnedUnexpectedAsyncResultAsyncState=The entry point returned an IAsyncResult instance with an invalid AsyncState property. The IAsyncResult's AsyncState property must match the state object parameter provided to the entry point. -AppVerifier_Errors_SyncContextSendOrPostCalledAfterRequestCompleted=A thread attempted to call SynchronizationContext.Send or SynchronizationContext.Post after the request associated with the SynchronizationContext had already completed. \ No newline at end of file +AppVerifier_Errors_SyncContextSendOrPostCalledAfterRequestCompleted=A thread attempted to call SynchronizationContext.Send or SynchronizationContext.Post after the request associated with the SynchronizationContext had already completed. +AppVerifier_Errors_SyncContextSendOrPostCalledBetweenNotifications=A thread attempted to call SynchronizationContext.Send or SynchronizationContext.Post while ASP.NET is not processing any request pipeline notification. +AppVerifier_Errors_SyncContextPostCalledInNestedNotification=A thread attempted to call SynchronizationContext.Post while processing a nested request notification. This may result in undefined behavior. +AppVerifier_Errors_RequestNotificationCompletedSynchronouslyWithNotificationContextPending=An inconsistency was found after processing an integrated IIS request pipeline notification. Even though the notification completed synchronously it had left pending async completions. +AppVerifier_Errors_NotificationContextHasChangedAfterSynchronouslyProcessingNotification=An inconsistency was found after processing an integrated IIS request pipeline notification. The NotificationContext has unexpectedly changed while synchronously processing a notification. +AppVerifier_Errors_PendingProcessRequestNotificationStatusAfterCompletingNestedNotification=An inconsistency was found after processing an integrated IIS request pipeline notification. Nested notifications such as RQ_SEND_RESPONSE have to be processed synchronously and can not leave pending async work. + +Request_Queue_Limit_Per_Session_Exceeded=The request queue limit of the session is exceeded. + +MembershipPasswordFormat_Obsoleted=Unsecured Passwords Format Detected. The Membership Provider that contains the unsecure passwords format is: {0}. The obsoleted password format is: {1}. For more information, see https://go.microsoft.com/fwlink/?linkid=834784. + +Unhandled_Monitor_Exception=An unhandled exception occurred while executing '{0}' in '{1}'. diff --git a/System.Web/ThreadContext.cs b/System.Web/ThreadContext.cs index 297504069..bfd7b04d5 100644 --- a/System.Web/ThreadContext.cs +++ b/System.Web/ThreadContext.cs @@ -61,7 +61,7 @@ internal void AssociateWithCurrentThread(bool setImpersonationContext) { /* * !! IMPORTANT !! - * Keep this logic in [....] with DisassociateFromCurrentThread and EnterExecutionContext. + * Keep this logic in sync with DisassociateFromCurrentThread and EnterExecutionContext. */ // attach http context to the call context @@ -128,7 +128,7 @@ internal void DisassociateFromCurrentThread() { /* * !! IMPORTANT !! - * Keep this logic in [....] with AssociateWithCurrentThread and EnterExecutionContext. + * Keep this logic in sync with AssociateWithCurrentThread and EnterExecutionContext. */ Current = _originalThreadContextCurrent; @@ -176,7 +176,7 @@ internal Action EnterExecutionContext() { /* * !! IMPORTANT !! - * Keep this logic in [....] with AssociateWithCurrentThread and DisassociateFromCurrentThread. + * Keep this logic in sync with AssociateWithCurrentThread and DisassociateFromCurrentThread. */ // ExecutionContext.Run replaces the current impersonation token, so we need to impersonate diff --git a/System.Web/UI/DataSourceCache.cs b/System.Web/UI/DataSourceCache.cs index 6eae42a49..d88029dd9 100644 --- a/System.Web/UI/DataSourceCache.cs +++ b/System.Web/UI/DataSourceCache.cs @@ -133,7 +133,7 @@ public void Invalidate(string key) { throw new InvalidOperationException(SR.GetString(SR.DataSourceCache_CacheMustBeEnabled)); } - HttpRuntime.CacheInternal.Remove(key); + HttpRuntime.Cache.InternalCache.Remove(key); } @@ -151,7 +151,7 @@ public object LoadDataFromCache(string key) { throw new InvalidOperationException(SR.GetString(SR.DataSourceCache_CacheMustBeEnabled)); } - return HttpRuntime.CacheInternal.Get(key); + return HttpRuntime.Cache.InternalCache.Get(key); } @@ -227,7 +227,11 @@ protected virtual void SaveDataToCacheInternal(string key, object data, CacheDep aggregateCacheDependency.Add(new CacheDependency[] { dependency }); } - HttpRuntime.CacheInternal.UtcInsert(key, data, aggregateCacheDependency, utcAbsoluteExpiryTime, slidingExpiryTimeSpan); + HttpRuntime.Cache.InternalCache.Insert(key, data, new CacheInsertOptions() { + Dependencies = aggregateCacheDependency, + AbsoluteExpiration = utcAbsoluteExpiryTime, + SlidingExpiration = slidingExpiryTimeSpan + }); } diff --git a/System.Web/UI/HTMLTextWriter.cs b/System.Web/UI/HTMLTextWriter.cs index af76ac63b..b5c395a74 100644 --- a/System.Web/UI/HTMLTextWriter.cs +++ b/System.Web/UI/HTMLTextWriter.cs @@ -98,7 +98,7 @@ public virtual bool IsValidFormAttribute(String attribute) { public const char StyleEqualsChar = ':'; public const string DefaultTabString = "\t"; - // The DesignerRegion attribute name must be kept in [....] with + // The DesignerRegion attribute name must be kept in sync with // System.Web.UI.Design.DesignerRegion.DesignerRegionNameAttribute internal const string DesignerRegionAttributeName = "_designerRegion"; diff --git a/System.Web/UI/ObjectStateFormatter.cs b/System.Web/UI/ObjectStateFormatter.cs index 5eb66eae4..7e60b164e 100644 --- a/System.Web/UI/ObjectStateFormatter.cs +++ b/System.Web/UI/ObjectStateFormatter.cs @@ -189,7 +189,7 @@ internal List<string> GetSpecificPurposes() { return null; } - // Note: duplicated (somewhat) in GetMacKeyModifier, keep in [....] + // Note: duplicated (somewhat) in GetMacKeyModifier, keep in sync // See that method for comments on why these modifiers are in place List<string> specificPurposes = new List<string>() { @@ -216,7 +216,7 @@ private byte[] GetMacKeyModifier() { return null; } - // Note: duplicated (somewhat) in GetSpecificPurposes, keep in [....] + // Note: duplicated (somewhat) in GetSpecificPurposes, keep in sync // Use the page's directory and class name as part of the key (ASURT 64044) uint pageHashCode = _page.GetClientStateIdentifier(); diff --git a/System.Web/UI/Page.cs b/System.Web/UI/Page.cs index 974680fd7..3fb982447 100644 --- a/System.Web/UI/Page.cs +++ b/System.Web/UI/Page.cs @@ -195,7 +195,7 @@ public class Page: TemplateControl, IHttpHandler { private const string PageSubmitScriptKey = "PageSubmitScript"; private const string PageReEnableControlsScriptKey = "PageReEnableControlsScript"; - // NOTE: Make sure this stays in [....] with MobilePage.PageRegisteredControlsThatRequirePostBackKey + // NOTE: Make sure this stays in sync with MobilePage.PageRegisteredControlsThatRequirePostBackKey // private const string PageRegisteredControlsThatRequirePostBackKey = "__ControlsRequirePostBackKey__"; @@ -3234,7 +3234,7 @@ private async Task<bool> LoadPostDataAsync(IPostBackDataHandler consumer, string bool changed; // ListControl family controls call EnsureDataBound in consumer.LoadPostData, which could be an async call in 4.6. - // LoadPostData, however, is a [....] method, which means we cannot await EnsureDataBound in the method. + // LoadPostData, however, is a sync method, which means we cannot await EnsureDataBound in the method. // To workaround this, for ListControl family controls, we call EnsureDataBound before we call into LoadPostData. if (AppSettings.EnableAsyncModelBinding && consumer is ListControl) { var listControl = consumer as ListControl; diff --git a/System.Web/UI/WebControls/AdRotator.cs b/System.Web/UI/WebControls/AdRotator.cs index a5bd1f389..e69f94a31 100644 --- a/System.Web/UI/WebControls/AdRotator.cs +++ b/System.Web/UI/WebControls/AdRotator.cs @@ -454,8 +454,8 @@ private AdRec [] GetFileData(string fileName) { // try to get it from the ASP.NET cache string fileKey = CacheInternal.PrefixAdRotator + ((!String.IsNullOrEmpty(physicalPath)) ? physicalPath : virtualPath.VirtualPathString); - CacheInternal cacheInternal = System.Web.HttpRuntime.CacheInternal; - AdRec [] adRecs = cacheInternal[fileKey] as AdRec[]; + CacheStoreProvider cacheInternal = System.Web.HttpRuntime.Cache.InternalCache; + AdRec[] adRecs = cacheInternal.Get(fileKey) as AdRec[]; if (adRecs == null) { // Otherwise load it @@ -481,7 +481,7 @@ private AdRec [] GetFileData(string fileName) { if (dependency != null) { using (dependency) { // and store it in the cache, dependent on the file name - cacheInternal.UtcInsert(fileKey, adRecs, dependency); + cacheInternal.Insert(fileKey, adRecs, new CacheInsertOptions() { Dependencies = dependency }); } } } diff --git a/System.Web/UI/WebControls/ChangePassword.cs b/System.Web/UI/WebControls/ChangePassword.cs index 458844466..cd906e11d 100644 --- a/System.Web/UI/WebControls/ChangePassword.cs +++ b/System.Web/UI/WebControls/ChangePassword.cs @@ -1939,9 +1939,9 @@ protected virtual void OnCancelButtonClick(EventArgs e) { string cancelPageUrl = CancelDestinationPageUrl; if (!String.IsNullOrEmpty(cancelPageUrl)) { - // [....] suggested that we should not terminate execution of current page, to give + // Microsoft suggested that we should not terminate execution of current page, to give // page a chance to cleanup its resources. This may be less performant though. - // [....] suggested that we need to call ResolveClientUrl before redirecting. + // Microsoft suggested that we need to call ResolveClientUrl before redirecting. // Example is this control inside user control, want redirect relative to user control dir. Page.Response.Redirect(ResolveClientUrl(cancelPageUrl), false); } @@ -1993,9 +1993,9 @@ protected virtual void OnContinueButtonClick(EventArgs e) { string continuePageUrl = ContinueDestinationPageUrl; if (!String.IsNullOrEmpty(continuePageUrl)) { - // [....] suggested that we should not terminate execution of current page, to give + // Microsoft suggested that we should not terminate execution of current page, to give // page a chance to cleanup its resources. This may be less performant though. - // [....] suggested that we need to call ResolveClientUrl before redirecting. + // Microsoft suggested that we need to call ResolveClientUrl before redirecting. // Example is this control inside user control, want redirect relative to user control dir. Page.Response.Redirect(ResolveClientUrl(continuePageUrl), false); } @@ -2066,9 +2066,9 @@ private void PerformSuccessAction(string email, string userName, string newPassw string successPageUrl = SuccessPageUrl; if (!String.IsNullOrEmpty(successPageUrl)) { - // [....] suggested that we should not terminate execution of current page, to give + // Microsoft suggested that we should not terminate execution of current page, to give // page a chance to cleanup its resources. This may be less performant though. - // [....] suggested that we need to call ResolveClientUrl before redirecting. + // Microsoft suggested that we need to call ResolveClientUrl before redirecting. // Example is this control inside user control, want redirect relative to user control dir. Page.Response.Redirect(ResolveClientUrl(successPageUrl), false); } diff --git a/System.Web/UI/WebControls/DetailsView.cs b/System.Web/UI/WebControls/DetailsView.cs index c51c96272..268143d08 100644 --- a/System.Web/UI/WebControls/DetailsView.cs +++ b/System.Web/UI/WebControls/DetailsView.cs @@ -2867,7 +2867,7 @@ private bool LoadHiddenFieldState(string pageIndex, string dataKey) { propertyChanged = true; // since we can't go into insert mode in a callback, oldPageIndex should never be -1 and different from PageIndex - Debug.Assert(oldPageIndex >= 0, "Page indeces are out of [....] from callback hidden field state"); + Debug.Assert(oldPageIndex >= 0, "Page indeces are out of sync from callback hidden field state"); _pageIndex = oldPageIndex; string oldDataKeyString = dataKey; diff --git a/System.Web/UI/WebControls/PasswordRecovery.cs b/System.Web/UI/WebControls/PasswordRecovery.cs index f75ce6aa4..a236ddde5 100644 --- a/System.Web/UI/WebControls/PasswordRecovery.cs +++ b/System.Web/UI/WebControls/PasswordRecovery.cs @@ -1569,9 +1569,9 @@ protected virtual void OnUserLookupError(EventArgs e) { private void PerformSuccessAction() { string successPageUrl = SuccessPageUrl; if (!String.IsNullOrEmpty(successPageUrl)) { - // [....] suggested that we should not terminate execution of current page, to give + // Microsoft suggested that we should not terminate execution of current page, to give // page a chance to cleanup its resources. This may be less performant though. - // [....] suggested that we need to call ResolveClientUrl before redirecting. + // Microsoft suggested that we need to call ResolveClientUrl before redirecting. // Example is this control inside user control, want redirect relative to user control dir. Page.Response.Redirect(ResolveClientUrl(successPageUrl), false); } diff --git a/System.Web/UI/WebControls/Wizard.cs b/System.Web/UI/WebControls/Wizard.cs index 4aa0a6f25..882c5adce 100644 --- a/System.Web/UI/WebControls/Wizard.cs +++ b/System.Web/UI/WebControls/Wizard.cs @@ -1876,9 +1876,9 @@ protected virtual void OnFinishButtonClick(WizardNavigationEventArgs e) { string finishPageUrl = FinishDestinationPageUrl; if (!String.IsNullOrEmpty(finishPageUrl)) { - // [....] suggested that we should not terminate execution of current page, to give + // Microsoft suggested that we should not terminate execution of current page, to give // page a chance to cleanup its resources. This may be less performant though. - // [....] suggested that we need to call ResolveClientUrl before redirecting. + // Microsoft suggested that we need to call ResolveClientUrl before redirecting. // Example is this control inside user control, want redirect relative to user control dir. Page.Response.Redirect(ResolveClientUrl(finishPageUrl), false); } diff --git a/System.Web/UI/WebControls/xml.cs b/System.Web/UI/WebControls/xml.cs index 93ec3e60d..fd57f86d6 100644 --- a/System.Web/UI/WebControls/xml.cs +++ b/System.Web/UI/WebControls/xml.cs @@ -403,7 +403,7 @@ private void LoadTransformFromSource() { string physicalPath; ResolvePhysicalOrVirtualPath(_transformSource, out virtualPath, out physicalPath); - CacheInternal cacheInternal = HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; string key = CacheInternal.PrefixLoadXPath + ((physicalPath != null) ? physicalPath : virtualPath.VirtualPathString); @@ -436,7 +436,8 @@ private void LoadTransformFromSource() { // Cache it, but only if we got a dependency if (dependency != null) { using (dependency) { - cacheInternal.UtcInsert(key, ((_compiledTransform == null) ? (object)_transform : (object)_compiledTransform), dependency); + cacheInternal.Insert(key, ((_compiledTransform == null) ? (object)_transform : (object)_compiledTransform), + new CacheInsertOptions() { Dependencies = dependency }); } } } @@ -467,7 +468,7 @@ private void LoadXmlDocument() { // Make it absolute and check security string physicalPath = MapPathSecure(_documentSource); - CacheInternal cacheInternal = System.Web.HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = System.Web.HttpRuntime.Cache.InternalCache; string key = CacheInternal.PrefixLoadXml + physicalPath; _document = (XmlDocument) cacheInternal.Get(key); @@ -480,7 +481,7 @@ private void LoadXmlDocument() { _document = new XmlDocument(); _document.Load(XmlUtils.CreateXmlReader(stream, physicalPath)); - cacheInternal.UtcInsert(key, _document, dependency); + cacheInternal.Insert(key, _document, new CacheInsertOptions() { Dependencies = dependency }); } } else { @@ -511,7 +512,7 @@ private void LoadXPathDocument() { string physicalPath; ResolvePhysicalOrVirtualPath(_documentSource, out virtualPath, out physicalPath); - CacheInternal cacheInternal = HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; string key = CacheInternal.PrefixLoadXPath + ((physicalPath != null) ? physicalPath : virtualPath.VirtualPathString); @@ -533,7 +534,7 @@ private void LoadXPathDocument() { // Cache it, but only if we got a dependency if (dependency != null) { using (dependency) { - cacheInternal.UtcInsert(key, _xpathDocument, dependency); + cacheInternal.Insert(key, _xpathDocument, new CacheInsertOptions() { Dependencies = dependency }); } } } diff --git a/System.Web/UI/WebParts/CatalogZoneBase.cs b/System.Web/UI/WebParts/CatalogZoneBase.cs index 597b93fd5..46968b54d 100644 --- a/System.Web/UI/WebParts/CatalogZoneBase.cs +++ b/System.Web/UI/WebParts/CatalogZoneBase.cs @@ -549,7 +549,7 @@ protected override void RenderBody(HtmlTextWriter writer) { // Mozilla renders padding on an empty TD without this attribute writer.AddStyleAttribute(HtmlTextWriterStyle.Padding, "0"); - // Add an extra row with height of 100%, to [....] up any extra space + // Add an extra row with height of 100%, to Microsoft up any extra space // if the height of the zone is larger than its contents // Mac IE needs height=100% set on <td> instead of <tr> writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "100%"); diff --git a/System.Web/UI/WebParts/EditorPart.cs b/System.Web/UI/WebParts/EditorPart.cs index 66e496112..051143d56 100644 --- a/System.Web/UI/WebParts/EditorPart.cs +++ b/System.Web/UI/WebParts/EditorPart.cs @@ -246,7 +246,7 @@ internal void SetZone(EditorZoneBase zone) { } /// <devdoc> - /// Called by the Zone when the EditorPart should [....] its values because other EditorParts + /// Called by the Zone when the EditorPart should sync its values because other EditorParts /// may have changed control properties. This is only called after all the ApplyChanges have returned. /// </devdoc> public abstract void SyncChanges(); diff --git a/System.Web/UI/WebParts/EditorZoneBase.cs b/System.Web/UI/WebParts/EditorZoneBase.cs index de13bd300..ab7ee071b 100644 --- a/System.Web/UI/WebParts/EditorZoneBase.cs +++ b/System.Web/UI/WebParts/EditorZoneBase.cs @@ -412,7 +412,7 @@ protected override void RenderBody(HtmlTextWriter writer) { // Mozilla renders padding on an empty TD without this attribute writer.AddStyleAttribute(HtmlTextWriterStyle.Padding, "0"); - // Add an extra row with height of 100%, to [....] up any extra space + // Add an extra row with height of 100%, to Microsoft up any extra space // if the height of the zone is larger than its contents // Mac IE needs height=100% set on <td> instead of <tr> writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "100%"); diff --git a/System.Web/UI/WebParts/WebPartManager.cs b/System.Web/UI/WebParts/WebPartManager.cs index c5b349523..136ff0bf1 100644 --- a/System.Web/UI/WebParts/WebPartManager.cs +++ b/System.Web/UI/WebParts/WebPartManager.cs @@ -2691,7 +2691,7 @@ private static void ImportSkipTo(XmlReader reader, string elementToFind) { /// <devdoc> /// Never throws except for null arguments. Returns an error message in the out parameter instead. - /// [[....]] I investigated whether this could be refactored to share common code with + /// [Microsoft] I investigated whether this could be refactored to share common code with /// LoadDynamicWebPart(), but it seems the methods are too different. /// </devdoc> public virtual WebPart ImportWebPart(XmlReader reader, out string errorMessage) { diff --git a/System.Web/UI/WebParts/WebPartZoneBase.cs b/System.Web/UI/WebParts/WebPartZoneBase.cs index 4fd1f72fd..7dc790dc4 100644 --- a/System.Web/UI/WebParts/WebPartZoneBase.cs +++ b/System.Web/UI/WebParts/WebPartZoneBase.cs @@ -1261,7 +1261,7 @@ protected override void RenderBody(HtmlTextWriter writer) { } if (orientation == Orientation.Vertical) { - // Add an extra row with height of 100%, to [....] up any extra space + // Add an extra row with height of 100%, to Microsoft up any extra space // if the height of the zone is larger than its contents writer.RenderBeginTag(HtmlTextWriterTag.Tr); @@ -1276,7 +1276,7 @@ protected override void RenderBody(HtmlTextWriter writer) { writer.RenderEndTag(); // Tr } else { - // Add an extra cell with width of 100%, to [....] up any extra space + // Add an extra cell with width of 100%, to Microsoft up any extra space // if the width of the zone is larger than its contents. writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%"); diff --git a/System.Web/UnsafeNativeMethods.cs b/System.Web/UnsafeNativeMethods.cs index e6f404375..f31af9df3 100644 --- a/System.Web/UnsafeNativeMethods.cs +++ b/System.Web/UnsafeNativeMethods.cs @@ -663,7 +663,7 @@ internal static extern int GetSHA1Hash(byte[] data, int dataSize, // List of functions supported by PMCallISAPI // // ATTENTION!! - // If you change this list, make sure it is in [....] with the + // If you change this list, make sure it is in sync with the // CallISAPIFunc enum in ecbdirect.h // internal enum CallISAPIFunc : int { diff --git a/System.Web/Util/AppSettings.cs b/System.Web/Util/AppSettings.cs index c0d444110..d9a78e5da 100644 --- a/System.Web/Util/AppSettings.cs +++ b/System.Web/Util/AppSettings.cs @@ -130,6 +130,9 @@ private static void EnsureSettingsLoaded() { if (settings == null || !Boolean.TryParse(settings["aspnet:EnableAsyncModelBinding"], out _enableAsyncModelBinding)) _enableAsyncModelBinding = BinaryCompatibility.Current.TargetsAtLeastFramework46; + if (settings == null || !int.TryParse(settings["aspnet:RequestQueueLimitPerSession"], out _requestQueueLimitPerSession) || _requestQueueLimitPerSession < 0) + _requestQueueLimitPerSession = BinaryCompatibility.Current.TargetsAtLeastFramework463 ? DefaultRequestQueueLimitPerSession : UnlimitedRequestsPerSession; + _settingsInitialized = true; } } @@ -492,5 +495,16 @@ internal static bool EnableAsyncModelBinding { return _enableAsyncModelBinding; } } + + internal const int UnlimitedRequestsPerSession = Int32.MaxValue; + internal const int DefaultRequestQueueLimitPerSession = 50; + // Limit of queued requests per session + private static int _requestQueueLimitPerSession; + internal static int RequestQueueLimitPerSession { + get { + EnsureSettingsLoaded(); + return _requestQueueLimitPerSession; + } + } } } diff --git a/System.Web/Util/AppVerifier.cs b/System.Web/Util/AppVerifier.cs index f45390c0d..272ed3ee4 100644 --- a/System.Web/Util/AppVerifier.cs +++ b/System.Web/Util/AppVerifier.cs @@ -305,7 +305,7 @@ internal static Func<AsyncCallback, object, IAsyncResult> WrapBeginMethodImpl(Ht // BeginHandler hasn't yet returned, so this call may be synchronous or asynchronous. // We can tell by comparing the current thread with the thread which called BeginHandler. // From a correctness perspective, it is valid to invoke the AsyncCallback delegate either - // synchronously or asynchronously. From [....]: if 'CompletedSynchronously = true', then + // synchronously or asynchronously. From Microsoft: if 'CompletedSynchronously = true', then // AsyncCallback invocation can happen either on the same thread or on a different thread, // just as long as BeginHandler hasn't yet returned (which in true in this case). if (!asyncResult.CompletedSynchronously) { diff --git a/System.Web/Util/AspCompat.cs b/System.Web/Util/AspCompat.cs index 6a123dfba..79343a26e 100644 --- a/System.Web/Util/AspCompat.cs +++ b/System.Web/Util/AspCompat.cs @@ -300,7 +300,7 @@ internal static void CheckThreadingModel(String progidDisplayName, Guid clsid) { return; // try cache first - CacheInternal cacheInternal = HttpRuntime.CacheInternal; + CacheStoreProvider cacheInternal = HttpRuntime.Cache.InternalCache; String key = CacheInternal.PrefixAspCompatThreading + progidDisplayName; String threadingModel = (String)cacheInternal.Get(key); RegistryKey regKey = null; @@ -321,7 +321,7 @@ internal static void CheckThreadingModel(String progidDisplayName, Guid clsid) { if (threadingModel == null) threadingModel = String.Empty; - cacheInternal.UtcInsert(key, threadingModel); + cacheInternal.Insert(key, threadingModel, null); } if (StringUtil.EqualsIgnoreCase(threadingModel, "Apartment")) { diff --git a/System.Web/Util/BinaryCompatibility.cs b/System.Web/Util/BinaryCompatibility.cs index eabc339b8..f044f5af8 100644 --- a/System.Web/Util/BinaryCompatibility.cs +++ b/System.Web/Util/BinaryCompatibility.cs @@ -17,7 +17,13 @@ internal sealed class BinaryCompatibility { internal const string TargetFrameworkKey = "ASPNET_TARGETFRAMEWORK"; // quick accessor for the current AppDomain's instance - public static readonly BinaryCompatibility Current = new BinaryCompatibility(AppDomain.CurrentDomain.GetData(TargetFrameworkKey) as FrameworkName); + public static readonly BinaryCompatibility Current; + + static BinaryCompatibility() { + Current = new BinaryCompatibility(AppDomain.CurrentDomain.GetData(TargetFrameworkKey) as FrameworkName); + + TelemetryLogger.LogTargetFramework(Current.TargetFramework); + } public BinaryCompatibility(FrameworkName frameworkName) { // parse version from FrameworkName, otherwise use a default value @@ -32,6 +38,7 @@ public BinaryCompatibility(FrameworkName frameworkName) { TargetsAtLeastFramework452 = (version >= VersionUtil.Framework452); TargetsAtLeastFramework46 = (version >= VersionUtil.Framework46); TargetsAtLeastFramework461 = (version >= VersionUtil.Framework461); + TargetsAtLeastFramework463 = (version >= VersionUtil.Framework463); } public bool TargetsAtLeastFramework45 { get; private set; } @@ -39,6 +46,7 @@ public BinaryCompatibility(FrameworkName frameworkName) { public bool TargetsAtLeastFramework452 { get; private set; } public bool TargetsAtLeastFramework46 { get; private set; } public bool TargetsAtLeastFramework461 { get; private set; } + public bool TargetsAtLeastFramework463 { get; private set; } public Version TargetFramework { get; private set; } diff --git a/System.Web/Util/DateTimeUtil.cs b/System.Web/Util/DateTimeUtil.cs index 467907f31..52335a1af 100644 --- a/System.Web/Util/DateTimeUtil.cs +++ b/System.Web/Util/DateTimeUtil.cs @@ -8,9 +8,17 @@ namespace System.Web.Util { using System; + internal enum TimeUnit { + Unknown = 0, + Days, + Hours, + Minutes, + Seconds, + Milliseconds + }; + internal sealed class DateTimeUtil { private DateTimeUtil() {} - const long FileTimeOffset = 504911232000000000; static readonly DateTime MinValuePlusOneDay = DateTime.MinValue.AddDays(1); static readonly DateTime MaxValueMinusOneDay = DateTime.MaxValue.AddDays(-1); @@ -46,6 +54,26 @@ static internal DateTime ConvertToLocalTime(DateTime utcTime) { return utcTime.ToLocalTime(); } + + static internal TimeSpan GetTimeoutFromTimeUnit(int timeoutValue, TimeUnit timeoutUnit) { + switch (timeoutUnit) { + case TimeUnit.Days: + return new TimeSpan(timeoutValue, 0, 0, 0); + case TimeUnit.Hours: + return new TimeSpan(timeoutValue, 0, 0); + case TimeUnit.Seconds: + return new TimeSpan(0, 0, timeoutValue); + case TimeUnit.Milliseconds: + return new TimeSpan(0, 0, 0, 0, timeoutValue); + case TimeUnit.Minutes: + return new TimeSpan(0, timeoutValue, 0); + case TimeUnit.Unknown: + default: + break; + } + + throw new ArgumentException(SR.GetString(SR.InvalidArgumentValue, "timeoutUnit")); + } } } diff --git a/System.Web/Util/ParseHttpDate.cs b/System.Web/Util/ParseHttpDate.cs index f34ba5fcd..0de88fe30 100644 --- a/System.Web/Util/ParseHttpDate.cs +++ b/System.Web/Util/ParseHttpDate.cs @@ -92,7 +92,7 @@ static int make_month(string s, int startIndex) } else if ( monthIndex == (sbyte) 'R' ) { // - // if s[1] is 'a' then [....], if 'p' then April + // if s[1] is 'a' then Microsoft, if 'p' then April // if ( s_monthIndexTable[(s[1 + startIndex]-0x40) & 0x3f] == (sbyte) 'A' ) { diff --git a/System.Web/Util/SecUtil.cs b/System.Web/Util/SecUtil.cs index 9a104eabb..db01aa656 100644 --- a/System.Web/Util/SecUtil.cs +++ b/System.Web/Util/SecUtil.cs @@ -158,7 +158,7 @@ internal static void CheckArrayParameter(ref string[] param, bool checkForNull, Hashtable values = new Hashtable(param.Length); for (int i = param.Length - 1; i >= 0; i--) { - SecUtility.CheckParameter(ref param[i], checkForNull, checkIfEmpty, checkForCommas, maxSize, + SecUtility.CheckParameter(ref param[i], checkForNull, checkIfEmpty, checkForCommas, maxSize, paramName + "[ " + i.ToString(CultureInfo.InvariantCulture) + " ]"); if (values.Contains(param[i])) { throw new ArgumentException(SR.GetString(SR.Parameter_duplicate_array_element, paramName), paramName); @@ -215,6 +215,17 @@ internal static int GetIntValue(NameValueCollection config, string valueName, in return iValue; } + internal static TimeUnit GetTimeoutUnit(NameValueCollection config, string valueName, TimeUnit defaultValue) { + TimeUnit unit; + string sValue = config[valueName]; + + if (sValue == null || !Enum.TryParse(sValue, out unit)) { + return defaultValue; + } + + return unit; + } + internal static int? GetNullableIntValue(NameValueCollection config, string valueName) { int iValue; string sValue = config[valueName]; diff --git a/System.Web/Util/VersionUtil.cs b/System.Web/Util/VersionUtil.cs index 5d485eabb..36985525b 100644 --- a/System.Web/Util/VersionUtil.cs +++ b/System.Web/Util/VersionUtil.cs @@ -24,6 +24,7 @@ internal static class VersionUtil { public static readonly Version Framework452 = new Version(4, 5, 2); public static readonly Version Framework46 = new Version(4, 6); public static readonly Version Framework461 = new Version(4, 6, 1); + public static readonly Version Framework463 = new Version(4, 6, 3); // Convenience accessor for the "default" framework version; various configuration // switches can use this as a default value. This value must only be bumped during diff --git a/System.Web/cacheexpires.cspp b/System.Web/cacheexpires.cspp new file mode 100644 index 000000000..fb5e31665 --- /dev/null +++ b/System.Web/cacheexpires.cspp @@ -0,0 +1,1328 @@ +//------------------------------------------------------------------------------ +// <copyright file="CacheExpires.cs" company="Microsoft"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +//------------------------------------------------------------------------------ + +namespace System.Web.Caching { + using System.Runtime.InteropServices; + using System.Text; + using System.Threading; + using System.Web; + using System.Web.Util; + using System.Collections; + + + // ExpiresEntryRef defines a reference to a ExpiresEntry in the ExpiresBucket data structure. + // An entry is identified by its index into the ExpiresBucket._pages array, and its + // index into the ExpiresPage._entries array. + // + // Bytes 0-7 of the reference are for the index into the ExpiresPage._entries array. + // Bytes 8-31 of the reference are for the index into the ExpiresBucket._pages array. + // + struct ExpiresEntryRef { + // The invalid reference is 0. + static internal readonly ExpiresEntryRef INVALID = new ExpiresEntryRef(0, 0); + + const uint ENTRY_MASK = 0x000000ffu; + const uint PAGE_MASK = 0xffffff00u; + const int PAGE_SHIFT = 8; + + uint _ref; + + internal ExpiresEntryRef(int pageIndex, int entryIndex) { + Debug.Assert((pageIndex & 0x00ffffff) == pageIndex, "(pageIndex & 0x00ffffff) == pageIndex"); + Debug.Assert((entryIndex & ENTRY_MASK) == entryIndex, "(entryIndex & ENTRY_MASK) == entryIndex"); + Debug.Assert(entryIndex != 0 || pageIndex == 0, "entryIndex != 0 || pageIndex == 0"); + + _ref = ( (((uint)pageIndex) << PAGE_SHIFT) | (((uint)(entryIndex)) & ENTRY_MASK) ); + } + + public override bool Equals(object value) { + if (value is ExpiresEntryRef) { + return _ref == ((ExpiresEntryRef)value)._ref; + } + + return false; + } +#if NOT_USED + public static bool Equals(ExpiresEntryRef r1, ExpiresEntryRef r2) { + return r1._ref == r2._ref; + } +#endif + public static bool operator !=(ExpiresEntryRef r1, ExpiresEntryRef r2) { + return r1._ref != r2._ref; + } + public static bool operator ==(ExpiresEntryRef r1, ExpiresEntryRef r2) { + return r1._ref == r2._ref; + } + + public override int GetHashCode() { + return (int) _ref; + } + +#if DBG + public override string ToString() { + return PageIndex + ":" + Index; + } +#endif + + // The index into the ExpiresBucket._pages array. + internal int PageIndex { + get { + int result = (int) (_ref >> PAGE_SHIFT); + return result; + } + } + + + // The index into the _entries array. + internal int Index { + get { + int result = (int) (_ref & ENTRY_MASK); + return result; + } + } + + // Is the reference invalid? + internal bool IsInvalid { + get { + return _ref == 0; + } + } + } + + // overhead is 12 bytes + [StructLayout(LayoutKind.Explicit)] + struct ExpiresEntry { + // _utcExpires holds the expiration time of the item. + // When an ExpiresEntry is not in use, _utcExpires is + // no longer needed, so we can use its memory to hold + // an index into the page's free list, and a count + // of free entries and whether or not it is on an expires list. + [FieldOffset(0)] + internal DateTime _utcExpires; // expires + + [FieldOffset(0)] + internal ExpiresEntryRef _next; // free list + + [FieldOffset(4)] + internal int _cFree; // count of free entries in list at expires[0] + // 1 if inFlush, 0 if free + [FieldOffset(8)] + internal CacheEntry _cacheEntry; // cache entry + } + + // A page to hold the array of ExpiresEntry. + struct ExpiresPage { + internal ExpiresEntry[] _entries; // array of ExpiresEntry. + internal int _pageNext; // next page on the free page or free entry list + internal int _pagePrev; // prev page on the free page or free entry list + } + + // A list of ExpiresPages. + struct ExpiresPageList { + internal int _head; // head of list + internal int _tail; // tail of list + } + + // + // Class ExpiresBucket contains all the entries that expire within a given interval + // every cycle of buckets. + // + // For example, if the inverval length is 20 seconds, and there are 60 buckets, + // then bucket 4 will contain all items that expire between: + // 00:01:20 and 00:01:40 + // 00:21:20 and 00:21:40 + // 00:41:20 and 00:41:40 + // 01:01:20 and 01:01:40 + // ... + // + // When we flush expired items, we need to examine every item in every bucket to + // determine its expiration time. We potentially call FlushExpiredItems() every time + // we need to trim items from the cache when there is memory pressure, which can + // occur several times a second. + // + // To avoid a full scan on every call to FlushExpiredItems(), we maintain a count + // of the items that expire within the first interval since the last full scan, and + // only scan all entries in the bucket when there are items to flush. The first + // interval is split into smaller intervals, and counts are kept of all items that need to + // be flushed up to the time of that interval. + // + // Continuing with the example above, the first interval would be split into + // 4 intervals of 5 seconds: + // + // If the last full scan occurred at 00:01:20 ... + // _counts[0] contains the number of items expiring before 00:01:25 + // _counts[1] contains the number of items expiring before 00:01:30 + // _counts[2] contains the number of items expiring before 00:01:35 + // _counts[3] contains the number of items expiring before 00:01:40 + // + // If there were 3 items in this bucket expiring at 00:01:27, 00:01:31, and 00:01:34 ... + // _counts[0] == 0 + // _counts[1] == 1 + // _counts[2] == 3 + // _counts[3] == 3 + // + // We further reduce the number of scans by keeping the minimum expiration time + // of an item in the bucket. If FlushExpiredItems() is called before the minimum + // expiration time, we do not need to perform the scan. Note that if the item with the + // minimum expiration time is removed, we do not update the minimum expiration time, + // so it is only a heuristic. + // + sealed class ExpiresBucket { + // We use _entries[0] to hold the head of the free list, and the count of items in the free list. + internal const int NUM_ENTRIES = 127; + const int LENGTH_ENTRIES = 128; + + const int MIN_PAGES_INCREMENT = 10; + const int MAX_PAGES_INCREMENT = 340; // (size of a page on x86) / (12 bytes per UsagePage) + const double MIN_LOAD_FACTOR = 0.5; // minimum ratio of used to total entries before we will reduce + + const int COUNTS_LENGTH=4; // length of _counts array + + // timespan represented by each count entry + static readonly TimeSpan COUNT_INTERVAL= new TimeSpan(CacheExpires._tsPerBucket.Ticks / COUNTS_LENGTH); + + readonly CacheExpires _cacheExpires; // parent CacheExpires object + readonly byte _bucket; // index of this bucket + + ExpiresPage[] _pages; // page array + +#if IA64 + volatile +#endif + int _cEntriesInUse; // count of ExpiresEntry's in use +#if IA64 + volatile +#endif + int _cPagesInUse; // count of ExpiresPage's in use +#if IA64 + volatile +#endif + int _cEntriesInFlush; // count of ExpiresEntry's in process of being flushed +#if IA64 + volatile +#endif + int _minEntriesInUse; // minimum number of entries in use before we reduce + + ExpiresPageList _freePageList; // list of free pages (_entries == null) + ExpiresPageList _freeEntryList; // list of pages with free entries (entry.FreeCountCount > 0) + +#if IA64 + volatile +#endif + bool _blockReduce; // block calls to Reduce() while in FlushExpiredItems + + // Minimum expiration date of the items in this bucket. + // Note that it is only a heursitic - if an item that is + // the minimum is removed, the minimum will not be updated. + // The minimum is reset when the bucket is flushed. + DateTime _utcMinExpires; + + // An exact count of the number of items that expire in the first period + // since the last full scan. We use this to determine whether or not to + // flush expired items when we are trimming items from the cache. + int[] _counts; + + // The last time a flush occured, at which time we recalculate the counts. + DateTime _utcLastCountReset; + + internal ExpiresBucket(CacheExpires cacheExpires, byte bucket, DateTime utcNow) { + _cacheExpires = cacheExpires; + _bucket = bucket; + _counts = new int[COUNTS_LENGTH]; + ResetCounts(utcNow); + InitZeroPages(); + + Debug.Validate("CacheValidateExpires", this); + } + + void InitZeroPages() { + Debug.Assert(_cPagesInUse == 0, "_cPagesInUse == 0"); + Debug.Assert(_cEntriesInUse == 0, "_cEntriesInUse == 0"); + Debug.Assert(_cEntriesInFlush == 0, "_cEntriesInFlush == 0"); + + _pages = null; + _minEntriesInUse = -1; + _freePageList._head = -1; + _freePageList._tail = -1; + _freeEntryList._head = -1; + _freeEntryList._tail = -1; + } + +// Use macros so that the code is inlined in the function +#define EntriesI(i) (_pages[(i)]._entries) + +#define EntriesR(entryRef) (_pages[(entryRef.PageIndex)]._entries) + +#define PagePrev(i) (_pages[(i)]._pagePrev) + +#define PageNext(i) (_pages[(i)]._pageNext) + +#define FreeEntryHead(entries) ((entries)[0]._next) + +#define FreeEntryCount(entries) ((entries)[0]._cFree) + +#if DBG + bool EntryIsFree(ExpiresEntryRef entryRef) { + return EntriesR(entryRef)[entryRef.Index]._cacheEntry == null; + } +#endif + + // Reset the counts array and min expiration time. + void ResetCounts(DateTime utcNow) { + _utcLastCountReset = utcNow; + _utcMinExpires = DateTime.MaxValue; + + for (int i = 0; i < _counts.Length; i++) { + _counts[i] = 0; + } + } + + // Return the index into the _counts array of all items that + // expire by the given expiration time. Note that the index + // may be larger than the length of the array. + int GetCountIndex(DateTime utcExpires) { + return Math.Max(0, (int) ((utcExpires - _utcLastCountReset).Ticks / COUNT_INTERVAL.Ticks)); + } + + // Add counts for the expiration time. + void AddCount(DateTime utcExpires) { + int ci = GetCountIndex(utcExpires); + for (int i = _counts.Length - 1; i >= ci; i--) { + _counts[i]++; + } + + if (utcExpires < _utcMinExpires) { + _utcMinExpires = utcExpires; + } + } + + // Remove counts for the expiration time + void RemoveCount(DateTime utcExpires) { + int ci = GetCountIndex(utcExpires); + for (int i = _counts.Length - 1; i >= ci; i--) { + _counts[i]--; + } + } + + // Get the number of items that expire before utcExpires. + int GetExpiresCount(DateTime utcExpires) { + if (utcExpires < _utcMinExpires) + return 0; + + int ci = GetCountIndex(utcExpires); + if (ci >= _counts.Length) + return _cEntriesInUse; + + return _counts[ci]; + } + + // Add a page to the head of a list. + void AddToListHead(int pageIndex, ref ExpiresPageList list) { + Debug.Assert((list._head == -1) == (list._tail == -1), "(list._head == -1) == (list._tail == -1)"); + + PagePrev(pageIndex) = -1; + PageNext(pageIndex) = list._head; + if (list._head != -1) { + Debug.Assert(PagePrev(list._head) == -1, "PagePrev(list._head) == -1"); + PagePrev(list._head) = pageIndex; + } + else { + list._tail = pageIndex; + } + + list._head = pageIndex; + } + + // Add a page to the tail of a list. + void AddToListTail(int pageIndex, ref ExpiresPageList list) { + Debug.Assert((list._head == -1) == (list._tail == -1), "(list._head == -1) == (list._tail == -1)"); + + PageNext(pageIndex) = -1; + PagePrev(pageIndex) = list._tail; + if (list._tail != -1) { + Debug.Assert(PageNext(list._tail) == -1, "PageNext(list._tail) == -1"); + PageNext(list._tail) = pageIndex; + } + else { + list._head = pageIndex; + } + + list._tail = pageIndex; + } + + // Remove a page from the head of a list. + int RemoveFromListHead(ref ExpiresPageList list) { + Debug.Assert(list._head != -1, "list._head != -1"); + + int oldHead = list._head; + RemoveFromList(oldHead, ref list); + return oldHead; + } + + // Remove a page from the list. + void RemoveFromList(int pageIndex, ref ExpiresPageList list) { + Debug.Assert((list._head == -1) == (list._tail == -1), "(list._head == -1) == (list._tail == -1)"); + + if (PagePrev(pageIndex) != -1) { + Debug.Assert(PageNext(PagePrev(pageIndex)) == pageIndex, "PageNext(PagePrev(pageIndex)) == pageIndex"); + PageNext(PagePrev(pageIndex)) = PageNext(pageIndex); + } + else { + Debug.Assert(list._head == pageIndex, "list._head == pageIndex"); + list._head = PageNext(pageIndex); + } + + if (PageNext(pageIndex) != -1) { + Debug.Assert(PagePrev(PageNext(pageIndex)) == pageIndex, "PagePrev(PageNext(pageIndex)) == pageIndex"); + PagePrev(PageNext(pageIndex)) = PagePrev(pageIndex); + } + else { + Debug.Assert(list._tail == pageIndex, "list._tail == pageIndex"); + list._tail = PagePrev(pageIndex); + } + + PagePrev(pageIndex) = -1; + PageNext(pageIndex) = -1; + } + + // Move a page to the head of the list + void MoveToListHead(int pageIndex, ref ExpiresPageList list) { + Debug.Assert(list._head != -1, "list._head != -1"); + Debug.Assert(list._tail != -1, "list._tail != -1"); + + // already at head? + if (list._head == pageIndex) + return; + + // remove from list + RemoveFromList(pageIndex, ref list); + + // add to head + AddToListHead(pageIndex, ref list); + } + + // Move to the tail of the list + void MoveToListTail(int pageIndex, ref ExpiresPageList list) { + Debug.Assert(list._head != -1, "list._head != -1"); + Debug.Assert(list._tail != -1, "list._tail != -1"); + + // already at tail? + if (list._tail == pageIndex) + return; + + // remove from list + RemoveFromList(pageIndex, ref list); + + // add to head + AddToListTail(pageIndex, ref list); + } + + // Update _minEntriesInUse when _cPagesInUse changes. + // When _cEntriesInUse falls below _minEntriesInUse, + // a call to Reduce() will consolidate entries onto fewer pages. + // If _minEntries == -1, then a call to Reduce() will never reduce the number of pages. + void UpdateMinEntries() { + if (_cPagesInUse <= 1) { + _minEntriesInUse = -1; + } + else { + int capacity = _cPagesInUse * NUM_ENTRIES; + Debug.Assert(capacity > 0, "capacity > 0"); + Debug.Assert(MIN_LOAD_FACTOR < 1.0, "MIN_LOAD_FACTOR < 1.0"); + + _minEntriesInUse = (int) (capacity * MIN_LOAD_FACTOR); + + // Don't allow a reduce if there are not enough free entries to + // remove a page. + if ((_minEntriesInUse - 1) > ((_cPagesInUse - 1) * NUM_ENTRIES)) { + _minEntriesInUse = -1; + } + } + +#if DBG + if (Debug.IsTagPresent("CacheExpiresNoReduce") && Debug.IsTagEnabled("CacheExpiresNoReduce")) { + _minEntriesInUse = -1; + } +#endif + + } + + // Remove a ExpiresPage that is in use, and put in on the list of free pages. + void RemovePage(int pageIndex) { + Debug.Assert(FreeEntryCount(EntriesI(pageIndex)) == NUM_ENTRIES, "FreeEntryCount(EntriesI(pageIndex)) == NUM_ENTRIES"); + + // release the page from the free entries list + RemoveFromList(pageIndex, ref _freeEntryList); + + // Add the page to the free pages list + AddToListHead(pageIndex, ref _freePageList); + + // remove reference to page + Debug.Assert(EntriesI(pageIndex) != null, "EntriesI(pageIndex) != null"); + EntriesI(pageIndex) = null; + + // decrement count of pages and update _cMinEntriesInUse + _cPagesInUse--; + if (_cPagesInUse == 0) { + InitZeroPages(); + } + else { + UpdateMinEntries(); + } + } + + // Get a free ExpiresEntry. + ExpiresEntryRef GetFreeExpiresEntry() { + // get the page of the free entry + Debug.Assert(_freeEntryList._head >= 0, "_freeEntryList._head >= 0"); + int pageIndex = _freeEntryList._head; + + // get a free entry from _entries + ExpiresEntry[] entries = EntriesI(pageIndex); + int entryIndex = FreeEntryHead(entries).Index; + + // fixup free list and count + FreeEntryHead(entries) = entries[entryIndex]._next; + FreeEntryCount(entries)--; + if (FreeEntryCount(entries) == 0) { + // remove page from list of free pages + Debug.Assert(FreeEntryHead(entries).IsInvalid, "FreeEntryHead(entries).IsInvalid"); + RemoveFromList(pageIndex, ref _freeEntryList); + } + +#if DBG + Debug.Assert(EntryIsFree(new ExpiresEntryRef(pageIndex, entryIndex)), "EntryIsFree(new ExpiresEntryRef(pageIndex, entryIndex))"); + if (!FreeEntryHead(entries).IsInvalid) { + Debug.Assert(FreeEntryHead(entries).Index != entryIndex, "FreeEntryHead(entries).Index != entryIndex"); + Debug.Assert(EntryIsFree(new ExpiresEntryRef(pageIndex, FreeEntryHead(entries).Index)), "EntryIsFree(new ExpiresEntryRef(pageIndex, FreeEntryHead(entries).Index))"); + } +#endif + + return new ExpiresEntryRef(pageIndex, entryIndex); + } + + + // Add a ExpiresEntry to the free entry list. + void AddExpiresEntryToFreeList(ExpiresEntryRef entryRef) { + ExpiresEntry[] entries = EntriesR(entryRef); + int entryIndex = entryRef.Index; + + Debug.Assert(entries[entryIndex]._cacheEntry == null, "entries[entryIndex]._cacheEntry == null"); + entries[entryIndex]._cFree = 0; + + entries[entryIndex]._next = FreeEntryHead(entries); + FreeEntryHead(entries) = entryRef; + + _cEntriesInUse--; + int pageIndex = entryRef.PageIndex; + FreeEntryCount(entries)++; + if (FreeEntryCount(entries) == 1) { + // add page to head of list of free pages + AddToListHead(pageIndex, ref _freeEntryList); + } + else if (FreeEntryCount(entries) == NUM_ENTRIES) { + RemovePage(pageIndex); + } + } + + // Expand the capacity of the ExpiresBucket to hold more CacheEntry's. + // We will need to allocate a new page, and perhaps expand the _pages array. + // Note that we never collapse the _pages array. + void Expand() { + Debug.Assert(_cPagesInUse * NUM_ENTRIES == _cEntriesInUse, "_cPagesInUse * NUM_ENTRIES == _cEntriesInUse"); + Debug.Assert(_freeEntryList._head == -1, "_freeEntryList._head == -1"); + Debug.Assert(_freeEntryList._tail == -1, "_freeEntryList._tail == -1"); + + // exapnd _pages if there are no more + if (_freePageList._head == -1) { + // alloc new pages array + int oldLength; + if (_pages == null) { + oldLength = 0; + } + else { + oldLength = _pages.Length; + } + + Debug.Assert(_cPagesInUse == oldLength, "_cPagesInUse == oldLength"); + Debug.Assert(_cEntriesInUse == oldLength * NUM_ENTRIES, "_cEntriesInUse == oldLength * ExpiresEntryRef.NUM_ENTRIES"); + + int newLength = oldLength * 2; + newLength = Math.Max(oldLength + MIN_PAGES_INCREMENT, newLength); + newLength = Math.Min(newLength, oldLength + MAX_PAGES_INCREMENT); + Debug.Assert(newLength > oldLength, "newLength > oldLength"); + + ExpiresPage[] newPages = new ExpiresPage[newLength]; + + // copy original pages + for (int i = 0; i < oldLength; i++) { + newPages[i] = _pages[i]; + } + + // setup free list of new pages + for (int i = oldLength; i < newPages.Length; i++) { + newPages[i]._pagePrev = i - 1; + newPages[i]._pageNext = i + 1; + } + + newPages[oldLength]._pagePrev = -1; + newPages[newPages.Length - 1]._pageNext = -1; + + // use new pages array + _freePageList._head = oldLength; + _freePageList._tail = newPages.Length - 1; + + _pages = newPages; + } + + // move from free page list to free entries list + int pageIndex = RemoveFromListHead(ref _freePageList); + AddToListHead(pageIndex, ref _freeEntryList); + + // create the entries + ExpiresEntry[] entries = new ExpiresEntry[LENGTH_ENTRIES]; + FreeEntryCount(entries) = NUM_ENTRIES; + + // init free list + for (int i = 0; i < entries.Length - 1; i++) { + entries[i]._next = new ExpiresEntryRef(pageIndex, i + 1); + } + entries[entries.Length - 1]._next = ExpiresEntryRef.INVALID; + + EntriesI(pageIndex) = entries; + + // increment count of pages and update _minEntriesInUse + _cPagesInUse++; + UpdateMinEntries(); + } + + // Consolidate ExpiresEntry's onto fewer pages when there are too many + // free entries. + void Reduce() { + // Test if we need to consolidate. + if (_cEntriesInUse >= _minEntriesInUse || _blockReduce) + return; + + Debug.Assert(_freeEntryList._head != -1, "_freeEntryList._head != -1"); + Debug.Assert(_freeEntryList._tail != -1, "_freeEntryList._tail != -1"); + Debug.Assert(_freeEntryList._head != _freeEntryList._tail, "_freeEntryList._head != _freeEntryList._tail"); + + // Rearrange free page list to put pages with more free entries at the tail + int meanFree = (int) (NUM_ENTRIES - (NUM_ENTRIES * MIN_LOAD_FACTOR)); + int pageIndexLast = _freeEntryList._tail; + int pageIndexCurrent = _freeEntryList._head; + int pageIndexNext; + ExpiresEntry[] entries; + + for (;;) { + pageIndexNext = PageNext(pageIndexCurrent); + + // move pages with greater than mean number + // of free items to tail, move the others to head + if (FreeEntryCount(EntriesI(pageIndexCurrent)) > meanFree) { + MoveToListTail(pageIndexCurrent, ref _freeEntryList); + } + else { + MoveToListHead(pageIndexCurrent, ref _freeEntryList); + } + + // check if entire list has been examined + if (pageIndexCurrent == pageIndexLast) + break; + + // iterate + pageIndexCurrent = pageIndexNext; + } + + // Move entries from the free pages at the tail to the + // free pages at the front, and release the free pages at the tail. + for (;;) { + // See if there is room left to move entries used by the page. + if (_freeEntryList._tail == -1) + break; + + entries = EntriesI(_freeEntryList._tail); + Debug.Assert(FreeEntryCount(entries) > 0, "FreeEntryCount(entries) > 0"); + int availableFreeEntries = (_cPagesInUse * NUM_ENTRIES) - FreeEntryCount(entries) - _cEntriesInUse; + if (availableFreeEntries < (NUM_ENTRIES - FreeEntryCount(entries))) + break; + + // Move each entry from the page at the tail to a page at the head. + for (int i = 1; i < entries.Length; i++) { + // skip the free entries + if (entries[i]._cacheEntry == null) + continue; + + // get a free ExpiresEntry from the head of the list. + Debug.Assert(_freeEntryList._head != _freeEntryList._tail, "_freeEntryList._head != _freeEntryList._tail"); + ExpiresEntryRef newRef = GetFreeExpiresEntry(); + Debug.Assert(newRef.PageIndex != _freeEntryList._tail, "newRef.PageIndex != _freeEntryList._tail"); + + // update the CacheEntry + CacheEntry cacheEntry = entries[i]._cacheEntry; + +#if DBG + ExpiresEntryRef oldRef = new ExpiresEntryRef(_freeEntryList._tail, i); + Debug.Assert(cacheEntry.ExpiresEntryRef == oldRef, "cacheEntry.ExpiresEntryRef == oldRef"); +#endif + + cacheEntry.ExpiresEntryRef = newRef; + + // copy old entry to new entry + ExpiresEntry[] newEntries = EntriesR(newRef); + newEntries[newRef.Index] = entries[i]; + + // Update free entry count for debugging. We don't bother + // to fix up the free entry list for this page as we are + // going to release the page. + FreeEntryCount(entries)++; + } + + // now the page is free - release its memory + RemovePage(_freeEntryList._tail); + + Debug.Validate("CacheValidateExpires", this); + } + } + + // Add an entry to the bucket. This may occur the first time an item is added to the cache, + // or when the CacheEntry has a sliding expiration and is moved from one bucket to another. + internal void AddCacheEntry(CacheEntry cacheEntry) { + lock (this) { + // Test if the item is still added to the cache. When CacheExpires.UtcUpdate() is called, + // the item is removed from CacheExpires, and the CacheEntry could be removed by Cache.Remove() + // on another thread while we are in this function. + if ((cacheEntry.State & (CacheEntry.EntryState.AddedToCache | CacheEntry.EntryState.AddingToCache)) == 0) + return; + + // If item is already added to a bucket, do nothing. + ExpiresEntryRef entryRef = cacheEntry.ExpiresEntryRef; + Debug.Assert((cacheEntry.ExpiresBucket == 0xff) == entryRef.IsInvalid, "(cacheEntry.ExpiresBucket == 0xff) == entryRef.IsInvalid"); + if (cacheEntry.ExpiresBucket != 0xff || !entryRef.IsInvalid) + return; + + // Expand if there are no free ExpiresEntry's available. + if (_freeEntryList._head == -1) { + Expand(); + } + + // get the free entry + ExpiresEntryRef freeRef = GetFreeExpiresEntry(); + Debug.Assert(cacheEntry.ExpiresBucket == 0xff, "cacheEntry.ExpiresBucket == 0xff"); + Debug.Assert(cacheEntry.ExpiresEntryRef.IsInvalid, "cacheEntry.ExpiresEntryRef.IsInvalid"); + cacheEntry.ExpiresBucket = _bucket; + cacheEntry.ExpiresEntryRef = freeRef; + + // initialize index + ExpiresEntry[] entries = EntriesR(freeRef); + int entryIndex = freeRef.Index; + entries[entryIndex]._cacheEntry = cacheEntry; + entries[entryIndex]._utcExpires = cacheEntry.UtcExpires; + + // update the count + AddCount(cacheEntry.UtcExpires); + + _cEntriesInUse++; + +#if DBG + { + Debug.Trace("CacheExpiresAdd", + "Added item=" + cacheEntry.Key + + ",_bucket=" + _bucket + + ",_ref=" + freeRef + + ",now=" + Debug.FormatLocalDate(DateTime.Now) + + ",expires=" + DateTimeUtil.ConvertToLocalTime(cacheEntry.UtcExpires)); + + Debug.Validate("CacheValidateExpires", this); + Debug.Dump("CacheExpiresAdd", this); + } +#endif + + // Test again if the item is still added to the cache. When an update occurs, + // the item is removed from CacheExpires, and the CacheEntry could be removed + // on another thread while we are in this function. + // Since we don't know whether or not CacheSingle.UpdateCache has called CacheExpires.Remove(), + // we remove the item ourselves. RemoveCacheEntryNoLock protects itself against more than + // one remove of the cache item. + if ((cacheEntry.State & (CacheEntry.EntryState.AddedToCache | CacheEntry.EntryState.AddingToCache)) == 0) { + RemoveCacheEntryNoLock(cacheEntry); + } + } + } + + // Remove an item from the bucket. The caller must have a lock. + void RemoveCacheEntryNoLock(CacheEntry cacheEntry) { + ExpiresEntryRef entryRef = cacheEntry.ExpiresEntryRef; + if (cacheEntry.ExpiresBucket != _bucket || entryRef.IsInvalid) + return; + + ExpiresEntry[] entries = EntriesR(entryRef); + int entryIndex = entryRef.Index; + +#if DBG + Debug.Assert(cacheEntry == entries[entryIndex]._cacheEntry, "cacheEntry == entries[entryIndex]._cacheEntry"); +#endif + + // update Count + RemoveCount(entries[entryIndex]._utcExpires); + + // update the cache entry + cacheEntry.ExpiresBucket = 0xff; + cacheEntry.ExpiresEntryRef = ExpiresEntryRef.INVALID; + entries[entryIndex]._cacheEntry = null; + + // add to free list + AddExpiresEntryToFreeList(entryRef); + + // reset count if able + if (_cEntriesInUse == 0) { + ResetCounts(DateTime.UtcNow); + } + + // remove pages if necessary + Reduce(); + + Debug.Trace("CacheExpiresRemove", + "Removed item=" + cacheEntry.Key + + ",_bucket=" + _bucket + + ",ref=" + entryRef + + ",now=" + Debug.FormatLocalDate(DateTime.Now) + + ",expires=" + DateTimeUtil.ConvertToLocalTime(cacheEntry.UtcExpires)); + + + Debug.Validate("CacheValidateExpires", this); + Debug.Dump("CacheExpiresRemove", this); + } + + // Remove an item from the bucket. + internal void RemoveCacheEntry(CacheEntry cacheEntry) { + lock (this) { + RemoveCacheEntryNoLock(cacheEntry); + } + } + + // Update the expiration time of a cache entry, and the count. + internal void UtcUpdateCacheEntry(CacheEntry cacheEntry, DateTime utcExpires) { + lock (this) { + ExpiresEntryRef entryRef = cacheEntry.ExpiresEntryRef; + if (cacheEntry.ExpiresBucket != _bucket || entryRef.IsInvalid) + return; + + ExpiresEntry[] entries = EntriesR(entryRef); + int entryIndex = entryRef.Index; + + Debug.Assert(cacheEntry == entries[entryIndex]._cacheEntry); + + // update count + RemoveCount(entries[entryIndex]._utcExpires); + AddCount(utcExpires); + + // update expires entry + entries[entryIndex]._utcExpires = utcExpires; + + // update the cache entry + cacheEntry.UtcExpires = utcExpires; + + Debug.Validate("CacheValidateExpires", this); + Debug.Trace("CacheExpiresUpdate", "Updated item " + cacheEntry.Key + " in bucket " + _bucket); + } + } + + // Flush expired items from the cache. + internal int FlushExpiredItems(DateTime utcNow, bool useInsertBlock) { + // Check if there is something to flush + if (_cEntriesInUse == 0 || GetExpiresCount(utcNow) == 0) + return 0; + + Debug.Assert(_cEntriesInFlush == 0, "_cEntriesInFlush == 0"); + + // We create a list of ExpiresEntry's that we wish to flush. These entries + // are not considered free, so the page that holds them will not be removed. + ExpiresEntryRef inFlushHead = ExpiresEntryRef.INVALID; + + ExpiresEntry[] entries; + int entryIndex; + CacheEntry cacheEntry; + int flushed = 0; + + try { + if (useInsertBlock) { + // Block insertion into the Cache if we're under high memory pressure + _cacheExpires.CacheSingle.BlockInsertIfNeeded(); + } + + lock (this) { + Debug.Assert(_blockReduce == false, "_blockReduce == false"); + + // Recheck if there is something to flush. + if (_cEntriesInUse == 0 || GetExpiresCount(utcNow) == 0) + return 0; + +#if DBG + Debug.Trace("CacheExpiresFlush", "FlushExpiredItems ExpiresCount=" + GetExpiresCount(utcNow) + + " bucket=" + _bucket + "; Time=" + Debug.FormatLocalDate(DateTime.Now)); +#endif + + // Walk through all ExpiresEntries, create a list of expired items, + // and recalculate count heuristics. + ResetCounts(utcNow); + int cPages = _cPagesInUse; + for (int i = 0; i < _pages.Length; i++) { + entries = _pages[i]._entries; + if (entries != null) { + int cEntries = NUM_ENTRIES - FreeEntryCount(entries); + for (int j = 1; j < entries.Length; j++) { + cacheEntry = entries[j]._cacheEntry; + if (cacheEntry != null) { + if (entries[j]._utcExpires > utcNow) { + AddCount(entries[j]._utcExpires); + } + else { + // Remove reference from CacheEntry. We must do this before we + // release the lock, otherwise the item would be corrupted if + // UpdateCacheEntry or RemoveCacheEntry were called. + cacheEntry.ExpiresBucket = 0xff; + cacheEntry.ExpiresEntryRef = ExpiresEntryRef.INVALID; + + // distinguish between items on free list and inflush list for debugging + entries[j]._cFree = 1; + + // add it to the inFlush list + entries[j]._next = inFlushHead; + inFlushHead = new ExpiresEntryRef(i, j); + + flushed++; + _cEntriesInFlush++; + } + + cEntries--; + if (cEntries == 0) + break; + } + } + + cPages--; + if (cPages == 0) + break; + } + } + + if (flushed == 0) { + Debug.Trace("CacheExpiresFlushTotal", "FlushExpiredItems flushed " + flushed + + " expired items, bucket=" + _bucket + "; Time=" + Debug.FormatLocalDate(DateTime.Now)); + + return 0; + } + + // prevent pages from being moved by blocking Reduce(). + _blockReduce = true; + } + } + finally { + if (useInsertBlock) { + // Don't hold any insertblock before we remove Cache items. If not, the following + // deadlock scenario may happen: + // - 3rd party code hold lock A, call Cache.Insert, which wait for the Cache insertblock + // - FlushExpiredItems holds the Cache insertBlock, call Cache.Remove, which call + // 3rd party CacheItemRemovedCallback, which then try to get lock A + + _cacheExpires.CacheSingle.UnblockInsert(); + } + } + + Debug.Assert(!inFlushHead.IsInvalid, "!inFlushHead.IsInvalid"); + + // Remove items on the inFlush list from the rest of the cache. + CacheSingle cacheSingle = _cacheExpires.CacheSingle; + ExpiresEntryRef current = inFlushHead; + ExpiresEntryRef next; + while (!current.IsInvalid) { + entries = EntriesR(current); + entryIndex = current.Index; + + next = entries[entryIndex]._next; + + // remove the entry + cacheEntry = entries[entryIndex]._cacheEntry; + entries[entryIndex]._cacheEntry = null; + Debug.Assert(cacheEntry.ExpiresEntryRef.IsInvalid, "cacheEntry.ExpiresEntryRef.IsInvalid"); + cacheSingle.Remove(cacheEntry, CacheItemRemovedReason.Expired); + + //iterate + current = next; + } + + try { + if (useInsertBlock) { + // Block insertion into the Cache if we're under high memory pressure + _cacheExpires.CacheSingle.BlockInsertIfNeeded(); + } + + lock (this) { + // add each ExpiresEntry to the free list + current = inFlushHead; + while (!current.IsInvalid) { + entries = EntriesR(current); + entryIndex = current.Index; + + next = entries[entryIndex]._next; + + _cEntriesInFlush--; + AddExpiresEntryToFreeList(current); + + //iterate + current = next; + } + + // try to reduce + Debug.Assert(_cEntriesInFlush == 0, "_cEntriesInFlush == 0"); + _blockReduce = false; + Reduce(); + + Debug.Trace("CacheExpiresFlushTotal", "FlushExpiredItems flushed " + flushed + + " expired items, bucket=" + _bucket + "; Time=" + Debug.FormatLocalDate(DateTime.Now)); + + Debug.Validate("CacheValidateExpires", this); + Debug.Dump("CacheExpiresFlush", this); + } + } + finally { + if (useInsertBlock) { + _cacheExpires.CacheSingle.UnblockInsert(); + } + } + + return flushed; + } + +#if DBG + internal void DebugValidate() { + int cFree = 0; + int cEntriesInUse = 0; + int cPagesInUse = 0; + int pagesLength; + int[] counts = new int[COUNTS_LENGTH]; + + if (_pages == null) { + pagesLength = 0; + } + else { + pagesLength = _pages.Length; + } + + Debug.CheckValid(-1 <= _freePageList._head && _freePageList._head <= pagesLength, "-1 <= _freePageList._head && _freePageList._head <= pagesLength"); + Debug.CheckValid(-1 <= _freeEntryList._head && _freeEntryList._head <= pagesLength, "-1 <= _freeEntryList._head && _freeEntryList._head <= pagesLength"); + Debug.CheckValid(-1 <= _freeEntryList._tail && _freeEntryList._tail <= pagesLength, "-1 <= _freeEntryList._tail && _freeEntryList._tail <= pagesLength"); + Debug.CheckValid((_freeEntryList._head == -1) == (_freeEntryList._tail == -1), "(_freeEntryList._head == -1) == (_freeEntryList._tail == -1)"); + Debug.CheckValid(_minEntriesInUse >= -1, "_minEntriesInUse >= -1"); + Debug.CheckValid(_cEntriesInFlush >= 0, "_cEntriesInFlush >= 0"); + + // check counts + for (int i = 0; i < pagesLength; i++) { + ExpiresEntry[] entries = _pages[i]._entries; + if (entries != null) { + cPagesInUse++; + cFree = 0; + + Debug.CheckValid(entries[0]._cacheEntry == null, "entries[0]._cacheEntry == null"); + + for (int j = 1; j < entries.Length; j++) { + if (entries[j]._cacheEntry == null && entries[j]._cFree == 0) { + cFree++; + } + else { + cEntriesInUse++; + } + + if (entries[j]._cacheEntry != null && entries[j]._cFree != 1) { + int ci = GetCountIndex(entries[j]._utcExpires); + for (int k = _counts.Length - 1; k >= ci; k--) { + counts[k]++; + } + } + } + + Debug.CheckValid(cFree == FreeEntryCount(entries), "cFree == FreeEntryCount(entries)"); + + // walk the free list + cFree = 0; + if (!FreeEntryHead(entries).IsInvalid) { + int j = FreeEntryHead(entries).Index; + for (;;) { + cFree++; + Debug.CheckValid(cFree <= FreeEntryCount(entries), "cFree <= FreeEntryCount(entries)"); + + if (entries[j]._next.IsInvalid) + break; + + j = entries[j]._next.Index; + } + } + Debug.CheckValid(cFree == FreeEntryCount(entries), "cFree == FreeEntryCount(entries)"); + } + } + + Debug.CheckValid(cPagesInUse == _cPagesInUse, "cPagesInUse == _cPagesInUse"); + Debug.CheckValid(cEntriesInUse == _cEntriesInUse, "cEntriesInUse == _cEntriesInUse"); + + for (int i = 0; i < _counts.Length; i++) { + Debug.CheckValid(_counts[i] == counts[i], "_counts[i] == counts[i]"); + } + + // walk the free slot list + int cFreeSlots = 0; + if (_freePageList._head != -1) { + for (int i = _freePageList._head; i != -1; i = _pages[i]._pageNext) { + cFreeSlots++; + Debug.CheckValid(cFreeSlots <= pagesLength, "cFreeSlots <= pagesLength"); + Debug.CheckValid(_pages[i]._entries == null, "_pages[i]._entries == null"); + if (_freePageList._head != i) { + Debug.CheckValid(PageNext(PagePrev(i)) == i, "PageNext(PagePrev(i)) == i"); + } + + if (_freePageList._tail != i) { + Debug.CheckValid(PagePrev(PageNext(i)) == i, "PagePrev(PageNext(i)) == i"); + } + } + } + Debug.CheckValid(cFreeSlots == pagesLength - _cPagesInUse, "cFreeSlots == pagesLength - _cPagesInUse"); + + // walk the free page list + int cFreeEntries = 0; + int cFreePages = 0; + if (_freeEntryList._head != -1) { + for (int i = _freeEntryList._head; i != -1; i = _pages[i]._pageNext) { + cFreePages++; + Debug.CheckValid(cFreePages <= pagesLength, "cFreePages < pagesLength"); + ExpiresEntry[] entries = _pages[i]._entries; + Debug.CheckValid(entries != null, "entries != null"); + cFreeEntries += FreeEntryCount(entries); + if (_freeEntryList._head != i) { + Debug.CheckValid(PageNext(PagePrev(i)) == i, "PageNext(PagePrev(i)) == i"); + } + + if (_freeEntryList._tail != i) { + Debug.CheckValid(PagePrev(PageNext(i)) == i, "PagePrev(PageNext(i)) == i"); + } + } + } + + Debug.CheckValid(cFreeEntries == (_cPagesInUse * NUM_ENTRIES) - _cEntriesInUse, "cFreeEntries == (_cPagesInUse * NUM_ENTRIES) - _cEntriesInUse"); + } + + internal string DebugDescription(string indent) { + StringBuilder sb = new StringBuilder(); + string i2 = indent + " "; + + sb.Append(indent + + "_bucket=" + _bucket + + ",_cEntriesInUse=" + _cEntriesInUse + + ",_cPagesInUse=" + _cPagesInUse + + ",_pages is " + (_pages == null ? "null" : "non-null") + + ",_minEntriesInUse=" + _minEntriesInUse + + ",_freePageList._head=" + _freePageList._head + + ",_freeEntryList._head=" + _freeEntryList._head + + ",_freeEntryList._tail=" + _freeEntryList._tail + + "\n"); + + return sb.ToString(); + } +#endif + } + + + /* + * Provides an expiration service for entries in the cache. + * Items with expiration times are placed into a configurable + * number of buckets. Each minute a bucket is examined for + * expired items. + */ + sealed class CacheExpires { + internal static readonly TimeSpan MIN_UPDATE_DELTA = new TimeSpan(0, 0, 1); + internal static readonly TimeSpan MIN_FLUSH_INTERVAL = new TimeSpan(0, 0, 1); + internal static readonly TimeSpan _tsPerBucket = new TimeSpan(0, 0, 20); + + const int NUMBUCKETS = 30; + static readonly TimeSpan _tsPerCycle = new TimeSpan(NUMBUCKETS * _tsPerBucket.Ticks); + + readonly CacheSingle _cacheSingle; + readonly ExpiresBucket[] _buckets; + DisposableGCHandleRef<Timer> _timerHandleRef; + DateTime _utcLastFlush; + int _inFlush; + + + internal CacheExpires(CacheSingle cacheSingle) { + Debug.Assert(NUMBUCKETS < Byte.MaxValue); + + DateTime utcNow = DateTime.UtcNow; + + _cacheSingle = cacheSingle; + _buckets = new ExpiresBucket[NUMBUCKETS]; + for (byte b = 0; b < _buckets.Length; b++) { + _buckets[b] = new ExpiresBucket(this, b, utcNow); + } + } + + int UtcCalcExpiresBucket(DateTime utcDate) { + long ticksFromCycleStart = utcDate.Ticks % _tsPerCycle.Ticks; + int bucket = (int) (((ticksFromCycleStart / _tsPerBucket.Ticks) + 1) % NUMBUCKETS); + + return bucket; + } + + int FlushExpiredItems(bool checkDelta, bool useInsertBlock) { + int flushed = 0; + + if (Interlocked.Exchange(ref _inFlush, 1) == 0) { + try { + // if the timer was disposed, return without doing anything + if (_timerHandleRef == null) { + return 0; + } + DateTime utcNow = DateTime.UtcNow; + if (!checkDelta || utcNow - _utcLastFlush >= MIN_FLUSH_INTERVAL || utcNow < _utcLastFlush) { + _utcLastFlush = utcNow; + foreach (ExpiresBucket bucket in _buckets) { + flushed += bucket.FlushExpiredItems(utcNow, useInsertBlock); + } + + Debug.Trace("CacheExpiresFlushTotal", "FlushExpiredItems flushed a total of " + flushed + " items; Time=" + Debug.FormatLocalDate(DateTime.Now)); + Debug.Dump("CacheExpiresFlush", this); + } + + } + finally { + Interlocked.Exchange(ref _inFlush, 0); + } + } + + return flushed; + } + + internal int FlushExpiredItems(bool useInsertBlock) { + return FlushExpiredItems(true, useInsertBlock); + } + + void TimerCallback(object state) { + FlushExpiredItems(false, false); + } + + internal void EnableExpirationTimer(bool enable) { +#if DBG + if (Debug.IsTagPresent("Timer") && !Debug.IsTagEnabled("Timer")) { + enable = false; + } +#endif + + if (enable) { + if (_timerHandleRef == null) { + DateTime utcNow = DateTime.UtcNow; + TimeSpan due = _tsPerBucket - (new TimeSpan(utcNow.Ticks % _tsPerBucket.Ticks)); + Timer timer = new Timer(new TimerCallback(this.TimerCallback), null, + due.Ticks / TimeSpan.TicksPerMillisecond, _tsPerBucket.Ticks / TimeSpan.TicksPerMillisecond); + _timerHandleRef = new DisposableGCHandleRef<Timer>(timer); + + Debug.Trace("Cache", "Cache expiration timer created."); + } + } + else { + DisposableGCHandleRef<Timer> timerHandleRef = _timerHandleRef; + if (timerHandleRef != null && Interlocked.CompareExchange(ref _timerHandleRef, null, timerHandleRef) == timerHandleRef) { + timerHandleRef.Dispose(); + Debug.Trace("Cache", "Cache expiration timer disposed."); + while (_inFlush != 0) { + Thread.Sleep(100); + } + } + } + } + + internal CacheSingle CacheSingle { + get { + return _cacheSingle; + } + } + + /* + * Adds an entry to the expires list. + * + * @param entry The cache entry to add. + */ + internal void Add(CacheEntry cacheEntry) { + DateTime utcNow = DateTime.UtcNow; + if (utcNow > cacheEntry.UtcExpires) { + cacheEntry.UtcExpires = utcNow; + } + + int bucket = UtcCalcExpiresBucket(cacheEntry.UtcExpires); + _buckets[bucket].AddCacheEntry(cacheEntry); + } + + /* + * Removes an entry from the expires list. + * + * @param entry The cache entry to remove. + */ + internal void Remove(CacheEntry cacheEntry) { + byte bucket = cacheEntry.ExpiresBucket; + if (bucket != 0xff) { + _buckets[bucket].RemoveCacheEntry(cacheEntry); + } + } + + /* + * Updates an entry. + * + */ + internal void UtcUpdate(CacheEntry cacheEntry, DateTime utcNewExpires) { + int oldBucket = cacheEntry.ExpiresBucket; + int newBucket = UtcCalcExpiresBucket(utcNewExpires); + + if (oldBucket != newBucket) { + Debug.Trace("CacheExpiresUpdate", + "Updating item " + cacheEntry.Key + " from bucket " + oldBucket + " to new bucket " + newBucket); + + if (oldBucket != 0xff) { + _buckets[oldBucket].RemoveCacheEntry(cacheEntry); + cacheEntry.UtcExpires = utcNewExpires; + _buckets[newBucket].AddCacheEntry(cacheEntry); + } + } else { + if (oldBucket != 0xff) { + _buckets[oldBucket].UtcUpdateCacheEntry(cacheEntry, utcNewExpires); + } + } + } + + +#if DBG + internal void DebugValidate() { + int i; + + for (i = 0; i < _buckets.Length; i++) { + _buckets[i].DebugValidate(); + } + } + + internal string DebugDescription(string indent) { + int i; + StringBuilder sb = new StringBuilder(); + string i2 = indent + " "; + + sb.Append(indent); + sb.Append("Cache expires\n"); + + for (i = 0; i < _buckets.Length; i++) { + sb.Append(_buckets[i].DebugDescription(i2)); + } + + return sb.ToString(); + } +#endif + } +} + diff --git a/System.Web/cacheusage.cspp b/System.Web/cacheusage.cspp new file mode 100644 index 000000000..601b034d0 --- /dev/null +++ b/System.Web/cacheusage.cspp @@ -0,0 +1,1537 @@ +//------------------------------------------------------------------------------ +// <copyright file="CacheUsage.cs" company="Microsoft"> +// Copyright (c) Microsoft Corporation. All rights reserved. +// </copyright> +//------------------------------------------------------------------------------ + +// +// This is the implementation of an LRU2 list for the cache, which is used +// to flush the least frequently used items when memory pressure is low. +// +// LRU2 is similar to LRU (Least Recently Used), but it keeps track of the +// second to last use of an item, thereby measuring the average interval +// between references to an item. This has the advantage over LRU of keeping +// items that are frequently used, but haven't been used just at the time that +// we need to flush. +// +// Please note that when we insert a new item in the list, we treat the addition +// as a reference by itself. So the 1st reference goes to the head, +// and the 2nd reference goes to the head of the 2nd reference list. +// +// ................................................... +// For example: +// Action List (Head...Tail) +// ------ ------------------ +// Insert A A1 A2 +// Insert B B1 A1 B2 A2 +// Insert C C1 B1 A1 C2 B2 A2 +// Ref B B1 C1 B2 A1 C2 A2 +// Ref A A1 B1 C1 B2 A2 C2 +// Ref B B1 A1 B2 C1 A2 C2 +// Ref C C1 B1 A1 B2 C2 A2 +// Ref A A1 C1 B1 A2 B2 C2 +// +// When flushing, we will start scanning from the tail, and flush all 2nd references we find. +// For example, if we want to flush 2 items, we will find C2 and B2, +// and thus we will flush item B and C. +// ................................................... +// +// An item in the LRU2 list is represented by a UsageEntry struct. This struct +// contains the reference to the cache entry, and the linked list entries for +// both the most recent first and second references to the entry. To distinguish +// between a link to an item's first reference and its second reference, we use +// a positive index for the first reference, and a negative index for the second +// reference. +// +// ................................................... +// For example: +// Logically I have this list +// Head Tail +// A1 B1 C2 C1 B2 A2 +// +// Physically, A, B and C are stored in an array, and their indexes are 1, 2 and 3. +// +// So their ref1 and ref2 values will be: +// +// Entry(index) Ref1.Prev Ref1.Next Ref2.Prev Ref2.Next +// ----- --------- --------- --------- --------- +// (Head == 1 (point to A1)) +// A(1) 0 2 (B1) -2 (B2) 0 +// B(2) 1 (A1) -3 (C2) 3 (C1) -1 (A2) +// C(3) -3 (C2) -2 (B2) 2 (B1) 3 (C1) +// ................................................... +// +// To efficiently store potentially millions of cache items in the LRU2, +// we adopt a paging model. Each UsagePage contains an array of 127 UsageEntry +// structs (whose size is slightly less than one x86 memory page). A reference +// to a UsageEntry is thus defined by 2 index, the index of the page, and the +// index in the page's array of UsageEntry's. +// +// When the number of free entries rises above a threshold, we reduce the number +// of pages in use. +// +// In order to efficiently items in an array of arrays, we must use the C++ macro +// preprocessor. The jitter will not inline small functions, and we cannot represent +// access to a UsageEntry as a property, since the propery requires an index parameter. +// + +namespace System.Web.Caching { + using System.Runtime.InteropServices; + using System.Text; + using System.Threading; + using System.Web; + using System.Web.Util; + using System.Collections; + using System; + + // UsageEntryRef defines a reference to a UsageEntry in the UsageBucket data structure. + // An entry is identified by its index into the UsageBucket._pages array, and its + // index into the UsagePage._entries array. + // + // Bits 0-7 of the reference are for the index into the UsagePage._entries array. + // Bits 8-31 of the reference are for the index into the UsageBucket._pages array. + // + // A reference to a UsageEntry may be to either its first or second reference in + // the UsageBucket._lastRef list. The second reference will have a negative index. + // + struct UsageEntryRef { + // The invalid reference is 0. + static internal readonly UsageEntryRef INVALID = new UsageEntryRef(0, 0); + + const uint ENTRY_MASK = 0x000000ffu; + const uint PAGE_MASK = 0xffffff00u; + const int PAGE_SHIFT = 8; + + uint _ref; + + internal UsageEntryRef(int pageIndex, int entryIndex) { + Debug.Assert((pageIndex & 0x00ffffff) == pageIndex, "(pageIndex & 0x00ffffff) == pageIndex"); + Debug.Assert((Math.Abs(entryIndex) & ENTRY_MASK) == (Math.Abs(entryIndex)), "(Math.Abs(entryIndex) & ENTRY_MASK) == Math.Abs(entryIndex)"); + Debug.Assert(entryIndex != 0 || pageIndex == 0, "entryIndex != 0 || pageIndex == 0"); + + // Please note that because the range of valid entryIndex is -127 to 127, so + // 1 byte is big enough to hold the value. + + _ref = ( (((uint)pageIndex) << PAGE_SHIFT) | (((uint)(entryIndex)) & ENTRY_MASK) ); + } + + public override bool Equals(object value) { + if (value is UsageEntryRef) { + return _ref == ((UsageEntryRef)value)._ref; + } + + return false; + } + +#if NOT_USED + public static bool Equals(UsageEntryRef r1, UsageEntryRef r2) { + return r1._ref == r2._ref; + } +#endif + public static bool operator ==(UsageEntryRef r1, UsageEntryRef r2) { + return r1._ref == r2._ref; + } + + public static bool operator !=(UsageEntryRef r1, UsageEntryRef r2) { + return r1._ref != r2._ref; + } + + public override int GetHashCode() { + return (int) _ref; + } + +#if DBG + public override string ToString() { + if (IsRef1) { + return PageIndex + ":" + Ref1Index; + } + else if (IsRef2) { + return PageIndex + ":" + -Ref2Index; + } + else { + return "0"; + } + } +#endif + + // The index into the UsageBucket._pages array. + internal int PageIndex { + get { + int result = (int) (_ref >> PAGE_SHIFT); + return result; + } + } + + + // The index for UsageEntry._ref1 in the UsagePage._entries array. + internal int Ref1Index { + get { + int result = (int) (sbyte) (_ref & ENTRY_MASK); + Debug.Assert(result > 0, "result > 0"); + return result; + } + } + + // The index for UsageEntry._ref2 in the UsagePage._entries array. + internal int Ref2Index { + get { + int result = (int) (sbyte) (_ref & ENTRY_MASK); + Debug.Assert(result < 0, "result < 0"); + return -result; + } + } + + // Is the reference for the first reference? + internal bool IsRef1 { + get { + return ((int) (sbyte) (_ref & ENTRY_MASK)) > 0; + } + } + + // Is the reference for the second reference? + internal bool IsRef2 { + get { + return ((int) (sbyte) (_ref & ENTRY_MASK)) < 0; + } + } + + // Is the reference invalid? + internal bool IsInvalid { + get { + return _ref == 0; + } + } + } + + // A link to an item in the last references list. + struct UsageEntryLink { + internal UsageEntryRef _next; + internal UsageEntryRef _prev; + } + + // A cache entry in the LRU2 list. It contains the pointer to the + // cache entry, the date it was added to the list, and the links + // to the first and second references to the item in the list. + [StructLayout(LayoutKind.Explicit)] + struct UsageEntry { + // The entry's first reference in the last reference list. + // _ref1._next is also used for the following purposes when + // the entry is not on the last reference list: + // * As a link in the free entry list for a page. + // * As a link in the list of items to flush in FlushUnderUsedItems. + // + [FieldOffset(0)] + internal UsageEntryLink _ref1; + + // _entries[0]._ref1._next is used to hold the head of the free entries + // list. We use the space in _ref1._prev to hold the number + // of free entries in the list. + [FieldOffset(4)] + internal int _cFree; + + // The entry's second reference in the last reference list. + [FieldOffset(8)] + internal UsageEntryLink _ref2; + + // The date the entry was added to the list. + // If the date is 0 (DateTime.MinValue), the entry is free. + [FieldOffset(16)] + internal DateTime _utcDate; + + // The cache entry. + [FieldOffset(24)] + internal CacheEntry _cacheEntry; + } + + // A page to hold the array of UsageEntry. + struct UsagePage { + internal UsageEntry[] _entries; // array of UsagEntry. + internal int _pageNext; // next page on the free page or free entry list + internal int _pagePrev; // prev page on the free page or free entry list + } + + // A list of UsagePages. + struct UsagePageList { + internal int _head; // head of list + internal int _tail; // tail of list + } + + sealed class UsageBucket { + // We cannot use array index 0 for entries, because we need an array index to + // be different than its negation, and -0 = 0. + // We use _entries[0] to hold the head of the free list, and the size of the free list. + internal const int NUM_ENTRIES = 127; + const int LENGTH_ENTRIES = 128; + + const int MIN_PAGES_INCREMENT = 10; + const int MAX_PAGES_INCREMENT = 340; // (size of a page on x86) / (12 bytes per UsagePage) + const double MIN_LOAD_FACTOR = 0.5; // minimum ratio of used to total entries before we will reduce + + CacheUsage _cacheUsage; // parent usage object + byte _bucket; // priority of this bucket + + UsagePage[] _pages; // list of pages + int _cEntriesInUse; // count of UsageEntry's in use + int _cPagesInUse; // count of UsagePage's in use + int _cEntriesInFlush; // count of UsageEntry's in process of being flushed + int _minEntriesInUse; // minimum number of entries in use before we reduce + + UsagePageList _freePageList; // list of free pages (_entries == null) + UsagePageList _freeEntryList; // list of pages with free entries (entry.FreeCountCount > 0) + + UsageEntryRef _lastRefHead; // head of list of last refs + UsageEntryRef _lastRefTail; // tail of list of last refs + UsageEntryRef _addRef2Head; // head of ref2 list + + bool _blockReduce; // block calls to Reduce() while in FlushUnderUsedItems + + + internal UsageBucket(CacheUsage cacheUsage, byte bucket) { + _cacheUsage = cacheUsage; + _bucket = bucket; + InitZeroPages(); + } + + void InitZeroPages() { + Debug.Assert(_cPagesInUse == 0, "_cPagesInUse == 0"); + Debug.Assert(_cEntriesInUse == 0, "_cEntriesInUse == 0"); + Debug.Assert(_cEntriesInFlush == 0, "_cEntriesInFlush == 0"); + Debug.Assert(_lastRefHead.IsInvalid, "_lastRefHead.IsInvalid"); + Debug.Assert(_lastRefTail.IsInvalid, "_lastRefTail.IsInvalid"); + Debug.Assert(_addRef2Head.IsInvalid, "_addRef2Head.IsInvalid"); + + _pages = null; + _minEntriesInUse = -1; + _freePageList._head = -1; + _freePageList._tail = -1; + _freeEntryList._head = -1; + _freeEntryList._tail = -1; + } + + +// Use macros so that the code is inlined in the function +#define EntriesI(i) (_pages[(i)]._entries) + +#define EntriesR(entryRef) (_pages[(entryRef.PageIndex)]._entries) + +#define PagePrev(i) (_pages[(i)]._pagePrev) + +#define PageNext(i) (_pages[(i)]._pageNext) + +#define FreeEntryHead(entries) ((entries)[0]._ref1._next) + +#define FreeEntryCount(entries) ((entries)[0]._cFree) + +#define CreateRef1(entryRef) (new UsageEntryRef((entryRef).PageIndex, (entryRef).Ref2Index)) + +#define CreateRef2(entryRef) (new UsageEntryRef((entryRef).PageIndex, -(entryRef).Ref1Index)) + + +#if DBG + bool EntryIsFree(UsageEntryRef entryRef) { + return EntriesR(entryRef)[entryRef.Ref1Index]._cacheEntry == null && + EntriesR(entryRef)[entryRef.Ref1Index]._utcDate == DateTime.MinValue; + } + + bool EntryIsUsed(UsageEntryRef entryRef) { + if (entryRef.IsRef1) { + return EntriesR(entryRef)[entryRef.Ref1Index]._cacheEntry != null && + EntriesR(entryRef)[entryRef.Ref1Index]._utcDate != DateTime.MinValue; + } + else { + return EntriesR(entryRef)[entryRef.Ref2Index]._cacheEntry != null && + EntriesR(entryRef)[entryRef.Ref2Index]._utcDate != DateTime.MinValue; + } + } +#endif + + // Add a page to the head of a list. + void AddToListHead(int pageIndex, ref UsagePageList list) { + Debug.Assert((list._head == -1) == (list._tail == -1), "(list._head == -1) == (list._tail == -1)"); + + PagePrev(pageIndex) = -1; + PageNext(pageIndex) = list._head; + if (list._head != -1) { + Debug.Assert(PagePrev(list._head) == -1, "PagePrev(list._head) == -1"); + PagePrev(list._head) = pageIndex; + } + else { + list._tail = pageIndex; + } + + list._head = pageIndex; + } + + // Add a page to the tail of a list. + void AddToListTail(int pageIndex, ref UsagePageList list) { + Debug.Assert((list._head == -1) == (list._tail == -1), "(list._head == -1) == (list._tail == -1)"); + + PageNext(pageIndex) = -1; + PagePrev(pageIndex) = list._tail; + if (list._tail != -1) { + Debug.Assert(PageNext(list._tail) == -1, "PageNext(list._tail) == -1"); + PageNext(list._tail) = pageIndex; + } + else { + list._head = pageIndex; + } + + list._tail = pageIndex; + } + + // Remove a page from the head of a list. + int RemoveFromListHead(ref UsagePageList list) { + Debug.Assert(list._head != -1, "list._head != -1"); + + int oldHead = list._head; + RemoveFromList(oldHead, ref list); + return oldHead; + } + + // Remove a page from the list. + void RemoveFromList(int pageIndex, ref UsagePageList list) { + Debug.Assert((list._head == -1) == (list._tail == -1), "(list._head == -1) == (list._tail == -1)"); + + if (PagePrev(pageIndex) != -1) { + Debug.Assert(PageNext(PagePrev(pageIndex)) == pageIndex, "PageNext(PagePrev(pageIndex)) == pageIndex"); + PageNext(PagePrev(pageIndex)) = PageNext(pageIndex); + } + else { + Debug.Assert(list._head == pageIndex, "list._head == pageIndex"); + list._head = PageNext(pageIndex); + } + + if (PageNext(pageIndex) != -1) { + Debug.Assert(PagePrev(PageNext(pageIndex)) == pageIndex, "PagePrev(PageNext(pageIndex)) == pageIndex"); + PagePrev(PageNext(pageIndex)) = PagePrev(pageIndex); + } + else { + Debug.Assert(list._tail == pageIndex, "list._tail == pageIndex"); + list._tail = PagePrev(pageIndex); + } + + PagePrev(pageIndex) = -1; + PageNext(pageIndex) = -1; + } + + // Move a page to the head of the list + void MoveToListHead(int pageIndex, ref UsagePageList list) { + Debug.Assert(list._head != -1, "list._head != -1"); + Debug.Assert(list._tail != -1, "list._tail != -1"); + + // already at head? + if (list._head == pageIndex) + return; + + // remove from list + RemoveFromList(pageIndex, ref list); + + // add to head + AddToListHead(pageIndex, ref list); + } + + // Move to the tail of the list + void MoveToListTail(int pageIndex, ref UsagePageList list) { + Debug.Assert(list._head != -1, "list._head != -1"); + Debug.Assert(list._tail != -1, "list._tail != -1"); + + // already at tail? + if (list._tail == pageIndex) + return; + + // remove from list + RemoveFromList(pageIndex, ref list); + + // add to head + AddToListTail(pageIndex, ref list); + } + + // Update _minEntriesInUse when _cPagesInUse changes. + // When _cEntriesInUse falls below _minEntriesInUse, + // a call to Reduce() will consolidate entries onto fewer pages. + // If _minEntries == -1, then a call to Reduce() will never reduce the number of pages. + void UpdateMinEntries() { + if (_cPagesInUse <= 1) { + _minEntriesInUse = -1; + } + else { + int capacity = _cPagesInUse * NUM_ENTRIES; + Debug.Assert(capacity > 0, "capacity > 0"); + Debug.Assert(MIN_LOAD_FACTOR < 1.0, "MIN_LOAD_FACTOR < 1.0"); + + _minEntriesInUse = (int) (capacity * MIN_LOAD_FACTOR); + + // Don't allow a reduce if there are not enough free entries to + // remove a page. + // Note: _minEntriesInUse - 1 == max # of entries still in use when Reduce() happens + // (_cPagesInUse - 1) * NUM_ENTRIES == capacity after one page is freed + if ((_minEntriesInUse - 1) > ((_cPagesInUse - 1) * NUM_ENTRIES)) { + _minEntriesInUse = -1; + } + } + +#if DBG + if (Debug.IsTagPresent("CacheUsageNoReduce") && Debug.IsTagEnabled("CacheUsageNoReduce")) { + _minEntriesInUse = -1; + } +#endif + + } + + // Remove a UsagePage that is in use, and put in on the list of free pages. + void RemovePage(int pageIndex) { + Debug.Assert(FreeEntryCount(EntriesI(pageIndex)) == NUM_ENTRIES, "FreeEntryCount(EntriesI(pageIndex)) == NUM_ENTRIES"); + + // release the page from the free entries list + RemoveFromList(pageIndex, ref _freeEntryList); + + // Add the page to the free pages list + AddToListHead(pageIndex, ref _freePageList); + + // remove reference to page + Debug.Assert(EntriesI(pageIndex) != null, "EntriesI(pageIndex) != null"); + EntriesI(pageIndex) = null; + + // decrement count of pages and update _cMinEntriesInUse + _cPagesInUse--; + if (_cPagesInUse == 0) { + InitZeroPages(); + } + else { + UpdateMinEntries(); + } + } + +#if DBG + UsageEntryRef GetLastRefNext(UsageEntryRef entryRef) { + if (entryRef.IsRef1) { + return EntriesR(entryRef)[entryRef.Ref1Index]._ref1._next; + } + else if (entryRef.IsRef2) { + return EntriesR(entryRef)[entryRef.Ref2Index]._ref2._next; + } + else { + return _lastRefHead; + } + } + + UsageEntryRef GetLastRefPrev(UsageEntryRef entryRef) { + if (entryRef.IsRef1) { + return EntriesR(entryRef)[entryRef.Ref1Index]._ref1._prev; + } + else if (entryRef.IsRef2) { + return EntriesR(entryRef)[entryRef.Ref2Index]._ref2._prev; + } + else { + return _lastRefTail; + } + } +#endif + + // Set the _next reference in the last reference list. + // We must do this with a macro to force inlining. +#define SetLastRefNext(entryRef, next) { \ + if ((entryRef).IsRef1) { \ + EntriesR((entryRef))[(entryRef).Ref1Index]._ref1._next = (next); \ + } \ + else if ((entryRef).IsRef2) { \ + EntriesR((entryRef))[(entryRef).Ref2Index]._ref2._next = (next); \ + } \ + else { \ + _lastRefHead = (next); \ + } \ + } \ + + // Set the _prev reference in the last reference list. + // We must do this with a macro to force inlining. +#define SetLastRefPrev(entryRef, prev) { \ + if ((entryRef).IsRef1) { \ + EntriesR((entryRef))[(entryRef).Ref1Index]._ref1._prev = (prev); \ + } \ + else if ((entryRef).IsRef2) { \ + EntriesR((entryRef))[(entryRef).Ref2Index]._ref2._prev = (prev); \ + } \ + else { \ + _lastRefTail = (prev); \ + } \ + } \ + + // Get a free UsageEntry. + UsageEntryRef GetFreeUsageEntry() { + // get the page of the free entry + Debug.Assert(_freeEntryList._head >= 0, "_freeEntryList._head >= 0"); + int pageIndex = _freeEntryList._head; + + // get a free entry from _entries + UsageEntry[] entries = EntriesI(pageIndex); + int entryIndex = FreeEntryHead(entries).Ref1Index; + + // fixup free list and count + FreeEntryHead(entries) = entries[entryIndex]._ref1._next; + FreeEntryCount(entries)--; + if (FreeEntryCount(entries) == 0) { + // remove page from list of free pages + Debug.Assert(FreeEntryHead(entries).IsInvalid, "FreeEntryHead(entries).IsInvalid"); + RemoveFromList(pageIndex, ref _freeEntryList); + } + +#if DBG + Debug.Assert(EntryIsFree(new UsageEntryRef(pageIndex, entryIndex)), "EntryIsFree(new UsageEntryRef(pageIndex, entryIndex))"); + if (!FreeEntryHead(entries).IsInvalid) { + Debug.Assert(FreeEntryHead(entries).Ref1Index != entryIndex, "FreeEntryHead(entries).Ref1Index != entryIndex"); + Debug.Assert(EntryIsFree(new UsageEntryRef(pageIndex, FreeEntryHead(entries).Ref1Index)), "EntryIsFree(new UsageEntryRef(pageIndex, FreeEntryHead(entries).Ref1Index))"); + } +#endif + + return new UsageEntryRef(pageIndex, entryIndex); + } + + // Add a UsageEntry to the free entry list. + void AddUsageEntryToFreeList(UsageEntryRef entryRef) { + Debug.Assert(entryRef.IsRef1, "entryRef.IsRef1"); + + UsageEntry[] entries = EntriesR(entryRef); + int entryIndex = entryRef.Ref1Index; + + Debug.Assert(entries[entryIndex]._cacheEntry == null, "entries[entryIndex]._cacheEntry == null"); + entries[entryIndex]._utcDate = DateTime.MinValue; + entries[entryIndex]._ref1._prev = UsageEntryRef.INVALID; + entries[entryIndex]._ref2._next = UsageEntryRef.INVALID; + entries[entryIndex]._ref2._prev = UsageEntryRef.INVALID; + + entries[entryIndex]._ref1._next = FreeEntryHead(entries); + FreeEntryHead(entries) = entryRef; + + _cEntriesInUse--; + int pageIndex = entryRef.PageIndex; + FreeEntryCount(entries)++; + if (FreeEntryCount(entries) == 1) { + // add page to head of list of free pages + AddToListHead(pageIndex, ref _freeEntryList); + } + else if (FreeEntryCount(entries) == NUM_ENTRIES) { + RemovePage(pageIndex); + } + } + + // Expand the capacity of the UsageBucket to hold more CacheEntry's. + // We will need to allocate a new page, and perhaps expand the _pages array. + // Note that we never collapse the _pages array. + void Expand() { + Debug.Assert(_cPagesInUse * NUM_ENTRIES == _cEntriesInUse, "_cPagesInUse * NUM_ENTRIES == _cEntriesInUse"); + Debug.Assert(_freeEntryList._head == -1, "_freeEntryList._head == -1"); + Debug.Assert(_freeEntryList._tail == -1, "_freeEntryList._tail == -1"); + + // exapnd _pages if there are no more + if (_freePageList._head == -1) { + // alloc new pages array + int oldLength; + if (_pages == null) { + oldLength = 0; + } + else { + oldLength = _pages.Length; + } + + Debug.Assert(_cPagesInUse == oldLength, "_cPagesInUse == oldLength"); + Debug.Assert(_cEntriesInUse == oldLength * NUM_ENTRIES, "_cEntriesInUse == oldLength * ExpiresEntryRef.NUM_ENTRIES"); + + int newLength = oldLength * 2; + newLength = Math.Max(oldLength + MIN_PAGES_INCREMENT, newLength); + newLength = Math.Min(newLength, oldLength + MAX_PAGES_INCREMENT); + Debug.Assert(newLength > oldLength, "newLength > oldLength"); + + UsagePage[] newPages = new UsagePage[newLength]; + + // copy original pages + for (int i = 0; i < oldLength; i++) { + newPages[i] = _pages[i]; + } + + // setup free list of new pages + for (int i = oldLength; i < newPages.Length; i++) { + newPages[i]._pagePrev = i - 1; + newPages[i]._pageNext = i + 1; + } + + newPages[oldLength]._pagePrev = -1; + newPages[newPages.Length - 1]._pageNext = -1; + + // use new pages array + _freePageList._head = oldLength; + _freePageList._tail = newPages.Length - 1; + + _pages = newPages; + } + + // move from free page list to free entries list + int pageIndex = RemoveFromListHead(ref _freePageList); + AddToListHead(pageIndex, ref _freeEntryList); + + // create the entries + UsageEntry[] entries = new UsageEntry[LENGTH_ENTRIES]; + FreeEntryCount(entries) = NUM_ENTRIES; + + // init free list + for (int i = 0; i < entries.Length - 1; i++) { + entries[i]._ref1._next = new UsageEntryRef(pageIndex, i + 1); + } + entries[entries.Length - 1]._ref1._next = UsageEntryRef.INVALID; + + EntriesI(pageIndex) = entries; + + // increment count of pages and update _minEntriesInUse + _cPagesInUse++; + UpdateMinEntries(); + } + + // Consolidate UsageEntry's onto fewer pages when there are too many + // free entries. + void Reduce() { + // Test if we need to consolidate. + if (_cEntriesInUse >= _minEntriesInUse || _blockReduce) + return; + + Debug.Assert(_freeEntryList._head != -1, "_freeEntryList._head != -1"); + Debug.Assert(_freeEntryList._tail != -1, "_freeEntryList._tail != -1"); + Debug.Assert(_freeEntryList._head != _freeEntryList._tail, "_freeEntryList._head != _freeEntryList._tail"); + + // Rearrange free page list to put pages with more free entries at the tail + int meanFree = (int) (NUM_ENTRIES - (NUM_ENTRIES * MIN_LOAD_FACTOR)); + int pageIndexLast = _freeEntryList._tail; + int pageIndexCurrent = _freeEntryList._head; + int pageIndexNext; + UsageEntry[] entries; + + for (;;) { + pageIndexNext = PageNext(pageIndexCurrent); + + // move pages with greater than mean number + // of free items to tail, move the others to head + if (FreeEntryCount(EntriesI(pageIndexCurrent)) > meanFree) { + MoveToListTail(pageIndexCurrent, ref _freeEntryList); + } + else { + MoveToListHead(pageIndexCurrent, ref _freeEntryList); + } + + // check if entire list has been examined + if (pageIndexCurrent == pageIndexLast) + break; + + // iterate + pageIndexCurrent = pageIndexNext; + } + + // Move entries from the free pages at the tail to the + // free pages at the front, and release the free pages at the tail. + for (;;) { + // See if there is room left to move entries used by the page. + if (_freeEntryList._tail == -1) + break; + + entries = EntriesI(_freeEntryList._tail); + Debug.Assert(FreeEntryCount(entries) > 0, "FreeEntryCount(entries) > 0"); + int availableFreeEntries = (_cPagesInUse * NUM_ENTRIES) - FreeEntryCount(entries) - _cEntriesInUse; + if (availableFreeEntries < (NUM_ENTRIES - FreeEntryCount(entries))) + break; + + // Move each entry from the page at the tail to a page at the head. + for (int i = 1; i < entries.Length; i++) { + // skip the free entries + if (entries[i]._cacheEntry == null) + continue; + + // get a free UsageEntry from the head of the list. + Debug.Assert(_freeEntryList._head != _freeEntryList._tail, "_freeEntryList._head != _freeEntryList._tail"); + UsageEntryRef newRef1 = GetFreeUsageEntry(); + UsageEntryRef newRef2 = CreateRef2(newRef1); + Debug.Assert(newRef1.PageIndex != _freeEntryList._tail, "newRef1.PageIndex != _freeEntryList._tail"); + + UsageEntryRef oldRef1 = new UsageEntryRef(_freeEntryList._tail, i); + UsageEntryRef oldRef2 = CreateRef2(oldRef1); + + // update the CacheEntry + CacheEntry cacheEntry = entries[i]._cacheEntry; + Debug.Assert(cacheEntry.UsageEntryRef == oldRef1, "cacheEntry.UsageEntryRef == oldRef1"); + cacheEntry.UsageEntryRef = newRef1; + + // copy old entry to new entry + UsageEntry[] newEntries = EntriesR(newRef1); + newEntries[newRef1.Ref1Index] = entries[i]; + + // Update free entry count for debugging. We don't bother + // to fix up the free entry list for this page as we are + // going to release the page. + FreeEntryCount(entries)++; + + // Update the last ref list. We need to be careful when + // references to the entry refer to the same entry. + + // ref1 + UsageEntryRef prev = newEntries[newRef1.Ref1Index]._ref1._prev; + Debug.Assert(prev != oldRef2, "prev != oldRef2"); + + UsageEntryRef next = newEntries[newRef1.Ref1Index]._ref1._next; + if (next == oldRef2) { + next = newRef2; + } + +#if DBG + Debug.Assert(GetLastRefNext(prev) == oldRef1, "GetLastRefNext(prev) == oldRef1"); + Debug.Assert(GetLastRefPrev(next) == oldRef1, "GetLastRefPrev(next) == oldRef1"); +#endif + + SetLastRefNext(prev, newRef1); + SetLastRefPrev(next, newRef1); + + // ref2 + prev = newEntries[newRef1.Ref1Index]._ref2._prev; + if (prev == oldRef1) { + prev = newRef1; + } + + next = newEntries[newRef1.Ref1Index]._ref2._next; + Debug.Assert(next != oldRef1, "next != oldRef1"); + +#if DBG + Debug.Assert(GetLastRefNext(prev) == oldRef2, "GetLastRefNext(prev) == oldRef2"); + Debug.Assert(GetLastRefPrev(next) == oldRef2, "GetLastRefPrev(next) == oldRef2"); +#endif + + SetLastRefNext(prev, newRef2); + SetLastRefPrev(next, newRef2); + + // _addRef2Head + if (_addRef2Head == oldRef2) { + _addRef2Head = newRef2; + } + } + + // now the page is free - release its memory + RemovePage(_freeEntryList._tail); + + Debug.Validate("CacheValidateUsage", this); + } + } + + // Add a new UsageEntry for a CacheEntry. + internal void AddCacheEntry(CacheEntry cacheEntry) { + lock (this) { + // Expand if there are no free UsageEntry's available. + if (_freeEntryList._head == -1) { + Expand(); + } + + // get the free entry + UsageEntryRef freeRef1 = GetFreeUsageEntry(); + UsageEntryRef freeRef2 = CreateRef2(freeRef1); + Debug.Assert(cacheEntry.UsageEntryRef.IsInvalid, "cacheEntry.UsageEntryRef.IsInvalid"); + cacheEntry.UsageEntryRef = freeRef1; + + // initialize index + UsageEntry[] entries = EntriesR(freeRef1); + int entryIndex = freeRef1.Ref1Index; + entries[entryIndex]._cacheEntry = cacheEntry; + entries[entryIndex]._utcDate = DateTime.UtcNow; + + // add ref1 to head of entire list, ref2 to head of new ref2 list +#if DBG + Debug.Assert(!_addRef2Head.IsRef1, "!_addRef2Head.IsRef1"); + Debug.Assert(!_lastRefTail.IsRef1, "!_lastRefTail.IsRef1"); + Debug.Assert(!_lastRefHead.IsRef2, "!_lastRefHead.IsRef2"); + Debug.Assert(_lastRefTail.IsInvalid == _lastRefHead.IsInvalid, "_lastRefTail.IsInvalid == _lastRefHead.IsInvalid"); + Debug.Assert(!_lastRefTail.IsInvalid || _addRef2Head.IsInvalid, "!_lastRefTail.IsInvalid || _addRef2Head.IsInvalid"); + Debug.Assert(GetLastRefNext(_lastRefTail).IsInvalid, "GetLastRefNext(_lastRefTail).IsInvalid"); + Debug.Assert(GetLastRefPrev(_lastRefHead).IsInvalid, "GetLastRefPrev(_lastRefHead).IsInvalid"); +#endif + + entries[entryIndex]._ref1._prev = UsageEntryRef.INVALID; + entries[entryIndex]._ref2._next = _addRef2Head; + if (_lastRefHead.IsInvalid) { + entries[entryIndex]._ref1._next = freeRef2; + entries[entryIndex]._ref2._prev = freeRef1; + _lastRefTail = freeRef2; + } + else { + entries[entryIndex]._ref1._next = _lastRefHead; + SetLastRefPrev(_lastRefHead, freeRef1); + + UsageEntryRef next, prev; + if (_addRef2Head.IsInvalid) { + prev = _lastRefTail; + next = UsageEntryRef.INVALID; + } + else { + prev = EntriesR(_addRef2Head)[_addRef2Head.Ref2Index]._ref2._prev; + next = _addRef2Head; + } + + entries[entryIndex]._ref2._prev = prev; + SetLastRefNext(prev, freeRef2); + SetLastRefPrev(next, freeRef2); + } + + _lastRefHead = freeRef1; + _addRef2Head = freeRef2; + + _cEntriesInUse++; + + Debug.Trace("CacheUsageAdd", + "Added item=" + cacheEntry.Key + + ",_bucket=" + _bucket + + ",ref=" + freeRef1); + + Debug.Validate("CacheValidateUsage", this); + Debug.Dump("CacheUsageAdd", this); + } + } + + // Remove an entry from the last references list. + void RemoveEntryFromLastRefList(UsageEntryRef entryRef) { + Debug.Assert(entryRef.IsRef1, "entryRef.IsRef1"); + UsageEntry[] entries = EntriesR(entryRef); + int entryIndex = entryRef.Ref1Index; + + // remove ref1 from list + UsageEntryRef prev = entries[entryIndex]._ref1._prev; + UsageEntryRef next = entries[entryIndex]._ref1._next; + +#if DBG + Debug.Assert(GetLastRefNext(prev) == entryRef, "GetLastRefNext(prev) == entryRef"); + Debug.Assert(GetLastRefPrev(next) == entryRef, "GetLastRefPrev(next) == entryRef"); +#endif + + SetLastRefNext(prev, next); + SetLastRefPrev(next, prev); + + // remove ref2 from list + prev = entries[entryIndex]._ref2._prev; + next = entries[entryIndex]._ref2._next; + + UsageEntryRef entryRef2 = CreateRef2(entryRef); + +#if DBG + Debug.Assert(GetLastRefNext(prev) == entryRef2, "GetLastRefNext(prev) == entryRef2"); + Debug.Assert(GetLastRefPrev(next) == entryRef2, "GetLastRefPrev(next) == entryRef2"); +#endif + + SetLastRefNext(prev, next); + SetLastRefPrev(next, prev); + + // fixup _addRef2Head + if (_addRef2Head == entryRef2) { + _addRef2Head = next; + } + } + + // Remove a CacheEntry from the UsageBucket. + internal void RemoveCacheEntry(CacheEntry cacheEntry) { + lock (this) { + // The cache entry could have been removed from the cache while + // we are in the middle of FlushUnderUsedItems, after we have + // released the lock and before we ourselves call Cache.Remove(). + // Guard against that here. + UsageEntryRef entryRef = cacheEntry.UsageEntryRef; + if (entryRef.IsInvalid) + return; + + UsageEntry[] entries = EntriesR(entryRef); + int entryIndex = entryRef.Ref1Index; + +#if DBG + Debug.Assert(entryRef.IsRef1, "entryRef.IsRef1"); + Debug.Assert(EntryIsUsed(entryRef), "EntryIsUsed(entryRef)"); + Debug.Assert(cacheEntry == entries[entryIndex]._cacheEntry, "cacheEntry == entries[entryIndex]._cacheEntry"); +#endif + + // update the cache entry + cacheEntry.UsageEntryRef = UsageEntryRef.INVALID; + entries[entryIndex]._cacheEntry = null; + + // remove from last ref list + RemoveEntryFromLastRefList(entryRef); + + // add to free list + AddUsageEntryToFreeList(entryRef); + + // remove pages if necessary + Reduce(); + + Debug.Trace("CacheUsageRemove", + "Removed item=" + cacheEntry.Key + + ",_bucket=" + _bucket + + ",ref=" + entryRef); + + Debug.Validate("CacheValidateUsage", this); + Debug.Dump("CacheUsageRemove", this); + } + } + + // Update the CacheEntry in the last references list. + internal void UpdateCacheEntry(CacheEntry cacheEntry) { + lock (this) { + // The cache entry could have been retreived from the cache while + // we are in the middle of FlushUnderUsedItems, after we have + // released the lock and before we ourselves call Cache.Remove(). + // Guard against that here. + UsageEntryRef entryRef = cacheEntry.UsageEntryRef; + if (entryRef.IsInvalid) + return; + +#if DBG + Debug.Assert(entryRef.IsRef1, "entryRef.IsRef1"); + Debug.Assert(EntryIsUsed(entryRef), "EntryIsUsed(entryRef)"); + Debug.Assert(!_lastRefHead.IsInvalid, "!_lastRefHead.IsInvalid"); + Debug.Assert(!_lastRefTail.IsInvalid, "!_lastRefTail.IsInvalid"); +#endif + + UsageEntry[] entries = EntriesR(entryRef); + int entryIndex = entryRef.Ref1Index; + UsageEntryRef entryRef2 = CreateRef2(entryRef); + + // remove ref2 from list + UsageEntryRef prev = entries[entryIndex]._ref2._prev; + UsageEntryRef next = entries[entryIndex]._ref2._next; + +#if DBG + Debug.Assert(GetLastRefNext(prev) == entryRef2, "GetLastRefNext(prev) == entryRef2"); + Debug.Assert(GetLastRefPrev(next) == entryRef2, "GetLastRefPrev(next) == entryRef2"); +#endif + + SetLastRefNext(prev, next); + SetLastRefPrev(next, prev); + + // fixup _addRef2Head + if (_addRef2Head == entryRef2) { + _addRef2Head = next; + } + + // move ref1 to ref2 + entries[entryIndex]._ref2 = entries[entryIndex]._ref1; + prev = entries[entryIndex]._ref2._prev; + next = entries[entryIndex]._ref2._next; + +#if DBG + Debug.Assert(GetLastRefNext(prev) == entryRef, "GetLastRefNext(prev) == entryRef"); + Debug.Assert(GetLastRefPrev(next) == entryRef, "GetLastRefPrev(next) == entryRef"); +#endif + + SetLastRefNext(prev, entryRef2); + SetLastRefPrev(next, entryRef2); + + // put ref1 at head of list + entries[entryIndex]._ref1._prev = UsageEntryRef.INVALID; + entries[entryIndex]._ref1._next = _lastRefHead; + +#if DBG + Debug.Assert(GetLastRefPrev(_lastRefHead).IsInvalid, "GetLastRefPrev(_lastRefHead).IsInvalid"); +#endif + + SetLastRefPrev(_lastRefHead, entryRef); + _lastRefHead = entryRef; + + Debug.Trace("CacheUsageUpdate", + "Updated item=" + cacheEntry.Key + + ",_bucket=" + _bucket + + ",ref=" + entryRef); + + Debug.Validate("CacheValidateUsage", this); + Debug.Dump("CacheUsageUpdate", this); + } + } + + // Flush under used items from the cache. + // If force is false, then we will skip items that have not aged enough + // to accumulate history. + // publicEntriesFlushed keeps track of the number of public entries that are flushed + internal int FlushUnderUsedItems(int maxFlush, bool force, ref int publicEntriesFlushed, ref int ocEntriesFlushed) { +#if DBG + if (Debug.IsTagPresent("CacheUsageNoFlush") && Debug.IsTagEnabled("CacheUsageNoFlush")) + return 0; +#endif + + // Check if there is something to flush + if (_cEntriesInUse == 0) + return 0; + + Debug.Assert(maxFlush > 0, "maxFlush is not greater than 0, instead is " + maxFlush); + Debug.Assert(_cEntriesInFlush == 0, "_cEntriesInFlush == 0"); + + // We create a list of UsageEntry's that we wish to flush. These entries + // are not considered free, so the page that holds them will not be removed. + // inFlushHead will point to the head of that list, while we use the same + // UsageEntry._ref1 to chain them together (after we remove them from + // the LastRef list.) + UsageEntryRef inFlushHead = UsageEntryRef.INVALID; + + UsageEntryRef prev, prevNext; + DateTime utcDate; + UsageEntry[] entries; + int entryIndex; + CacheEntry cacheEntry; + int flushed = 0; + + try { + // Block insertion into the Cache if we're under high memory pressure + _cacheUsage.CacheSingle.BlockInsertIfNeeded(); + + lock (this) { + Debug.Assert(_blockReduce == false, "_blockReduce == false"); + + // Recheck if there is something to flush. + if (_cEntriesInUse == 0) + return 0; + + DateTime utcNow = DateTime.UtcNow; + + // Walk the ref2 list backwards, as these are the items that have + // been used least. + for (prev = _lastRefTail; _cEntriesInFlush < maxFlush && !prev.IsInvalid; prev = prevNext) { + Debug.Assert(_cEntriesInUse > 0, "_cEntriesInUse > 0"); + + // Set prevNext before possibly freeing an item. + // Examine only at ref2 items so we don't enumerate an + // item twice. + prevNext = EntriesR(prev)[prev.Ref2Index]._ref2._prev; + while (prevNext.IsRef1) { + prevNext = EntriesR(prevNext)[prevNext.Ref1Index]._ref1._prev; + } + +#if DBG + Debug.Assert(prev.IsRef2, "prev.IsRef2"); + Debug.Assert(EntryIsUsed(prev), "EntryIsUsed(prev)"); + Debug.Assert(EntryIsUsed(prev), "EntryIsUsed(prev)"); +#endif + + entries = EntriesR(prev); + entryIndex = prev.Ref2Index; + + // Do not remove an item if it was recently added to the last references list, + // as it has not had enough time to accumulate usage history. + if (!force) { + utcDate = entries[entryIndex]._utcDate; + Debug.Assert(utcDate != DateTime.MinValue, "utcDate != DateTime.MinValue"); + + if (utcNow - utcDate <= CacheUsage.NEWADD_INTERVAL && utcNow >= utcDate) + continue; + } + + UsageEntryRef prev1 = CreateRef1(prev); + cacheEntry = entries[entryIndex]._cacheEntry; + Debug.Assert(cacheEntry.UsageEntryRef == prev1, "cacheEntry.UsageEntryRef == prev1"); + Debug.Trace("CacheUsageFlushUnderUsedItem", "Flushing underused items, item=" + cacheEntry.Key + ", bucket=" + _bucket); + + // Remove reference from CacheEntry. We must do this before we + // release the lock, otherwise the item would be corrupted if + // UpdateCacheEntry or RemoveCacheEntry were called. + cacheEntry.UsageEntryRef = UsageEntryRef.INVALID; + + // Keep track of how many public entries were flushed + if (cacheEntry.IsPublic) { + publicEntriesFlushed ++; + } + else if (cacheEntry.IsOutputCache) { + ocEntriesFlushed++; + } + + // remove from lastref list + RemoveEntryFromLastRefList(prev1); + + // add it to the inFlush list + entries[entryIndex]._ref1._next = inFlushHead; + inFlushHead = prev1; + + flushed++; + _cEntriesInFlush++; + } + + if (flushed == 0) { + Debug.Trace("CacheUsageFlushTotal", "Flush(" + maxFlush + "," + force + ") removed " + flushed + + " underused items; Time=" + Debug.FormatLocalDate(DateTime.Now)); + + return 0; + } + + + // We are about to leave the lock. However, we still have to use the + // locally created "inFlush list" after that. That's why we have to + // set _blockReduce to true to prevent Reduce() from moving the + // entries around. + _blockReduce = true; + } + } + finally { + // Don't hold any insertblock before we remove Cache items. If not, the following + // deadlock scenario may happen: + // - 3rd party code hold lock A, call Cache.Insert, which wait for the Cache insertblock + // - FlushUnderUsedItems holds the Cache insertBlock, call Cache.Remove, which call + // 3rd party CacheItemRemovedCallback, which then try to get lock A + + _cacheUsage.CacheSingle.UnblockInsert(); + } + + // We need to release the lock because when we do remove below, + // some CacheRemoveCallback user code might run that might + // do a cache insert in another thread, and will cause + // a CacheUsage insert/remove/update, we will block + // that thread, which cause a deadlock if the user code is + // waiting for that thread to finish its job. + + Debug.Assert(!inFlushHead.IsInvalid, "!inFlushHead.IsInvalid"); + + // Remove items on the inFlush list from the rest of the cache. + CacheSingle cacheSingle = _cacheUsage.CacheSingle; + UsageEntryRef current = inFlushHead; + UsageEntryRef next; + while (!current.IsInvalid) { + entries = EntriesR(current); + entryIndex = current.Ref1Index; + + next = entries[entryIndex]._ref1._next; + + // remove the entry + cacheEntry = entries[entryIndex]._cacheEntry; + entries[entryIndex]._cacheEntry = null; + Debug.Assert(cacheEntry.UsageEntryRef.IsInvalid, "cacheEntry.UsageEntryRef.IsInvalid"); + cacheSingle.Remove(cacheEntry, CacheItemRemovedReason.Underused); + + //iterate + current = next; + } + + try { + // Block insertion into the Cache if we're under high memory pressure + _cacheUsage.CacheSingle.BlockInsertIfNeeded(); + + lock (this) { + // add each UsageEntry to the free list + current = inFlushHead; + while (!current.IsInvalid) { + entries = EntriesR(current); + entryIndex = current.Ref1Index; + + next = entries[entryIndex]._ref1._next; + + _cEntriesInFlush--; + AddUsageEntryToFreeList(current); + + //iterate + current = next; + } + + // try to reduce + Debug.Assert(_cEntriesInFlush == 0, "_cEntriesInFlush == 0"); + _blockReduce = false; + Reduce(); + + Debug.Trace("CacheUsageFlushTotal", "Flush(" + maxFlush + "," + force + ") removed " + flushed + + " underused items; Time=" + Debug.FormatLocalDate(DateTime.Now)); + + Debug.Validate("CacheValidateUsage", this); + Debug.Dump("CacheUsageFlush", this); + } + } + finally { + _cacheUsage.CacheSingle.UnblockInsert(); + } + + return flushed; + } + +#if DBG + internal void DebugValidate() { + int cFree = 0; + int cEntriesInUse = 0; + int cPagesInUse = 0; + int pagesLength; + + if (_pages == null) { + pagesLength = 0; + } + else { + pagesLength = _pages.Length; + } + + Debug.CheckValid(-1 <= _freePageList._head && _freePageList._head <= pagesLength, "-1 <= _freePageList._head && _freePageList._head <= pagesLength"); + Debug.CheckValid(-1 <= _freeEntryList._head && _freeEntryList._head <= pagesLength, "-1 <= _freeEntryList._head && _freeEntryList._head <= pagesLength"); + Debug.CheckValid(-1 <= _freeEntryList._tail && _freeEntryList._tail <= pagesLength, "-1 <= _freeEntryList._tail && _freeEntryList._tail <= pagesLength"); + Debug.CheckValid((_freeEntryList._head == -1) == (_freeEntryList._tail == -1), "(_freeEntryList._head == -1) == (_freeEntryList._tail == -1)"); + Debug.CheckValid(_minEntriesInUse >= -1, "_minEntriesInUse >= -1"); + Debug.CheckValid(_lastRefHead.IsInvalid == _lastRefTail.IsInvalid, "_lastRefHead.IsInvalid == _lastRefTail.IsInvalid"); + Debug.CheckValid(!_lastRefTail.IsInvalid || _addRef2Head.IsInvalid, "!_lastRefTail.IsInvalid || _addRef2Head.IsInvalid"); + Debug.CheckValid(!_lastRefHead.IsRef2, "!_lastRefHead.IsRef2"); + Debug.CheckValid(!_lastRefTail.IsRef1, "!_lastRefTail.IsRef1"); + Debug.CheckValid(!_addRef2Head.IsRef1, "!_addRef2Head.IsRef1"); + Debug.CheckValid(_cEntriesInFlush >= 0, "_cEntriesInFlush >= 0"); + + // check counts + for (int i = 0; i < pagesLength; i++) { + UsageEntry[] entries = _pages[i]._entries; + if (entries != null) { + cPagesInUse++; + cFree = 0; + + Debug.CheckValid(entries[0]._cacheEntry == null, "entries[0]._cacheEntry == null"); + Debug.CheckValid(entries[0]._utcDate == DateTime.MinValue, "entries[0]._utcDate == DateTime.MinValue"); + + for (int j = 1; j < entries.Length; j++) { + if (EntryIsFree(new UsageEntryRef(i, j))) { + cFree++; + } + else { + cEntriesInUse++; + } + } + + Debug.CheckValid(cFree == FreeEntryCount(entries), "cFree == FreeEntryCount(entries)"); + + // walk the free list + cFree = 0; + if (!FreeEntryHead(entries).IsInvalid) { + int j = FreeEntryHead(entries).Ref1Index; + for (;;) { + cFree++; + Debug.CheckValid(cFree <= FreeEntryCount(entries), "cFree <= FreeEntryCount(entries)"); + + if (entries[j]._ref1._next.IsInvalid) + break; + + j = entries[j]._ref1._next.Ref1Index; + } + } + Debug.CheckValid(cFree == FreeEntryCount(entries), "cFree == FreeEntryCount(entries)"); + } + } + + Debug.CheckValid(cPagesInUse == _cPagesInUse, "cPagesInUse == _cPagesInUse"); + Debug.CheckValid(cEntriesInUse == _cEntriesInUse, "cEntriesInUse == _cEntriesInUse"); + + // walk the free slot list + int cFreeSlots = 0; + if (_freePageList._head != -1) { + for (int i = _freePageList._head; i != -1; i = _pages[i]._pageNext) { + cFreeSlots++; + Debug.CheckValid(cFreeSlots <= pagesLength, "cFreeSlots <= pagesLength"); + Debug.CheckValid(_pages[i]._entries == null, "_pages[i]._entries == null"); + if (_freePageList._head != i) { + Debug.CheckValid(PageNext(PagePrev(i)) == i, "PageNext(PagePrev(i)) == i"); + } + + if (_freePageList._tail != i) { + Debug.CheckValid(PagePrev(PageNext(i)) == i, "PagePrev(PageNext(i)) == i"); + } + } + } + Debug.CheckValid(cFreeSlots == pagesLength - _cPagesInUse, "cFreeSlots == pagesLength - _cPagesInUse"); + + // walk the free page list + int cFreeEntries = 0; + int cFreePages = 0; + if (_freeEntryList._head != -1) { + for (int i = _freeEntryList._head; i != -1; i = _pages[i]._pageNext) { + cFreePages++; + Debug.CheckValid(cFreePages <= pagesLength, "cFreePages < pagesLength"); + UsageEntry[] entries = _pages[i]._entries; + Debug.CheckValid(entries != null, "entries != null"); + cFreeEntries += FreeEntryCount(entries); + if (_freeEntryList._head != i) { + Debug.CheckValid(PageNext(PagePrev(i)) == i, "PageNext(PagePrev(i)) == i"); + } + + if (_freeEntryList._tail != i) { + Debug.CheckValid(PagePrev(PageNext(i)) == i, "PagePrev(PageNext(i)) == i"); + } + } + } + + Debug.CheckValid(cFreeEntries == (_cPagesInUse * NUM_ENTRIES) - _cEntriesInUse, "cFreeEntries == (_cPagesInUse * NUM_ENTRIES) - _cEntriesInUse"); + + // walk last ref list forwards + int cTotalRefs = 2 * (_cEntriesInUse - _cEntriesInFlush); + int cRefs = 0; + UsageEntryRef last = UsageEntryRef.INVALID; + UsageEntryRef next = _lastRefHead; + while (!next.IsInvalid) { + cRefs++; + Debug.CheckValid(cRefs <= cTotalRefs, "cRefs <= cTotalRefs"); + Debug.CheckValid(EntryIsUsed(next), "EntryIsUsed(next)"); + Debug.CheckValid(GetLastRefPrev(next) == last, "GetLastRefPrev(next) == last"); + last = next; + next = GetLastRefNext(next); + } + + Debug.CheckValid(cRefs == cTotalRefs, "cRefs == cTotalRefs"); + + // walk list backwards + cRefs = 0; + last = UsageEntryRef.INVALID; + UsageEntryRef prev = _lastRefTail; + while (!prev.IsInvalid) { + cRefs++; + Debug.CheckValid(cRefs <= cTotalRefs, "cRefs <= cTotalRefs"); + Debug.CheckValid(EntryIsUsed(prev), "EntryIsUsed(next)"); + Debug.CheckValid(GetLastRefNext(prev) == last, "GetLastRefPrev(next) == last"); + last = prev; + prev = GetLastRefPrev(prev); + } + + Debug.CheckValid(cRefs == cTotalRefs, "cRefs == cTotalRefs"); + + // walk the add2ref list + cRefs = 0; + last = GetLastRefPrev(_addRef2Head); + next = _addRef2Head; + while (!next.IsInvalid) { + cRefs++; + Debug.CheckValid(cRefs <= (cTotalRefs / 2), "cRefs <= (cTotalRefs / 2)"); + Debug.CheckValid(EntryIsUsed(next), "EntryIsUsed(next)"); + Debug.CheckValid(GetLastRefPrev(next) == last, "GetLastRefPrev(next) == last"); + Debug.CheckValid(!next.IsRef1, "!next.IsRef1"); + last = next; + next = GetLastRefNext(next); + } + + Debug.CheckValid(cRefs <= (cTotalRefs / 2), "cRefs <= (cTotalRefs / 2)"); + } + + internal string DebugDescription(string indent) { + StringBuilder sb = new StringBuilder(); + string i2 = indent + " "; + + sb.Append(indent + + "_bucket=" + _bucket + + ",_cEntriesInUse=" + _cEntriesInUse + + ",_cPagesInUse=" + _cPagesInUse + + ",_pages is " + (_pages == null ? "null" : "non-null") + + ",_minEntriesInUse=" + _minEntriesInUse + + ",_freePageList._head=" + _freePageList._head + + ",_freeEntryList._head=" + _freeEntryList._head + + ",_freeEntryList._tail=" + _freeEntryList._tail + + "\n"); + + sb.Append(indent + "Refs list, in order:\n"); + + UsageEntryRef next = _lastRefHead; + while (!next.IsInvalid) { + if (next.IsRef1) { + sb.Append(i2 + next.PageIndex + ":" + next.Ref1Index + " (1): " + EntriesR(next)[next.Ref1Index]._cacheEntry.Key + "\n"); + } + else { + sb.Append(i2 + next.PageIndex + ":" + next.Ref2Index + " (2): " + EntriesR(next)[next.Ref2Index]._cacheEntry.Key + "\n"); + } + + next = GetLastRefNext(next); + } + + return sb.ToString(); + } +#endif + } + + class CacheUsage { + internal static readonly TimeSpan NEWADD_INTERVAL = new TimeSpan(0, 0, 10); + internal static readonly TimeSpan CORRELATED_REQUEST_TIMEOUT = new TimeSpan(0, 0, 1); + internal static readonly TimeSpan MIN_LIFETIME_FOR_USAGE = NEWADD_INTERVAL; + const byte NUMBUCKETS = (byte) (CacheItemPriority.High); + const int MAX_REMOVE = 1024; // one page of poiners to CacheEntry's + + readonly CacheSingle _cacheSingle; + internal readonly UsageBucket[] _buckets; + int _inFlush; + + internal CacheUsage(CacheSingle cacheSingle) { + Debug.Assert((int) CacheItemPriority.Low == 1, "(int) CacheItemPriority.Low == 1"); + + _cacheSingle = cacheSingle; + _buckets = new UsageBucket[NUMBUCKETS]; + for (byte b = 0; b < _buckets.Length; b++) { + _buckets[b] = new UsageBucket(this, b); + } + } + + internal CacheSingle CacheSingle { + get { + return _cacheSingle; + } + } + + internal void Add(CacheEntry cacheEntry) { + byte bucket = cacheEntry.UsageBucket; + Debug.Assert(bucket != 0xff, "bucket != 0xff"); + _buckets[bucket].AddCacheEntry(cacheEntry); + } + + internal void Remove(CacheEntry cacheEntry) { + byte bucket = cacheEntry.UsageBucket; + if (bucket != 0xff) { + _buckets[bucket].RemoveCacheEntry(cacheEntry); + } + } + + internal void Update(CacheEntry cacheEntry) { + byte bucket = cacheEntry.UsageBucket; + if (bucket != 0xff) { + _buckets[bucket].UpdateCacheEntry(cacheEntry); + } + } + + // publicEntriesFlushed keeps track of the number of public entries that are flushed + internal int FlushUnderUsedItems(int toFlush, ref int publicEntriesFlushed, ref int ocEntriesFlushed) { + int flushed = 0; + + if (Interlocked.Exchange(ref _inFlush, 1) == 0) { + try { + foreach (UsageBucket usageBucket in _buckets) { + int flushedOne = usageBucket.FlushUnderUsedItems(toFlush - flushed, + false, + ref publicEntriesFlushed, + ref ocEntriesFlushed); + flushed += flushedOne; + if (flushed >= toFlush) + break; + } + + if (flushed < toFlush) { + foreach (UsageBucket usageBucket in _buckets) { + int flushedOne = usageBucket.FlushUnderUsedItems(toFlush - flushed, + true, + ref publicEntriesFlushed, + ref ocEntriesFlushed); + flushed += flushedOne; + if (flushed >= toFlush) + break; + } + } + } + finally { + Interlocked.Exchange(ref _inFlush, 0); + } + } + + return flushed; + } + +#if DBG + internal void DebugValidate() { + foreach (UsageBucket usageBucket in _buckets) { + usageBucket.DebugValidate(); + } + } + + internal string DebugDescription(string indent) { + StringBuilder sb = new StringBuilder(); + string i2 = indent + " "; + + sb.Append(indent); + sb.Append("Cache Usage\n"); + + foreach (UsageBucket usageBucket in _buckets) { + sb.Append(usageBucket.DebugDescription(i2)); + } + + return sb.ToString(); + } +#endif + } +} diff --git a/System.Web/httpserverutility.cs b/System.Web/httpserverutility.cs index 0b4299665..54ea1bc16 100644 --- a/System.Web/httpserverutility.cs +++ b/System.Web/httpserverutility.cs @@ -492,7 +492,7 @@ private void ExecuteInternal(IHttpHandler handler, TextWriter writer, bool prese targetPage.SmartNavigation = true; #pragma warning restore 0618 - // If the target page is async need to save/restore [....] context + // If the target page is async need to save/restore sync context if (targetPage is IHttpAsyncHandler) { savedSyncContext = _context.InstallNewAspNetSynchronizationContext(); } diff --git a/System.Web/misc/SecurityUtils.cs b/System.Web/misc/SecurityUtils.cs index 76e02fafb..159dedbb6 100644 --- a/System.Web/misc/SecurityUtils.cs +++ b/System.Web/misc/SecurityUtils.cs @@ -8,11 +8,11 @@ */ -#if WINFORMS_NAMESPACE +#if Microsoft_NAMESPACE namespace System.Windows.Forms #elif DRAWING_NAMESPACE namespace System.Drawing -#elif WINFORMS_PUBLIC_GRAPHICS_LIBRARY +#elif Microsoft_PUBLIC_GRAPHICS_LIBRARY namespace System.Internal #elif SYSTEM_NAMESPACE namespace System @@ -127,7 +127,7 @@ internal static object SecureCreateInstance(Type type, object[] args, bool allow return Activator.CreateInstance(type, flags, null, args, null); } -#if (!WINFORMS_NAMESPACE) +#if (!Microsoft_NAMESPACE) /// <devdoc> /// This helper method provides safe access to Activator.CreateInstance. diff --git a/System.Workflow.Activities/Common/BasePropertyDescriptor.cs b/System.Workflow.Activities/Common/BasePropertyDescriptor.cs index edf00c3bb..ce27594af 100644 --- a/System.Workflow.Activities/Common/BasePropertyDescriptor.cs +++ b/System.Workflow.Activities/Common/BasePropertyDescriptor.cs @@ -22,7 +22,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Common\Shared - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Common\Shared\BasePropertyDescriptor.cs *********************************************************************/ diff --git a/System.Workflow.Activities/Common/CompModHelpers.cs b/System.Workflow.Activities/Common/CompModHelpers.cs index cc6b22aba..755e13a69 100644 --- a/System.Workflow.Activities/Common/CompModHelpers.cs +++ b/System.Workflow.Activities/Common/CompModHelpers.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Common\Shared - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Common\Shared\CompModHelpers.cs *********************************************************************/ diff --git a/System.Workflow.Activities/Common/CompilerHelpers.cs b/System.Workflow.Activities/Common/CompilerHelpers.cs index d02d9fe91..27ec4c11f 100644 --- a/System.Workflow.Activities/Common/CompilerHelpers.cs +++ b/System.Workflow.Activities/Common/CompilerHelpers.cs @@ -10,7 +10,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Common\Shared - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Common\Shared\CompilerHelpers.cs *********************************************************************/ diff --git a/System.Workflow.Activities/Common/DelegateTypeInfo.cs b/System.Workflow.Activities/Common/DelegateTypeInfo.cs index c3667ac5b..a7f911669 100644 --- a/System.Workflow.Activities/Common/DelegateTypeInfo.cs +++ b/System.Workflow.Activities/Common/DelegateTypeInfo.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Common\Shared - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Common\Shared\DelegateTypeInfo.cs *********************************************************************/ diff --git a/System.Workflow.Activities/Common/NativeMethods.cs b/System.Workflow.Activities/Common/NativeMethods.cs index 38e72c5ab..8870aea03 100644 --- a/System.Workflow.Activities/Common/NativeMethods.cs +++ b/System.Workflow.Activities/Common/NativeMethods.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Common\Shared - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Common\Shared\NativeMethods.cs *********************************************************************/ namespace System.Workflow.Activities.Common diff --git a/System.Workflow.Activities/Common/TypeSystemHelpers.cs b/System.Workflow.Activities/Common/TypeSystemHelpers.cs index caa3bbcf2..d8cc8d986 100644 --- a/System.Workflow.Activities/Common/TypeSystemHelpers.cs +++ b/System.Workflow.Activities/Common/TypeSystemHelpers.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Common\Shared - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Common\Shared\TypeSystemHelpers.cs *********************************************************************/ namespace System.Workflow.Activities.Common diff --git a/System.Workflow.Activities/Common/ValidationHelpers.cs b/System.Workflow.Activities/Common/ValidationHelpers.cs index b0ada5fd4..65a902590 100644 --- a/System.Workflow.Activities/Common/ValidationHelpers.cs +++ b/System.Workflow.Activities/Common/ValidationHelpers.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Common\Shared - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Common\Shared\ValidationHelpers.cs *********************************************************************/ namespace System.Workflow.Activities.Common diff --git a/System.Workflow.Activities/Common/Walker.cs b/System.Workflow.Activities/Common/Walker.cs index 9bd77fe7e..7e450ac2b 100644 --- a/System.Workflow.Activities/Common/Walker.cs +++ b/System.Workflow.Activities/Common/Walker.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Common\Shared - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Common\Shared\Walker.cs *********************************************************************/ namespace System.Workflow.Activities.Common diff --git a/System.Workflow.Activities/Common/userdatakeys.cs b/System.Workflow.Activities/Common/userdatakeys.cs index 96aeacd92..b2a5a7a33 100644 --- a/System.Workflow.Activities/Common/userdatakeys.cs +++ b/System.Workflow.Activities/Common/userdatakeys.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Common\Shared - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Common\Shared\userdatakeys.cs *********************************************************************/ namespace System.Workflow.Activities.Common diff --git a/System.Workflow.Activities/LocalService/FollowerQueueCreator.cs b/System.Workflow.Activities/LocalService/FollowerQueueCreator.cs index a9088872f..3db7b1ea9 100644 --- a/System.Workflow.Activities/LocalService/FollowerQueueCreator.cs +++ b/System.Workflow.Activities/LocalService/FollowerQueueCreator.cs @@ -1,4 +1,4 @@ -#region Using directives +#region Using directives using System; using System.Diagnostics; diff --git a/System.Workflow.ComponentModel/AuthoringOM/Compiler/TypeSystem/DesignTimeType.cs b/System.Workflow.ComponentModel/AuthoringOM/Compiler/TypeSystem/DesignTimeType.cs index 32eec08bf..3b0c2765a 100644 --- a/System.Workflow.ComponentModel/AuthoringOM/Compiler/TypeSystem/DesignTimeType.cs +++ b/System.Workflow.ComponentModel/AuthoringOM/Compiler/TypeSystem/DesignTimeType.cs @@ -1120,7 +1120,7 @@ private List<T> GetCodeDomMembers<T>() // add default constructors for classes unless they // exist in the source code. Unfortunately, this cannot be easily // fixed in the CodeDomParser because the code dom returned by that - // class is expected to kept in [....] with the real source code. + // class is expected to kept in sync with the real source code. // So we cannot "fabricate" a default constructor there without // breaking lots of assumptions elsewhere in the code. // Instead, we add a default constructor here, if necessary. diff --git a/System.Workflow.ComponentModel/AuthoringOM/Design/CommandSet.cs b/System.Workflow.ComponentModel/AuthoringOM/Design/CommandSet.cs index d621aec24..27a55ac98 100644 --- a/System.Workflow.ComponentModel/AuthoringOM/Design/CommandSet.cs +++ b/System.Workflow.ComponentModel/AuthoringOM/Design/CommandSet.cs @@ -80,7 +80,7 @@ public CommandSet(IServiceProvider serviceProvider) // Properties new CommandSetItem(new EventHandler(OnStatusAlways), new EventHandler(OnMenuDesignerProperties), WorkflowMenuCommands.DesignerProperties), - // IMPORTANT: [....] does not handle this command, so VS.NET sends it to solution explorer + // IMPORTANT: Microsoft does not handle this command, so VS.NET sends it to solution explorer // window, which enables this meu item on the for the current file node new CommandSetItem(new EventHandler(OnStatusAlways), new EventHandler(OnViewCode), new CommandID(StandardCommands.Cut.Guid, 333)), @@ -563,7 +563,7 @@ private bool SendKeyDownCommand(Keys key) WorkflowView view = rootDesigner.GetView(ViewTechnology.Default) as WorkflowView; if (view != null) { - //because the some key presses are not coming into the [....] OnKeyDown + //because the some key presses are not coming into the Microsoft OnKeyDown //we need to do this work around to manually send the keypress into the designer KeyEventArgs eventArgs = new KeyEventArgs(key); diff --git a/System.Workflow.ComponentModel/AuthoringOM/Design/Dialogs/ThemeConfigurationDialog.cs b/System.Workflow.ComponentModel/AuthoringOM/Design/Dialogs/ThemeConfigurationDialog.cs index aa9a5ced9..ad60d2bfc 100644 --- a/System.Workflow.ComponentModel/AuthoringOM/Design/Dialogs/ThemeConfigurationDialog.cs +++ b/System.Workflow.ComponentModel/AuthoringOM/Design/Dialogs/ThemeConfigurationDialog.cs @@ -25,7 +25,7 @@ namespace System.Workflow.ComponentModel.Design [Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")] public sealed class ThemeConfigurationDialog : System.Windows.Forms.Form { - #region [....] Generated Members + #region Microsoft Generated Members private System.Windows.Forms.Button button3; private System.Windows.Forms.TreeView designerTreeView; private System.Windows.Forms.Label themeNameLabel; diff --git a/System.Workflow.ComponentModel/AuthoringOM/Design/Dialogs/WorkflowPageSetupDialog.cs b/System.Workflow.ComponentModel/AuthoringOM/Design/Dialogs/WorkflowPageSetupDialog.cs index 57f8cb537..0c0d1897e 100644 --- a/System.Workflow.ComponentModel/AuthoringOM/Design/Dialogs/WorkflowPageSetupDialog.cs +++ b/System.Workflow.ComponentModel/AuthoringOM/Design/Dialogs/WorkflowPageSetupDialog.cs @@ -14,7 +14,7 @@ namespace System.Workflow.ComponentModel.Design [Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")] public sealed class WorkflowPageSetupDialog : System.Windows.Forms.Form { - #region [....] Desiger Generated Members + #region Microsoft Desiger Generated Members private System.ComponentModel.Container components = null; private System.Windows.Forms.TabControl tabs; private System.Windows.Forms.PictureBox landscapePicture; diff --git a/System.Workflow.ComponentModel/AuthoringOM/Design/MenuCommands.cs b/System.Workflow.ComponentModel/AuthoringOM/Design/MenuCommands.cs index 9d07b2e10..c8701dd8f 100644 --- a/System.Workflow.ComponentModel/AuthoringOM/Design/MenuCommands.cs +++ b/System.Workflow.ComponentModel/AuthoringOM/Design/MenuCommands.cs @@ -60,7 +60,7 @@ public sealed class WorkflowMenuCommands : StandardCommands private const int cmdidWOEShowAll = 0x3107; public const int FirstZoomCommand = cmdidWOEZoom400; //the first and last zoom commands - public const int LastZoomCommand = cmdidWOEShowAll; //should be in [....] with the \private\Core\Tools\OrchestrationDesignerUI\PkgCmdID.h + public const int LastZoomCommand = cmdidWOEShowAll; //should be in sync with the \private\Core\Tools\OrchestrationDesignerUI\PkgCmdID.h // page layout private const int cmdidDefaultPage = 0x3110; diff --git a/System.Workflow.ComponentModel/AuthoringOM/Design/ReferenceService.cs b/System.Workflow.ComponentModel/AuthoringOM/Design/ReferenceService.cs index 14e64a3ae..a2ca29c6a 100644 --- a/System.Workflow.ComponentModel/AuthoringOM/Design/ReferenceService.cs +++ b/System.Workflow.ComponentModel/AuthoringOM/Design/ReferenceService.cs @@ -64,7 +64,7 @@ private void EnsureReferences() { // If the references are null, create them for the first time and connect // up our events to listen to changes to the container. Otherwise, check to - // see if the added or removed lists contain anything for us to [....] up. + // see if the added or removed lists contain anything for us to sync up. // if (this.references == null) { diff --git a/System.Workflow.ComponentModel/AuthoringOM/Design/StructuredCompositeActivityDesigner.cs b/System.Workflow.ComponentModel/AuthoringOM/Design/StructuredCompositeActivityDesigner.cs index 0decc066f..ed7ed08ff 100644 --- a/System.Workflow.ComponentModel/AuthoringOM/Design/StructuredCompositeActivityDesigner.cs +++ b/System.Workflow.ComponentModel/AuthoringOM/Design/StructuredCompositeActivityDesigner.cs @@ -150,7 +150,7 @@ public DesignerView ActiveView //activities with errors we want to reveal these activities DesignerHelpers.RefreshDesignerActions(Activity.Site); - //Keep the dynamic action and designer verbs in [....] + //Keep the dynamic action and designer verbs in sync RefreshDesignerVerbs(); } } diff --git a/System.Workflow.ComponentModel/AuthoringOM/Design/WorkflowView.cs b/System.Workflow.ComponentModel/AuthoringOM/Design/WorkflowView.cs index 1b8a6df80..320e30b6d 100644 --- a/System.Workflow.ComponentModel/AuthoringOM/Design/WorkflowView.cs +++ b/System.Workflow.ComponentModel/AuthoringOM/Design/WorkflowView.cs @@ -181,7 +181,7 @@ public WorkflowView(IServiceProvider serviceProvider) //Initialize the tooltip shown this.workflowToolTip = new WorkflowToolTip(this); - //[....] the global theme change event, which is fired by the theme infrastructure for theme change + //Sync the global theme change event, which is fired by the theme infrastructure for theme change WorkflowTheme.ThemeChanged += new EventHandler(OnThemeChange); //Create the core message filters diff --git a/System.Workflow.ComponentModel/Shared/BasePropertyDescriptor.cs b/System.Workflow.ComponentModel/Shared/BasePropertyDescriptor.cs index edb21a0ab..9a6b5209a 100644 --- a/System.Workflow.ComponentModel/Shared/BasePropertyDescriptor.cs +++ b/System.Workflow.ComponentModel/Shared/BasePropertyDescriptor.cs @@ -21,7 +21,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Activities\Common - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Activities\Common\BasePropertyDescriptor.cs *********************************************************************/ diff --git a/System.Workflow.ComponentModel/Shared/CompModHelpers.cs b/System.Workflow.ComponentModel/Shared/CompModHelpers.cs index 2183def57..1b666c9e5 100644 --- a/System.Workflow.ComponentModel/Shared/CompModHelpers.cs +++ b/System.Workflow.ComponentModel/Shared/CompModHelpers.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Activities\Common - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Activities\Common\CompModHelpers.cs *********************************************************************/ namespace System.Workflow.ComponentModel.Design diff --git a/System.Workflow.ComponentModel/Shared/CompilerHelpers.cs b/System.Workflow.ComponentModel/Shared/CompilerHelpers.cs index c6dceb5b0..437248e7e 100644 --- a/System.Workflow.ComponentModel/Shared/CompilerHelpers.cs +++ b/System.Workflow.ComponentModel/Shared/CompilerHelpers.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Activities\Common - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Activities\Common\CompilerHelpers.cs *********************************************************************/ diff --git a/System.Workflow.ComponentModel/Shared/DelegateTypeInfo.cs b/System.Workflow.ComponentModel/Shared/DelegateTypeInfo.cs index 01603ca74..3539c96ed 100644 --- a/System.Workflow.ComponentModel/Shared/DelegateTypeInfo.cs +++ b/System.Workflow.ComponentModel/Shared/DelegateTypeInfo.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Activities\Common - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Activities\Common\DelegateTypeInfo.cs *********************************************************************/ namespace System.Workflow.ComponentModel diff --git a/System.Workflow.ComponentModel/Shared/NativeMethods.cs b/System.Workflow.ComponentModel/Shared/NativeMethods.cs index f6e921b5f..cfd5e0e81 100644 --- a/System.Workflow.ComponentModel/Shared/NativeMethods.cs +++ b/System.Workflow.ComponentModel/Shared/NativeMethods.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Activities\Common - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Activities\Common\NativeMethods.cs *********************************************************************/ namespace System.Workflow.Interop diff --git a/System.Workflow.ComponentModel/Shared/TypeSystemHelpers.cs b/System.Workflow.ComponentModel/Shared/TypeSystemHelpers.cs index 9b53df5ee..896ddf1cd 100644 --- a/System.Workflow.ComponentModel/Shared/TypeSystemHelpers.cs +++ b/System.Workflow.ComponentModel/Shared/TypeSystemHelpers.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Activities\Common - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Activities\Common\TypeSystemHelpers.cs *********************************************************************/ namespace System.Workflow.ComponentModel.Compiler diff --git a/System.Workflow.ComponentModel/Shared/ValidationHelpers.cs b/System.Workflow.ComponentModel/Shared/ValidationHelpers.cs index a93a3d061..6f80c6056 100644 --- a/System.Workflow.ComponentModel/Shared/ValidationHelpers.cs +++ b/System.Workflow.ComponentModel/Shared/ValidationHelpers.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Activities\Common - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Activities\Common\ValidationHelpers.cs *********************************************************************/ namespace System.Workflow.ComponentModel.Compiler diff --git a/System.Workflow.ComponentModel/Shared/Walker.cs b/System.Workflow.ComponentModel/Shared/Walker.cs index e47e60f1c..1a8c8858e 100644 --- a/System.Workflow.ComponentModel/Shared/Walker.cs +++ b/System.Workflow.ComponentModel/Shared/Walker.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Activities\Common - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Activities\Common\Walker.cs *********************************************************************/ namespace System.Workflow.ComponentModel diff --git a/System.Workflow.ComponentModel/Shared/userdatakeys.cs b/System.Workflow.ComponentModel/Shared/userdatakeys.cs index 9812b64d2..3afb84b96 100644 --- a/System.Workflow.ComponentModel/Shared/userdatakeys.cs +++ b/System.Workflow.ComponentModel/Shared/userdatakeys.cs @@ -9,7 +9,7 @@ /********************************************************************* * NOTE: A copy of this file exists at: WF\Activities\Common - * The two files must be kept in [....]. Any change made here must also + * The two files must be kept in sync. Any change made here must also * be made to WF\Activities\Common\UserDataKeys.cs *********************************************************************/ namespace System.Workflow.ComponentModel diff --git a/System.Workflow.Runtime/ExecutorLocksHeldException.cs b/System.Workflow.Runtime/ExecutorLocksHeldException.cs index ba6ece5f1..2744a3bf9 100644 --- a/System.Workflow.Runtime/ExecutorLocksHeldException.cs +++ b/System.Workflow.Runtime/ExecutorLocksHeldException.cs @@ -10,7 +10,7 @@ // REVISIONS // Date Ver By Remarks // ~~~~~~~~~~ ~~~ ~~~~~~~~ ~~~~~~~~~~~~~~ -// 03/08/01 1.0 [....] Created. +// 03/08/01 1.0 Microsoft Created. // **************************************************************************** using System; using System.Runtime.Serialization; diff --git a/System.Workflow.Runtime/Hosting/WorkflowWebHostingModule.cs b/System.Workflow.Runtime/Hosting/WorkflowWebHostingModule.cs index a5155c762..aa4a26754 100644 --- a/System.Workflow.Runtime/Hosting/WorkflowWebHostingModule.cs +++ b/System.Workflow.Runtime/Hosting/WorkflowWebHostingModule.cs @@ -10,7 +10,7 @@ // REVISIONS // Date Ver By Remarks // ~~~~~~~~~~ ~~~ ~~~~~~~~ ~~~~~~~~~~~~~~ -// 02/22/05 1.0 [....] Implementation. +// 02/22/05 1.0 Microsoft Implementation. * ****************************************************************************/ #region Using directives diff --git a/System.Workflow.Runtime/System/Activities/Statements/Interop.cs b/System.Workflow.Runtime/System/Activities/Statements/Interop.cs index c45bac9f2..e82732e73 100644 --- a/System.Workflow.Runtime/System/Activities/Statements/Interop.cs +++ b/System.Workflow.Runtime/System/Activities/Statements/Interop.cs @@ -1453,7 +1453,7 @@ void ProcessNestedChildren(System.Workflow.ComponentModel.Activity interopBody, } } - //This needs to be in [....] with the table in the spec + //This needs to be in sync with the table in the spec //We use this internally to keep a hashset of validation data enum InteropValidationEnum { diff --git a/System.Workflow.Runtime/WorkflowEventArgs.cs b/System.Workflow.Runtime/WorkflowEventArgs.cs index 9e811599a..a81dd7b35 100644 --- a/System.Workflow.Runtime/WorkflowEventArgs.cs +++ b/System.Workflow.Runtime/WorkflowEventArgs.cs @@ -71,7 +71,7 @@ public Activity WorkflowDefinition if (this._workflowDefinition == null) { // Clone the original definition after locking the - // definition's [....] object which was passed in + // definition's sync object which was passed in // the constructor. This is so that the host cannot // corrupt the shared definition Activity tempDefinition = this._originalWorkflowDefinition.Clone(); diff --git a/System.Workflow.Runtime/WorkflowExecutor.cs b/System.Workflow.Runtime/WorkflowExecutor.cs index 0d2d2daf4..9194516f9 100644 --- a/System.Workflow.Runtime/WorkflowExecutor.cs +++ b/System.Workflow.Runtime/WorkflowExecutor.cs @@ -961,7 +961,7 @@ private bool ProtectedPersist(bool unlock) if (WorkflowExecutor.IsIrrecoverableException(e)) { throw; - } //@@undone: for [....]:- we should not be running exception handler, when we are unlocking. + } //@@undone: for Microsoft:- we should not be running exception handler, when we are unlocking. else if (this.WorkflowStatus != WorkflowStatus.Suspended && this.IsInstanceValid) { // the persistence attempt threw an exception @@ -1548,7 +1548,7 @@ private bool PerformUnloading(bool handleExceptions) } } - // shutsdown the schedule instance [....] + // shutsdown the schedule instance sync internal void Unload() { WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Got an unload request for instance {0}", this.InstanceIdString); @@ -1612,7 +1612,7 @@ internal void Unload() #region Terminate - // terminates the schedule instance [....] + // terminates the schedule instance sync // must be called only from outside the instance... the thread running the instance must // never call this method... it should call TerminateOnIdle instead. internal void Terminate(string error) @@ -1748,7 +1748,7 @@ internal bool TerminateOnIdle(string error) #region Abort - // aborts the schedule instance [....] + // aborts the schedule instance sync // must be called only from outside the instance... the thread running the instance must // never call this method... it should call AbortOnIdle instead. internal void Abort() @@ -1860,7 +1860,7 @@ internal void AbortOnIdle() #region Suspend - // suspends the schedule instance [....] + // suspends the schedule instance sync // must be called only from outside the instance... the thread running the instance must // never call this method... it should call SuspendOnIdle instead. internal bool Suspend(string error) @@ -1966,7 +1966,7 @@ internal bool SuspendOnIdle(string error) #region Resume - // resumes the schedule instance [....] + // resumes the schedule instance sync // must be called only from outside the instance... the thread running the instance must // never call this method... it should call ResumeOnIdle instead. internal void Resume() @@ -1996,7 +1996,7 @@ internal void Resume() //@@Undone-- bmalhi there is one test in bat //which fails here. This check is right thing but im //commenting it out for bat. - // [....]: this fails because when we load an instance into memory it grabs + // Microsoft: this fails because when we load an instance into memory it grabs // the scheduler lock and starts running. By the time the user Resume request // gets the scheduler lock the instance is often done (the AbortBat test case scenario) // Balinder is attempting a fix to separate rehydration from resuming execution. diff --git a/System.WorkflowServices/System/ServiceModel/WorkflowServiceHost.cs b/System.WorkflowServices/System/ServiceModel/WorkflowServiceHost.cs index 87b3b2378..f4610d89c 100644 --- a/System.WorkflowServices/System/ServiceModel/WorkflowServiceHost.cs +++ b/System.WorkflowServices/System/ServiceModel/WorkflowServiceHost.cs @@ -64,7 +64,7 @@ public WorkflowServiceHost(Stream workflowDefinition, Stream ruleDefinition, ITy // Based on prior art from WCF: // ServiceModel.lst:System.ServiceModel.ServiceHost..ctor(System.Object,System.Uri[]) // |DoNotCallOverridableMethodsInConstructors - // |[....]|By design, don't want to complicate ServiceHost state model + // |Microsoft|By design, don't want to complicate ServiceHost state model [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] internal WorkflowServiceHost(WorkflowDefinitionContext workflowDefinitionContext, params Uri[] baseAddress) : base() diff --git a/System.WorkflowServices/System/Workflow/Activities/Design/OperationPickerDialog.cs b/System.WorkflowServices/System/Workflow/Activities/Design/OperationPickerDialog.cs index 81662844a..4a7018c1d 100644 --- a/System.WorkflowServices/System/Workflow/Activities/Design/OperationPickerDialog.cs +++ b/System.WorkflowServices/System/Workflow/Activities/Design/OperationPickerDialog.cs @@ -303,7 +303,7 @@ private void OperationPickerDialogLoad(object sender, EventArgs e) // This is to make the selected operation the selected item in the operationsListBox. - // This needs to be done to work around the [....] bug causing selection events to not fire till form is loaded. + // This needs to be done to work around the Microsoft bug causing selection events to not fire till form is loaded. if (this.selectedOperation != null) { SelectServiceOperation(this.selectedOperation); diff --git a/System.WorkflowServices/System/Workflow/Runtime/Hosting/SynchronizationContextWorkflowSchedulerService.cs b/System.WorkflowServices/System/Workflow/Runtime/Hosting/SynchronizationContextWorkflowSchedulerService.cs index 76380ee64..bae23fc0b 100644 --- a/System.WorkflowServices/System/Workflow/Runtime/Hosting/SynchronizationContextWorkflowSchedulerService.cs +++ b/System.WorkflowServices/System/Workflow/Runtime/Hosting/SynchronizationContextWorkflowSchedulerService.cs @@ -84,7 +84,7 @@ internal static class SynchronizationContextPostHelper public static void Post(SynchronizationContext synchronizationContext, SendOrPostCallback callback, object state) { - Fx.Assert(synchronizationContext != null, "Null [....] Context"); + Fx.Assert(synchronizationContext != null, "Null Sync Context"); Fx.Assert(callback != null, "Null Callback"); synchronizationContext.OperationStarted(); diff --git a/System.Xml/InternalApis/NDP_Common/inc/Win8Helpers.cs b/System.Xml/InternalApis/NDP_Common/inc/Win8Helpers.cs index 065662f2e..b2508ba53 100644 --- a/System.Xml/InternalApis/NDP_Common/inc/Win8Helpers.cs +++ b/System.Xml/InternalApis/NDP_Common/inc/Win8Helpers.cs @@ -2,7 +2,7 @@ // <copyright file="Compilation.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace Microsoft.Win32 { diff --git a/System.Xml/System/Xml/Base64Decoder.cs b/System.Xml/System/Xml/Base64Decoder.cs index 6fce5e708..700f00247 100644 --- a/System.Xml/System/Xml/Base64Decoder.cs +++ b/System.Xml/System/Xml/Base64Decoder.cs @@ -2,7 +2,7 @@ // <copyright file="Base64Decoder.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Base64Encoder.cs b/System.Xml/System/Xml/Base64Encoder.cs index 2e5db862d..826dda147 100644 --- a/System.Xml/System/Xml/Base64Encoder.cs +++ b/System.Xml/System/Xml/Base64Encoder.cs @@ -3,7 +3,7 @@ // <copyright file="Base64Encoder.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Text; diff --git a/System.Xml/System/Xml/BinHexDecoder.cs b/System.Xml/System/Xml/BinHexDecoder.cs index a5b8c826a..f0e3e37cb 100644 --- a/System.Xml/System/Xml/BinHexDecoder.cs +++ b/System.Xml/System/Xml/BinHexDecoder.cs @@ -2,7 +2,7 @@ // <copyright file="BinHexDecoder.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/BinHexEncoder.cs b/System.Xml/System/Xml/BinHexEncoder.cs index 84af530c3..80aaef885 100644 --- a/System.Xml/System/Xml/BinHexEncoder.cs +++ b/System.Xml/System/Xml/BinHexEncoder.cs @@ -3,7 +3,7 @@ // <copyright file="BinHexEncoder.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/BinaryXml/SqlUtils.cs b/System.Xml/System/Xml/BinaryXml/SqlUtils.cs index ac782eede..f431af850 100644 --- a/System.Xml/System/Xml/BinaryXml/SqlUtils.cs +++ b/System.Xml/System/Xml/BinaryXml/SqlUtils.cs @@ -2,7 +2,7 @@ // <copyright file="XmlBinaryWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/BinaryXml/XmlBinaryReader.cs b/System.Xml/System/Xml/BinaryXml/XmlBinaryReader.cs index 7ec7d87c0..249bf8a70 100644 --- a/System.Xml/System/Xml/BinaryXml/XmlBinaryReader.cs +++ b/System.Xml/System/Xml/BinaryXml/XmlBinaryReader.cs @@ -2,7 +2,7 @@ // <copyright file="XmlBinaryWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/BinaryXml/XmlBinaryReaderAsync.cs b/System.Xml/System/Xml/BinaryXml/XmlBinaryReaderAsync.cs index c246cd780..c5617d0be 100644 --- a/System.Xml/System/Xml/BinaryXml/XmlBinaryReaderAsync.cs +++ b/System.Xml/System/Xml/BinaryXml/XmlBinaryReaderAsync.cs @@ -2,7 +2,7 @@ // <copyright file="XmlBinaryWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/BitStack.cs b/System.Xml/System/Xml/BitStack.cs index 1a24b0503..af5df11c2 100644 --- a/System.Xml/System/Xml/BitStack.cs +++ b/System.Xml/System/Xml/BitStack.cs @@ -2,7 +2,7 @@ // <copyright file="BitStack.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Bits.cs b/System.Xml/System/Xml/Bits.cs index c971932da..e33134c3d 100644 --- a/System.Xml/System/Xml/Bits.cs +++ b/System.Xml/System/Xml/Bits.cs @@ -2,7 +2,7 @@ // <copyright file="Bits.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/ByteStack.cs b/System.Xml/System/Xml/ByteStack.cs index dad824cbb..d1dac9ff8 100644 --- a/System.Xml/System/Xml/ByteStack.cs +++ b/System.Xml/System/Xml/ByteStack.cs @@ -2,7 +2,7 @@ // <copyright file="ByteStack.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Cache/XPathDocumentBuilder.cs b/System.Xml/System/Xml/Cache/XPathDocumentBuilder.cs index 5ca097401..7282d5455 100644 --- a/System.Xml/System/Xml/Cache/XPathDocumentBuilder.cs +++ b/System.Xml/System/Xml/Cache/XPathDocumentBuilder.cs @@ -2,7 +2,7 @@ // <copyright file="XPathDocumentBuilder.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; using System.Globalization; diff --git a/System.Xml/System/Xml/Cache/XPathDocumentIterator.cs b/System.Xml/System/Xml/Cache/XPathDocumentIterator.cs index 54d2808d1..937c44a75 100644 --- a/System.Xml/System/Xml/Cache/XPathDocumentIterator.cs +++ b/System.Xml/System/Xml/Cache/XPathDocumentIterator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathDocumentIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Xml/System/Xml/Cache/XPathDocumentNavigator.cs b/System.Xml/System/Xml/Cache/XPathDocumentNavigator.cs index d5884ff33..f46468ff6 100644 --- a/System.Xml/System/Xml/Cache/XPathDocumentNavigator.cs +++ b/System.Xml/System/Xml/Cache/XPathDocumentNavigator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathDocumentNavigator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; using System.IO; diff --git a/System.Xml/System/Xml/Cache/XPathNode.cs b/System.Xml/System/Xml/Cache/XPathNode.cs index 1706a413b..9170badb6 100644 --- a/System.Xml/System/Xml/Cache/XPathNode.cs +++ b/System.Xml/System/Xml/Cache/XPathNode.cs @@ -2,7 +2,7 @@ // <copyright file="XPathNode.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Xml/System/Xml/Cache/XPathNodeHelper.cs b/System.Xml/System/Xml/Cache/XPathNodeHelper.cs index d41386dc0..fbc150cb5 100644 --- a/System.Xml/System/Xml/Cache/XPathNodeHelper.cs +++ b/System.Xml/System/Xml/Cache/XPathNodeHelper.cs @@ -2,7 +2,7 @@ // <copyright file="XPathNodeHelper.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; using System.Diagnostics; diff --git a/System.Xml/System/Xml/Cache/XPathNodeInfoAtom.cs b/System.Xml/System/Xml/Cache/XPathNodeInfoAtom.cs index b2bd27cfc..f65ab8c14 100644 --- a/System.Xml/System/Xml/Cache/XPathNodeInfoAtom.cs +++ b/System.Xml/System/Xml/Cache/XPathNodeInfoAtom.cs @@ -2,7 +2,7 @@ // <copyright file="XPathNodeInfoAtom.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Collections; using System.Text; diff --git a/System.Xml/System/Xml/Core/CharEntityEncoderFallback.cs b/System.Xml/System/Xml/Core/CharEntityEncoderFallback.cs index 9ada03fbd..00aad6ab9 100644 --- a/System.Xml/System/Xml/Core/CharEntityEncoderFallback.cs +++ b/System.Xml/System/Xml/Core/CharEntityEncoderFallback.cs @@ -2,7 +2,7 @@ // <copyright file="CharEntitiesEncodingFallback.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Text; diff --git a/System.Xml/System/Xml/Core/HtmlEncodedRawTextWriter.cs b/System.Xml/System/Xml/Core/HtmlEncodedRawTextWriter.cs index 3e87a2880..aa90db35c 100644 --- a/System.Xml/System/Xml/Core/HtmlEncodedRawTextWriter.cs +++ b/System.Xml/System/Xml/Core/HtmlEncodedRawTextWriter.cs @@ -3,7 +3,7 @@ // <copyright file="HtmlRawTextWriterGenerator.cxx" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ // WARNING: This file is generated and should not be modified directly. Instead, diff --git a/System.Xml/System/Xml/Core/HtmlTernaryTree.cs b/System.Xml/System/Xml/Core/HtmlTernaryTree.cs index ea40a4b17..67a2eb4e8 100644 --- a/System.Xml/System/Xml/Core/HtmlTernaryTree.cs +++ b/System.Xml/System/Xml/Core/HtmlTernaryTree.cs @@ -2,7 +2,7 @@ // <copyright file="TernaryTreeGenerator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ // // This file is generated by TernaryTreeGenerator.cs, diff --git a/System.Xml/System/Xml/Core/HtmlUtf8RawTextWriter.cs b/System.Xml/System/Xml/Core/HtmlUtf8RawTextWriter.cs index ce58ac04c..6cca7607c 100644 --- a/System.Xml/System/Xml/Core/HtmlUtf8RawTextWriter.cs +++ b/System.Xml/System/Xml/Core/HtmlUtf8RawTextWriter.cs @@ -3,7 +3,7 @@ // <copyright file="HtmlRawTextWriterGenerator.cxx" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ // WARNING: This file is generated and should not be modified directly. Instead, diff --git a/System.Xml/System/Xml/Core/IncrementalReadDecoders.cs b/System.Xml/System/Xml/Core/IncrementalReadDecoders.cs index 75aa39c93..accabc8ae 100644 --- a/System.Xml/System/Xml/Core/IncrementalReadDecoders.cs +++ b/System.Xml/System/Xml/Core/IncrementalReadDecoders.cs @@ -2,7 +2,7 @@ // <copyright file="IncrementalReadDecoder.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Xml/System/Xml/Core/QueryOutputWriter.cs b/System.Xml/System/Xml/Core/QueryOutputWriter.cs index 38d96cab2..b2eb04606 100644 --- a/System.Xml/System/Xml/Core/QueryOutputWriter.cs +++ b/System.Xml/System/Xml/Core/QueryOutputWriter.cs @@ -2,7 +2,7 @@ // <copyright file=QueryOutputWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Core/QueryOutputWriterV1.cs b/System.Xml/System/Xml/Core/QueryOutputWriterV1.cs index 7804b49e6..b8118da24 100644 --- a/System.Xml/System/Xml/Core/QueryOutputWriterV1.cs +++ b/System.Xml/System/Xml/Core/QueryOutputWriterV1.cs @@ -2,7 +2,7 @@ // <copyright file=QueryOutputWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/ReadContentAsBinaryHelper.cs b/System.Xml/System/Xml/Core/ReadContentAsBinaryHelper.cs index 2279ac9d4..f901bb3b8 100644 --- a/System.Xml/System/Xml/Core/ReadContentAsBinaryHelper.cs +++ b/System.Xml/System/Xml/Core/ReadContentAsBinaryHelper.cs @@ -3,7 +3,7 @@ // <copyright file="ReadContentAsBinaryHelper.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Xml/System/Xml/Core/ReadOnlyTernaryTree.cs b/System.Xml/System/Xml/Core/ReadOnlyTernaryTree.cs index c18e27b12..e2bdd673a 100644 --- a/System.Xml/System/Xml/Core/ReadOnlyTernaryTree.cs +++ b/System.Xml/System/Xml/Core/ReadOnlyTernaryTree.cs @@ -2,7 +2,7 @@ // <copyright file="ReadOnlyTernaryTree.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; @@ -17,7 +17,7 @@ internal enum TernaryTreeByte {characterByte = 0, leftTree = 1, rightTree = 2, // // XSL HTML output method properties // - // Keep the first four bits in [....], so that the element and attribute mask operation can be combined. + // Keep the first four bits in sync, so that the element and attribute mask operation can be combined. internal enum ElementProperties : uint {DEFAULT = 0, URI_PARENT = 1, BOOL_PARENT = 2, NAME_PARENT = 4, EMPTY = 8, NO_ENTITIES = 16, HEAD = 32, BLOCK_WS = 64, HAS_NS = 128} internal enum AttributeProperties : uint {DEFAULT = 0, URI = 1, BOOLEAN = 2, NAME = 4} diff --git a/System.Xml/System/Xml/Core/SecureStringHasher.cs b/System.Xml/System/Xml/Core/SecureStringHasher.cs index 95684b22d..a0e126082 100644 --- a/System.Xml/System/Xml/Core/SecureStringHasher.cs +++ b/System.Xml/System/Xml/Core/SecureStringHasher.cs @@ -2,7 +2,7 @@ // <copyright file="SecureStringHasher.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/TextEncodedRawTextWriter.cs b/System.Xml/System/Xml/Core/TextEncodedRawTextWriter.cs index d09ec7789..6565d5d3d 100644 --- a/System.Xml/System/Xml/Core/TextEncodedRawTextWriter.cs +++ b/System.Xml/System/Xml/Core/TextEncodedRawTextWriter.cs @@ -3,7 +3,7 @@ // <copyright file="TextWriterGenerator.cxx" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ // WARNING: This file is generated and should not be modified directly. Instead, diff --git a/System.Xml/System/Xml/Core/TextUtf8RawTextWriter.cs b/System.Xml/System/Xml/Core/TextUtf8RawTextWriter.cs index 1ed397e8f..4192d3285 100644 --- a/System.Xml/System/Xml/Core/TextUtf8RawTextWriter.cs +++ b/System.Xml/System/Xml/Core/TextUtf8RawTextWriter.cs @@ -3,7 +3,7 @@ // <copyright file="TextWriterGenerator.cxx" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ // WARNING: This file is generated and should not be modified directly. Instead, diff --git a/System.Xml/System/Xml/Core/ValidatingReaderNodeData.cs b/System.Xml/System/Xml/Core/ValidatingReaderNodeData.cs index 0220c3ac4..35ebb9344 100644 --- a/System.Xml/System/Xml/Core/ValidatingReaderNodeData.cs +++ b/System.Xml/System/Xml/Core/ValidatingReaderNodeData.cs @@ -2,7 +2,7 @@ // <copyright file="ValidatingReaderNodeData.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlAsyncCheckReader.cs b/System.Xml/System/Xml/Core/XmlAsyncCheckReader.cs index acfc26412..5c8e6dbfa 100644 --- a/System.Xml/System/Xml/Core/XmlAsyncCheckReader.cs +++ b/System.Xml/System/Xml/Core/XmlAsyncCheckReader.cs @@ -55,7 +55,7 @@ private void CheckAsync() { } } - #region [....] Methods, Properties Check + #region Sync Methods, Properties Check public override XmlReaderSettings Settings { get { diff --git a/System.Xml/System/Xml/Core/XmlAsyncCheckWriter.cs b/System.Xml/System/Xml/Core/XmlAsyncCheckWriter.cs index 9d3d1259b..2ec002e88 100644 --- a/System.Xml/System/Xml/Core/XmlAsyncCheckWriter.cs +++ b/System.Xml/System/Xml/Core/XmlAsyncCheckWriter.cs @@ -28,7 +28,7 @@ private void CheckAsync() { } } - #region [....] Methods, Properties Check + #region Sync Methods, Properties Check public override XmlWriterSettings Settings { get { diff --git a/System.Xml/System/Xml/Core/XmlAutoDetectWriter.cs b/System.Xml/System/Xml/Core/XmlAutoDetectWriter.cs index be7bdf2f1..c36fceca0 100644 --- a/System.Xml/System/Xml/Core/XmlAutoDetectWriter.cs +++ b/System.Xml/System/Xml/Core/XmlAutoDetectWriter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlAutoDetectWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ diff --git a/System.Xml/System/Xml/Core/XmlCharCheckingReader.cs b/System.Xml/System/Xml/Core/XmlCharCheckingReader.cs index e7494e219..4d57beeb3 100644 --- a/System.Xml/System/Xml/Core/XmlCharCheckingReader.cs +++ b/System.Xml/System/Xml/Core/XmlCharCheckingReader.cs @@ -3,7 +3,7 @@ // <copyright file="XmlCharCheckingReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlCharCheckingWriter.cs b/System.Xml/System/Xml/Core/XmlCharCheckingWriter.cs index d997aaf59..706383bba 100644 --- a/System.Xml/System/Xml/Core/XmlCharCheckingWriter.cs +++ b/System.Xml/System/Xml/Core/XmlCharCheckingWriter.cs @@ -4,7 +4,7 @@ // <copyright file="XmlCharCheckingWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ diff --git a/System.Xml/System/Xml/Core/XmlEncodedRawTextWriter.cs b/System.Xml/System/Xml/Core/XmlEncodedRawTextWriter.cs index 15d6839fb..ea644332b 100644 --- a/System.Xml/System/Xml/Core/XmlEncodedRawTextWriter.cs +++ b/System.Xml/System/Xml/Core/XmlEncodedRawTextWriter.cs @@ -3,7 +3,7 @@ // <copyright file="XmlRawTextWriterGenerator.cxx" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ // WARNING: This file is generated and should not be modified directly. Instead, diff --git a/System.Xml/System/Xml/Core/XmlEventCache.cs b/System.Xml/System/Xml/Core/XmlEventCache.cs index 2f9b8e7dc..b48dd010f 100644 --- a/System.Xml/System/Xml/Core/XmlEventCache.cs +++ b/System.Xml/System/Xml/Core/XmlEventCache.cs @@ -2,7 +2,7 @@ // <copyright file="XmlEventCache.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Xml/System/Xml/Core/XmlParserContext.cs b/System.Xml/System/Xml/Core/XmlParserContext.cs index c6427aa67..6b70e55b4 100644 --- a/System.Xml/System/Xml/Core/XmlParserContext.cs +++ b/System.Xml/System/Xml/Core/XmlParserContext.cs @@ -2,7 +2,7 @@ // <copyright file="XmlParserContext.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Xml; diff --git a/System.Xml/System/Xml/Core/XmlRawWriter.cs b/System.Xml/System/Xml/Core/XmlRawWriter.cs index 0de566338..6c05735bc 100644 --- a/System.Xml/System/Xml/Core/XmlRawWriter.cs +++ b/System.Xml/System/Xml/Core/XmlRawWriter.cs @@ -3,7 +3,7 @@ // <copyright file="XmlRawWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlReader.cs b/System.Xml/System/Xml/Core/XmlReader.cs index 444944542..40379dd15 100644 --- a/System.Xml/System/Xml/Core/XmlReader.cs +++ b/System.Xml/System/Xml/Core/XmlReader.cs @@ -3,7 +3,7 @@ // <copyright file="XmlReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.IO; diff --git a/System.Xml/System/Xml/Core/XmlReaderSettings.cs b/System.Xml/System/Xml/Core/XmlReaderSettings.cs index c3ceeb85d..5f1f12eee 100644 --- a/System.Xml/System/Xml/Core/XmlReaderSettings.cs +++ b/System.Xml/System/Xml/Core/XmlReaderSettings.cs @@ -2,7 +2,7 @@ // <copyright file="XmlReaderSettings.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.IO; diff --git a/System.Xml/System/Xml/Core/XmlSubtreeReader.cs b/System.Xml/System/Xml/Core/XmlSubtreeReader.cs index c78e851ad..602e1acb3 100644 --- a/System.Xml/System/Xml/Core/XmlSubtreeReader.cs +++ b/System.Xml/System/Xml/Core/XmlSubtreeReader.cs @@ -3,7 +3,7 @@ // <copyright file="XmlSubtreeReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlTextEncoder.cs b/System.Xml/System/Xml/Core/XmlTextEncoder.cs index 8c90585f9..7e4c58fd1 100644 --- a/System.Xml/System/Xml/Core/XmlTextEncoder.cs +++ b/System.Xml/System/Xml/Core/XmlTextEncoder.cs @@ -2,7 +2,7 @@ // <copyright file="XmlTextWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlTextReader.cs b/System.Xml/System/Xml/Core/XmlTextReader.cs index 2ce8ee9b5..096f9b5cb 100644 --- a/System.Xml/System/Xml/Core/XmlTextReader.cs +++ b/System.Xml/System/Xml/Core/XmlTextReader.cs @@ -3,7 +3,7 @@ // <copyright file="XmlTextReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlTextReaderImpl.cs b/System.Xml/System/Xml/Core/XmlTextReaderImpl.cs index 8ac1d7065..ab3997554 100644 --- a/System.Xml/System/Xml/Core/XmlTextReaderImpl.cs +++ b/System.Xml/System/Xml/Core/XmlTextReaderImpl.cs @@ -3,7 +3,7 @@ // <copyright file="XmlTextReaderImpl.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlTextReaderImplHelpers.cs b/System.Xml/System/Xml/Core/XmlTextReaderImplHelpers.cs index 3a031b704..8d3dcd6f8 100644 --- a/System.Xml/System/Xml/Core/XmlTextReaderImplHelpers.cs +++ b/System.Xml/System/Xml/Core/XmlTextReaderImplHelpers.cs @@ -3,7 +3,7 @@ // <copyright file="XmlTextReaderHelpers.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlTextWriter.cs b/System.Xml/System/Xml/Core/XmlTextWriter.cs index 731426702..4f6a768e7 100644 --- a/System.Xml/System/Xml/Core/XmlTextWriter.cs +++ b/System.Xml/System/Xml/Core/XmlTextWriter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlTextWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlUtf8RawTextWriter.cs b/System.Xml/System/Xml/Core/XmlUtf8RawTextWriter.cs index 9267f3cf1..02614e348 100644 --- a/System.Xml/System/Xml/Core/XmlUtf8RawTextWriter.cs +++ b/System.Xml/System/Xml/Core/XmlUtf8RawTextWriter.cs @@ -3,7 +3,7 @@ // <copyright file="XmlRawTextWriterGenerator.cxx" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ // WARNING: This file is generated and should not be modified directly. Instead, diff --git a/System.Xml/System/Xml/Core/XmlValidatingReader.cs b/System.Xml/System/Xml/Core/XmlValidatingReader.cs index 5027da2ff..9c997f144 100644 --- a/System.Xml/System/Xml/Core/XmlValidatingReader.cs +++ b/System.Xml/System/Xml/Core/XmlValidatingReader.cs @@ -2,7 +2,7 @@ // <copyright file="XmlValidatingReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlValidatingReaderImpl.cs b/System.Xml/System/Xml/Core/XmlValidatingReaderImpl.cs index 7836c255b..55d380288 100644 --- a/System.Xml/System/Xml/Core/XmlValidatingReaderImpl.cs +++ b/System.Xml/System/Xml/Core/XmlValidatingReaderImpl.cs @@ -3,7 +3,7 @@ // <copyright file="XmlValidatingReaderImpl.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlWellFormedWriter.cs b/System.Xml/System/Xml/Core/XmlWellFormedWriter.cs index 30bf76c54..e03913edc 100644 --- a/System.Xml/System/Xml/Core/XmlWellFormedWriter.cs +++ b/System.Xml/System/Xml/Core/XmlWellFormedWriter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlWellFormedWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlWellFormedWriterHelpers.cs b/System.Xml/System/Xml/Core/XmlWellFormedWriterHelpers.cs index 6454136ea..144d806e5 100644 --- a/System.Xml/System/Xml/Core/XmlWellFormedWriterHelpers.cs +++ b/System.Xml/System/Xml/Core/XmlWellFormedWriterHelpers.cs @@ -3,7 +3,7 @@ // <copyright file="XmlWellFormedWriterHelpers.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlWrappingReader.cs b/System.Xml/System/Xml/Core/XmlWrappingReader.cs index 5aba9d28d..0bddf6c93 100644 --- a/System.Xml/System/Xml/Core/XmlWrappingReader.cs +++ b/System.Xml/System/Xml/Core/XmlWrappingReader.cs @@ -3,7 +3,7 @@ // <copyright file="XmlWrappingReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlWrappingWriter.cs b/System.Xml/System/Xml/Core/XmlWrappingWriter.cs index 6176c6dd5..f73c5eb90 100644 --- a/System.Xml/System/Xml/Core/XmlWrappingWriter.cs +++ b/System.Xml/System/Xml/Core/XmlWrappingWriter.cs @@ -4,7 +4,7 @@ // <copyright file="XmlWrapingWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ diff --git a/System.Xml/System/Xml/Core/XmlWriter.cs b/System.Xml/System/Xml/Core/XmlWriter.cs index 64ce1c429..f4ca61856 100644 --- a/System.Xml/System/Xml/Core/XmlWriter.cs +++ b/System.Xml/System/Xml/Core/XmlWriter.cs @@ -3,7 +3,7 @@ // <copyright file="XmlWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Core/XmlWriterAsync.cs b/System.Xml/System/Xml/Core/XmlWriterAsync.cs index bd18d0db0..e799402b0 100644 --- a/System.Xml/System/Xml/Core/XmlWriterAsync.cs +++ b/System.Xml/System/Xml/Core/XmlWriterAsync.cs @@ -263,7 +263,7 @@ public virtual Task WriteNodeAsync(XmlReader reader, bool defattr) { // Copies the current node from the given reader to the writer (including child nodes), and if called on an element moves the XmlReader // to the corresponding end element. - //use [....] methods on the reader + //use sync methods on the reader internal async Task WriteNodeAsync_CallSyncReader(XmlReader reader, bool defattr) { bool canReadChunk = reader.CanReadValueChunk; diff --git a/System.Xml/System/Xml/Core/XmlWriterSettings.cs b/System.Xml/System/Xml/Core/XmlWriterSettings.cs index 321debcd6..4cf699ad1 100644 --- a/System.Xml/System/Xml/Core/XmlWriterSettings.cs +++ b/System.Xml/System/Xml/Core/XmlWriterSettings.cs @@ -2,7 +2,7 @@ // <copyright file="XmlWriterSettings.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Collections.Generic; diff --git a/System.Xml/System/Xml/Core/XsdCachingReader.cs b/System.Xml/System/Xml/Core/XsdCachingReader.cs index eabe7e09a..2775de956 100644 --- a/System.Xml/System/Xml/Core/XsdCachingReader.cs +++ b/System.Xml/System/Xml/Core/XsdCachingReader.cs @@ -3,7 +3,7 @@ // <copyright file="XsdCachingReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.IO; diff --git a/System.Xml/System/Xml/Core/XsdValidatingReader.cs b/System.Xml/System/Xml/Core/XsdValidatingReader.cs index 78b479a94..1624db0c1 100644 --- a/System.Xml/System/Xml/Core/XsdValidatingReader.cs +++ b/System.Xml/System/Xml/Core/XsdValidatingReader.cs @@ -3,7 +3,7 @@ // <copyright file="XsdValidatingReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.IO; diff --git a/System.Xml/System/Xml/DiagnosticsSwitches.cs b/System.Xml/System/Xml/DiagnosticsSwitches.cs index 18e16e93e..aa2a2be4f 100644 --- a/System.Xml/System/Xml/DiagnosticsSwitches.cs +++ b/System.Xml/System/Xml/DiagnosticsSwitches.cs @@ -2,7 +2,7 @@ // <copyright file="DiagnosticsSwitches.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/DocumentSchemaValidator.cs b/System.Xml/System/Xml/Dom/DocumentSchemaValidator.cs index 61467a7e2..ad2afe144 100644 --- a/System.Xml/System/Xml/Dom/DocumentSchemaValidator.cs +++ b/System.Xml/System/Xml/Dom/DocumentSchemaValidator.cs @@ -2,7 +2,7 @@ // <copyright file="XmlDocumentValidator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Dom/DocumentXPathNavigator.cs b/System.Xml/System/Xml/Dom/DocumentXPathNavigator.cs index 651565088..519989144 100644 --- a/System.Xml/System/Xml/Dom/DocumentXPathNavigator.cs +++ b/System.Xml/System/Xml/Dom/DocumentXPathNavigator.cs @@ -2,7 +2,7 @@ // <copyright file="DocumentXPathNavigator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Dom/DocumentXmlWriter.cs b/System.Xml/System/Xml/Dom/DocumentXmlWriter.cs index b81819b7f..a593fc00f 100644 --- a/System.Xml/System/Xml/Dom/DocumentXmlWriter.cs +++ b/System.Xml/System/Xml/Dom/DocumentXmlWriter.cs @@ -2,7 +2,7 @@ // <copyright file="DocumentXmlWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Dom/DomNameTable.cs b/System.Xml/System/Xml/Dom/DomNameTable.cs index f804251dd..1887cf8fe 100644 --- a/System.Xml/System/Xml/Dom/DomNameTable.cs +++ b/System.Xml/System/Xml/Dom/DomNameTable.cs @@ -2,7 +2,7 @@ // <copyright file="DomNameTable.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Dom/XPathNodeList.cs b/System.Xml/System/Xml/Dom/XPathNodeList.cs index 72cce94b6..375f9c645 100644 --- a/System.Xml/System/Xml/Dom/XPathNodeList.cs +++ b/System.Xml/System/Xml/Dom/XPathNodeList.cs @@ -2,7 +2,7 @@ // <copyright file="XPathNodeList.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlAttribute.cs b/System.Xml/System/Xml/Dom/XmlAttribute.cs index 5a78890c5..e72968196 100644 --- a/System.Xml/System/Xml/Dom/XmlAttribute.cs +++ b/System.Xml/System/Xml/Dom/XmlAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlAttributeCollection.cs b/System.Xml/System/Xml/Dom/XmlAttributeCollection.cs index 5825e1d6b..bfe86a970 100644 --- a/System.Xml/System/Xml/Dom/XmlAttributeCollection.cs +++ b/System.Xml/System/Xml/Dom/XmlAttributeCollection.cs @@ -2,7 +2,7 @@ // <copyright file="XmlAttributeCollection.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ diff --git a/System.Xml/System/Xml/Dom/XmlCDataSection.cs b/System.Xml/System/Xml/Dom/XmlCDataSection.cs index 9879cf9e5..b1f2676b1 100644 --- a/System.Xml/System/Xml/Dom/XmlCDataSection.cs +++ b/System.Xml/System/Xml/Dom/XmlCDataSection.cs @@ -2,7 +2,7 @@ // <copyright file="XmlCDATASection.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlCharacterData.cs b/System.Xml/System/Xml/Dom/XmlCharacterData.cs index 3744cd8bc..6797b896b 100644 --- a/System.Xml/System/Xml/Dom/XmlCharacterData.cs +++ b/System.Xml/System/Xml/Dom/XmlCharacterData.cs @@ -2,7 +2,7 @@ // <copyright file="XmlCharacterData.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { using System.Diagnostics; diff --git a/System.Xml/System/Xml/Dom/XmlChildEnumerator.cs b/System.Xml/System/Xml/Dom/XmlChildEnumerator.cs index 41a25efe2..d17bffe83 100644 --- a/System.Xml/System/Xml/Dom/XmlChildEnumerator.cs +++ b/System.Xml/System/Xml/Dom/XmlChildEnumerator.cs @@ -2,7 +2,7 @@ // <copyright file="XmlChildEnumerator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlChildNodes.cs b/System.Xml/System/Xml/Dom/XmlChildNodes.cs index 6450c64f6..391b56667 100644 --- a/System.Xml/System/Xml/Dom/XmlChildNodes.cs +++ b/System.Xml/System/Xml/Dom/XmlChildNodes.cs @@ -2,7 +2,7 @@ // <copyright file="XmlChildNodes.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { using System.Collections; diff --git a/System.Xml/System/Xml/Dom/XmlComment.cs b/System.Xml/System/Xml/Dom/XmlComment.cs index 087c7546a..8e7289c89 100644 --- a/System.Xml/System/Xml/Dom/XmlComment.cs +++ b/System.Xml/System/Xml/Dom/XmlComment.cs @@ -2,7 +2,7 @@ // <copyright file="XmlComment.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlDeclaration.cs b/System.Xml/System/Xml/Dom/XmlDeclaration.cs index bd8ab0ef6..8de8430a3 100644 --- a/System.Xml/System/Xml/Dom/XmlDeclaration.cs +++ b/System.Xml/System/Xml/Dom/XmlDeclaration.cs @@ -2,7 +2,7 @@ // <copyright file="XmlDeclaration.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlDocument.cs b/System.Xml/System/Xml/Dom/XmlDocument.cs index dff26fa7d..03d419b0d 100644 --- a/System.Xml/System/Xml/Dom/XmlDocument.cs +++ b/System.Xml/System/Xml/Dom/XmlDocument.cs @@ -2,7 +2,7 @@ // <copyright file="XmlDocument.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml diff --git a/System.Xml/System/Xml/Dom/XmlDocumentFragment.cs b/System.Xml/System/Xml/Dom/XmlDocumentFragment.cs index 1ee01648c..ef3e33eca 100644 --- a/System.Xml/System/Xml/Dom/XmlDocumentFragment.cs +++ b/System.Xml/System/Xml/Dom/XmlDocumentFragment.cs @@ -2,7 +2,7 @@ // <copyright file="XmlDocumentFragment.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ // <code>DocumentFragment</code> is a "lightweight" or "minimal" diff --git a/System.Xml/System/Xml/Dom/XmlDocumentType.cs b/System.Xml/System/Xml/Dom/XmlDocumentType.cs index 27daa745e..19ae68b98 100644 --- a/System.Xml/System/Xml/Dom/XmlDocumentType.cs +++ b/System.Xml/System/Xml/Dom/XmlDocumentType.cs @@ -2,7 +2,7 @@ // <copyright file="XmlDocumentType.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlDomTextWriter.cs b/System.Xml/System/Xml/Dom/XmlDomTextWriter.cs index 228d6ff1f..0369f5e16 100644 --- a/System.Xml/System/Xml/Dom/XmlDomTextWriter.cs +++ b/System.Xml/System/Xml/Dom/XmlDomTextWriter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlDomTextWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlElement.cs b/System.Xml/System/Xml/Dom/XmlElement.cs index 66171a917..e2d979845 100644 --- a/System.Xml/System/Xml/Dom/XmlElement.cs +++ b/System.Xml/System/Xml/Dom/XmlElement.cs @@ -2,7 +2,7 @@ // <copyright file="XmlElement.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Dom/XmlElementList.cs b/System.Xml/System/Xml/Dom/XmlElementList.cs index d76e66c2a..ef190d83c 100644 --- a/System.Xml/System/Xml/Dom/XmlElementList.cs +++ b/System.Xml/System/Xml/Dom/XmlElementList.cs @@ -2,7 +2,7 @@ // <copyright file="XmlElementList.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlEntity.cs b/System.Xml/System/Xml/Dom/XmlEntity.cs index 3576d03a7..0522631c1 100644 --- a/System.Xml/System/Xml/Dom/XmlEntity.cs +++ b/System.Xml/System/Xml/Dom/XmlEntity.cs @@ -2,7 +2,7 @@ // <copyright file="XmlEntity.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlEntityReference.cs b/System.Xml/System/Xml/Dom/XmlEntityReference.cs index d9ee2866b..4bb982a16 100644 --- a/System.Xml/System/Xml/Dom/XmlEntityReference.cs +++ b/System.Xml/System/Xml/Dom/XmlEntityReference.cs @@ -2,7 +2,7 @@ // <copyright file="XmlEntityReference.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ // <code>EntityReference</code> objects may be inserted into the structure diff --git a/System.Xml/System/Xml/Dom/XmlImplementation.cs b/System.Xml/System/Xml/Dom/XmlImplementation.cs index 0082d7faf..13711af70 100644 --- a/System.Xml/System/Xml/Dom/XmlImplementation.cs +++ b/System.Xml/System/Xml/Dom/XmlImplementation.cs @@ -2,7 +2,7 @@ // <copyright file="XmlImplementation.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Globalization; diff --git a/System.Xml/System/Xml/Dom/XmlLinkedNode.cs b/System.Xml/System/Xml/Dom/XmlLinkedNode.cs index 0c29d1527..9e62d4674 100644 --- a/System.Xml/System/Xml/Dom/XmlLinkedNode.cs +++ b/System.Xml/System/Xml/Dom/XmlLinkedNode.cs @@ -2,7 +2,7 @@ // <copyright file="XmlLinkedNode.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlLoader.cs b/System.Xml/System/Xml/Dom/XmlLoader.cs index 988ab2d16..ca642eff4 100644 --- a/System.Xml/System/Xml/Dom/XmlLoader.cs +++ b/System.Xml/System/Xml/Dom/XmlLoader.cs @@ -2,7 +2,7 @@ // <copyright file="XmlLoader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlName.cs b/System.Xml/System/Xml/Dom/XmlName.cs index 0b9723361..dc217a6e6 100644 --- a/System.Xml/System/Xml/Dom/XmlName.cs +++ b/System.Xml/System/Xml/Dom/XmlName.cs @@ -2,7 +2,7 @@ // <copyright file="XmlName.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlNamedNodemap.cs b/System.Xml/System/Xml/Dom/XmlNamedNodemap.cs index 5def2f6d2..aa1f05e28 100644 --- a/System.Xml/System/Xml/Dom/XmlNamedNodemap.cs +++ b/System.Xml/System/Xml/Dom/XmlNamedNodemap.cs @@ -2,7 +2,7 @@ // <copyright file="XmlNamedNodeMap.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlNode.cs b/System.Xml/System/Xml/Dom/XmlNode.cs index cebe87087..d814e3d23 100644 --- a/System.Xml/System/Xml/Dom/XmlNode.cs +++ b/System.Xml/System/Xml/Dom/XmlNode.cs @@ -2,7 +2,7 @@ // <copyright file="XmlNode.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlNodeChangedEventArgs.cs b/System.Xml/System/Xml/Dom/XmlNodeChangedEventArgs.cs index 617f0b54c..ac4c5097e 100644 --- a/System.Xml/System/Xml/Dom/XmlNodeChangedEventArgs.cs +++ b/System.Xml/System/Xml/Dom/XmlNodeChangedEventArgs.cs @@ -2,7 +2,7 @@ // <copyright file="XmlNodeChangedEventArgs.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlNodeList.cs b/System.Xml/System/Xml/Dom/XmlNodeList.cs index 697ae9264..d19afba0b 100644 --- a/System.Xml/System/Xml/Dom/XmlNodeList.cs +++ b/System.Xml/System/Xml/Dom/XmlNodeList.cs @@ -2,7 +2,7 @@ // <copyright file="XmlNodeList.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlNodeReader.cs b/System.Xml/System/Xml/Dom/XmlNodeReader.cs index 514b79fb8..2ef079a48 100644 --- a/System.Xml/System/Xml/Dom/XmlNodeReader.cs +++ b/System.Xml/System/Xml/Dom/XmlNodeReader.cs @@ -2,7 +2,7 @@ // <copyright file="XmlNodeReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml diff --git a/System.Xml/System/Xml/Dom/XmlNotation.cs b/System.Xml/System/Xml/Dom/XmlNotation.cs index 79be847a2..527bdcf6b 100644 --- a/System.Xml/System/Xml/Dom/XmlNotation.cs +++ b/System.Xml/System/Xml/Dom/XmlNotation.cs @@ -2,7 +2,7 @@ // <copyright file="XmlNotation.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlProcessingInstruction.cs b/System.Xml/System/Xml/Dom/XmlProcessingInstruction.cs index c940944be..04d09502a 100644 --- a/System.Xml/System/Xml/Dom/XmlProcessingInstruction.cs +++ b/System.Xml/System/Xml/Dom/XmlProcessingInstruction.cs @@ -2,7 +2,7 @@ // <copyright file="XmlProcessingInstruction.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/Dom/XmlSignificantWhiteSpace.cs b/System.Xml/System/Xml/Dom/XmlSignificantWhiteSpace.cs index 70cd9498a..d083222ae 100644 --- a/System.Xml/System/Xml/Dom/XmlSignificantWhiteSpace.cs +++ b/System.Xml/System/Xml/Dom/XmlSignificantWhiteSpace.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSignificantWhiteSpace.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml diff --git a/System.Xml/System/Xml/Dom/XmlText.cs b/System.Xml/System/Xml/Dom/XmlText.cs index 4d9e3dc10..52d745741 100644 --- a/System.Xml/System/Xml/Dom/XmlText.cs +++ b/System.Xml/System/Xml/Dom/XmlText.cs @@ -2,7 +2,7 @@ // <copyright file="XmlText.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml diff --git a/System.Xml/System/Xml/Dom/XmlUnspecifiedAttribute.cs b/System.Xml/System/Xml/Dom/XmlUnspecifiedAttribute.cs index c1a0974d0..fecd81cc5 100644 --- a/System.Xml/System/Xml/Dom/XmlUnspecifiedAttribute.cs +++ b/System.Xml/System/Xml/Dom/XmlUnspecifiedAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlUnspecifiedAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml diff --git a/System.Xml/System/Xml/Dom/XmlWhitespace.cs b/System.Xml/System/Xml/Dom/XmlWhitespace.cs index ce4f166e8..3e0df6ab3 100644 --- a/System.Xml/System/Xml/Dom/XmlWhitespace.cs +++ b/System.Xml/System/Xml/Dom/XmlWhitespace.cs @@ -2,7 +2,7 @@ // <copyright file="XmlWhitespace.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml diff --git a/System.Xml/System/Xml/EmptyEnumerator.cs b/System.Xml/System/Xml/EmptyEnumerator.cs index b9c7f41d8..5d9787f12 100644 --- a/System.Xml/System/Xml/EmptyEnumerator.cs +++ b/System.Xml/System/Xml/EmptyEnumerator.cs @@ -2,7 +2,7 @@ // <copyright file="EmptyEnumerator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/HWStack.cs b/System.Xml/System/Xml/HWStack.cs index 9df2ad165..2f076f8c8 100644 --- a/System.Xml/System/Xml/HWStack.cs +++ b/System.Xml/System/Xml/HWStack.cs @@ -2,7 +2,7 @@ // <copyright file="HWStack.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/IXmlLineInfo.cs b/System.Xml/System/Xml/IXmlLineInfo.cs index a5503a177..438840e1c 100644 --- a/System.Xml/System/Xml/IXmlLineInfo.cs +++ b/System.Xml/System/Xml/IXmlLineInfo.cs @@ -2,7 +2,7 @@ // <copyright file="IXmlLineInfo.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/LineInfo.cs b/System.Xml/System/Xml/LineInfo.cs index 4095a490d..76afcce36 100644 --- a/System.Xml/System/Xml/LineInfo.cs +++ b/System.Xml/System/Xml/LineInfo.cs @@ -2,7 +2,7 @@ // <copyright file="LineInfo.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/NameTable.cs b/System.Xml/System/Xml/NameTable.cs index debdacdd3..9ffc2ff5e 100644 --- a/System.Xml/System/Xml/NameTable.cs +++ b/System.Xml/System/Xml/NameTable.cs @@ -2,7 +2,7 @@ // <copyright file="NameTable.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Ref.cs b/System.Xml/System/Xml/Ref.cs index f90790b10..8df1dc313 100644 --- a/System.Xml/System/Xml/Ref.cs +++ b/System.Xml/System/Xml/Ref.cs @@ -2,7 +2,7 @@ // <copyright file="Ref.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Diagnostics; diff --git a/System.Xml/System/Xml/Resolvers/XmlPreloadedResolver.cs b/System.Xml/System/Xml/Resolvers/XmlPreloadedResolver.cs index 69f9f41d7..e3b347a51 100644 --- a/System.Xml/System/Xml/Resolvers/XmlPreloadedResolver.cs +++ b/System.Xml/System/Xml/Resolvers/XmlPreloadedResolver.cs @@ -2,7 +2,7 @@ // <copyright file="XmlPreloadedResolver.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.IO; diff --git a/System.Xml/System/Xml/Resolvers/XmlPreloadedResolverAsync.cs b/System.Xml/System/Xml/Resolvers/XmlPreloadedResolverAsync.cs index 01cde42a3..109c6e6ad 100644 --- a/System.Xml/System/Xml/Resolvers/XmlPreloadedResolverAsync.cs +++ b/System.Xml/System/Xml/Resolvers/XmlPreloadedResolverAsync.cs @@ -2,7 +2,7 @@ // <copyright file="XmlPreloadedResolver.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.IO; diff --git a/System.Xml/System/Xml/Schema/Asttree.cs b/System.Xml/System/Xml/Schema/Asttree.cs index 48074ea45..31facd0a7 100644 --- a/System.Xml/System/Xml/Schema/Asttree.cs +++ b/System.Xml/System/Xml/Schema/Asttree.cs @@ -2,7 +2,7 @@ // <copyright file="asttree.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/AutoValidator.cs b/System.Xml/System/Xml/Schema/AutoValidator.cs index a18d39a6b..33231373d 100644 --- a/System.Xml/System/Xml/Schema/AutoValidator.cs +++ b/System.Xml/System/Xml/Schema/AutoValidator.cs @@ -2,7 +2,7 @@ // <copyright file="AutoValidator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/BaseProcessor.cs b/System.Xml/System/Xml/Schema/BaseProcessor.cs index 287f39f7a..e6cf4bd1e 100644 --- a/System.Xml/System/Xml/Schema/BaseProcessor.cs +++ b/System.Xml/System/Xml/Schema/BaseProcessor.cs @@ -2,7 +2,7 @@ // <copyright file="BaseProcessor.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/BaseValidator.cs b/System.Xml/System/Xml/Schema/BaseValidator.cs index a41795d18..772630727 100644 --- a/System.Xml/System/Xml/Schema/BaseValidator.cs +++ b/System.Xml/System/Xml/Schema/BaseValidator.cs @@ -2,7 +2,7 @@ // <copyright file="BaseValidator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/BitSet.cs b/System.Xml/System/Xml/Schema/BitSet.cs index 564c593ce..f8573bbcf 100644 --- a/System.Xml/System/Xml/Schema/BitSet.cs +++ b/System.Xml/System/Xml/Schema/BitSet.cs @@ -2,7 +2,7 @@ // <copyright file="BitSet.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/Chameleonkey.cs b/System.Xml/System/Xml/Schema/Chameleonkey.cs index 2cf8040e5..b487289d7 100644 --- a/System.Xml/System/Xml/Schema/Chameleonkey.cs +++ b/System.Xml/System/Xml/Schema/Chameleonkey.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaExternal.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/CompiledidEntityConstraint.cs b/System.Xml/System/Xml/Schema/CompiledidEntityConstraint.cs index afe0acdf7..d6bb8a5ea 100644 --- a/System.Xml/System/Xml/Schema/CompiledidEntityConstraint.cs +++ b/System.Xml/System/Xml/Schema/CompiledidEntityConstraint.cs @@ -2,7 +2,7 @@ // <copyright file="CompiledIdentityConstraint.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/ConstraintStruct.cs b/System.Xml/System/Xml/Schema/ConstraintStruct.cs index 4e6cbfc1c..33c6391c8 100644 --- a/System.Xml/System/Xml/Schema/ConstraintStruct.cs +++ b/System.Xml/System/Xml/Schema/ConstraintStruct.cs @@ -2,7 +2,7 @@ // <copyright file="ConstraintStruct.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/ContentValidator.cs b/System.Xml/System/Xml/Schema/ContentValidator.cs index fcee874bd..a2eb25b66 100644 --- a/System.Xml/System/Xml/Schema/ContentValidator.cs +++ b/System.Xml/System/Xml/Schema/ContentValidator.cs @@ -2,7 +2,7 @@ // <copyright file="ContentValidator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Xml/System/Xml/Schema/DataTypeImplementation.cs b/System.Xml/System/Xml/Schema/DataTypeImplementation.cs index efeab3644..2e85e1866 100644 --- a/System.Xml/System/Xml/Schema/DataTypeImplementation.cs +++ b/System.Xml/System/Xml/Schema/DataTypeImplementation.cs @@ -2,7 +2,7 @@ // <copyright file="DatatypeImplementation.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { @@ -805,7 +805,7 @@ protected int Compare(byte[] value1, byte[] value2) { return 0; } -#if PRIYAL +#if Microsoft protected object GetValueToCheck(object value, IXmlNamespaceResolver nsmgr) { object valueToCheck = value; string resId; diff --git a/System.Xml/System/Xml/Schema/DtdParser.cs b/System.Xml/System/Xml/Schema/DtdParser.cs index a9d85fc20..c72fe649f 100644 --- a/System.Xml/System/Xml/Schema/DtdParser.cs +++ b/System.Xml/System/Xml/Schema/DtdParser.cs @@ -3,7 +3,7 @@ // <copyright file="DtdParser.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Schema/DtdValidator.cs b/System.Xml/System/Xml/Schema/DtdValidator.cs index f103e3da0..086df1b39 100644 --- a/System.Xml/System/Xml/Schema/DtdValidator.cs +++ b/System.Xml/System/Xml/Schema/DtdValidator.cs @@ -2,7 +2,7 @@ // <copyright file="DtdValidator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/FacetChecker.cs b/System.Xml/System/Xml/Schema/FacetChecker.cs index 398a2aa52..ea32d7099 100644 --- a/System.Xml/System/Xml/Schema/FacetChecker.cs +++ b/System.Xml/System/Xml/Schema/FacetChecker.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaFacet.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/Inference/Infer.cs b/System.Xml/System/Xml/Schema/Inference/Infer.cs index 2c7ce79c3..18b13628c 100644 --- a/System.Xml/System/Xml/Schema/Inference/Infer.cs +++ b/System.Xml/System/Xml/Schema/Inference/Infer.cs @@ -2,8 +2,8 @@ // <copyright file="Infer.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> -// <owner current="false" primary="false">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> +// <owner current="false" primary="false">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs b/System.Xml/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs index d41c45f14..69a3156bf 100644 --- a/System.Xml/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs +++ b/System.Xml/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs @@ -2,8 +2,8 @@ // <copyright file="XmlSchemaInferenceException.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> -// <owner current="false" primary="false">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> +// <owner current="false" primary="false">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema diff --git a/System.Xml/System/Xml/Schema/NamespaceList.cs b/System.Xml/System/Xml/Schema/NamespaceList.cs index 7cb6a8a33..93ecf3f60 100644 --- a/System.Xml/System/Xml/Schema/NamespaceList.cs +++ b/System.Xml/System/Xml/Schema/NamespaceList.cs @@ -2,7 +2,7 @@ // <copyright file="NamespaceList.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ diff --git a/System.Xml/System/Xml/Schema/Parser.cs b/System.Xml/System/Xml/Schema/Parser.cs index 4f38bf400..e296e7446 100644 --- a/System.Xml/System/Xml/Schema/Parser.cs +++ b/System.Xml/System/Xml/Schema/Parser.cs @@ -3,7 +3,7 @@ // <copyright file="Parser.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/Preprocessor.cs b/System.Xml/System/Xml/Schema/Preprocessor.cs index e7dd3880a..06af06469 100644 --- a/System.Xml/System/Xml/Schema/Preprocessor.cs +++ b/System.Xml/System/Xml/Schema/Preprocessor.cs @@ -2,7 +2,7 @@ // <copyright file="Preprocessor.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/SchemaAttDef.cs b/System.Xml/System/Xml/Schema/SchemaAttDef.cs index 48becdf5b..0cd4d5757 100644 --- a/System.Xml/System/Xml/Schema/SchemaAttDef.cs +++ b/System.Xml/System/Xml/Schema/SchemaAttDef.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaAttDef.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/SchemaCollectionCompiler.cs b/System.Xml/System/Xml/Schema/SchemaCollectionCompiler.cs index 314986435..e716aa30d 100644 --- a/System.Xml/System/Xml/Schema/SchemaCollectionCompiler.cs +++ b/System.Xml/System/Xml/Schema/SchemaCollectionCompiler.cs @@ -2,7 +2,7 @@ // <copyright file="Compiler.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/SchemaCollectionpreProcessor.cs b/System.Xml/System/Xml/Schema/SchemaCollectionpreProcessor.cs index 82e408150..f2fa40056 100644 --- a/System.Xml/System/Xml/Schema/SchemaCollectionpreProcessor.cs +++ b/System.Xml/System/Xml/Schema/SchemaCollectionpreProcessor.cs @@ -2,7 +2,7 @@ // <copyright file="Preprocessor.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/SchemaDeclBase.cs b/System.Xml/System/Xml/Schema/SchemaDeclBase.cs index 65c11d09c..22f1d1dc8 100644 --- a/System.Xml/System/Xml/Schema/SchemaDeclBase.cs +++ b/System.Xml/System/Xml/Schema/SchemaDeclBase.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaDeclBase.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/SchemaElementDecl.cs b/System.Xml/System/Xml/Schema/SchemaElementDecl.cs index 52d641f92..345c89d13 100644 --- a/System.Xml/System/Xml/Schema/SchemaElementDecl.cs +++ b/System.Xml/System/Xml/Schema/SchemaElementDecl.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaElementDecl.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/SchemaEntity.cs b/System.Xml/System/Xml/Schema/SchemaEntity.cs index c0c96d0d9..f326c5bfe 100644 --- a/System.Xml/System/Xml/Schema/SchemaEntity.cs +++ b/System.Xml/System/Xml/Schema/SchemaEntity.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaEntity.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/SchemaInfo.cs b/System.Xml/System/Xml/Schema/SchemaInfo.cs index 6429bcad3..294ef6a35 100644 --- a/System.Xml/System/Xml/Schema/SchemaInfo.cs +++ b/System.Xml/System/Xml/Schema/SchemaInfo.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaInfo.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Schema/SchemaNames.cs b/System.Xml/System/Xml/Schema/SchemaNames.cs index fb87652be..c255e23f5 100644 --- a/System.Xml/System/Xml/Schema/SchemaNames.cs +++ b/System.Xml/System/Xml/Schema/SchemaNames.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaNames.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/SchemaNamespacemanager.cs b/System.Xml/System/Xml/Schema/SchemaNamespacemanager.cs index af750839a..ee380b1c1 100644 --- a/System.Xml/System/Xml/Schema/SchemaNamespacemanager.cs +++ b/System.Xml/System/Xml/Schema/SchemaNamespacemanager.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaNamespaceManager.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/SchemaNotation.cs b/System.Xml/System/Xml/Schema/SchemaNotation.cs index 2c9604ce5..e156aa006 100644 --- a/System.Xml/System/Xml/Schema/SchemaNotation.cs +++ b/System.Xml/System/Xml/Schema/SchemaNotation.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaNotation.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/SchemaSetCompiler.cs b/System.Xml/System/Xml/Schema/SchemaSetCompiler.cs index d1dc9412e..348c2763c 100644 --- a/System.Xml/System/Xml/Schema/SchemaSetCompiler.cs +++ b/System.Xml/System/Xml/Schema/SchemaSetCompiler.cs @@ -2,7 +2,7 @@ // <copyright file="Compiler.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { @@ -591,7 +591,7 @@ private XmlSchemaSimpleType[] CompileBaseMemberTypes(XmlSchemaSimpleType simpleT } //Now add the baseTypes that are defined inside the union itself - XmlSchemaObjectCollection mainBaseTypes = mainUnion.BaseTypes; //TODO check for null + XmlSchemaObjectCollection mainBaseTypes = mainUnion.BaseTypes; // if (mainBaseTypes != null) { for (int i = 0; i < mainBaseTypes.Count; ++i) { XmlSchemaSimpleType st = (XmlSchemaSimpleType)mainBaseTypes[i]; @@ -1365,7 +1365,7 @@ private bool IsGroupBaseFromAny(XmlSchemaGroupBase derivedGroupBase, XmlSchemaAn return true; } -#if PRIYAL +#if Microsoft private bool IsElementFromGroupBase(XmlSchemaElement derivedElement, XmlSchemaGroupBase baseGroupBase, bool skipEmptableOnly) { if (!IsRangeSimple(baseGroupBase.MinOccurs, baseGroupBase.MaxOccurs) || !IsRangeSimple(derivedElement.MinOccurs, derivedElement.MaxOccurs)) { return IsElementFromGroupBase(derivedElement, baseGroupBase); //SPEC COMPLIANT diff --git a/System.Xml/System/Xml/Schema/ValidationEventArgs.cs b/System.Xml/System/Xml/Schema/ValidationEventArgs.cs index 8cce19ff1..779280b7e 100644 --- a/System.Xml/System/Xml/Schema/ValidationEventArgs.cs +++ b/System.Xml/System/Xml/Schema/ValidationEventArgs.cs @@ -2,7 +2,7 @@ // <copyright file="ValidationEventArgs.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/ValidationState.cs b/System.Xml/System/Xml/Schema/ValidationState.cs index 8d60154db..8efbae5e5 100644 --- a/System.Xml/System/Xml/Schema/ValidationState.cs +++ b/System.Xml/System/Xml/Schema/ValidationState.cs @@ -2,7 +2,7 @@ // <copyright file="validationstate.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XdrBuilder.cs b/System.Xml/System/Xml/Schema/XdrBuilder.cs index d19527ca7..fb5d27057 100644 --- a/System.Xml/System/Xml/Schema/XdrBuilder.cs +++ b/System.Xml/System/Xml/Schema/XdrBuilder.cs @@ -2,7 +2,7 @@ // <copyright file="XdrBuilder.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XdrValidator.cs b/System.Xml/System/Xml/Schema/XdrValidator.cs index 232088c90..1f68d23b7 100644 --- a/System.Xml/System/Xml/Schema/XdrValidator.cs +++ b/System.Xml/System/Xml/Schema/XdrValidator.cs @@ -2,7 +2,7 @@ // <copyright file="XdrValidator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlAtomicValue.cs b/System.Xml/System/Xml/Schema/XmlAtomicValue.cs index b5f81386b..20356ef46 100644 --- a/System.Xml/System/Xml/Schema/XmlAtomicValue.cs +++ b/System.Xml/System/Xml/Schema/XmlAtomicValue.cs @@ -2,7 +2,7 @@ // <copyright file="XmlAtomicValue.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Xml/System/Xml/Schema/XmlSchema.cs b/System.Xml/System/Xml/Schema/XmlSchema.cs index 569b5bf53..58e4d475e 100644 --- a/System.Xml/System/Xml/Schema/XmlSchema.cs +++ b/System.Xml/System/Xml/Schema/XmlSchema.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchema.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaAll.cs b/System.Xml/System/Xml/Schema/XmlSchemaAll.cs index 2b84df839..049a900b6 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaAll.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaAll.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaAll.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaAnnotated.cs b/System.Xml/System/Xml/Schema/XmlSchemaAnnotated.cs index 48c108af7..836e430db 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaAnnotated.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaAnnotated.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaAnnotated.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaAnnotation.cs b/System.Xml/System/Xml/Schema/XmlSchemaAnnotation.cs index c3a052d0e..9fd7fd10f 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaAnnotation.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaAnnotation.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaAnnotation.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaAny.cs b/System.Xml/System/Xml/Schema/XmlSchemaAny.cs index a57e92753..a811ed67e 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaAny.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaAny.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaAny.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaAnyAttribute.cs b/System.Xml/System/Xml/Schema/XmlSchemaAnyAttribute.cs index c1fc90449..8eb31c731 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaAnyAttribute.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaAnyAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaAnyAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaAppInfo.cs b/System.Xml/System/Xml/Schema/XmlSchemaAppInfo.cs index c738d792a..aba46e610 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaAppInfo.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaAppInfo.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaAppInfo.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaAttribute.cs b/System.Xml/System/Xml/Schema/XmlSchemaAttribute.cs index 30eebaaac..4920ccbbe 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaAttribute.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Xml/System/Xml/Schema/XmlSchemaAttributeGroup.cs b/System.Xml/System/Xml/Schema/XmlSchemaAttributeGroup.cs index f05e75f10..46ee40ef0 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaAttributeGroup.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaAttributeGroup.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaAttributeGroup.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaAttributeGroupref.cs b/System.Xml/System/Xml/Schema/XmlSchemaAttributeGroupref.cs index d42202a8f..b69122fe3 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaAttributeGroupref.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaAttributeGroupref.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaAttributeGroupRef.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaChoice.cs b/System.Xml/System/Xml/Schema/XmlSchemaChoice.cs index db19ae6e2..9e4e15769 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaChoice.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaChoice.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaChoice.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaCollection.cs b/System.Xml/System/Xml/Schema/XmlSchemaCollection.cs index 38b1e0240..23f4a3c21 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaCollection.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaCollection.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaCollection.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaCompilationSettings.cs b/System.Xml/System/Xml/Schema/XmlSchemaCompilationSettings.cs index babedcc1c..c0544a162 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaCompilationSettings.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaCompilationSettings.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaDerivationMethod.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaComplexContent.cs b/System.Xml/System/Xml/Schema/XmlSchemaComplexContent.cs index 87560df0c..7fd72fb39 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaComplexContent.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaComplexContent.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaComplexContent.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaComplexContentExtension.cs b/System.Xml/System/Xml/Schema/XmlSchemaComplexContentExtension.cs index 8404e53b5..ba4213a29 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaComplexContentExtension.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaComplexContentExtension.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaComplexContentExtension.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaComplexContentRestriction.cs b/System.Xml/System/Xml/Schema/XmlSchemaComplexContentRestriction.cs index 522d63544..1879a3b34 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaComplexContentRestriction.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaComplexContentRestriction.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaComplexContentRestriction.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaComplexType.cs b/System.Xml/System/Xml/Schema/XmlSchemaComplexType.cs index 1db07809c..0ce2f136c 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaComplexType.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaComplexType.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaComplexType.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaDataType.cs b/System.Xml/System/Xml/Schema/XmlSchemaDataType.cs index 164891340..28bd99b2d 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaDataType.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaDataType.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaDatatype.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Collections; using System.Diagnostics; @@ -337,7 +337,7 @@ internal static string XdrCanonizeUri(string uri, XmlNameTable nameTable, Schema return canonicalUri; } -#if PRIYAL +#if Microsoft private bool CanConvert(object value, System.Type inputType, System.Type defaultType, out string resId) { resId = null; decimal decimalValue; diff --git a/System.Xml/System/Xml/Schema/XmlSchemaDocumentation.cs b/System.Xml/System/Xml/Schema/XmlSchemaDocumentation.cs index 8468b38d2..a3d46ffb9 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaDocumentation.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaDocumentation.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaDocumentation.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaElement.cs b/System.Xml/System/Xml/Schema/XmlSchemaElement.cs index fd7e91449..52604d931 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaElement.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaElement.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaElement.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.ComponentModel; diff --git a/System.Xml/System/Xml/Schema/XmlSchemaException.cs b/System.Xml/System/Xml/Schema/XmlSchemaException.cs index 508c058bb..6f9aebcca 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaException.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaException.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaException.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaExternal.cs b/System.Xml/System/Xml/Schema/XmlSchemaExternal.cs index 29f2d0d73..b5e41e694 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaExternal.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaExternal.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaExternal.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaFacet.cs b/System.Xml/System/Xml/Schema/XmlSchemaFacet.cs index df6402047..1a5478697 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaFacet.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaFacet.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaFacet.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaGroup.cs b/System.Xml/System/Xml/Schema/XmlSchemaGroup.cs index 0453e2f6d..df6049d0c 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaGroup.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaGroup.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaGroup.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaGroupRef.cs b/System.Xml/System/Xml/Schema/XmlSchemaGroupRef.cs index 8f6bfd74f..973cfbf60 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaGroupRef.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaGroupRef.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaGroupRef.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaIdEntityConstraint.cs b/System.Xml/System/Xml/Schema/XmlSchemaIdEntityConstraint.cs index 94ff513cd..768a05dfb 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaIdEntityConstraint.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaIdEntityConstraint.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaIdentityConstraint.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaImport.cs b/System.Xml/System/Xml/Schema/XmlSchemaImport.cs index 4683a0a74..68aa2a3fe 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaImport.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaImport.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaImport.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaInclude.cs b/System.Xml/System/Xml/Schema/XmlSchemaInclude.cs index 143944e44..a7d9fc838 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaInclude.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaInclude.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaInclude.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaInfo.cs b/System.Xml/System/Xml/Schema/XmlSchemaInfo.cs index 81d503a13..e8a764df5 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaInfo.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaInfo.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaInfo.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Xml; diff --git a/System.Xml/System/Xml/Schema/XmlSchemaNotation.cs b/System.Xml/System/Xml/Schema/XmlSchemaNotation.cs index 38178eccd..cc14abe77 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaNotation.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaNotation.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaNotation.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaObject.cs b/System.Xml/System/Xml/Schema/XmlSchemaObject.cs index 7c42f39bc..70c41758f 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaObject.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaObject.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaObject.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaObjectCollection.cs b/System.Xml/System/Xml/Schema/XmlSchemaObjectCollection.cs index a3e46ec07..aa392aea9 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaObjectCollection.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaObjectCollection.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaObjectCollection.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaObjectTable.cs b/System.Xml/System/Xml/Schema/XmlSchemaObjectTable.cs index 5277ce639..ff82368dd 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaObjectTable.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaObjectTable.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaObjectTable.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaParticle.cs b/System.Xml/System/Xml/Schema/XmlSchemaParticle.cs index 7ed178dbe..4317b7302 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaParticle.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaParticle.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaParticle.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaRedefine.cs b/System.Xml/System/Xml/Schema/XmlSchemaRedefine.cs index baa659da8..1eb572a43 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaRedefine.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaRedefine.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaRedefine.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaSequence.cs b/System.Xml/System/Xml/Schema/XmlSchemaSequence.cs index 9ea17ae09..73a329725 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaSequence.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaSequence.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaSequence.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaSet.cs b/System.Xml/System/Xml/Schema/XmlSchemaSet.cs index ab9d27e27..978f36793 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaSet.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaSet.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaSet.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Diagnostics; using System.Collections; diff --git a/System.Xml/System/Xml/Schema/XmlSchemaSimpleContent.cs b/System.Xml/System/Xml/Schema/XmlSchemaSimpleContent.cs index 72b8e838c..09e12ca1d 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaSimpleContent.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaSimpleContent.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaSimpleContent.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaSimpleContentExtension.cs b/System.Xml/System/Xml/Schema/XmlSchemaSimpleContentExtension.cs index bd843c600..518fc1a80 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaSimpleContentExtension.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaSimpleContentExtension.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaSimpleContentExtension.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaSimpleContentRestriction.cs b/System.Xml/System/Xml/Schema/XmlSchemaSimpleContentRestriction.cs index 44ba84957..6d5572294 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaSimpleContentRestriction.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaSimpleContentRestriction.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaSimpleContentRestriction.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaSimpleType.cs b/System.Xml/System/Xml/Schema/XmlSchemaSimpleType.cs index fc2d9a636..7c5f4e01c 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaSimpleType.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaSimpleType.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaSimpleType.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeList.cs b/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeList.cs index b61ad2ced..e4c1d46e3 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeList.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeList.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaSimpleTypeList.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeRestriction.cs b/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeRestriction.cs index 00a50e25d..ed297392f 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeRestriction.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeRestriction.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaSimpleTypeRestriction.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeUnion.cs b/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeUnion.cs index 7b0f5d209..b79aa843e 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeUnion.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaSimpleTypeUnion.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaSimpleTypeUnion.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaSubstitutionGroup.cs b/System.Xml/System/Xml/Schema/XmlSchemaSubstitutionGroup.cs index 57c128310..8a9a38a1f 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaSubstitutionGroup.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaSubstitutionGroup.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaSubstitutionGroup.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaType.cs b/System.Xml/System/Xml/Schema/XmlSchemaType.cs index 033fa6c43..03330c744 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaType.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaType.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaType.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Xml/System/Xml/Schema/XmlSchemaValidationException.cs b/System.Xml/System/Xml/Schema/XmlSchemaValidationException.cs index 7f6719ef1..855c9e0cb 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaValidationException.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaValidationException.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaValidationException.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XmlSchemaValidator.cs b/System.Xml/System/Xml/Schema/XmlSchemaValidator.cs index acfd701d4..6d42c73a6 100644 --- a/System.Xml/System/Xml/Schema/XmlSchemaValidator.cs +++ b/System.Xml/System/Xml/Schema/XmlSchemaValidator.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaValidator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Schema/XmlValueConverter.cs b/System.Xml/System/Xml/Schema/XmlValueConverter.cs index 02ccfd06e..10742ccec 100644 --- a/System.Xml/System/Xml/Schema/XmlValueConverter.cs +++ b/System.Xml/System/Xml/Schema/XmlValueConverter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlValueConverter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; using System.Xml; diff --git a/System.Xml/System/Xml/Schema/XsdBuilder.cs b/System.Xml/System/Xml/Schema/XsdBuilder.cs index 21c0ddc0e..1b003a79e 100644 --- a/System.Xml/System/Xml/Schema/XsdBuilder.cs +++ b/System.Xml/System/Xml/Schema/XsdBuilder.cs @@ -2,7 +2,7 @@ // <copyright file="XsdBuilder.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XsdDateTime.cs b/System.Xml/System/Xml/Schema/XsdDateTime.cs index 41b2d7223..923651d28 100644 --- a/System.Xml/System/Xml/Schema/XsdDateTime.cs +++ b/System.Xml/System/Xml/Schema/XsdDateTime.cs @@ -2,7 +2,7 @@ // <copyright file="XsdDuration.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XsdDuration.cs b/System.Xml/System/Xml/Schema/XsdDuration.cs index cd8d56364..8efe7a1fb 100644 --- a/System.Xml/System/Xml/Schema/XsdDuration.cs +++ b/System.Xml/System/Xml/Schema/XsdDuration.cs @@ -2,7 +2,7 @@ // <copyright file="XsdDuration.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Schema/XsdValidator.cs b/System.Xml/System/Xml/Schema/XsdValidator.cs index 32f4e9275..eeed4aeca 100644 --- a/System.Xml/System/Xml/Schema/XsdValidator.cs +++ b/System.Xml/System/Xml/Schema/XsdValidator.cs @@ -2,7 +2,7 @@ // <copyright file="XsdValidator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Schema { diff --git a/System.Xml/System/Xml/Serialization/Advanced/SchemaImporterExtension.cs b/System.Xml/System/Xml/Serialization/Advanced/SchemaImporterExtension.cs index 405b942ee..c619b6c7a 100644 --- a/System.Xml/System/Xml/Serialization/Advanced/SchemaImporterExtension.cs +++ b/System.Xml/System/Xml/Serialization/Advanced/SchemaImporterExtension.cs @@ -2,7 +2,7 @@ // <copyright file="IXmlSerializable.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization.Advanced { diff --git a/System.Xml/System/Xml/Serialization/CodeExporter.cs b/System.Xml/System/Xml/Serialization/CodeExporter.cs index 5084e376c..4b1cfbc7e 100644 --- a/System.Xml/System/Xml/Serialization/CodeExporter.cs +++ b/System.Xml/System/Xml/Serialization/CodeExporter.cs @@ -2,7 +2,7 @@ // <copyright file="CodeExporter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/CodeGenerator.cs b/System.Xml/System/Xml/Serialization/CodeGenerator.cs index 59daa34a2..bba1d884d 100644 --- a/System.Xml/System/Xml/Serialization/CodeGenerator.cs +++ b/System.Xml/System/Xml/Serialization/CodeGenerator.cs @@ -2,7 +2,7 @@ // <copyright file="CodeGenerator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/Serialization/CodeIdentifier.cs b/System.Xml/System/Xml/Serialization/CodeIdentifier.cs index 324f1af21..c0dea737d 100644 --- a/System.Xml/System/Xml/Serialization/CodeIdentifier.cs +++ b/System.Xml/System/Xml/Serialization/CodeIdentifier.cs @@ -2,7 +2,7 @@ // <copyright file="CodeIdentifier.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/CodeIdentifiers.cs b/System.Xml/System/Xml/Serialization/CodeIdentifiers.cs index 1213c82f2..33c37fb94 100644 --- a/System.Xml/System/Xml/Serialization/CodeIdentifiers.cs +++ b/System.Xml/System/Xml/Serialization/CodeIdentifiers.cs @@ -2,7 +2,7 @@ // <copyright file="CodeIdentifiers.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/Compilation.cs b/System.Xml/System/Xml/Serialization/Compilation.cs index 686958833..7706d7f97 100644 --- a/System.Xml/System/Xml/Serialization/Compilation.cs +++ b/System.Xml/System/Xml/Serialization/Compilation.cs @@ -2,7 +2,7 @@ // <copyright file="Compilation.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/Compiler.cs b/System.Xml/System/Xml/Serialization/Compiler.cs index a415250e5..1cd1c6499 100644 --- a/System.Xml/System/Xml/Serialization/Compiler.cs +++ b/System.Xml/System/Xml/Serialization/Compiler.cs @@ -2,7 +2,7 @@ // <copyright file="Compiler.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/Configuration/ConfigurationStrings.cs b/System.Xml/System/Xml/Serialization/Configuration/ConfigurationStrings.cs index 76688cdf0..34b7f45b4 100644 --- a/System.Xml/System/Xml/Serialization/Configuration/ConfigurationStrings.cs +++ b/System.Xml/System/Xml/Serialization/Configuration/ConfigurationStrings.cs @@ -2,7 +2,7 @@ // <copyright file="ConfigurationStrings.cs" company="Microsoft Corporation"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization.Configuration { diff --git a/System.Xml/System/Xml/Serialization/Configuration/DateTimeSerializationSection.cs b/System.Xml/System/Xml/Serialization/Configuration/DateTimeSerializationSection.cs index 027acb398..35fe5d870 100644 --- a/System.Xml/System/Xml/Serialization/Configuration/DateTimeSerializationSection.cs +++ b/System.Xml/System/Xml/Serialization/Configuration/DateTimeSerializationSection.cs @@ -2,7 +2,7 @@ // <copyright file="DateTimeSerializationSection.cs" company="Microsoft Corporation"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization.Configuration diff --git a/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionElement.cs b/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionElement.cs index 7f39043eb..d9888c041 100644 --- a/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionElement.cs +++ b/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionElement.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaImporterExtensionElement.cs" company="Microsoft Corporation"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization.Configuration diff --git a/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionElementCollection.cs b/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionElementCollection.cs index e07656322..3f899c42c 100644 --- a/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionElementCollection.cs +++ b/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionElementCollection.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaImporterExtensionElementCollection.cs" company="Microsoft Corporation"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization.Configuration diff --git a/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionsSection.cs b/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionsSection.cs index 3ecdd9aa4..24cceb88b 100644 --- a/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionsSection.cs +++ b/System.Xml/System/Xml/Serialization/Configuration/SchemaImporterExtensionsSection.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaImporterExtensionsSection.cs" company="Microsoft Corporation"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization.Configuration diff --git a/System.Xml/System/Xml/Serialization/Configuration/SerializationSectionGroup.cs b/System.Xml/System/Xml/Serialization/Configuration/SerializationSectionGroup.cs index 331af984e..d580ade6d 100644 --- a/System.Xml/System/Xml/Serialization/Configuration/SerializationSectionGroup.cs +++ b/System.Xml/System/Xml/Serialization/Configuration/SerializationSectionGroup.cs @@ -2,7 +2,7 @@ // <copyright file="SerializationSectionGroup.cs" company="Microsoft Corporation"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization.Configuration diff --git a/System.Xml/System/Xml/Serialization/ImportContext.cs b/System.Xml/System/Xml/Serialization/ImportContext.cs index 7a4bd83ad..0020cbd41 100644 --- a/System.Xml/System/Xml/Serialization/ImportContext.cs +++ b/System.Xml/System/Xml/Serialization/ImportContext.cs @@ -2,7 +2,7 @@ // <copyright file="ImportContext.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/Mappings.cs b/System.Xml/System/Xml/Serialization/Mappings.cs index b1143fdd1..b8be09a3a 100644 --- a/System.Xml/System/Xml/Serialization/Mappings.cs +++ b/System.Xml/System/Xml/Serialization/Mappings.cs @@ -2,7 +2,7 @@ // <copyright file="Mappings.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/Models.cs b/System.Xml/System/Xml/Serialization/Models.cs index a555726ea..adeb66317 100644 --- a/System.Xml/System/Xml/Serialization/Models.cs +++ b/System.Xml/System/Xml/Serialization/Models.cs @@ -2,7 +2,7 @@ // <copyright file="Models.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/NameTable.cs b/System.Xml/System/Xml/Serialization/NameTable.cs index eb9a3973a..9df48e366 100644 --- a/System.Xml/System/Xml/Serialization/NameTable.cs +++ b/System.Xml/System/Xml/Serialization/NameTable.cs @@ -2,7 +2,7 @@ // <copyright file="NameTable.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/PrimitiveXmlSerializers.cs b/System.Xml/System/Xml/Serialization/PrimitiveXmlSerializers.cs index 5915f59b1..d2df57b81 100644 --- a/System.Xml/System/Xml/Serialization/PrimitiveXmlSerializers.cs +++ b/System.Xml/System/Xml/Serialization/PrimitiveXmlSerializers.cs @@ -2,7 +2,7 @@ // <copyright file="PrimitiveXmlSerializers.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SchemaImporter.cs b/System.Xml/System/Xml/Serialization/SchemaImporter.cs index df6e2baa7..98b437c73 100644 --- a/System.Xml/System/Xml/Serialization/SchemaImporter.cs +++ b/System.Xml/System/Xml/Serialization/SchemaImporter.cs @@ -2,7 +2,7 @@ // <copyright file="SchemaImporter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SchemaObjectWriter.cs b/System.Xml/System/Xml/Serialization/SchemaObjectWriter.cs index 0c356f8b4..c3cdc3dfa 100644 --- a/System.Xml/System/Xml/Serialization/SchemaObjectWriter.cs +++ b/System.Xml/System/Xml/Serialization/SchemaObjectWriter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaSerializer.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapAttributeAttribute.cs b/System.Xml/System/Xml/Serialization/SoapAttributeAttribute.cs index c67b07494..b7d0b0173 100644 --- a/System.Xml/System/Xml/Serialization/SoapAttributeAttribute.cs +++ b/System.Xml/System/Xml/Serialization/SoapAttributeAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="SoapAttributeAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapAttributeOverrides.cs b/System.Xml/System/Xml/Serialization/SoapAttributeOverrides.cs index 70e4578fd..973efa75f 100644 --- a/System.Xml/System/Xml/Serialization/SoapAttributeOverrides.cs +++ b/System.Xml/System/Xml/Serialization/SoapAttributeOverrides.cs @@ -2,7 +2,7 @@ // <copyright file="SoapAttributeOverrides.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapAttributes.cs b/System.Xml/System/Xml/Serialization/SoapAttributes.cs index 7e51c2ae2..1351c4f24 100644 --- a/System.Xml/System/Xml/Serialization/SoapAttributes.cs +++ b/System.Xml/System/Xml/Serialization/SoapAttributes.cs @@ -2,7 +2,7 @@ // <copyright file="SoapAttributes.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapCodeExporter.cs b/System.Xml/System/Xml/Serialization/SoapCodeExporter.cs index f7b9ed878..0f6903891 100644 --- a/System.Xml/System/Xml/Serialization/SoapCodeExporter.cs +++ b/System.Xml/System/Xml/Serialization/SoapCodeExporter.cs @@ -2,7 +2,7 @@ // <copyright file="SoapCodeExporter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapElementAttribute.cs b/System.Xml/System/Xml/Serialization/SoapElementAttribute.cs index b30a00770..d1efc68cc 100644 --- a/System.Xml/System/Xml/Serialization/SoapElementAttribute.cs +++ b/System.Xml/System/Xml/Serialization/SoapElementAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="SoapElementAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapEnumAttribute.cs b/System.Xml/System/Xml/Serialization/SoapEnumAttribute.cs index 28af677d6..badd54f86 100644 --- a/System.Xml/System/Xml/Serialization/SoapEnumAttribute.cs +++ b/System.Xml/System/Xml/Serialization/SoapEnumAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="SoapEnumAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapIgnoreAttribute.cs b/System.Xml/System/Xml/Serialization/SoapIgnoreAttribute.cs index fbd44f768..d4b6f158a 100644 --- a/System.Xml/System/Xml/Serialization/SoapIgnoreAttribute.cs +++ b/System.Xml/System/Xml/Serialization/SoapIgnoreAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="SoapIgnoreAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapIncludeAttribute.cs b/System.Xml/System/Xml/Serialization/SoapIncludeAttribute.cs index 5c406d7f5..b94e97973 100644 --- a/System.Xml/System/Xml/Serialization/SoapIncludeAttribute.cs +++ b/System.Xml/System/Xml/Serialization/SoapIncludeAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="SoapIncludeAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapReflectionImporter.cs b/System.Xml/System/Xml/Serialization/SoapReflectionImporter.cs index 5c7fdae0c..89159cfe0 100644 --- a/System.Xml/System/Xml/Serialization/SoapReflectionImporter.cs +++ b/System.Xml/System/Xml/Serialization/SoapReflectionImporter.cs @@ -2,7 +2,7 @@ // <copyright file="SoapReflectionImporter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapSchemaExporter.cs b/System.Xml/System/Xml/Serialization/SoapSchemaExporter.cs index 17d6dfd57..aaf94a644 100644 --- a/System.Xml/System/Xml/Serialization/SoapSchemaExporter.cs +++ b/System.Xml/System/Xml/Serialization/SoapSchemaExporter.cs @@ -2,7 +2,7 @@ // <copyright file="SoapSchemaExporter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapSchemaImporter.cs b/System.Xml/System/Xml/Serialization/SoapSchemaImporter.cs index 65a6e2a38..f36606e7b 100644 --- a/System.Xml/System/Xml/Serialization/SoapSchemaImporter.cs +++ b/System.Xml/System/Xml/Serialization/SoapSchemaImporter.cs @@ -2,7 +2,7 @@ // <copyright file="SoapSchemaImporter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapSchemamember.cs b/System.Xml/System/Xml/Serialization/SoapSchemamember.cs index 09f0e10d7..eb710ad17 100644 --- a/System.Xml/System/Xml/Serialization/SoapSchemamember.cs +++ b/System.Xml/System/Xml/Serialization/SoapSchemamember.cs @@ -2,7 +2,7 @@ // <copyright file="SoapSchemaMember.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SoapTypeAttribute.cs b/System.Xml/System/Xml/Serialization/SoapTypeAttribute.cs index 450f4ce5a..51b16412c 100644 --- a/System.Xml/System/Xml/Serialization/SoapTypeAttribute.cs +++ b/System.Xml/System/Xml/Serialization/SoapTypeAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="SoapTypeAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/SourceInfo.cs b/System.Xml/System/Xml/Serialization/SourceInfo.cs index 1663c89a9..b0337dfe8 100644 --- a/System.Xml/System/Xml/Serialization/SourceInfo.cs +++ b/System.Xml/System/Xml/Serialization/SourceInfo.cs @@ -2,7 +2,7 @@ // <copyright file="SourceInfo.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/Types.cs b/System.Xml/System/Xml/Serialization/Types.cs index f924a4374..103b424f9 100644 --- a/System.Xml/System/Xml/Serialization/Types.cs +++ b/System.Xml/System/Xml/Serialization/Types.cs @@ -2,7 +2,7 @@ // <copyright file="Types.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { @@ -476,7 +476,7 @@ static TypeScope() { AddPrimitive(typeof(byte[]), "base64Binary", "ByteArrayBase64", TypeFlags.AmbiguousDataType | TypeFlags.CanBeAttributeValue | TypeFlags.CanBeElementValue | TypeFlags.HasCustomFormatter | TypeFlags.Reference | TypeFlags.IgnoreDefault | TypeFlags.XmlEncodingNotRequired | TypeFlags.HasDefaultConstructor); AddPrimitive(typeof(byte[]), "hexBinary", "ByteArrayHex", TypeFlags.AmbiguousDataType | TypeFlags.CanBeAttributeValue | TypeFlags.CanBeElementValue | TypeFlags.HasCustomFormatter | TypeFlags.Reference | TypeFlags.IgnoreDefault | TypeFlags.XmlEncodingNotRequired | TypeFlags.HasDefaultConstructor); - // NOTE, [....]: byte[] can also be used to mean array of bytes. That datatype is not a primitive, so we + // NOTE, Microsoft: byte[] can also be used to mean array of bytes. That datatype is not a primitive, so we // can't use the AmbiguousDataType mechanism. To get an array of bytes in literal XML, apply [XmlArray] or // [XmlArrayItem]. diff --git a/System.Xml/System/Xml/Serialization/XmlAnyAttributeAttribute.cs b/System.Xml/System/Xml/Serialization/XmlAnyAttributeAttribute.cs index 87a78f38d..aee71d513 100644 --- a/System.Xml/System/Xml/Serialization/XmlAnyAttributeAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlAnyAttributeAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlAnyAttributeAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlAnyElementAttribute.cs b/System.Xml/System/Xml/Serialization/XmlAnyElementAttribute.cs index d83ce1e40..d9479840f 100644 --- a/System.Xml/System/Xml/Serialization/XmlAnyElementAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlAnyElementAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlAnyElementAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlAnyElementAttributes.cs b/System.Xml/System/Xml/Serialization/XmlAnyElementAttributes.cs index 898934b90..58a9fc1cc 100644 --- a/System.Xml/System/Xml/Serialization/XmlAnyElementAttributes.cs +++ b/System.Xml/System/Xml/Serialization/XmlAnyElementAttributes.cs @@ -2,7 +2,7 @@ // <copyright file="XmlAnyElementAttributes.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlArrayAttribute.cs b/System.Xml/System/Xml/Serialization/XmlArrayAttribute.cs index 6011b322f..f2f777ba4 100644 --- a/System.Xml/System/Xml/Serialization/XmlArrayAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlArrayAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlArrayAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlArrayItemAttribute.cs b/System.Xml/System/Xml/Serialization/XmlArrayItemAttribute.cs index a476a7eda..e652fb697 100644 --- a/System.Xml/System/Xml/Serialization/XmlArrayItemAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlArrayItemAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlArrayItemAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlArrayItemAttributes.cs b/System.Xml/System/Xml/Serialization/XmlArrayItemAttributes.cs index b5fbde2b9..fb335d877 100644 --- a/System.Xml/System/Xml/Serialization/XmlArrayItemAttributes.cs +++ b/System.Xml/System/Xml/Serialization/XmlArrayItemAttributes.cs @@ -2,7 +2,7 @@ // <copyright file="XmlArrayItemAttributes.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlAttributeAttribute.cs b/System.Xml/System/Xml/Serialization/XmlAttributeAttribute.cs index 07751a9b3..f7d59c32f 100644 --- a/System.Xml/System/Xml/Serialization/XmlAttributeAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlAttributeAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlAttributeAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlAttributeOverrides.cs b/System.Xml/System/Xml/Serialization/XmlAttributeOverrides.cs index af725a332..bdb8893ec 100644 --- a/System.Xml/System/Xml/Serialization/XmlAttributeOverrides.cs +++ b/System.Xml/System/Xml/Serialization/XmlAttributeOverrides.cs @@ -2,7 +2,7 @@ // <copyright file="XmlAttributeOverrides.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlAttributes.cs b/System.Xml/System/Xml/Serialization/XmlAttributes.cs index 58437daba..31bb36612 100644 --- a/System.Xml/System/Xml/Serialization/XmlAttributes.cs +++ b/System.Xml/System/Xml/Serialization/XmlAttributes.cs @@ -2,7 +2,7 @@ // <copyright file="XmlAttributes.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlChoiceIdentifierAttribute.cs b/System.Xml/System/Xml/Serialization/XmlChoiceIdentifierAttribute.cs index c30af562a..021d99d07 100644 --- a/System.Xml/System/Xml/Serialization/XmlChoiceIdentifierAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlChoiceIdentifierAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlChoiceIdentifierAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlCodeExporter.cs b/System.Xml/System/Xml/Serialization/XmlCodeExporter.cs index 690a9d8e1..bb8d1e177 100644 --- a/System.Xml/System/Xml/Serialization/XmlCodeExporter.cs +++ b/System.Xml/System/Xml/Serialization/XmlCodeExporter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlCodeExporter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlElementAttribute.cs b/System.Xml/System/Xml/Serialization/XmlElementAttribute.cs index cb302c652..bbe4dea20 100644 --- a/System.Xml/System/Xml/Serialization/XmlElementAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlElementAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlElementAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlElementAttributes.cs b/System.Xml/System/Xml/Serialization/XmlElementAttributes.cs index a94e8215b..d868493f2 100644 --- a/System.Xml/System/Xml/Serialization/XmlElementAttributes.cs +++ b/System.Xml/System/Xml/Serialization/XmlElementAttributes.cs @@ -2,7 +2,7 @@ // <copyright file="XmlElementAttributes.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlEnumAttribute.cs b/System.Xml/System/Xml/Serialization/XmlEnumAttribute.cs index 3c658f592..969830dc0 100644 --- a/System.Xml/System/Xml/Serialization/XmlEnumAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlEnumAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlEnumAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlIgnoreAttribute.cs b/System.Xml/System/Xml/Serialization/XmlIgnoreAttribute.cs index 1205bb29f..3aafd13b7 100644 --- a/System.Xml/System/Xml/Serialization/XmlIgnoreAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlIgnoreAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlIgnoreAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlIncludeAttribute.cs b/System.Xml/System/Xml/Serialization/XmlIncludeAttribute.cs index 54034c8e1..7616791ae 100644 --- a/System.Xml/System/Xml/Serialization/XmlIncludeAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlIncludeAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlIncludeAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlMapping.cs b/System.Xml/System/Xml/Serialization/XmlMapping.cs index 6158e7773..33efdae68 100644 --- a/System.Xml/System/Xml/Serialization/XmlMapping.cs +++ b/System.Xml/System/Xml/Serialization/XmlMapping.cs @@ -2,7 +2,7 @@ // <copyright file="XmlMapping.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlMemberMapping.cs b/System.Xml/System/Xml/Serialization/XmlMemberMapping.cs index 1636b004a..ee5af6c4d 100644 --- a/System.Xml/System/Xml/Serialization/XmlMemberMapping.cs +++ b/System.Xml/System/Xml/Serialization/XmlMemberMapping.cs @@ -2,7 +2,7 @@ // <copyright file="XmlMemberMapping.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlMembersMapping.cs b/System.Xml/System/Xml/Serialization/XmlMembersMapping.cs index cfda29252..75331e3de 100644 --- a/System.Xml/System/Xml/Serialization/XmlMembersMapping.cs +++ b/System.Xml/System/Xml/Serialization/XmlMembersMapping.cs @@ -2,7 +2,7 @@ // <copyright file="XmlMembersMapping.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlNamespaceDeclarationsAttribute.cs b/System.Xml/System/Xml/Serialization/XmlNamespaceDeclarationsAttribute.cs index efe61e284..ff139a068 100644 --- a/System.Xml/System/Xml/Serialization/XmlNamespaceDeclarationsAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlNamespaceDeclarationsAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlNamespaceDeclarationsAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlReflectionImporter.cs b/System.Xml/System/Xml/Serialization/XmlReflectionImporter.cs index 67ee9bc54..679017453 100644 --- a/System.Xml/System/Xml/Serialization/XmlReflectionImporter.cs +++ b/System.Xml/System/Xml/Serialization/XmlReflectionImporter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlReflectionImporter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlReflectionMember.cs b/System.Xml/System/Xml/Serialization/XmlReflectionMember.cs index 2c9c0699d..d3f36fe92 100644 --- a/System.Xml/System/Xml/Serialization/XmlReflectionMember.cs +++ b/System.Xml/System/Xml/Serialization/XmlReflectionMember.cs @@ -2,7 +2,7 @@ // <copyright file="XmlReflectionMember.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlRootAttribute.cs b/System.Xml/System/Xml/Serialization/XmlRootAttribute.cs index fd00efa54..622539303 100644 --- a/System.Xml/System/Xml/Serialization/XmlRootAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlRootAttribute.cs @@ -3,7 +3,7 @@ // <copyright file="XmlRootAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSchemaExporter.cs b/System.Xml/System/Xml/Serialization/XmlSchemaExporter.cs index 8c0704b15..d8e6e1318 100644 --- a/System.Xml/System/Xml/Serialization/XmlSchemaExporter.cs +++ b/System.Xml/System/Xml/Serialization/XmlSchemaExporter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaExporter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSchemaImporter.cs b/System.Xml/System/Xml/Serialization/XmlSchemaImporter.cs index 2f4309b4f..1f7aa1d1a 100644 --- a/System.Xml/System/Xml/Serialization/XmlSchemaImporter.cs +++ b/System.Xml/System/Xml/Serialization/XmlSchemaImporter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemaImporter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSchemaProviderAttribute.cs b/System.Xml/System/Xml/Serialization/XmlSchemaProviderAttribute.cs index ccdeec6bb..27c46a662 100644 --- a/System.Xml/System/Xml/Serialization/XmlSchemaProviderAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlSchemaProviderAttribute.cs @@ -3,7 +3,7 @@ // <copyright file="XmlSchemaProviderAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSchemas.cs b/System.Xml/System/Xml/Serialization/XmlSchemas.cs index eef8682e7..1e3e27f8e 100644 --- a/System.Xml/System/Xml/Serialization/XmlSchemas.cs +++ b/System.Xml/System/Xml/Serialization/XmlSchemas.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSchemas.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSerializationGeneratedCode.cs b/System.Xml/System/Xml/Serialization/XmlSerializationGeneratedCode.cs index a46500689..d3f838001 100644 --- a/System.Xml/System/Xml/Serialization/XmlSerializationGeneratedCode.cs +++ b/System.Xml/System/Xml/Serialization/XmlSerializationGeneratedCode.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSerializationGeneratedCode.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSerializationILGen.cs b/System.Xml/System/Xml/Serialization/XmlSerializationILGen.cs index 564d888ef..3460db55b 100644 --- a/System.Xml/System/Xml/Serialization/XmlSerializationILGen.cs +++ b/System.Xml/System/Xml/Serialization/XmlSerializationILGen.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSerializationILGen.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSerializationReader.cs b/System.Xml/System/Xml/Serialization/XmlSerializationReader.cs index 9bbd7e244..50c5e3b3e 100644 --- a/System.Xml/System/Xml/Serialization/XmlSerializationReader.cs +++ b/System.Xml/System/Xml/Serialization/XmlSerializationReader.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSerializationReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { @@ -4185,7 +4185,7 @@ void WriteArray(string source, string arrayName, ArrayMapping arrayMapping, bool memberMapping.TypeDesc = arrayMapping.TypeDesc; memberMapping.ReadOnly = readOnly; Member member = new Member(this, source, arrayName, 0, memberMapping, false); - member.IsNullable = false;//Note, [....]: IsNullable is set to false since null condition (xsi:nil) is already handled by 'ReadNull()' + member.IsNullable = false;//Note, Microsoft: IsNullable is set to false since null condition (xsi:nil) is already handled by 'ReadNull()' Member[] members = new Member[] { member }; WriteMemberBegin(members); diff --git a/System.Xml/System/Xml/Serialization/XmlSerializationReaderILGen.cs b/System.Xml/System/Xml/Serialization/XmlSerializationReaderILGen.cs index e7f2c1bef..6ba4b2d7f 100644 --- a/System.Xml/System/Xml/Serialization/XmlSerializationReaderILGen.cs +++ b/System.Xml/System/Xml/Serialization/XmlSerializationReaderILGen.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSerializationReaderILGen.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { @@ -2881,7 +2881,7 @@ void WriteArray(string source, string arrayName, ArrayMapping arrayMapping, bool memberMapping.MemberInfo = memberInfos[source.Substring(3)]; } Member member = new Member(this, source, arrayName, elementIndex, memberMapping, false); - member.IsNullable = false;//Note, [....]: IsNullable is set to false since null condition (xsi:nil) is already handled by 'ReadNull()' + member.IsNullable = false;//Note, Microsoft: IsNullable is set to false since null condition (xsi:nil) is already handled by 'ReadNull()' Member[] members = new Member[] { member }; WriteMemberBegin(members); diff --git a/System.Xml/System/Xml/Serialization/XmlSerializationWriter.cs b/System.Xml/System/Xml/Serialization/XmlSerializationWriter.cs index 69bbbd408..d15b2bf9b 100644 --- a/System.Xml/System/Xml/Serialization/XmlSerializationWriter.cs +++ b/System.Xml/System/Xml/Serialization/XmlSerializationWriter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSerializationWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { @@ -3627,7 +3627,7 @@ internal string GetStringForMember(string obj, string memberName, TypeDesc typeD return "(("+typeDesc.CSharpName+")"+obj+").@"+memberName; } //throw GetReflectionVariableException(saveTypeDesc.CSharpName,memberName); - // NOTE, [....]:Must never happen. If it does let the code + // NOTE, Microsoft:Must never happen. If it does let the code // gen continue to help debugging what's gone wrong. // Eventually the compilation will fail. return "["+obj+"]"; diff --git a/System.Xml/System/Xml/Serialization/XmlSerializationWriterILGen.cs b/System.Xml/System/Xml/Serialization/XmlSerializationWriterILGen.cs index 0884a6c7b..05e529ea2 100644 --- a/System.Xml/System/Xml/Serialization/XmlSerializationWriterILGen.cs +++ b/System.Xml/System/Xml/Serialization/XmlSerializationWriterILGen.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSerializationWriterILGen.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSerializer.cs b/System.Xml/System/Xml/Serialization/XmlSerializer.cs index 9600e7603..eb11fe3b3 100644 --- a/System.Xml/System/Xml/Serialization/XmlSerializer.cs +++ b/System.Xml/System/Xml/Serialization/XmlSerializer.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSerializer.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSerializerAssemblyAttribute.cs b/System.Xml/System/Xml/Serialization/XmlSerializerAssemblyAttribute.cs index 677f7a15f..d8b1a898d 100644 --- a/System.Xml/System/Xml/Serialization/XmlSerializerAssemblyAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlSerializerAssemblyAttribute.cs @@ -3,7 +3,7 @@ // <copyright file="XmlSerializerAssemblyAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSerializerFactory.cs b/System.Xml/System/Xml/Serialization/XmlSerializerFactory.cs index 9163984f4..a4bf3a0a9 100644 --- a/System.Xml/System/Xml/Serialization/XmlSerializerFactory.cs +++ b/System.Xml/System/Xml/Serialization/XmlSerializerFactory.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSerializer.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSerializerNamespaces.cs b/System.Xml/System/Xml/Serialization/XmlSerializerNamespaces.cs index de689d2a5..ce3b533dc 100644 --- a/System.Xml/System/Xml/Serialization/XmlSerializerNamespaces.cs +++ b/System.Xml/System/Xml/Serialization/XmlSerializerNamespaces.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSerializerNamespaces.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlSerializerVersionAttribute.cs b/System.Xml/System/Xml/Serialization/XmlSerializerVersionAttribute.cs index 4b5d05ee5..be04e8991 100644 --- a/System.Xml/System/Xml/Serialization/XmlSerializerVersionAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlSerializerVersionAttribute.cs @@ -3,7 +3,7 @@ // <copyright file="XmlSerializerVersionAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlTextAttribute.cs b/System.Xml/System/Xml/Serialization/XmlTextAttribute.cs index 0d793ef7b..45fc96f74 100644 --- a/System.Xml/System/Xml/Serialization/XmlTextAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlTextAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlTextAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlTypeAttribute.cs b/System.Xml/System/Xml/Serialization/XmlTypeAttribute.cs index 636194687..59a472331 100644 --- a/System.Xml/System/Xml/Serialization/XmlTypeAttribute.cs +++ b/System.Xml/System/Xml/Serialization/XmlTypeAttribute.cs @@ -2,7 +2,7 @@ // <copyright file="XmlTypeAttribute.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/XmlTypeMapping.cs b/System.Xml/System/Xml/Serialization/XmlTypeMapping.cs index 4466a5160..c8240f3a0 100644 --- a/System.Xml/System/Xml/Serialization/XmlTypeMapping.cs +++ b/System.Xml/System/Xml/Serialization/XmlTypeMapping.cs @@ -2,7 +2,7 @@ // <copyright file="XmlTypeMapping.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/Xmlcustomformatter.cs b/System.Xml/System/Xml/Serialization/Xmlcustomformatter.cs index 1b814edf1..a50f8c744 100644 --- a/System.Xml/System/Xml/Serialization/Xmlcustomformatter.cs +++ b/System.Xml/System/Xml/Serialization/Xmlcustomformatter.cs @@ -2,7 +2,7 @@ // <copyright file="XmlCustomFormatter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/_Events.cs b/System.Xml/System/Xml/Serialization/_Events.cs index 491828807..ec9b3e782 100644 --- a/System.Xml/System/Xml/Serialization/_Events.cs +++ b/System.Xml/System/Xml/Serialization/_Events.cs @@ -2,7 +2,7 @@ // <copyright file="_Events.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/Serialization/indentedWriter.cs b/System.Xml/System/Xml/Serialization/indentedWriter.cs index 22dac15fd..5c6867eaf 100644 --- a/System.Xml/System/Xml/Serialization/indentedWriter.cs +++ b/System.Xml/System/Xml/Serialization/indentedWriter.cs @@ -2,7 +2,7 @@ // <copyright file="IndentedWriter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Serialization { diff --git a/System.Xml/System/Xml/ValidateNames.cs b/System.Xml/System/Xml/ValidateNames.cs index 34bc73279..bf034e162 100644 --- a/System.Xml/System/Xml/ValidateNames.cs +++ b/System.Xml/System/Xml/ValidateNames.cs @@ -2,7 +2,7 @@ // <copyright file="ValidateNames.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/XPath/Internal/AbsoluteQuery.cs b/System.Xml/System/Xml/XPath/Internal/AbsoluteQuery.cs index 7c126900c..1dc479fe5 100644 --- a/System.Xml/System/Xml/XPath/Internal/AbsoluteQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/AbsoluteQuery.cs @@ -2,7 +2,7 @@ // <copyright file="AbsoluteQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/AttributeQuery.cs b/System.Xml/System/Xml/XPath/Internal/AttributeQuery.cs index 93be02804..052dfbc45 100644 --- a/System.Xml/System/Xml/XPath/Internal/AttributeQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/AttributeQuery.cs @@ -2,7 +2,7 @@ // <copyright file="AttributeQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/Axis.cs b/System.Xml/System/Xml/XPath/Internal/Axis.cs index 658c08c7b..c64fb4307 100644 --- a/System.Xml/System/Xml/XPath/Internal/Axis.cs +++ b/System.Xml/System/Xml/XPath/Internal/Axis.cs @@ -2,7 +2,7 @@ // <copyright file="Axis.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/BaseAxisQuery.cs b/System.Xml/System/Xml/XPath/Internal/BaseAxisQuery.cs index 83170d035..91c37b719 100644 --- a/System.Xml/System/Xml/XPath/Internal/BaseAxisQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/BaseAxisQuery.cs @@ -2,7 +2,7 @@ // <copyright file="baseaxisquery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/BooleanExpr.cs b/System.Xml/System/Xml/XPath/Internal/BooleanExpr.cs index a8af11f65..fb3b9f7be 100644 --- a/System.Xml/System/Xml/XPath/Internal/BooleanExpr.cs +++ b/System.Xml/System/Xml/XPath/Internal/BooleanExpr.cs @@ -2,7 +2,7 @@ // <copyright file="BooleanExpr.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/BooleanFunctions.cs b/System.Xml/System/Xml/XPath/Internal/BooleanFunctions.cs index 4fa3553f2..b18ef609c 100644 --- a/System.Xml/System/Xml/XPath/Internal/BooleanFunctions.cs +++ b/System.Xml/System/Xml/XPath/Internal/BooleanFunctions.cs @@ -2,7 +2,7 @@ // <copyright file="BooleanFunctions.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/CacheAxisQuery.cs b/System.Xml/System/Xml/XPath/Internal/CacheAxisQuery.cs index 47dd13ee6..4a264f4e7 100644 --- a/System.Xml/System/Xml/XPath/Internal/CacheAxisQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/CacheAxisQuery.cs @@ -2,7 +2,7 @@ // <copyright file="CacheAxisQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/CacheChildrenQuery.cs b/System.Xml/System/Xml/XPath/Internal/CacheChildrenQuery.cs index 53954396c..3ad2a6fb2 100644 --- a/System.Xml/System/Xml/XPath/Internal/CacheChildrenQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/CacheChildrenQuery.cs @@ -2,7 +2,7 @@ // <copyright file="CacheChildrenQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/CacheOutputQuery.cs b/System.Xml/System/Xml/XPath/Internal/CacheOutputQuery.cs index 492358dbc..e6331502c 100644 --- a/System.Xml/System/Xml/XPath/Internal/CacheOutputQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/CacheOutputQuery.cs @@ -2,7 +2,7 @@ // <copyright file="CacheOutputQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/ChildrenQuery.cs b/System.Xml/System/Xml/XPath/Internal/ChildrenQuery.cs index a088816ba..7784a5ff4 100644 --- a/System.Xml/System/Xml/XPath/Internal/ChildrenQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/ChildrenQuery.cs @@ -2,7 +2,7 @@ // <copyright file="ChildrenQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/ClonableStack.cs b/System.Xml/System/Xml/XPath/Internal/ClonableStack.cs index b2bc17735..6181cd0d5 100644 --- a/System.Xml/System/Xml/XPath/Internal/ClonableStack.cs +++ b/System.Xml/System/Xml/XPath/Internal/ClonableStack.cs @@ -2,7 +2,7 @@ // <copyright file="ClonableStack.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/CompiledXPathExpr.cs b/System.Xml/System/Xml/XPath/Internal/CompiledXPathExpr.cs index f5fd38548..0f87cd367 100644 --- a/System.Xml/System/Xml/XPath/Internal/CompiledXPathExpr.cs +++ b/System.Xml/System/Xml/XPath/Internal/CompiledXPathExpr.cs @@ -2,7 +2,7 @@ // <copyright file="CompiledXpathExpr.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/ContextQuery.cs b/System.Xml/System/Xml/XPath/Internal/ContextQuery.cs index 98ccd0e78..56d4661d7 100644 --- a/System.Xml/System/Xml/XPath/Internal/ContextQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/ContextQuery.cs @@ -2,7 +2,7 @@ // <copyright file="ContextQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/DescendantBaseQuery.cs b/System.Xml/System/Xml/XPath/Internal/DescendantBaseQuery.cs index b05f45174..3fa58383c 100644 --- a/System.Xml/System/Xml/XPath/Internal/DescendantBaseQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/DescendantBaseQuery.cs @@ -2,7 +2,7 @@ // <copyright file="DescendantQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/DescendantQuery.cs b/System.Xml/System/Xml/XPath/Internal/DescendantQuery.cs index 309204697..317e0da51 100644 --- a/System.Xml/System/Xml/XPath/Internal/DescendantQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/DescendantQuery.cs @@ -2,7 +2,7 @@ // <copyright file="DescendantQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/DescendantoverDescendantQuery.cs b/System.Xml/System/Xml/XPath/Internal/DescendantoverDescendantQuery.cs index 140f6afe0..4cc0776e0 100644 --- a/System.Xml/System/Xml/XPath/Internal/DescendantoverDescendantQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/DescendantoverDescendantQuery.cs @@ -2,7 +2,7 @@ // <copyright file="DescendantOverDescendantQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/DocumentorderQuery.cs b/System.Xml/System/Xml/XPath/Internal/DocumentorderQuery.cs index 9f38f0c7f..0093670b3 100644 --- a/System.Xml/System/Xml/XPath/Internal/DocumentorderQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/DocumentorderQuery.cs @@ -2,7 +2,7 @@ // <copyright file="DocumentOrderQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/EmptyQuery.cs b/System.Xml/System/Xml/XPath/Internal/EmptyQuery.cs index 141206b5a..4469a732c 100644 --- a/System.Xml/System/Xml/XPath/Internal/EmptyQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/EmptyQuery.cs @@ -2,7 +2,7 @@ // <copyright file="EmptyQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/ExtensionQuery.cs b/System.Xml/System/Xml/XPath/Internal/ExtensionQuery.cs index 6069968f2..219afd68e 100644 --- a/System.Xml/System/Xml/XPath/Internal/ExtensionQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/ExtensionQuery.cs @@ -2,7 +2,7 @@ // <copyright file="ExtensionQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/Filter.cs b/System.Xml/System/Xml/XPath/Internal/Filter.cs index 4dd89f489..b30bce34c 100644 --- a/System.Xml/System/Xml/XPath/Internal/Filter.cs +++ b/System.Xml/System/Xml/XPath/Internal/Filter.cs @@ -2,7 +2,7 @@ // <copyright file="Filter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/FilterQuery.cs b/System.Xml/System/Xml/XPath/Internal/FilterQuery.cs index 257d441e2..04b9e7427 100644 --- a/System.Xml/System/Xml/XPath/Internal/FilterQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/FilterQuery.cs @@ -2,7 +2,7 @@ // <copyright file="FilterQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/FollowingQuery.cs b/System.Xml/System/Xml/XPath/Internal/FollowingQuery.cs index f6e837988..38235ba79 100644 --- a/System.Xml/System/Xml/XPath/Internal/FollowingQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/FollowingQuery.cs @@ -2,7 +2,7 @@ // <copyright file="followingquery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/FollowingSibling.cs b/System.Xml/System/Xml/XPath/Internal/FollowingSibling.cs index a50814eff..c26df84de 100644 --- a/System.Xml/System/Xml/XPath/Internal/FollowingSibling.cs +++ b/System.Xml/System/Xml/XPath/Internal/FollowingSibling.cs @@ -2,7 +2,7 @@ // <copyright file="followingsibling.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/ForwardPositionQuery.cs b/System.Xml/System/Xml/XPath/Internal/ForwardPositionQuery.cs index eef25bcce..34f5664b6 100644 --- a/System.Xml/System/Xml/XPath/Internal/ForwardPositionQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/ForwardPositionQuery.cs @@ -2,7 +2,7 @@ // <copyright file="ForwardPositionQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/Function.cs b/System.Xml/System/Xml/XPath/Internal/Function.cs index 1233c7235..027bc49f2 100644 --- a/System.Xml/System/Xml/XPath/Internal/Function.cs +++ b/System.Xml/System/Xml/XPath/Internal/Function.cs @@ -2,7 +2,7 @@ // <copyright file="Function.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/FunctionQuery.cs b/System.Xml/System/Xml/XPath/Internal/FunctionQuery.cs index 26fc0f7e0..795c71a1d 100644 --- a/System.Xml/System/Xml/XPath/Internal/FunctionQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/FunctionQuery.cs @@ -2,7 +2,7 @@ // <copyright file="FunctionQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/Group.cs b/System.Xml/System/Xml/XPath/Internal/Group.cs index 454ffb263..578826b68 100644 --- a/System.Xml/System/Xml/XPath/Internal/Group.cs +++ b/System.Xml/System/Xml/XPath/Internal/Group.cs @@ -2,7 +2,7 @@ // <copyright file="Group.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/GroupQuery.cs b/System.Xml/System/Xml/XPath/Internal/GroupQuery.cs index 597f93966..087d3bafa 100644 --- a/System.Xml/System/Xml/XPath/Internal/GroupQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/GroupQuery.cs @@ -2,7 +2,7 @@ // <copyright file="GroupQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/IdQuery.cs b/System.Xml/System/Xml/XPath/Internal/IdQuery.cs index 5a6e292fd..9f4c1589d 100644 --- a/System.Xml/System/Xml/XPath/Internal/IdQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/IdQuery.cs @@ -2,7 +2,7 @@ // <copyright file="IDQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/IteratorFilter.cs b/System.Xml/System/Xml/XPath/Internal/IteratorFilter.cs index e0718275e..09279e239 100644 --- a/System.Xml/System/Xml/XPath/Internal/IteratorFilter.cs +++ b/System.Xml/System/Xml/XPath/Internal/IteratorFilter.cs @@ -2,7 +2,7 @@ // <copyright file="IteratorFilter.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/LogicalExpr.cs b/System.Xml/System/Xml/XPath/Internal/LogicalExpr.cs index 8a59b0566..a0438225c 100644 --- a/System.Xml/System/Xml/XPath/Internal/LogicalExpr.cs +++ b/System.Xml/System/Xml/XPath/Internal/LogicalExpr.cs @@ -2,7 +2,7 @@ // <copyright file="LogicalExpr.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/MergeFilterQuery.cs b/System.Xml/System/Xml/XPath/Internal/MergeFilterQuery.cs index 0b354f536..741273921 100644 --- a/System.Xml/System/Xml/XPath/Internal/MergeFilterQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/MergeFilterQuery.cs @@ -2,7 +2,7 @@ // <copyright file="MergeFilterQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/NamespaceQuery.cs b/System.Xml/System/Xml/XPath/Internal/NamespaceQuery.cs index 36fd3fc1e..f3ad00498 100644 --- a/System.Xml/System/Xml/XPath/Internal/NamespaceQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/NamespaceQuery.cs @@ -2,7 +2,7 @@ // <copyright file="NamespaceQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/NodeFunctions.cs b/System.Xml/System/Xml/XPath/Internal/NodeFunctions.cs index e7607376b..cf9566dfd 100644 --- a/System.Xml/System/Xml/XPath/Internal/NodeFunctions.cs +++ b/System.Xml/System/Xml/XPath/Internal/NodeFunctions.cs @@ -2,7 +2,7 @@ // <copyright file="NodeFunctions.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/NumberFunctions.cs b/System.Xml/System/Xml/XPath/Internal/NumberFunctions.cs index b824bca29..72c11f917 100644 --- a/System.Xml/System/Xml/XPath/Internal/NumberFunctions.cs +++ b/System.Xml/System/Xml/XPath/Internal/NumberFunctions.cs @@ -2,7 +2,7 @@ // <copyright file="NumberFunctions.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/NumericExpr.cs b/System.Xml/System/Xml/XPath/Internal/NumericExpr.cs index ee2878f77..4a2fd0da6 100644 --- a/System.Xml/System/Xml/XPath/Internal/NumericExpr.cs +++ b/System.Xml/System/Xml/XPath/Internal/NumericExpr.cs @@ -2,7 +2,7 @@ // <copyright file="NumericExpr.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/Operand.cs b/System.Xml/System/Xml/XPath/Internal/Operand.cs index 6240de8ab..aebbd8ef7 100644 --- a/System.Xml/System/Xml/XPath/Internal/Operand.cs +++ b/System.Xml/System/Xml/XPath/Internal/Operand.cs @@ -2,7 +2,7 @@ // <copyright file="Operand.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/OperandQuery.cs b/System.Xml/System/Xml/XPath/Internal/OperandQuery.cs index 6cf3e30d8..b88525410 100644 --- a/System.Xml/System/Xml/XPath/Internal/OperandQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/OperandQuery.cs @@ -2,7 +2,7 @@ // <copyright file="OperandQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/Operator.cs b/System.Xml/System/Xml/XPath/Internal/Operator.cs index c4d7481fc..9739fb127 100644 --- a/System.Xml/System/Xml/XPath/Internal/Operator.cs +++ b/System.Xml/System/Xml/XPath/Internal/Operator.cs @@ -2,7 +2,7 @@ // <copyright file="Operator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/ParentQuery.cs b/System.Xml/System/Xml/XPath/Internal/ParentQuery.cs index 8a0a6deba..b755fa535 100644 --- a/System.Xml/System/Xml/XPath/Internal/ParentQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/ParentQuery.cs @@ -2,7 +2,7 @@ // <copyright file="ParentQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/PrecedingQuery.cs b/System.Xml/System/Xml/XPath/Internal/PrecedingQuery.cs index d56cac2bf..bc925cc1c 100644 --- a/System.Xml/System/Xml/XPath/Internal/PrecedingQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/PrecedingQuery.cs @@ -2,7 +2,7 @@ // <copyright file="precedingquery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/PrecedingSibling.cs b/System.Xml/System/Xml/XPath/Internal/PrecedingSibling.cs index 75399c76a..f690049c7 100644 --- a/System.Xml/System/Xml/XPath/Internal/PrecedingSibling.cs +++ b/System.Xml/System/Xml/XPath/Internal/PrecedingSibling.cs @@ -2,7 +2,7 @@ // <copyright file="precedingsibling.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/Query.cs b/System.Xml/System/Xml/XPath/Internal/Query.cs index 73eae5c5c..a70822ac7 100644 --- a/System.Xml/System/Xml/XPath/Internal/Query.cs +++ b/System.Xml/System/Xml/XPath/Internal/Query.cs @@ -2,7 +2,7 @@ // <copyright file="Query.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/QueryBuilder.cs b/System.Xml/System/Xml/XPath/Internal/QueryBuilder.cs index 19a56067a..580491f0f 100644 --- a/System.Xml/System/Xml/XPath/Internal/QueryBuilder.cs +++ b/System.Xml/System/Xml/XPath/Internal/QueryBuilder.cs @@ -2,7 +2,7 @@ // <copyright file="querybuilder.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/ResetableIterator.cs b/System.Xml/System/Xml/XPath/Internal/ResetableIterator.cs index 9943abe24..e48a28e36 100644 --- a/System.Xml/System/Xml/XPath/Internal/ResetableIterator.cs +++ b/System.Xml/System/Xml/XPath/Internal/ResetableIterator.cs @@ -2,7 +2,7 @@ // <copyright file="ResetableIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/ReversePositionQuery.cs b/System.Xml/System/Xml/XPath/Internal/ReversePositionQuery.cs index 406ed7e5b..35bd8eff2 100644 --- a/System.Xml/System/Xml/XPath/Internal/ReversePositionQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/ReversePositionQuery.cs @@ -2,7 +2,7 @@ // <copyright file="ReversePositionQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/Root.cs b/System.Xml/System/Xml/XPath/Internal/Root.cs index fbfee2646..ad0fa9c91 100644 --- a/System.Xml/System/Xml/XPath/Internal/Root.cs +++ b/System.Xml/System/Xml/XPath/Internal/Root.cs @@ -2,7 +2,7 @@ // <copyright file="Root.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/SortQuery.cs b/System.Xml/System/Xml/XPath/Internal/SortQuery.cs index 47e28a291..4be9a067e 100644 --- a/System.Xml/System/Xml/XPath/Internal/SortQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/SortQuery.cs @@ -2,7 +2,7 @@ // <copyright file="SortQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/StringFunctions.cs b/System.Xml/System/Xml/XPath/Internal/StringFunctions.cs index 1d545b5e5..8b477ecf7 100644 --- a/System.Xml/System/Xml/XPath/Internal/StringFunctions.cs +++ b/System.Xml/System/Xml/XPath/Internal/StringFunctions.cs @@ -2,7 +2,7 @@ // <copyright file="StringFunctions.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/UnionExpr.cs b/System.Xml/System/Xml/XPath/Internal/UnionExpr.cs index 79e24be6b..b14786fc6 100644 --- a/System.Xml/System/Xml/XPath/Internal/UnionExpr.cs +++ b/System.Xml/System/Xml/XPath/Internal/UnionExpr.cs @@ -2,7 +2,7 @@ // <copyright file="UnionExpr.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/ValueQuery.cs b/System.Xml/System/Xml/XPath/Internal/ValueQuery.cs index 41aa2e087..ee50b81b7 100644 --- a/System.Xml/System/Xml/XPath/Internal/ValueQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/ValueQuery.cs @@ -2,7 +2,7 @@ // <copyright file="ValueQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/Variable.cs b/System.Xml/System/Xml/XPath/Internal/Variable.cs index 1d6f50cf1..594b9c8ae 100644 --- a/System.Xml/System/Xml/XPath/Internal/Variable.cs +++ b/System.Xml/System/Xml/XPath/Internal/Variable.cs @@ -2,7 +2,7 @@ // <copyright file="Variable.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/VariableQuery.cs b/System.Xml/System/Xml/XPath/Internal/VariableQuery.cs index ce6b7132c..c2b6ee2e3 100644 --- a/System.Xml/System/Xml/XPath/Internal/VariableQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/VariableQuery.cs @@ -2,7 +2,7 @@ // <copyright file="VariableQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathAncestorIterator.cs b/System.Xml/System/Xml/XPath/Internal/XPathAncestorIterator.cs index 5f839cdfe..d0709058b 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathAncestorIterator.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathAncestorIterator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathAncestorIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathAncestorQuery.cs b/System.Xml/System/Xml/XPath/Internal/XPathAncestorQuery.cs index 503d1f600..1d2f04cc8 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathAncestorQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathAncestorQuery.cs @@ -2,7 +2,7 @@ // <copyright file="XPathAncestorQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathArrayIterator.cs b/System.Xml/System/Xml/XPath/Internal/XPathArrayIterator.cs index 724df0e32..9f16db6db 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathArrayIterator.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathArrayIterator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathArrayIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/XPath/Internal/XPathAxisIterator.cs b/System.Xml/System/Xml/XPath/Internal/XPathAxisIterator.cs index 512e8618f..c0aeb7005 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathAxisIterator.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathAxisIterator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathAxisIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathChildIterator.cs b/System.Xml/System/Xml/XPath/Internal/XPathChildIterator.cs index f87c9c761..2ea63b694 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathChildIterator.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathChildIterator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathChildIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathDescendantIterator.cs b/System.Xml/System/Xml/XPath/Internal/XPathDescendantIterator.cs index 2cf77bef2..5879555df 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathDescendantIterator.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathDescendantIterator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathDescendantIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathEmptyIterator.cs b/System.Xml/System/Xml/XPath/Internal/XPathEmptyIterator.cs index 6fa40453c..7970452a3 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathEmptyIterator.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathEmptyIterator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathEmptyIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathMultyIterator.cs b/System.Xml/System/Xml/XPath/Internal/XPathMultyIterator.cs index ef8cb5858..ac2f1fbec 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathMultyIterator.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathMultyIterator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathMultyIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathParser.cs b/System.Xml/System/Xml/XPath/Internal/XPathParser.cs index c6a07aaa5..0192d80a6 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathParser.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathParser.cs @@ -2,7 +2,7 @@ // <copyright file="XPathParser.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathScanner.cs b/System.Xml/System/Xml/XPath/Internal/XPathScanner.cs index 76e15142e..3b78f4fad 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathScanner.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathScanner.cs @@ -2,7 +2,7 @@ // <copyright file="XPathScanner.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathSelectionIterator.cs b/System.Xml/System/Xml/XPath/Internal/XPathSelectionIterator.cs index f09f8acc0..deb898114 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathSelectionIterator.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathSelectionIterator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathSelectionIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathSelfQuery.cs b/System.Xml/System/Xml/XPath/Internal/XPathSelfQuery.cs index e15cacaf7..33f932c26 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathSelfQuery.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathSelfQuery.cs @@ -2,7 +2,7 @@ // <copyright file="XPathSelfQuery.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/Internal/XPathSingletonIterator.cs b/System.Xml/System/Xml/XPath/Internal/XPathSingletonIterator.cs index 6e32451a8..4528669ed 100644 --- a/System.Xml/System/Xml/XPath/Internal/XPathSingletonIterator.cs +++ b/System.Xml/System/Xml/XPath/Internal/XPathSingletonIterator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathSingletonIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace MS.Internal.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/XPathDocument.cs b/System.Xml/System/Xml/XPath/XPathDocument.cs index 3bb8e8ad5..e1d9bbe8e 100644 --- a/System.Xml/System/Xml/XPath/XPathDocument.cs +++ b/System.Xml/System/Xml/XPath/XPathDocument.cs @@ -2,7 +2,7 @@ // <copyright file="XPathDocument.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; @@ -231,7 +231,7 @@ internal void LoadFromReader(XmlReader reader, XmlSpace space) { case XmlNodeType.Whitespace: // We intentionally ignore the reader.XmlSpace property here and blindly trust - // the reported node type. If the reported information is not in [....] + // the reported node type. If the reported information is not in sync // (in this case if the reader.XmlSpace == Preserve) then we make the choice // to trust the reported node type. Since we have no control over the input reader // we can't even assert here. diff --git a/System.Xml/System/Xml/XPath/XPathException.cs b/System.Xml/System/Xml/XPath/XPathException.cs index 533518ac8..8eb02788a 100644 --- a/System.Xml/System/Xml/XPath/XPathException.cs +++ b/System.Xml/System/Xml/XPath/XPathException.cs @@ -2,7 +2,7 @@ // <copyright file="XPathException.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/XPathExpr.cs b/System.Xml/System/Xml/XPath/XPathExpr.cs index 803907df7..195bf20b9 100644 --- a/System.Xml/System/Xml/XPath/XPathExpr.cs +++ b/System.Xml/System/Xml/XPath/XPathExpr.cs @@ -2,7 +2,7 @@ // <copyright file="XPathExpr.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.XPath { diff --git a/System.Xml/System/Xml/XPath/XPathItem.cs b/System.Xml/System/Xml/XPath/XPathItem.cs index ea954b05d..85653c0dc 100644 --- a/System.Xml/System/Xml/XPath/XPathItem.cs +++ b/System.Xml/System/Xml/XPath/XPathItem.cs @@ -2,7 +2,7 @@ // <copyright file="XPathItem.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; using System.Collections; diff --git a/System.Xml/System/Xml/XPath/XPathNavigator.cs b/System.Xml/System/Xml/XPath/XPathNavigator.cs index ae5ecbc9b..a1900faf0 100644 --- a/System.Xml/System/Xml/XPath/XPathNavigator.cs +++ b/System.Xml/System/Xml/XPath/XPathNavigator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathNavigator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.ComponentModel; diff --git a/System.Xml/System/Xml/XPath/XPathNavigatorKeyComparer.cs b/System.Xml/System/Xml/XPath/XPathNavigatorKeyComparer.cs index dc09acf20..f6c83e1a4 100644 --- a/System.Xml/System/Xml/XPath/XPathNavigatorKeyComparer.cs +++ b/System.Xml/System/Xml/XPath/XPathNavigatorKeyComparer.cs @@ -2,7 +2,7 @@ // <copyright file="XmlNavigatorReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.IO; diff --git a/System.Xml/System/Xml/XPath/XPathNavigatorReader.cs b/System.Xml/System/Xml/XPath/XPathNavigatorReader.cs index beab98822..12226d205 100644 --- a/System.Xml/System/Xml/XPath/XPathNavigatorReader.cs +++ b/System.Xml/System/Xml/XPath/XPathNavigatorReader.cs @@ -2,7 +2,7 @@ // <copyright file="XmlNavigatorReader.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.IO; diff --git a/System.Xml/System/Xml/XPath/XPathNodeIterator.cs b/System.Xml/System/Xml/XPath/XPathNodeIterator.cs index 3731627ed..2d60c8544 100644 --- a/System.Xml/System/Xml/XPath/XPathNodeIterator.cs +++ b/System.Xml/System/Xml/XPath/XPathNodeIterator.cs @@ -2,7 +2,7 @@ // <copyright file="XPathNodeIterator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Xml/System/Xml/XmlCharType.cs b/System.Xml/System/Xml/XmlCharType.cs index 46237198c..17946153f 100644 --- a/System.Xml/System/Xml/XmlCharType.cs +++ b/System.Xml/System/Xml/XmlCharType.cs @@ -6,7 +6,7 @@ // <copyright file="XmlCharType.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ //#define XMLCHARTYPE_USE_RESOURCE // load the character properties from resources (XmlCharType.bin must be linked to System.Xml.dll) diff --git a/System.Xml/System/Xml/XmlComplianceUtil.cs b/System.Xml/System/Xml/XmlComplianceUtil.cs index 3c204926d..c30f7263e 100644 --- a/System.Xml/System/Xml/XmlComplianceUtil.cs +++ b/System.Xml/System/Xml/XmlComplianceUtil.cs @@ -2,7 +2,7 @@ // <copyright file="XmlComplianceUtil.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System; diff --git a/System.Xml/System/Xml/XmlConvert.cs b/System.Xml/System/Xml/XmlConvert.cs index e8bdbe639..6942060d9 100644 --- a/System.Xml/System/Xml/XmlConvert.cs +++ b/System.Xml/System/Xml/XmlConvert.cs @@ -2,7 +2,7 @@ // <copyright file="XmlConvert.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/XmlDownloadManager.cs b/System.Xml/System/Xml/XmlDownloadManager.cs index 305dee8b7..e388818d1 100644 --- a/System.Xml/System/Xml/XmlDownloadManager.cs +++ b/System.Xml/System/Xml/XmlDownloadManager.cs @@ -2,7 +2,7 @@ // <copyright file="XmlDownloadManager.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/XmlEncoding.cs b/System.Xml/System/Xml/XmlEncoding.cs index c896a2136..012e1523d 100644 --- a/System.Xml/System/Xml/XmlEncoding.cs +++ b/System.Xml/System/Xml/XmlEncoding.cs @@ -2,7 +2,7 @@ // <copyright file="XmlEncoding.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Text; diff --git a/System.Xml/System/Xml/XmlException.cs b/System.Xml/System/Xml/XmlException.cs index 40594f747..2873952c6 100644 --- a/System.Xml/System/Xml/XmlException.cs +++ b/System.Xml/System/Xml/XmlException.cs @@ -2,7 +2,7 @@ // <copyright file="XmlException.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/XmlNamespacemanager.cs b/System.Xml/System/Xml/XmlNamespacemanager.cs index 7c825a1f3..7cab6b103 100644 --- a/System.Xml/System/Xml/XmlNamespacemanager.cs +++ b/System.Xml/System/Xml/XmlNamespacemanager.cs @@ -2,7 +2,7 @@ // <copyright file="XmlNamespaceManager.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/XmlNullResolver.cs b/System.Xml/System/Xml/XmlNullResolver.cs index 14dc8ded5..620bdc1c7 100644 --- a/System.Xml/System/Xml/XmlNullResolver.cs +++ b/System.Xml/System/Xml/XmlNullResolver.cs @@ -2,7 +2,7 @@ // <copyright file="XmlNullResolver.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ #if !SILVERLIGHT diff --git a/System.Xml/System/Xml/XmlQualifiedName.cs b/System.Xml/System/Xml/XmlQualifiedName.cs index c96a6636d..6aa29802b 100644 --- a/System.Xml/System/Xml/XmlQualifiedName.cs +++ b/System.Xml/System/Xml/XmlQualifiedName.cs @@ -2,7 +2,7 @@ // <copyright file="XmlQualifiedName.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/XmlResolver.cs b/System.Xml/System/Xml/XmlResolver.cs index 0576f38a8..2245d76d2 100644 --- a/System.Xml/System/Xml/XmlResolver.cs +++ b/System.Xml/System/Xml/XmlResolver.cs @@ -2,7 +2,7 @@ // <copyright file="XmlResolver.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml diff --git a/System.Xml/System/Xml/XmlSecureResolver.cs b/System.Xml/System/Xml/XmlSecureResolver.cs index b5b795ca7..31f28d141 100644 --- a/System.Xml/System/Xml/XmlSecureResolver.cs +++ b/System.Xml/System/Xml/XmlSecureResolver.cs @@ -2,7 +2,7 @@ // <copyright file="XmlSecureResolver.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml { diff --git a/System.Xml/System/Xml/XmlUrlResolver.cs b/System.Xml/System/Xml/XmlUrlResolver.cs index e762f5e35..7dc2e20af 100644 --- a/System.Xml/System/Xml/XmlUrlResolver.cs +++ b/System.Xml/System/Xml/XmlUrlResolver.cs @@ -2,7 +2,7 @@ // <copyright file="XmlUrlResolver.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Threading; diff --git a/System.Xml/System/Xml/Xslt/XslCompiledTransform.cs b/System.Xml/System/Xml/Xslt/XslCompiledTransform.cs index dda069806..455e8912a 100644 --- a/System.Xml/System/Xml/Xslt/XslCompiledTransform.cs +++ b/System.Xml/System/Xml/Xslt/XslCompiledTransform.cs @@ -2,7 +2,7 @@ // <copyright file="XslCompiledTransform.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> // <spec>http://webdata/xml/specs/XslCompiledTransform.xml</spec> //------------------------------------------------------------------------------ diff --git a/System.Xml/System/Xml/Xslt/XslTransform.cs b/System.Xml/System/Xml/Xslt/XslTransform.cs index e116f05e3..16031994e 100644 --- a/System.Xml/System/Xml/Xslt/XslTransform.cs +++ b/System.Xml/System/Xml/Xslt/XslTransform.cs @@ -2,7 +2,7 @@ // <copyright file="XslTransform.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ namespace System.Xml.Xsl { diff --git a/System.Xml/System/Xml/Xslt/XsltArgumentList.cs b/System.Xml/System/Xml/Xslt/XsltArgumentList.cs index d8f0c98b2..bc33f89cb 100644 --- a/System.Xml/System/Xml/Xslt/XsltArgumentList.cs +++ b/System.Xml/System/Xml/Xslt/XsltArgumentList.cs @@ -2,7 +2,7 @@ // <copyright file="XsltArgumentList.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Xml/System/Xml/Xslt/XsltContext.cs b/System.Xml/System/Xml/Xslt/XsltContext.cs index 64bf74fbd..ec37ade34 100644 --- a/System.Xml/System/Xml/Xslt/XsltContext.cs +++ b/System.Xml/System/Xml/Xslt/XsltContext.cs @@ -2,7 +2,7 @@ // <copyright file="XsltContext.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Collections; diff --git a/System.Xml/System/Xml/Xslt/XsltException.cs b/System.Xml/System/Xml/Xslt/XsltException.cs index 1f4aaf2c6..d724bcb10 100644 --- a/System.Xml/System/Xml/Xslt/XsltException.cs +++ b/System.Xml/System/Xml/Xslt/XsltException.cs @@ -2,7 +2,7 @@ // <copyright file="XsltException.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> //------------------------------------------------------------------------------ using System.Globalization; diff --git a/System.Xml/System/Xml/Xslt/XsltSettings.cs b/System.Xml/System/Xml/Xslt/XsltSettings.cs index fa0ad069f..ba4e27607 100644 --- a/System.Xml/System/Xml/Xslt/XsltSettings.cs +++ b/System.Xml/System/Xml/Xslt/XsltSettings.cs @@ -2,7 +2,7 @@ // <copyright file="XsltSettings.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <owner current="true" primary="true">[....]</owner> +// <owner current="true" primary="true">Microsoft</owner> // <spec>http://webdata/xml/specs/XslCompiledTransform.xml</spec> //------------------------------------------------------------------------------ diff --git a/System/System.txt b/System/System.txt index 72241a9c1..22eb1c6a2 100644 --- a/System/System.txt +++ b/System/System.txt @@ -122,6 +122,9 @@ Overflow_Int64=Value was either too large or too small for an Int64. Overflow_UInt32=Value was either too large or too small for a UInt32. Overflow_UInt64=Value was either too large or too small for a UInt64. Overflow_Decimal=Value was either too large or too small for a Decimal. +# +#endif // !SILVERLIGHT +# #=------------------------------------------------------------------= # Strings used by System.Runtime.Versioning @@ -132,9 +135,6 @@ Argument_FrameworkNameInvalidVersion=FrameworkName version component is invalid. Argument_FrameworkNameMissingVersion=FrameworkName version component is missing. # Strings used by System.Collections -# -#endif // !SILVERLIGHT -# ArgumentNull_Key=Key cannot be null. Argument_AddingDuplicate=An entry with the same key already exists. Argument_InvalidValue=Argument {0} should be larger than {1}. @@ -522,6 +522,7 @@ DirectoryObjectPathDescr=The fully qualified, or relative path to the directory FileObjectDetectEncodingDescr=Determines whether the file will be parsed to see if it has a byte order mark indicating its encoding. If it does, this will be used rather than the current specified encoding. FileObjectEncodingDescr=The encoding to use when reading the file. UTF-8 is the default. FileObjectPathDescr=The fully qualified, or relative path to the file you wish to read from. E.g., "myfile.txt". +#endif // !SILVERLIGHT #=------------------------------------------------------------------= # Security resources @@ -536,9 +537,7 @@ Arg_EmptyOrNullString=String cannot be empty or null. Arg_EmptyOrNullArray=Array cannot be empty or null. Argument_InvalidClassAttribute=The value of "class" attribute is invalid. Argument_InvalidNameType=The value of "nameType" is invalid. -#endif // !SILVERLIGHT InvalidOperation_EnumNotStarted=Enumeration has not started. Call MoveNext. -#if !SILVERLIGHT InvalidOperation_DuplicateItemNotAllowed=Duplicate items are not allowed in the collection. Cryptography_Asn_MismatchedOidInCollection=The AsnEncodedData object does not have the same OID for the collection. @@ -587,6 +586,7 @@ Security_InvalidValue=The {0} value was invalid. Unknown_Error=Unknown error. +#if !SILVERLIGHT security_ServiceNameCollection_EmptyServiceName=A service name must not be null or empty. security_ExtendedProtectionPolicy_UseDifferentConstructorForNever=To construct a policy with PolicyEnforcement.Never, the single-parameter constructor must be used. security_ExtendedProtectionPolicy_NoEmptyServiceNameCollection=The ServiceNameCollection must contain at least one service name. @@ -854,10 +854,10 @@ net_uri_BadUnicodeHostForIdn=An invalid Unicode character by IDN standards was s net_uri_GenericAuthorityNotDnsSafe=The generic authority '{0}' is not a valid dns name. net_uri_NotJustSerialization=UriComponents.SerializationInfoString must not be combined with other UriComponents. +net_emptystringcall=The parameter '{0}' cannot be an empty string. #if !SILVERLIGHT net_emptystringset=This property cannot be set to an empty string. -net_emptystringcall=The parameter '{0}' cannot be an empty string. net_headers_req=This collection holds response headers and cannot contain the specified request header. net_headers_rsp=This collection holds request headers and cannot contain the specified response header. @@ -1333,6 +1333,9 @@ net_log_socket_connected=Created connection from {0} to {1}. net_log_socket_accepted=Accepted connection from {0} to {1}. net_log_socket_not_logged_file=Not logging data from file: {0}. net_log_socket_connect_dnsendpoint=Connecting to a DnsEndPoint. +net_log_set_socketoption_reuseport={0}#{1} - Setting SocketOptionName.ReuseUnicastPort option for socket. +net_log_set_socketoption_reuseport_not_supported={0}#{1} - SocketOptionName.ReuseUnicastPort option not supported. +net_log_set_socketoption_reuseport_default_on=Registry key activated to enable SocketOptionName.ReuseUnicastPort socket option by default for all ServicePoint TCP connections. #=-------------------------- #= Email Strings @@ -1699,6 +1702,7 @@ CantGetStandardError=StandardError has not been redirected. CantMixSyncAsyncOperation= Cannot mix synchronous and asynchronous operation on process stream. NoFileMappingSize=Cannot retrieve file mapping size while initializing configuration settings. EnvironmentBlockTooLong=The environment block used to start a process cannot be longer than 65535 bytes. Your environment block is {0} bytes long. Remove some environment variables and try again. +CantSetDuplicatePassword=ProcessStartInfo.Password and ProcessStartInfo.PasswordInClearText cannot both be set. Use only one of them. #=------------------------------------------------------------------= # Strings used by the Serial ports and other areas using IO error reporting @@ -2130,6 +2134,13 @@ ResetActionRequiresNullItem=Reset action must be initialized with no changed ite ResetActionRequiresIndexMinus1=Reset action must be initialized with index -1. IndexCannotBeNegative=Index cannot be negative. ObservableCollectionReentrancyNotAllowed=Cannot change ObservableCollection during a CollectionChanged event. + +InvalidOperation_HCCountOverflow=Handle collector count overflows or underflows. +Argument_InvalidThreshold=maximumThreshold cannot be less than initialThreshold. #endif // !FEATURE_NETCORE #endif // INCLUDE_DEBUG + +#if !SILVERLIGHT +net_ssl_io_already_shutdown=Write operations are not allowed after the channel was shutdown. +#endif // !SILVERLIGHT diff --git a/System/compmod/microsoft/win32/UnsafeNativeMethods.cs b/System/compmod/microsoft/win32/UnsafeNativeMethods.cs index 958740229..00d024ca8 100644 --- a/System/compmod/microsoft/win32/UnsafeNativeMethods.cs +++ b/System/compmod/microsoft/win32/UnsafeNativeMethods.cs @@ -367,19 +367,19 @@ public static extern bool ReportEvent(SafeHandle hEventLog, short type, ushort c [DllImport(ExternDll.Advapi32, CharSet=System.Runtime.InteropServices.CharSet.Unicode, SetLastError=true)] [ResourceExposure(ResourceScope.None)] [return: MarshalAs(UnmanagedType.Bool)] - [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "[....]: EventLog is protected by EventLogPermission")] + [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Microsoft: EventLog is protected by EventLogPermission")] public static extern bool GetOldestEventLogRecord(SafeHandle hEventLog, out int number); [DllImport(ExternDll.Advapi32, CharSet=System.Runtime.InteropServices.CharSet.Unicode, SetLastError=true)] [ResourceExposure(ResourceScope.Machine)] [return: MarshalAs(UnmanagedType.Bool)] - [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "[....]: EventLog is protected by EventLogPermission")] + [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Microsoft: EventLog is protected by EventLogPermission")] public static extern bool ReadEventLog(SafeHandle hEventLog, int dwReadFlags, int dwRecordOffset, byte[] buffer, int numberOfBytesToRead, out int bytesRead, out int minNumOfBytesNeeded); [DllImport(ExternDll.Advapi32, CharSet=System.Runtime.InteropServices.CharSet.Unicode, SetLastError=true)] [ResourceExposure(ResourceScope.None)] [return: MarshalAs(UnmanagedType.Bool)] - [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "[....]: EventLog is protected by EventLogPermission")] + [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Microsoft: EventLog is protected by EventLogPermission")] public static extern bool NotifyChangeEventLog(SafeHandle hEventLog, SafeWaitHandle hEvent); [DllImport(ExternDll.Kernel32, EntryPoint="ReadDirectoryChangesW", CharSet=System.Runtime.InteropServices.CharSet.Auto, SetLastError=true)] diff --git a/System/compmod/microsoft/win32/safehandles/SafeEventLogReadHandle.cs b/System/compmod/microsoft/win32/safehandles/SafeEventLogReadHandle.cs index 56dad7b9e..9aa313096 100644 --- a/System/compmod/microsoft/win32/safehandles/SafeEventLogReadHandle.cs +++ b/System/compmod/microsoft/win32/safehandles/SafeEventLogReadHandle.cs @@ -7,7 +7,7 @@ ** ** Class: SafeEventLogReadHandle ** -** <EMAIL>Author: David Gutierrez ([....]) </EMAIL> +** <EMAIL>Author: David Gutierrez (Microsoft) </EMAIL> ** ** A wrapper for event log handles ** diff --git a/System/compmod/microsoft/win32/safehandles/SafeEventLogWriteHandle.cs b/System/compmod/microsoft/win32/safehandles/SafeEventLogWriteHandle.cs index 55d5f8ed7..060594b0c 100644 --- a/System/compmod/microsoft/win32/safehandles/SafeEventLogWriteHandle.cs +++ b/System/compmod/microsoft/win32/safehandles/SafeEventLogWriteHandle.cs @@ -7,7 +7,7 @@ ** ** Class: SafeEventLogWriteHandle ** -** <EMAIL>Author: David Gutierrez ([....]) </EMAIL> +** <EMAIL>Author: David Gutierrez (Microsoft) </EMAIL> ** ** A wrapper for event log handles ** diff --git a/System/compmod/microsoft/win32/safehandles/SafeFileMapViewHandle.cs b/System/compmod/microsoft/win32/safehandles/SafeFileMapViewHandle.cs index ba6ca911f..72e064091 100644 --- a/System/compmod/microsoft/win32/safehandles/SafeFileMapViewHandle.cs +++ b/System/compmod/microsoft/win32/safehandles/SafeFileMapViewHandle.cs @@ -7,7 +7,7 @@ ** ** Class: SafeFileMapViewHandle ** -** <EMAIL>Author: Brian Grunkemeyer ([....]) </EMAIL> +** <EMAIL>Author: Brian Grunkemeyer (Microsoft) </EMAIL> ** ** A wrapper for handles returned from MapViewOfFile, used ** for shared memory. diff --git a/System/compmod/microsoft/win32/safehandles/SafeFileMappingHandle.cs b/System/compmod/microsoft/win32/safehandles/SafeFileMappingHandle.cs index 35568910b..6a7db6b15 100644 --- a/System/compmod/microsoft/win32/safehandles/SafeFileMappingHandle.cs +++ b/System/compmod/microsoft/win32/safehandles/SafeFileMappingHandle.cs @@ -7,7 +7,7 @@ ** ** Class: SafeFileMappingHandle ** -** <EMAIL>Author: David Gutierrez ([....]) </EMAIL> +** <EMAIL>Author: David Gutierrez (Microsoft) </EMAIL> ** ** A wrapper for handle to file mappings, returned by ** CreateFileMapping and OpenFileMapping. Used for shared diff --git a/System/compmod/microsoft/win32/safehandles/SafeLibraryHandle.cs b/System/compmod/microsoft/win32/safehandles/SafeLibraryHandle.cs index ef4a1bb60..55dc02ab9 100644 --- a/System/compmod/microsoft/win32/safehandles/SafeLibraryHandle.cs +++ b/System/compmod/microsoft/win32/safehandles/SafeLibraryHandle.cs @@ -7,7 +7,7 @@ ** ** Class: SafeLibraryHandle ** -** <EMAIL>Author: David Gutierrez ([....]) </EMAIL> +** <EMAIL>Author: David Gutierrez (Microsoft) </EMAIL> ** ** A wrapper for a library handles ** diff --git a/System/compmod/microsoft/win32/safehandles/SafeLocalMemHandle.cs b/System/compmod/microsoft/win32/safehandles/SafeLocalMemHandle.cs index 86df5599a..8f2c8f513 100644 --- a/System/compmod/microsoft/win32/safehandles/SafeLocalMemHandle.cs +++ b/System/compmod/microsoft/win32/safehandles/SafeLocalMemHandle.cs @@ -7,7 +7,7 @@ ** ** Class: SafeLocalMemHandle ** -** <EMAIL>Author: David Gutierrez ([....]) </EMAIL> +** <EMAIL>Author: David Gutierrez (Microsoft) </EMAIL> ** ** A wrapper for handle to local memory ** diff --git a/System/compmod/microsoft/win32/safehandles/SafeTimerHandle.cs b/System/compmod/microsoft/win32/safehandles/SafeTimerHandle.cs index 65b3a0a10..68abca846 100644 --- a/System/compmod/microsoft/win32/safehandles/SafeTimerHandle.cs +++ b/System/compmod/microsoft/win32/safehandles/SafeTimerHandle.cs @@ -7,7 +7,7 @@ ** ** Class: SafeTimerHandle ** -** <EMAIL>Author: David Gutierrez ([....]) </EMAIL> +** <EMAIL>Author: David Gutierrez (Microsoft) </EMAIL> ** ** A wrapper for a timer handle ** diff --git a/System/compmod/microsoft/win32/safehandles/SafeUserTokenHandle.cs b/System/compmod/microsoft/win32/safehandles/SafeUserTokenHandle.cs index 25fb6d62d..f21aea760 100644 --- a/System/compmod/microsoft/win32/safehandles/SafeUserTokenHandle.cs +++ b/System/compmod/microsoft/win32/safehandles/SafeUserTokenHandle.cs @@ -7,7 +7,7 @@ ** ** Class: SafeUserTokenHandle ** -** <EMAIL>Author: David Gutierrez ([....]) </EMAIL> +** <EMAIL>Author: David Gutierrez (Microsoft) </EMAIL> ** ** A wrapper for a user token handle ** diff --git a/System/compmod/system/codedom/CodeArgumentReferenceExpression.cs b/System/compmod/system/codedom/CodeArgumentReferenceExpression.cs index 66eb9d755..7b074e028 100644 --- a/System/compmod/system/codedom/CodeArgumentReferenceExpression.cs +++ b/System/compmod/system/codedom/CodeArgumentReferenceExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeArgumentReferenceExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeArrayCreateExpression.cs b/System/compmod/system/codedom/CodeArrayCreateExpression.cs index e4517f1be..63e9b54e1 100644 --- a/System/compmod/system/codedom/CodeArrayCreateExpression.cs +++ b/System/compmod/system/codedom/CodeArrayCreateExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeArrayCreateExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeArrayIndexerExpression.cs b/System/compmod/system/codedom/CodeArrayIndexerExpression.cs index efacd8e4e..85e979746 100644 --- a/System/compmod/system/codedom/CodeArrayIndexerExpression.cs +++ b/System/compmod/system/codedom/CodeArrayIndexerExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeArrayIndexerExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeAssignStatement.cs b/System/compmod/system/codedom/CodeAssignStatement.cs index 1337fc719..2a5ccbe4c 100644 --- a/System/compmod/system/codedom/CodeAssignStatement.cs +++ b/System/compmod/system/codedom/CodeAssignStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeAssignStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeAttachEventStatement.cs b/System/compmod/system/codedom/CodeAttachEventStatement.cs index 78003316f..f3098a1a6 100644 --- a/System/compmod/system/codedom/CodeAttachEventStatement.cs +++ b/System/compmod/system/codedom/CodeAttachEventStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeAttachEventStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeAttributeArgument.cs b/System/compmod/system/codedom/CodeAttributeArgument.cs index 278ba1db5..218ff75b4 100644 --- a/System/compmod/system/codedom/CodeAttributeArgument.cs +++ b/System/compmod/system/codedom/CodeAttributeArgument.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeAttributeArgument.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeAttributeArgumentCollection.cs b/System/compmod/system/codedom/CodeAttributeArgumentCollection.cs index a7426cdfd..242803b58 100644 --- a/System/compmod/system/codedom/CodeAttributeArgumentCollection.cs +++ b/System/compmod/system/codedom/CodeAttributeArgumentCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeAttributeArgumentCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeAttributeDeclaration.cs b/System/compmod/system/codedom/CodeAttributeDeclaration.cs index 4216987dc..b10284664 100644 --- a/System/compmod/system/codedom/CodeAttributeDeclaration.cs +++ b/System/compmod/system/codedom/CodeAttributeDeclaration.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeAttributeDeclaration.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeAttributeDeclarationCollection.cs b/System/compmod/system/codedom/CodeAttributeDeclarationCollection.cs index 2c14d7893..e7a6baed5 100644 --- a/System/compmod/system/codedom/CodeAttributeDeclarationCollection.cs +++ b/System/compmod/system/codedom/CodeAttributeDeclarationCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeAttributeDeclarationCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeBinaryOperatorExpression.cs b/System/compmod/system/codedom/CodeBinaryOperatorExpression.cs index ee21644fb..e0c524343 100644 --- a/System/compmod/system/codedom/CodeBinaryOperatorExpression.cs +++ b/System/compmod/system/codedom/CodeBinaryOperatorExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeBinaryOperatorExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeCastExpression.cs b/System/compmod/system/codedom/CodeCastExpression.cs index c001c5806..f136ff617 100644 --- a/System/compmod/system/codedom/CodeCastExpression.cs +++ b/System/compmod/system/codedom/CodeCastExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeCastExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeCatchClause.cs b/System/compmod/system/codedom/CodeCatchClause.cs index 15ab8de22..6f8034806 100644 --- a/System/compmod/system/codedom/CodeCatchClause.cs +++ b/System/compmod/system/codedom/CodeCatchClause.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeCatchClause.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeCatchClauseCollection.cs b/System/compmod/system/codedom/CodeCatchClauseCollection.cs index ceb3e70ea..4d8b0b35c 100644 --- a/System/compmod/system/codedom/CodeCatchClauseCollection.cs +++ b/System/compmod/system/codedom/CodeCatchClauseCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeCatchClauseCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeChecksumPragma.cs b/System/compmod/system/codedom/CodeChecksumPragma.cs index a272b59d0..b18cb50f6 100644 --- a/System/compmod/system/codedom/CodeChecksumPragma.cs +++ b/System/compmod/system/codedom/CodeChecksumPragma.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeChecksumPragma.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeComment.cs b/System/compmod/system/codedom/CodeComment.cs index e639c3776..2b04dec59 100644 --- a/System/compmod/system/codedom/CodeComment.cs +++ b/System/compmod/system/codedom/CodeComment.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeComment.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeCommentStatement.cs b/System/compmod/system/codedom/CodeCommentStatement.cs index bd7598eb8..7872eaf03 100644 --- a/System/compmod/system/codedom/CodeCommentStatement.cs +++ b/System/compmod/system/codedom/CodeCommentStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeCommentStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeCommentStatementCollection.cs b/System/compmod/system/codedom/CodeCommentStatementCollection.cs index 9d0936dbf..f2360b564 100644 --- a/System/compmod/system/codedom/CodeCommentStatementCollection.cs +++ b/System/compmod/system/codedom/CodeCommentStatementCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeCommentStatementCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeCompileUnit.cs b/System/compmod/system/codedom/CodeCompileUnit.cs index 7a4102e62..24c0823e6 100644 --- a/System/compmod/system/codedom/CodeCompileUnit.cs +++ b/System/compmod/system/codedom/CodeCompileUnit.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeCompileUnit.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeConditionStatement.cs b/System/compmod/system/codedom/CodeConditionStatement.cs index f71df7145..65cf684d8 100644 --- a/System/compmod/system/codedom/CodeConditionStatement.cs +++ b/System/compmod/system/codedom/CodeConditionStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeConditionStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeConstructor.cs b/System/compmod/system/codedom/CodeConstructor.cs index 79a4e9906..0a29e5959 100644 --- a/System/compmod/system/codedom/CodeConstructor.cs +++ b/System/compmod/system/codedom/CodeConstructor.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeConstructor.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeDefaultValueExpression.cs b/System/compmod/system/codedom/CodeDefaultValueExpression.cs index 7ab33e6ba..d41abec56 100644 --- a/System/compmod/system/codedom/CodeDefaultValueExpression.cs +++ b/System/compmod/system/codedom/CodeDefaultValueExpression.cs @@ -1,4 +1,4 @@ -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.CodeDom { using System.Diagnostics; diff --git a/System/compmod/system/codedom/CodeDelegateCreateExpression.cs b/System/compmod/system/codedom/CodeDelegateCreateExpression.cs index d5f19dc78..ada4bf15b 100644 --- a/System/compmod/system/codedom/CodeDelegateCreateExpression.cs +++ b/System/compmod/system/codedom/CodeDelegateCreateExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeDelegateCreateExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeDelegateInvokeExpression.cs b/System/compmod/system/codedom/CodeDelegateInvokeExpression.cs index ccc099fba..c46bdf91e 100644 --- a/System/compmod/system/codedom/CodeDelegateInvokeExpression.cs +++ b/System/compmod/system/codedom/CodeDelegateInvokeExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeDelegateInvokeExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeDirectionExpression.cs b/System/compmod/system/codedom/CodeDirectionExpression.cs index 12288ac59..b6dcdc64d 100644 --- a/System/compmod/system/codedom/CodeDirectionExpression.cs +++ b/System/compmod/system/codedom/CodeDirectionExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeDirectionExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeDirectiveCollection.cs b/System/compmod/system/codedom/CodeDirectiveCollection.cs index 4a1decc69..c7f7b5a7a 100644 --- a/System/compmod/system/codedom/CodeDirectiveCollection.cs +++ b/System/compmod/system/codedom/CodeDirectiveCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeDirectiveCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeEntryPointMethod.cs b/System/compmod/system/codedom/CodeEntryPointMethod.cs index 74575ca3e..aa6541619 100644 --- a/System/compmod/system/codedom/CodeEntryPointMethod.cs +++ b/System/compmod/system/codedom/CodeEntryPointMethod.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeEntryPointMethod.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeEventReferenceExpression.cs b/System/compmod/system/codedom/CodeEventReferenceExpression.cs index 1a34b90ca..3eadd89bf 100644 --- a/System/compmod/system/codedom/CodeEventReferenceExpression.cs +++ b/System/compmod/system/codedom/CodeEventReferenceExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeEventReferenceExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeExpressionCollection.cs b/System/compmod/system/codedom/CodeExpressionCollection.cs index 1af19ae87..6c0b04414 100644 --- a/System/compmod/system/codedom/CodeExpressionCollection.cs +++ b/System/compmod/system/codedom/CodeExpressionCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeExpressionCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeExpressionStatement.cs b/System/compmod/system/codedom/CodeExpressionStatement.cs index 676ed9870..7fa7f8bae 100644 --- a/System/compmod/system/codedom/CodeExpressionStatement.cs +++ b/System/compmod/system/codedom/CodeExpressionStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeExpressionStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeFieldReferenceExpression.cs b/System/compmod/system/codedom/CodeFieldReferenceExpression.cs index 52ad0e101..279a2b27b 100644 --- a/System/compmod/system/codedom/CodeFieldReferenceExpression.cs +++ b/System/compmod/system/codedom/CodeFieldReferenceExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeFieldReferenceExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeGotoStatement.cs b/System/compmod/system/codedom/CodeGotoStatement.cs index a8b06a1ad..fa1e7c963 100644 --- a/System/compmod/system/codedom/CodeGotoStatement.cs +++ b/System/compmod/system/codedom/CodeGotoStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeGotoStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeIndexerExpression.cs b/System/compmod/system/codedom/CodeIndexerExpression.cs index cb41ce728..bd71984b7 100644 --- a/System/compmod/system/codedom/CodeIndexerExpression.cs +++ b/System/compmod/system/codedom/CodeIndexerExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeIndexerExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeIterationStatement.cs b/System/compmod/system/codedom/CodeIterationStatement.cs index 65d988ada..bcabe1bee 100644 --- a/System/compmod/system/codedom/CodeIterationStatement.cs +++ b/System/compmod/system/codedom/CodeIterationStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeIterationStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeLabeledStatement.cs b/System/compmod/system/codedom/CodeLabeledStatement.cs index e9d0a4d67..d378c4041 100644 --- a/System/compmod/system/codedom/CodeLabeledStatement.cs +++ b/System/compmod/system/codedom/CodeLabeledStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeLabeledStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeLinePragma.cs b/System/compmod/system/codedom/CodeLinePragma.cs index e83322d76..96064829f 100644 --- a/System/compmod/system/codedom/CodeLinePragma.cs +++ b/System/compmod/system/codedom/CodeLinePragma.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeLinePragma.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeMemberEvent.cs b/System/compmod/system/codedom/CodeMemberEvent.cs index d8ed1cc15..e7a05f69b 100644 --- a/System/compmod/system/codedom/CodeMemberEvent.cs +++ b/System/compmod/system/codedom/CodeMemberEvent.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeMemberEvent.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeMemberField.cs b/System/compmod/system/codedom/CodeMemberField.cs index a2d2877fc..0a6d89bcf 100644 --- a/System/compmod/system/codedom/CodeMemberField.cs +++ b/System/compmod/system/codedom/CodeMemberField.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeMemberField.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeMemberMethod.cs b/System/compmod/system/codedom/CodeMemberMethod.cs index e7632f7ff..1be222144 100644 --- a/System/compmod/system/codedom/CodeMemberMethod.cs +++ b/System/compmod/system/codedom/CodeMemberMethod.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeMemberMethod.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeMemberProperty.cs b/System/compmod/system/codedom/CodeMemberProperty.cs index c07ce9643..8eded2271 100644 --- a/System/compmod/system/codedom/CodeMemberProperty.cs +++ b/System/compmod/system/codedom/CodeMemberProperty.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeMemberProperty.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeMethodInvokeExpression.cs b/System/compmod/system/codedom/CodeMethodInvokeExpression.cs index d1d5fe7eb..b941059ea 100644 --- a/System/compmod/system/codedom/CodeMethodInvokeExpression.cs +++ b/System/compmod/system/codedom/CodeMethodInvokeExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeMethodInvokeExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeMethodReturnStatement.cs b/System/compmod/system/codedom/CodeMethodReturnStatement.cs index 6bcb6a1ab..3769a3a70 100644 --- a/System/compmod/system/codedom/CodeMethodReturnStatement.cs +++ b/System/compmod/system/codedom/CodeMethodReturnStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeMethodReturnStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeNamespace.cs b/System/compmod/system/codedom/CodeNamespace.cs index 9feea179f..6bef7fdfc 100644 --- a/System/compmod/system/codedom/CodeNamespace.cs +++ b/System/compmod/system/codedom/CodeNamespace.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeNamespace.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeNamespaceCollection.cs b/System/compmod/system/codedom/CodeNamespaceCollection.cs index 81b5d1199..654eb1f8d 100644 --- a/System/compmod/system/codedom/CodeNamespaceCollection.cs +++ b/System/compmod/system/codedom/CodeNamespaceCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeNamespaceCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeNamespaceImport.cs b/System/compmod/system/codedom/CodeNamespaceImport.cs index aed07620b..21fb016d0 100644 --- a/System/compmod/system/codedom/CodeNamespaceImport.cs +++ b/System/compmod/system/codedom/CodeNamespaceImport.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeNamespaceImport.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeNamespaceImportCollection.cs b/System/compmod/system/codedom/CodeNamespaceImportCollection.cs index 9015a63bc..e4b8c72df 100644 --- a/System/compmod/system/codedom/CodeNamespaceImportCollection.cs +++ b/System/compmod/system/codedom/CodeNamespaceImportCollection.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeNamespaceImportCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeObject.cs b/System/compmod/system/codedom/CodeObject.cs index f8f0993c5..97813e052 100644 --- a/System/compmod/system/codedom/CodeObject.cs +++ b/System/compmod/system/codedom/CodeObject.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeObject.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeObjectCreateExpression.cs b/System/compmod/system/codedom/CodeObjectCreateExpression.cs index 9604e90ba..6a09707e5 100644 --- a/System/compmod/system/codedom/CodeObjectCreateExpression.cs +++ b/System/compmod/system/codedom/CodeObjectCreateExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeObjectCreateExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeParameterDeclarationExpression.cs b/System/compmod/system/codedom/CodeParameterDeclarationExpression.cs index 9e9703409..5c3c1d58d 100644 --- a/System/compmod/system/codedom/CodeParameterDeclarationExpression.cs +++ b/System/compmod/system/codedom/CodeParameterDeclarationExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeParameterDeclarationExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeParameterDeclarationExpressionCollection.cs b/System/compmod/system/codedom/CodeParameterDeclarationExpressionCollection.cs index 2bc781bae..dad8668f1 100644 --- a/System/compmod/system/codedom/CodeParameterDeclarationExpressionCollection.cs +++ b/System/compmod/system/codedom/CodeParameterDeclarationExpressionCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeParameterDeclarationExpressionCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodePrimitiveExpression.cs b/System/compmod/system/codedom/CodePrimitiveExpression.cs index b64496141..e8cb3b0f5 100644 --- a/System/compmod/system/codedom/CodePrimitiveExpression.cs +++ b/System/compmod/system/codedom/CodePrimitiveExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodePrimitiveExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodePropertyReferenceExpression.cs b/System/compmod/system/codedom/CodePropertyReferenceExpression.cs index 28d511744..97b3f36b8 100644 --- a/System/compmod/system/codedom/CodePropertyReferenceExpression.cs +++ b/System/compmod/system/codedom/CodePropertyReferenceExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodePropertyReferenceExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeRegionDirective.cs b/System/compmod/system/codedom/CodeRegionDirective.cs index 1ecfe2e9b..058c64b23 100644 --- a/System/compmod/system/codedom/CodeRegionDirective.cs +++ b/System/compmod/system/codedom/CodeRegionDirective.cs @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // <copyright file="CodeChecksumPragma.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. diff --git a/System/compmod/system/codedom/CodeRemoveEventStatement.cs b/System/compmod/system/codedom/CodeRemoveEventStatement.cs index c767800ae..0f0c0f671 100644 --- a/System/compmod/system/codedom/CodeRemoveEventStatement.cs +++ b/System/compmod/system/codedom/CodeRemoveEventStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeRemoveEventStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeSnippetCompileUnit.cs b/System/compmod/system/codedom/CodeSnippetCompileUnit.cs index bdf6f35b0..df0b7eb0a 100644 --- a/System/compmod/system/codedom/CodeSnippetCompileUnit.cs +++ b/System/compmod/system/codedom/CodeSnippetCompileUnit.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeSnippetCompileUnit.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeSnippetExpression.cs b/System/compmod/system/codedom/CodeSnippetExpression.cs index 2e759abc8..18e87f7c6 100644 --- a/System/compmod/system/codedom/CodeSnippetExpression.cs +++ b/System/compmod/system/codedom/CodeSnippetExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeSnippetExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeSnippetStatement.cs b/System/compmod/system/codedom/CodeSnippetStatement.cs index 4190a8876..8c0387fe4 100644 --- a/System/compmod/system/codedom/CodeSnippetStatement.cs +++ b/System/compmod/system/codedom/CodeSnippetStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeSnippetStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeSnippetTypeMember.cs b/System/compmod/system/codedom/CodeSnippetTypeMember.cs index a2ae40489..a07dfa68a 100644 --- a/System/compmod/system/codedom/CodeSnippetTypeMember.cs +++ b/System/compmod/system/codedom/CodeSnippetTypeMember.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeSnippetTypeMember.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeStatement.cs b/System/compmod/system/codedom/CodeStatement.cs index cb56cfc08..3cdbebdc8 100644 --- a/System/compmod/system/codedom/CodeStatement.cs +++ b/System/compmod/system/codedom/CodeStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeStatementCollection.cs b/System/compmod/system/codedom/CodeStatementCollection.cs index b9ee3df11..d475921f4 100644 --- a/System/compmod/system/codedom/CodeStatementCollection.cs +++ b/System/compmod/system/codedom/CodeStatementCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeStatementCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeThrowExceptionStatement.cs b/System/compmod/system/codedom/CodeThrowExceptionStatement.cs index 59a9b44aa..f763c517c 100644 --- a/System/compmod/system/codedom/CodeThrowExceptionStatement.cs +++ b/System/compmod/system/codedom/CodeThrowExceptionStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeThrowExceptionStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTryCatchFinallyStatement.cs b/System/compmod/system/codedom/CodeTryCatchFinallyStatement.cs index 132691227..d79ff52b3 100644 --- a/System/compmod/system/codedom/CodeTryCatchFinallyStatement.cs +++ b/System/compmod/system/codedom/CodeTryCatchFinallyStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeTryCatchFinallyStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeConstructor.cs b/System/compmod/system/codedom/CodeTypeConstructor.cs index d2f737e9b..c9dd7346b 100644 --- a/System/compmod/system/codedom/CodeTypeConstructor.cs +++ b/System/compmod/system/codedom/CodeTypeConstructor.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeTypeConstructor.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeDeclaration.cs b/System/compmod/system/codedom/CodeTypeDeclaration.cs index a4c498834..c9c0c3769 100644 --- a/System/compmod/system/codedom/CodeTypeDeclaration.cs +++ b/System/compmod/system/codedom/CodeTypeDeclaration.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeTypeDeclaration.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeDeclarationCollection.cs b/System/compmod/system/codedom/CodeTypeDeclarationCollection.cs index 4d47a5afe..638ba5ff6 100644 --- a/System/compmod/system/codedom/CodeTypeDeclarationCollection.cs +++ b/System/compmod/system/codedom/CodeTypeDeclarationCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeTypeDeclarationCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeDelegate.cs b/System/compmod/system/codedom/CodeTypeDelegate.cs index a96b3b224..f0ad8368f 100644 --- a/System/compmod/system/codedom/CodeTypeDelegate.cs +++ b/System/compmod/system/codedom/CodeTypeDelegate.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeTypeDelegate.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeMember.cs b/System/compmod/system/codedom/CodeTypeMember.cs index 060d76d8c..38f0c0d1c 100644 --- a/System/compmod/system/codedom/CodeTypeMember.cs +++ b/System/compmod/system/codedom/CodeTypeMember.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeTypeMember.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeMemberCollection.cs b/System/compmod/system/codedom/CodeTypeMemberCollection.cs index 58acc0bb1..b4fe0211f 100644 --- a/System/compmod/system/codedom/CodeTypeMemberCollection.cs +++ b/System/compmod/system/codedom/CodeTypeMemberCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeTypeMemberCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeOfExpression.cs b/System/compmod/system/codedom/CodeTypeOfExpression.cs index a2ba738e4..dbd3498f7 100644 --- a/System/compmod/system/codedom/CodeTypeOfExpression.cs +++ b/System/compmod/system/codedom/CodeTypeOfExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeTypeOfExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeParameter.cs b/System/compmod/system/codedom/CodeTypeParameter.cs index d3acfd8c7..fd5e1164b 100644 --- a/System/compmod/system/codedom/CodeTypeParameter.cs +++ b/System/compmod/system/codedom/CodeTypeParameter.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeTypeParameter.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeParameterCollection.cs b/System/compmod/system/codedom/CodeTypeParameterCollection.cs index 42290c07b..9c03b81ab 100644 --- a/System/compmod/system/codedom/CodeTypeParameterCollection.cs +++ b/System/compmod/system/codedom/CodeTypeParameterCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeTypeParameterCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeReference.cs b/System/compmod/system/codedom/CodeTypeReference.cs index ad8389d7e..3ba435d53 100644 --- a/System/compmod/system/codedom/CodeTypeReference.cs +++ b/System/compmod/system/codedom/CodeTypeReference.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeTypeReference.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeReferenceCollection.cs b/System/compmod/system/codedom/CodeTypeReferenceCollection.cs index 4787c56ac..0324aff52 100644 --- a/System/compmod/system/codedom/CodeTypeReferenceCollection.cs +++ b/System/compmod/system/codedom/CodeTypeReferenceCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CodeTypeReferenceCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeTypeReferenceExpression.cs b/System/compmod/system/codedom/CodeTypeReferenceExpression.cs index 267323a8d..3fdc0ebfc 100644 --- a/System/compmod/system/codedom/CodeTypeReferenceExpression.cs +++ b/System/compmod/system/codedom/CodeTypeReferenceExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeTypeReferenceExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeVariableDeclarationStatement.cs b/System/compmod/system/codedom/CodeVariableDeclarationStatement.cs index 2569c3895..958a3386a 100644 --- a/System/compmod/system/codedom/CodeVariableDeclarationStatement.cs +++ b/System/compmod/system/codedom/CodeVariableDeclarationStatement.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeVariableDeclarationStatement.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/CodeVariableReferenceExpression.cs b/System/compmod/system/codedom/CodeVariableReferenceExpression.cs index 8ce716469..83bd33d4b 100644 --- a/System/compmod/system/codedom/CodeVariableReferenceExpression.cs +++ b/System/compmod/system/codedom/CodeVariableReferenceExpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeVariableReferenceExpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/codemethodreferenceexpression.cs b/System/compmod/system/codedom/codemethodreferenceexpression.cs index 96adf47cb..1b8c54a77 100644 --- a/System/compmod/system/codedom/codemethodreferenceexpression.cs +++ b/System/compmod/system/codedom/codemethodreferenceexpression.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="codemethodreferenceexpression.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/CodeCompiler.cs b/System/compmod/system/codedom/compiler/CodeCompiler.cs index 7eaaa9aab..45fb83a1e 100644 --- a/System/compmod/system/codedom/compiler/CodeCompiler.cs +++ b/System/compmod/system/codedom/compiler/CodeCompiler.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeCompiler.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/CodeDOMProvider.cs b/System/compmod/system/codedom/compiler/CodeDOMProvider.cs index 7fb7adce0..ff2004130 100644 --- a/System/compmod/system/codedom/compiler/CodeDOMProvider.cs +++ b/System/compmod/system/codedom/compiler/CodeDOMProvider.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeDOMProvider.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/CodeDomConfigurationHandler.cs b/System/compmod/system/codedom/compiler/CodeDomConfigurationHandler.cs index b72b1a989..e1633cc92 100644 --- a/System/compmod/system/codedom/compiler/CodeDomConfigurationHandler.cs +++ b/System/compmod/system/codedom/compiler/CodeDomConfigurationHandler.cs @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // <copyright file="CodeDomCompilationConfiguration.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. diff --git a/System/compmod/system/codedom/compiler/CodeGenerator.cs b/System/compmod/system/codedom/compiler/CodeGenerator.cs index 60cde1f27..0e7062b0b 100644 --- a/System/compmod/system/codedom/compiler/CodeGenerator.cs +++ b/System/compmod/system/codedom/compiler/CodeGenerator.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeGenerator.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/CodeGeneratorOptions.cs b/System/compmod/system/codedom/compiler/CodeGeneratorOptions.cs index d3a8dfb85..80f6a3ba5 100644 --- a/System/compmod/system/codedom/compiler/CodeGeneratorOptions.cs +++ b/System/compmod/system/codedom/compiler/CodeGeneratorOptions.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CodeGeneratorOptions.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/CodeValidator.cs b/System/compmod/system/codedom/compiler/CodeValidator.cs index 6abf4c89d..5164c804f 100644 --- a/System/compmod/system/codedom/compiler/CodeValidator.cs +++ b/System/compmod/system/codedom/compiler/CodeValidator.cs @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // <copyright file="CodeGenerator.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. diff --git a/System/compmod/system/codedom/compiler/CompilerError.cs b/System/compmod/system/codedom/compiler/CompilerError.cs index 0e4f0a3bb..c5c2661e3 100644 --- a/System/compmod/system/codedom/compiler/CompilerError.cs +++ b/System/compmod/system/codedom/compiler/CompilerError.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CompilerError.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/CompilerErrorCollection.cs b/System/compmod/system/codedom/compiler/CompilerErrorCollection.cs index 7b191fd9e..f35d185fc 100644 --- a/System/compmod/system/codedom/compiler/CompilerErrorCollection.cs +++ b/System/compmod/system/codedom/compiler/CompilerErrorCollection.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // <copyright file="CompilerErrorCollection.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // ------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/CompilerInfo.cs b/System/compmod/system/codedom/compiler/CompilerInfo.cs index 5e695adac..0cd93987b 100644 --- a/System/compmod/system/codedom/compiler/CompilerInfo.cs +++ b/System/compmod/system/codedom/compiler/CompilerInfo.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CompilerInfo.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/CompilerParameters.cs b/System/compmod/system/codedom/compiler/CompilerParameters.cs index f3b701998..4a3f826fc 100644 --- a/System/compmod/system/codedom/compiler/CompilerParameters.cs +++ b/System/compmod/system/codedom/compiler/CompilerParameters.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CompilerParameters.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/CompilerResults.cs b/System/compmod/system/codedom/compiler/CompilerResults.cs index 5168410e5..d2b7c231b 100644 --- a/System/compmod/system/codedom/compiler/CompilerResults.cs +++ b/System/compmod/system/codedom/compiler/CompilerResults.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="CompilerResults.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/Executor.cs b/System/compmod/system/codedom/compiler/Executor.cs index e9a97dad1..5fac36c6a 100644 --- a/System/compmod/system/codedom/compiler/Executor.cs +++ b/System/compmod/system/codedom/compiler/Executor.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="Executor.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/GeneratedCodeAttribute.cs b/System/compmod/system/codedom/compiler/GeneratedCodeAttribute.cs index 0066e7363..fd30ac50c 100644 --- a/System/compmod/system/codedom/compiler/GeneratedCodeAttribute.cs +++ b/System/compmod/system/codedom/compiler/GeneratedCodeAttribute.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="GeneratedCodeAttribute.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/IndentTextWriter.cs b/System/compmod/system/codedom/compiler/IndentTextWriter.cs index 0d6d57942..be86a9c17 100644 --- a/System/compmod/system/codedom/compiler/IndentTextWriter.cs +++ b/System/compmod/system/codedom/compiler/IndentTextWriter.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="IndentTextWriter.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/RedistVersionInfo.cs b/System/compmod/system/codedom/compiler/RedistVersionInfo.cs index bf8e4bf87..c3c0e970c 100644 --- a/System/compmod/system/codedom/compiler/RedistVersionInfo.cs +++ b/System/compmod/system/codedom/compiler/RedistVersionInfo.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="RedistVersionInfo.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/codedom/compiler/TempFiles.cs b/System/compmod/system/codedom/compiler/TempFiles.cs index da6925a11..f966f2684 100644 --- a/System/compmod/system/codedom/compiler/TempFiles.cs +++ b/System/compmod/system/codedom/compiler/TempFiles.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <copyright file="TempFiles.cs" company="Microsoft"> // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ diff --git a/System/compmod/system/collections/generic/stack.cs b/System/compmod/system/collections/generic/stack.cs index eb8d46d66..086926ce9 100644 --- a/System/compmod/system/collections/generic/stack.cs +++ b/System/compmod/system/collections/generic/stack.cs @@ -32,7 +32,7 @@ public class Stack<T> : IEnumerable<T>, IReadOnlyCollection<T> { private T[] _array; // Storage for stack elements private int _size; // Number of items in the stack. - private int _version; // Used to keep enumerator in [....] w/ collection. + private int _version; // Used to keep enumerator in sync w/ collection. #if !SILVERLIGHT [NonSerialized] #endif diff --git a/System/compmod/system/collections/objectmodel/observablecollection.cs b/System/compmod/system/collections/objectmodel/observablecollection.cs index 69f8a5c19..7e0a67da5 100644 --- a/System/compmod/system/collections/objectmodel/observablecollection.cs +++ b/System/compmod/system/collections/objectmodel/observablecollection.cs @@ -11,7 +11,7 @@ // See spec at http://avalon/connecteddata/Specs/Collection%20Interfaces.mht // // History: -// 11/22/2004 : [....] - created +// 11/22/2004 : Microsoft - created // //--------------------------------------------------------------------------- diff --git a/System/compmod/system/collections/specialized/marshalinghelpers.cs b/System/compmod/system/collections/specialized/marshalinghelpers.cs index 3bfa0b837..ed7120718 100644 --- a/System/compmod/system/collections/specialized/marshalinghelpers.cs +++ b/System/compmod/system/collections/specialized/marshalinghelpers.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System.Security; using System.Collections; diff --git a/System/compmod/system/componentmodel/AsyncOperation.cs b/System/compmod/system/componentmodel/AsyncOperation.cs index d3679b06a..7d596a07f 100644 --- a/System/compmod/system/componentmodel/AsyncOperation.cs +++ b/System/compmod/system/componentmodel/AsyncOperation.cs @@ -29,7 +29,7 @@ private AsyncOperation(object userSuppliedState, SynchronizationContext syncCont } /// <summary> - /// Destructor. Guarantees that [....] context will always get notified of completion. + /// Destructor. Guarantees that sync context will always get notified of completion. /// </summary> ~AsyncOperation() { diff --git a/System/compmod/system/componentmodel/MemberDescriptor.cs b/System/compmod/system/componentmodel/MemberDescriptor.cs index ebc36a83d..f6660d7aa 100644 --- a/System/compmod/system/componentmodel/MemberDescriptor.cs +++ b/System/compmod/system/componentmodel/MemberDescriptor.cs @@ -444,7 +444,7 @@ protected static MethodInfo FindMethod(Type componentClass, string name, Type[] } /// <devdoc> - /// Try to keep this reasonable in [....] with Equals(). Specifically, + /// Try to keep this reasonable in sync with Equals(). Specifically, /// if A.Equals(B) returns true, A & B should have the same hash code. /// </devdoc> public override int GetHashCode() { diff --git a/System/compmod/system/componentmodel/PropertyDescriptor.cs b/System/compmod/system/componentmodel/PropertyDescriptor.cs index ecfb46bc0..9915bcf85 100644 --- a/System/compmod/system/componentmodel/PropertyDescriptor.cs +++ b/System/compmod/system/componentmodel/PropertyDescriptor.cs @@ -347,7 +347,7 @@ public virtual object GetEditor(Type editorBaseType) { } /// <devdoc> - /// Try to keep this reasonable in [....] with Equals(). Specifically, + /// Try to keep this reasonable in sync with Equals(). Specifically, /// if A.Equals(B) returns true, A & B should have the same hash code. /// </devdoc> public override int GetHashCode() { diff --git a/System/compmod/system/componentmodel/design/DesignerVerb.cs b/System/compmod/system/componentmodel/design/DesignerVerb.cs index d9840075c..b10a8255a 100644 --- a/System/compmod/system/componentmodel/design/DesignerVerb.cs +++ b/System/compmod/system/componentmodel/design/DesignerVerb.cs @@ -30,7 +30,7 @@ public class DesignerVerb : MenuCommand { /// </devdoc> [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public DesignerVerb(string text, EventHandler handler) : base(handler, StandardCommands.VerbFirst) { - // NOTICE!!! When you changed the regex here, please change it in Designer\[....]\System\[....]\Design\TableLayoutPanelDesigner.cs + // NOTICE!!! When you changed the regex here, please change it in Designer\Microsoft\System\Microsoft\Design\TableLayoutPanelDesigner.cs // method "TrimText", too. Properties["Text"] = text == null ? null : Regex.Replace(text, @"\(\&.\)", ""); // VSWHIDBEY 485835 } diff --git a/System/compmod/system/diagnostics/assertwrapper.cs b/System/compmod/system/diagnostics/assertwrapper.cs index c6f638567..e6938156e 100644 --- a/System/compmod/system/diagnostics/assertwrapper.cs +++ b/System/compmod/system/diagnostics/assertwrapper.cs @@ -61,9 +61,9 @@ private static void ShowVsAssert(string stackTrace, StackFrame frame, string mes [DllImport(ExternDll.Fxassert, CharSet=System.Runtime.InteropServices.CharSet.Ansi, BestFitMapping=true)] [ResourceExposure(ResourceScope.None)] - [SuppressMessage("Microsoft.Globalization","CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId="0", Justification="[....]: VsAssert isn't making a security decision here and they don't provide Unicode versions, also it is internal to MS")] - [SuppressMessage("Microsoft.Globalization","CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId="1", Justification="[....]: VsAssert isn't making a security decision here and they don't provide Unicode versions, also it is internal to MS")] - [SuppressMessage("Microsoft.Globalization","CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId="2", Justification="[....]: VsAssert isn't making a security decision here and they don't provide Unicode versions, also it is internal to MS")] + [SuppressMessage("Microsoft.Globalization","CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId="0", Justification="Microsoft: VsAssert isn't making a security decision here and they don't provide Unicode versions, also it is internal to MS")] + [SuppressMessage("Microsoft.Globalization","CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId="1", Justification="Microsoft: VsAssert isn't making a security decision here and they don't provide Unicode versions, also it is internal to MS")] + [SuppressMessage("Microsoft.Globalization","CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId="2", Justification="Microsoft: VsAssert isn't making a security decision here and they don't provide Unicode versions, also it is internal to MS")] public static extern int VsAssert(string message, string assert, string file, int line, [In, Out]int[] pfDisable); [ResourceExposure(ResourceScope.None)] @@ -203,7 +203,7 @@ private static void ShowCFUserNotificationDisplayAlertAssert(string stackTrace, [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] #endif [SecuritySafeCritical] - [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "Microsoft.Win32.UnsafeNativeMethods.ReleaseDC(System.IntPtr,System.IntPtr)", Justification = "[....]: If the DC is not released there's not much we can do.")] + [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "Microsoft.Win32.UnsafeNativeMethods.ReleaseDC(System.IntPtr,System.IntPtr)", Justification = "Microsoft: If the DC is not released there's not much we can do.")] private static string TruncateMessageToFitScreen(string message) { const int MaxCharsPerLine = 80; diff --git a/System/misc/ClientUtils.cs b/System/misc/ClientUtils.cs index d350b64b6..d42c1cdf6 100644 --- a/System/misc/ClientUtils.cs +++ b/System/misc/ClientUtils.cs @@ -6,11 +6,11 @@ /* */ -#if WINFORMS_NAMESPACE +#if Microsoft_NAMESPACE namespace System.Windows.Forms #elif DRAWING_NAMESPACE namespace System.Drawing -#elif WINFORMS_PUBLIC_GRAPHICS_LIBRARY +#elif Microsoft_PUBLIC_GRAPHICS_LIBRARY namespace System.Internal #elif SYSTEM_NAMESPACE namespace System @@ -274,7 +274,7 @@ private static void Debug_NonSequentialEnumIsDefinedCheck(System.Enum value, int /// ----------------------------------------------------------------- /// /// </devdoc> -#if WINFORMS_NAMESPACE || WINFORMS_PUBLIC_GRAPHICS_LIBRARY || DRAWING_NAMESPACE +#if Microsoft_NAMESPACE || Microsoft_PUBLIC_GRAPHICS_LIBRARY || DRAWING_NAMESPACE internal class WeakRefCollection : IList { private int refCheckThreshold = Int32.MaxValue; // this means this is disabled by default. private ArrayList _innerList; diff --git a/System/misc/SecurityUtils.cs b/System/misc/SecurityUtils.cs index 76e02fafb..159dedbb6 100644 --- a/System/misc/SecurityUtils.cs +++ b/System/misc/SecurityUtils.cs @@ -8,11 +8,11 @@ */ -#if WINFORMS_NAMESPACE +#if Microsoft_NAMESPACE namespace System.Windows.Forms #elif DRAWING_NAMESPACE namespace System.Drawing -#elif WINFORMS_PUBLIC_GRAPHICS_LIBRARY +#elif Microsoft_PUBLIC_GRAPHICS_LIBRARY namespace System.Internal #elif SYSTEM_NAMESPACE namespace System @@ -127,7 +127,7 @@ internal static object SecureCreateInstance(Type type, object[] args, bool allow return Activator.CreateInstance(type, flags, null, args, null); } -#if (!WINFORMS_NAMESPACE) +#if (!Microsoft_NAMESPACE) /// <devdoc> /// This helper method provides safe access to Activator.CreateInstance. diff --git a/System/misc/externdll.cs b/System/misc/externdll.cs index 367fe80cf..c62ebe45b 100644 --- a/System/misc/externdll.cs +++ b/System/misc/externdll.cs @@ -72,6 +72,7 @@ internal static class ExternDll { public const string Fxassert = "Fxassert.dll"; public const string Shlwapi = "shlwapi.dll"; public const string Crypt32 = "crypt32.dll"; + public const string ShCore = "SHCore.dll"; // system.data specific internal const string Odbc32 = "odbc32.dll"; diff --git a/System/net/System/Net/Cache/HttpRequestCacheValidator.cs b/System/net/System/Net/Cache/HttpRequestCacheValidator.cs index 92dafc1f5..973e6b621 100644 --- a/System/net/System/Net/Cache/HttpRequestCacheValidator.cs +++ b/System/net/System/Net/Cache/HttpRequestCacheValidator.cs @@ -902,7 +902,7 @@ private unsafe void FetchCacheControl(string s, bool forCache) { // These if-else are two logically identical blocks that differ only in the way of how text search is done. // The text search is done differently for 32 and X-bits platforms. - // ATTN: You are responsible for keeping the rest of the logic in [....]. + // ATTN: You are responsible for keeping the rest of the logic in sync. if (IntPtr.Size == 4) { // We are on 32-bits platform diff --git a/System/net/System/Net/Cache/IERequestCache.cs b/System/net/System/Net/Cache/IERequestCache.cs index fb4467486..d7421af8e 100644 --- a/System/net/System/Net/Cache/IERequestCache.cs +++ b/System/net/System/Net/Cache/IERequestCache.cs @@ -51,7 +51,7 @@ internal WinInetCache(bool isPrivateCache, bool canWrite, bool async): base (isP ***********/ // Per VsWhidbey#88276 it was decided to not enforce any cache metadata limits for WinInet cache provider. - // ([....] 7/17 made this a const to avoid threading issues) + // (Microsoft 7/17 made this a const to avoid threading issues) //_MaximumResponseHeadersLength = Int32.MaxValue; this.async = async; diff --git a/System/net/System/Net/Cache/RequestCachePolicy.cs b/System/net/System/Net/Cache/RequestCachePolicy.cs index f66806904..704589af7 100644 --- a/System/net/System/Net/Cache/RequestCachePolicy.cs +++ b/System/net/System/Net/Cache/RequestCachePolicy.cs @@ -32,7 +32,7 @@ public enum RequestCacheLevel BypassCache = 1, // Only serve requests from cache, an exception is thrown if not found CacheOnly = 2, - // Serve from the cache, but will [....] up with the server if not found + // Serve from the cache, but will sync up with the server if not found CacheIfAvailable = 3, // Attempt to revalidate cache with the server, reload if unable to Revalidate = 4, @@ -105,7 +105,7 @@ public enum HttpRequestCacheLevel BypassCache = 1, // Only serve requests from cache, an exception is thrown if not found CacheOnly = 2, - // Serve from the cache, but will [....] up with the server if not found + // Serve from the cache, but will sync up with the server if not found CacheIfAvailable = 3, // Validate cached data with the server even if it looks fresh Revalidate = 4, diff --git a/System/net/System/Net/Configuration/DefaultProxySection.cs b/System/net/System/Net/Configuration/DefaultProxySection.cs index 13b735ef5..deb439b59 100644 --- a/System/net/System/Net/Configuration/DefaultProxySection.cs +++ b/System/net/System/Net/Configuration/DefaultProxySection.cs @@ -118,7 +118,7 @@ public bool UseDefaultCredentials // This allows us to prevent parent settings (machine.config) from propegating to higher config (app.config), unless // the higher config doesn't contain the section at all. That is, overriding defaultProxy is all-or-nothing. - // Template from [....]. + // Template from Microsoft. protected override void Reset(ConfigurationElement parentElement) { // Ignore the parentElement parameter by changing it to the default settings diff --git a/System/net/System/Net/Configuration/TimeoutValidationAttribute.cs b/System/net/System/Net/Configuration/TimeoutValidationAttribute.cs index 472273d81..0bc729b6a 100644 --- a/System/net/System/Net/Configuration/TimeoutValidationAttribute.cs +++ b/System/net/System/Net/Configuration/TimeoutValidationAttribute.cs @@ -3,7 +3,7 @@ namespace System.Net { using System.Configuration; using System.ComponentModel; - // NOTE [[....]]: The old validation attribute was removed from System.ll and is + // NOTE [Microsoft]: The old validation attribute was removed from System.ll and is // replaced by more flexible and robust validation/conversion design. // The change bellow is a simple fix to make things work with the least possible change ( it is an integration break ) // However, we already have a built-in support for configuration properties that store @@ -32,7 +32,7 @@ public override void Validate( object value ) { return; if (timeout <= 0 && timeout != System.Threading.Timeout.Infinite) { - // Note [[....]] : This is a lab integration fix. Old code did not have any error message at this point + // Note [Microsoft] : This is a lab integration fix. Old code did not have any error message at this point // This code change accomplishes the same result. However its highly reccomended that a specific error message is givven // to the user so they know what exaclty is the problem ( i.e. the value must be a positive integer or be Infinite ) // To accomplish this - an exception with the specific error message could be thrown ( ArgumentException is prefferred ) diff --git a/System/net/System/Net/FtpWebRequest.cs b/System/net/System/Net/FtpWebRequest.cs index 8d6ae247f..1e7c00c55 100644 --- a/System/net/System/Net/FtpWebRequest.cs +++ b/System/net/System/Net/FtpWebRequest.cs @@ -1320,7 +1320,7 @@ private void CheckError() { } } - // Return null only on [....] (if we're on the [....] thread). Otherwise throw if no context is available. + // Return null only on Sync (if we're on the Sync thread). Otherwise throw if no context is available. // // @@ -1331,7 +1331,7 @@ internal override ContextAwareResult GetWritingContext() else if (m_WriteAsyncResult != null) return m_WriteAsyncResult; - // [....]. + // Sync. GlobalLog.ThreadContract(ThreadKinds.User | ThreadKinds.Sync, "FtpWebRequest#" + ValidationHelper.HashString(this) + "::GetWritingContext"); return null; } @@ -1339,7 +1339,7 @@ internal override ContextAwareResult GetWritingContext() // // Provides an abstract way of having Async code callback into the request (saves a delegate) // - // ATTN this method is also called on [....] path when either command or data stream gets closed + // ATTN this method is also called on sync path when either command or data stream gets closed // Consider: Revisit the design of ftp streams // internal override void RequestCallback(object obj) @@ -1350,7 +1350,7 @@ internal override void RequestCallback(object obj) SyncRequestCallback(obj); } // - // Only executed for [....] requests when the pipline is completed + // Only executed for Sync requests when the pipline is completed // private void SyncRequestCallback(object obj) { @@ -1389,7 +1389,7 @@ private void SyncRequestCallback(object obj) isRevalidatedOrRetried =!m_CacheDone && (CacheProtocol.ProtocolStatus == CacheValidationStatus.Continue || CacheProtocol.ProtocolStatus == CacheValidationStatus.RetryResponseFromServer); - // This is for [....] Upload commands that do not get chance hit GetResponse loop + // This is for sync Upload commands that do not get chance hit GetResponse loop if (m_MethodInfo.IsUpload) { CheckCacheRetrieveOnResponse(); diff --git a/System/net/System/Net/HttpListenerRequest.cs b/System/net/System/Net/HttpListenerRequest.cs index a789a6ea2..96bbf5246 100644 --- a/System/net/System/Net/HttpListenerRequest.cs +++ b/System/net/System/Net/HttpListenerRequest.cs @@ -303,6 +303,8 @@ internal HttpListenerContext HttpListenerContext { // Note: RequestBuffer may get moved in memory. If you dereference a pointer from inside the RequestBuffer, // you must use 'OriginalBlobAddress' below to adjust the location of the pointer to match the location of // RequestBuffer. + // + internal byte[] RequestBuffer { get @@ -1017,7 +1019,7 @@ internal ChannelBinding GetChannelBinding() } internal IEnumerable<TokenBinding> GetTlsTokenBindings() { - + // Try to get the token binding if not created. if (Volatile.Read(ref m_TokenBindings) == null) { @@ -1063,10 +1065,18 @@ private void ProcessTlsTokenBindings() { } m_TokenBindings = new List<TokenBinding>(); - UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_TOKEN_BINDING_INFO* pTokenBindingInfo = UnsafeNclNativeMethods.HttpApi.GetTlsTokenBindingRequestInfo(RequestBuffer, OriginalBlobAddress); + UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_TOKEN_BINDING_INFO_V1* pTokenBindingInfo_V1 = null; + bool useV1TokenBinding = false; + // Only try to collect the old binding information if there is no V2 binding information available if (pTokenBindingInfo == null) + { + pTokenBindingInfo_V1 = UnsafeNclNativeMethods.HttpApi.GetTlsTokenBindingRequestInfo_V1(RequestBuffer, OriginalBlobAddress); + useV1TokenBinding = true; + } + + if (pTokenBindingInfo == null && pTokenBindingInfo_V1 == null) { // The current request isn't over TLS or the client or server doesn't support the token binding // protocol. This isn't an error; just return "nothing here". @@ -1075,13 +1085,35 @@ private void ProcessTlsTokenBindings() { UnsafeNclNativeMethods.HttpApi.HeapAllocHandle handle = null; m_TokenBindingVerifyMessageStatus = -1; - m_TokenBindingVerifyMessageStatus = UnsafeNclNativeMethods.HttpApi.TokenBindingVerifyMessage( - pTokenBindingInfo->TokenBinding, - pTokenBindingInfo->TokenBindingSize, - pTokenBindingInfo->KeyType, - pTokenBindingInfo->TlsUnique, - pTokenBindingInfo->TlsUniqueSize, - out handle); + + fixed (byte* pMemoryBlob = RequestBuffer){ + UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_V2* request = (UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_V2*)pMemoryBlob; + long fixup = pMemoryBlob - (byte*) OriginalBlobAddress; + + if (useV1TokenBinding && pTokenBindingInfo_V1 != null) + { + // Old V1 Token Binding protocol is still being used, so we need to verify the binding message using the old API + m_TokenBindingVerifyMessageStatus = UnsafeNclNativeMethods.HttpApi.TokenBindingVerifyMessage_V1( + pTokenBindingInfo_V1->TokenBinding + fixup, + pTokenBindingInfo_V1->TokenBindingSize, + (IntPtr)((byte*)(pTokenBindingInfo_V1->KeyType) + fixup), + pTokenBindingInfo_V1->TlsUnique + fixup, + pTokenBindingInfo_V1->TlsUniqueSize, + out handle); + } + else + { + // Use the V2 token binding behavior + m_TokenBindingVerifyMessageStatus = + UnsafeNclNativeMethods.HttpApi.TokenBindingVerifyMessage( + pTokenBindingInfo->TokenBinding + fixup, + pTokenBindingInfo->TokenBindingSize, + pTokenBindingInfo->KeyType, + pTokenBindingInfo->TlsUnique + fixup, + pTokenBindingInfo->TlsUniqueSize, + out handle); + } + } if (m_TokenBindingVerifyMessageStatus != 0) { @@ -1093,27 +1125,74 @@ private void ProcessTlsTokenBindings() { using (handle) { - UnsafeNclNativeMethods.HttpApi.TOKENBINDING_RESULT_LIST* pResultList = (UnsafeNclNativeMethods.HttpApi.TOKENBINDING_RESULT_LIST*)handle.DangerousGetHandle(); - for (int i = 0; i < pResultList->resultCount; i++) + // If we have an old binding, use the old binding behavior + if (useV1TokenBinding) + { + GenerateTokenBindings_V1(handle); + } + else { - UnsafeNclNativeMethods.HttpApi.TOKENBINDING_RESULT_DATA* pThisResultData = &pResultList->resultData[i]; + GenerateTokenBindings(handle); + } + } + } + + /// <summary> + /// Method to allow current bindings to be returned + /// </summary> + /// <param name="handle"></param> + private void GenerateTokenBindings(UnsafeNclNativeMethods.HttpApi.HeapAllocHandle handle) + { + UnsafeNclNativeMethods.HttpApi.TOKENBINDING_RESULT_LIST* pResultList = (UnsafeNclNativeMethods.HttpApi.TOKENBINDING_RESULT_LIST*)handle.DangerousGetHandle(); + for (int i = 0; i < pResultList->resultCount; i++) + { + UnsafeNclNativeMethods.HttpApi.TOKENBINDING_RESULT_DATA* pThisResultData = &pResultList->resultData[i]; - if (pThisResultData != null) + if (pThisResultData != null) + { + byte[] retVal = new byte[pThisResultData->identifierSize]; + Marshal.Copy((IntPtr)(pThisResultData->identifierData), retVal, 0, retVal.Length); + + if (pThisResultData->bindingType == UnsafeNclNativeMethods.HttpApi.TOKENBINDING_TYPE.TOKENBINDING_TYPE_PROVIDED) + { + m_TokenBindings.Add(new TokenBinding(TokenBindingType.Provided, retVal)); + } + else if (pThisResultData->bindingType == UnsafeNclNativeMethods.HttpApi.TOKENBINDING_TYPE.TOKENBINDING_TYPE_REFERRED) { - // Per http://tools.ietf.org/html/draft-ietf-tokbind-protocol-00, Sec. 4, - // We'll strip off the token binding type and return the remainder as an opaque blob. - Debug.Assert((long)(&pThisResultData->identifierData->hashAlgorithm) == (long)(pThisResultData->identifierData) + 1); - byte[] retVal = new byte[pThisResultData->identifierSize - 1]; - Marshal.Copy((IntPtr)(&pThisResultData->identifierData->hashAlgorithm), retVal, 0, retVal.Length); + m_TokenBindings.Add(new TokenBinding(TokenBindingType.Referred, retVal)); + } + } + } + } - if (pThisResultData->identifierData->bindingType == UnsafeNclNativeMethods.HttpApi.TOKENBINDING_TYPE.TOKENBINDING_TYPE_PROVIDED) - { - m_TokenBindings.Add(new TokenBinding(TokenBindingType.Provided, retVal)); - } - else if (pThisResultData->identifierData->bindingType == UnsafeNclNativeMethods.HttpApi.TOKENBINDING_TYPE.TOKENBINDING_TYPE_REFERRED) - { - m_TokenBindings.Add(new TokenBinding(TokenBindingType.Referred, retVal)); - } + /// <summary> + /// Compat method to allow V1 bindings to be returned + /// </summary> + /// <param name="handle"></param> + private void GenerateTokenBindings_V1(UnsafeNclNativeMethods.HttpApi.HeapAllocHandle handle) + { + UnsafeNclNativeMethods.HttpApi.TOKENBINDING_RESULT_LIST_V1* pResultList = (UnsafeNclNativeMethods.HttpApi.TOKENBINDING_RESULT_LIST_V1*)handle.DangerousGetHandle(); + for (int i = 0; i < pResultList->resultCount; i++) + { + UnsafeNclNativeMethods.HttpApi.TOKENBINDING_RESULT_DATA_V1* pThisResultData = &pResultList->resultData[i]; + + if (pThisResultData != null) + { + // Old V1 Token Binding protocol is still being used, so we need modify the binding message using the old behavior + + // Per http://tools.ietf.org/html/draft-ietf-tokbind-protocol-00, Sec. 4, + // We'll strip off the token binding type and return the remainder as an opaque blob. + Debug.Assert((long)(&pThisResultData->identifierData->hashAlgorithm) == (long)(pThisResultData->identifierData) + 1 ); + byte[] retVal = new byte[pThisResultData->identifierSize - 1]; + Marshal.Copy((IntPtr)(&pThisResultData->identifierData->hashAlgorithm), retVal, 0, retVal.Length); + + if (pThisResultData->identifierData->bindingType == UnsafeNclNativeMethods.HttpApi.TOKENBINDING_TYPE.TOKENBINDING_TYPE_PROVIDED) + { + m_TokenBindings.Add(new TokenBinding(TokenBindingType.Provided, retVal)); + } + else if (pThisResultData->identifierData->bindingType == UnsafeNclNativeMethods.HttpApi.TOKENBINDING_TYPE.TOKENBINDING_TYPE_REFERRED) + { + m_TokenBindings.Add(new TokenBinding(TokenBindingType.Referred, retVal)); } } } diff --git a/System/net/System/Net/HttpWebRequest.cs b/System/net/System/Net/HttpWebRequest.cs index 7fe34ea43..76e37ecea 100644 --- a/System/net/System/Net/HttpWebRequest.cs +++ b/System/net/System/Net/HttpWebRequest.cs @@ -153,7 +153,7 @@ private enum Booleans : uint { // Used by our Connection to block on being able to Read from our Connection private LazyAsyncResult _ConnectionReaderAResult; - // Once set, the Request either works Async or [....] internally + // Once set, the Request either works Async or Sync internally private TriState _RequestIsAsync; // Delegate that can be called on Continue Response @@ -406,7 +406,7 @@ internal bool NtlmKeepAlive { } } - // [....] code path only. + // Sync code path only. // True if ProcessWriteCallDone Should read for an additional response. // False if the 100Continue code will do the read in WriteHeaders. internal bool NeedsToReadForResponse { @@ -792,7 +792,7 @@ internal LazyAsyncResult ConnectionReaderAsyncResult { } // True, if the EndGetRequestStream or GetRequestStream call returned - // codereview: Used ONLY by [....] code + // codereview: Used ONLY by Sync code internal bool UserRetrievedWriteStream { get { return _WriteAResult != null && _WriteAResult.InternalPeekCompleted; @@ -1555,7 +1555,7 @@ public Stream GetRequestStream(out TransportContext context) { CurrentMethod = _OriginVerb; // Submit the Request, causes us to queue ourselves to a Connection and may block - // It has happened that [....] path uses this loop the Retry memeber for handling resubmissions. + // It has happened that Sync path uses this loop the Retry memeber for handling resubmissions. while (m_Retry && !_WriteAResult.InternalPeekCompleted) { _OldSubmitWriteStream = null; _SubmitWriteStream = null; @@ -1825,7 +1825,7 @@ private HttpProcessingResult DoSubmitRequestProcessing(ref Exception exception) { GlobalLog.Print("HttpWebRequest#" + ValidationHelper.HashString(this) + "::DoSubmitRequestProcessing() resubmiting this request."); - // Here is a little hack for [....] looping through BeginSubmitRequest. + // Here is a little hack for sync looping through BeginSubmitRequest. // We want to unlock cache protocol only if this is NOT a retry. if (CacheProtocol != null && _HttpResponse != null) CacheProtocol.Reset(); @@ -1856,7 +1856,7 @@ private HttpProcessingResult DoSubmitRequestProcessing(ref Exception exception) SubmitRequest(servicePoint); } else { - // under [....] conditions, we let GetResponse() loop calling BeginSubmitRequest() until we're done + // under sync conditions, we let GetResponse() loop calling BeginSubmitRequest() until we're done m_Retry = true; } result = HttpProcessingResult.WriteWait; @@ -2181,7 +2181,7 @@ public override WebResponse GetResponse() { Async = false; - // Since we don't really allow switching between [....] and async, if the request is already async, this needs to + // Since we don't really allow switching between sync and async, if the request is already async, this needs to // capture context for use in the ongoing async operations as if it were BeginGetResponse(). if (Async) { @@ -2206,7 +2206,7 @@ public override WebResponse GetResponse() { if (!gotResponse) { - //The previous call may have been async. If we are now doing a [....] call, we should + //The previous call may have been async. If we are now doing a sync call, we should //use the timeout if (_Timer == null) { _Timer = TimerQueue.CreateTimer(s_TimeoutCallback, this); @@ -3369,7 +3369,7 @@ internal void SetRequestSubmitDone(ConnectStream submitStream) { // // This line is needed ONLY if we got a connect failure (Abort can still happen at random time) // CallDone will check for the write side response processing and this is what we want. - // Note that [....] case already has a separate path to check for the response + // Note that Sync case already has a separate path to check for the response // if (Async && _CoreResponse != null && (object)_CoreResponse != (object)DBNull.Value) { @@ -3489,7 +3489,7 @@ internal void OpenWriteSideResponseWindow() // internal void CheckWriteSideResponseProcessing() { - // In [....] case never close the write side window + // In Sync case never close the write side window // Definitions of _CoreResponse: // - DBNull.Value - Uploading headers/body is in progress, but we haven't yet received a response. @@ -3595,7 +3595,7 @@ internal void SetAndOrProcessResponse(object responseOrException) { GlobalLog.Print("HttpWebRequest#" + ValidationHelper.HashString(this) + "::SetAndOrProcessResponse() - Write Thread will procees the response."); // - // Note for a [....] request a write side window is always open + // Note for a sync request a write side window is always open // if (!Async) { @@ -3991,7 +3991,7 @@ private bool IdentityRequired } } - // Return null only on [....] (if we're on the [....] thread). Otherwise throw if no context is available. + // Return null only on Sync (if we're on the Sync thread). Otherwise throw if no context is available. internal override ContextAwareResult GetConnectingContext() { if (!Async) @@ -4014,7 +4014,7 @@ internal override ContextAwareResult GetConnectingContext() return context; } - // Return null only on [....] (if we're on the [....] thread). Otherwise throw if no context is available. + // Return null only on Sync (if we're on the Sync thread). Otherwise throw if no context is available. internal override ContextAwareResult GetWritingContext() { if (!Async) @@ -4039,7 +4039,7 @@ internal override ContextAwareResult GetWritingContext() return context; } - // Return null only on [....] (if we're on the [....] thread). Otherwise throw if no context is available. + // Return null only on Sync (if we're on the Sync thread). Otherwise throw if no context is available. internal override ContextAwareResult GetReadingContext() { if (!Async) @@ -6025,12 +6025,12 @@ private void ClearRequestForResubmit(bool ntlmFollowupRequest) { // The second NTLM request is required to use the same connection, don't close it if (ntlmFollowupRequest) { - // We only want CallDone to do a [....] read now if 100Continue won't later + // We only want CallDone to do a sync read now if 100Continue won't later NeedsToReadForResponse = !ShouldWaitFor100Continue(); _SubmitWriteStream.CallDone(); } else if (!AllowWriteStreamBuffering) { - // We only want CloseInternal to do a [....] read now if 100Continue won't later + // We only want CloseInternal to do a sync read now if 100Continue won't later NeedsToReadForResponse = !ShouldWaitFor100Continue(); _SubmitWriteStream.CloseInternal(true); } @@ -6094,7 +6094,7 @@ private void FinishRequest(HttpWebResponse response, Exception errorException) // Never throws // private Stream MakeMemoryStream(Stream stream) { - // GlobalLog.ThreadContract(ThreadKinds.[....], "HttpWebRequest#" + ValidationHelper.HashString(this) + "::MakeMemoryStream"); + // GlobalLog.ThreadContract(ThreadKinds.Sync, "HttpWebRequest#" + ValidationHelper.HashString(this) + "::MakeMemoryStream"); if (stream == null || stream is SyncMemoryStream) return stream; diff --git a/System/net/System/Net/Internal.cs b/System/net/System/Net/Internal.cs index 0a0b503ff..3607bc10e 100644 --- a/System/net/System/Net/Internal.cs +++ b/System/net/System/Net/Internal.cs @@ -422,7 +422,7 @@ internal static class NclConstants } // - // A simple [....] point, useful for deferring work. Just an int value with helper methods. + // A simple sync point, useful for deferring work. Just an int value with helper methods. // This is used by HttpWebRequest to syncronize Reads/Writes while waiting for a 100-Continue response. // internal struct InterlockedGate diff --git a/System/net/System/Net/SecureProtocols/NegotiateStream.cs b/System/net/System/Net/SecureProtocols/NegotiateStream.cs index 4cd3b3833..511cae21a 100644 --- a/System/net/System/Net/SecureProtocols/NegotiateStream.cs +++ b/System/net/System/Net/SecureProtocols/NegotiateStream.cs @@ -93,7 +93,7 @@ public virtual void AuthenticateAsClient(NetworkCredential credential, TokenImpersonationLevel allowedImpersonationLevel) { #if DEBUG - using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.[....])) { + using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif _NegoState.ValidateCreateContext(_Package, false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel); _NegoState.ProcessAuthentication(null); @@ -199,7 +199,7 @@ public virtual void AuthenticateAsServer(NetworkCredential credential, TokenImpersonationLevel requiredImpersonationLevel) { #if DEBUG - using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.[....])) { + using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif _NegoState.ValidateCreateContext(_Package, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel); @@ -503,7 +503,7 @@ public override long Seek(long offset, SeekOrigin origin) { // Should this not block? public override void Flush() { #if DEBUG - using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.[....])) { + using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif InnerStream.Flush(); #if DEBUG @@ -531,7 +531,7 @@ protected override void Dispose(bool disposing) { public override int Read(byte[] buffer, int offset, int count) { #if DEBUG - using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.[....])) { + using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif _NegoState.CheckThrow(true); @@ -548,7 +548,7 @@ public override int Read(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count) { #if DEBUG - using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.[....])) { + using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif _NegoState.CheckThrow(true); diff --git a/System/net/System/Net/SecureProtocols/SslEnumTypes.cs b/System/net/System/Net/SecureProtocols/SslEnumTypes.cs index 9d40acc75..b88c44c2b 100644 --- a/System/net/System/Net/SecureProtocols/SslEnumTypes.cs +++ b/System/net/System/Net/SecureProtocols/SslEnumTypes.cs @@ -76,7 +76,13 @@ public enum HashAlgorithmType Md5 = (Alg.ClassHash | Alg.Any | Alg.NameMD5), - Sha1 = (Alg.ClassHash | Alg.Any | Alg.NameSHA) + Sha1 = (Alg.ClassHash | Alg.Any | Alg.NameSHA), + + Sha256 = (Alg.ClassHash | Alg.Any | Alg.NameSHA256), + + Sha384 = (Alg.ClassHash | Alg.Any | Alg.NameSHA384), + + Sha512 = (Alg.ClassHash | Alg.Any | Alg.NameSHA512) } } diff --git a/System/net/System/Net/SecureProtocols/SslStream.cs b/System/net/System/Net/SecureProtocols/SslStream.cs index 8b1efa799..424e36565 100644 --- a/System/net/System/Net/SecureProtocols/SslStream.cs +++ b/System/net/System/Net/SecureProtocols/SslStream.cs @@ -118,24 +118,19 @@ private X509Certificate userCertSelectionCallbackWrapper(string targetHost, X509 return _userCertificateSelectionCallback(this, targetHost, localCertificates, remoteCertificate, acceptableIssuers); } - private SslProtocols DefaultProtocols() - { - SslProtocols protocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls; - if (ServicePointManager.DisableStrongCrypto) - { - protocols = SslProtocols.Tls | SslProtocols.Ssl3; - } - - return protocols; - } - // // Client side auth // public virtual void AuthenticateAsClient(string targetHost) { - AuthenticateAsClient(targetHost, new X509CertificateCollection(), DefaultProtocols(), false); + AuthenticateAsClient(targetHost, new X509CertificateCollection(), ServicePointManager.DefaultSslProtocols, false); } + + public virtual void AuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, bool checkCertificateRevocation) + { + AuthenticateAsClient(targetHost, clientCertificates, ServicePointManager.DefaultSslProtocols, false); + } + // public virtual void AuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation) { @@ -148,9 +143,18 @@ public virtual void AuthenticateAsClient(string targetHost, X509CertificateColle [HostProtection(ExternalThreading=true)] public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, AsyncCallback asyncCallback, object asyncState) { - return BeginAuthenticateAsClient(targetHost, new X509CertificateCollection(), DefaultProtocols(), false, + return BeginAuthenticateAsClient(targetHost, new X509CertificateCollection(), ServicePointManager.DefaultSslProtocols, false, asyncCallback, asyncState); } + + [HostProtection(ExternalThreading = true)] + public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, + bool checkCertificateRevocation, AsyncCallback asyncCallback, + object asyncState) + { + return BeginAuthenticateAsClient(targetHost, clientCertificates, ServicePointManager.DefaultSslProtocols, checkCertificateRevocation, asyncCallback, asyncState); + } + // [HostProtection(ExternalThreading=true)] @@ -166,7 +170,6 @@ public virtual IAsyncResult BeginAuthenticateAsClient(string targetHost, X509Cer } // - public virtual void EndAuthenticateAsClient(IAsyncResult asyncResult) { _SslState.EndProcessAuthentication(asyncResult); @@ -179,8 +182,15 @@ public virtual void EndAuthenticateAsClient(IAsyncResult asyncResult) // public virtual void AuthenticateAsServer(X509Certificate serverCertificate) { - AuthenticateAsServer(serverCertificate, false, DefaultProtocols(), false); + AuthenticateAsServer(serverCertificate, false, ServicePointManager.DefaultSslProtocols, false); } + + public virtual void AuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired, + bool checkCertificateRevocation) + { + AuthenticateAsServer(serverCertificate, clientCertificateRequired, ServicePointManager.DefaultSslProtocols, checkCertificateRevocation); + } + // public virtual void AuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation) @@ -194,10 +204,19 @@ public virtual IAsyncResult BeginAuthenticateAsServer(X509Certificate serverCert { - return BeginAuthenticateAsServer(serverCertificate, false, DefaultProtocols(), false, + return BeginAuthenticateAsServer(serverCertificate, false, ServicePointManager.DefaultSslProtocols, false, asyncCallback, asyncState); } + + [HostProtection(ExternalThreading = true)] + public virtual IAsyncResult BeginAuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired, + bool checkCertificateRevocation, AsyncCallback asyncCallback, + object asyncState) + { + return BeginAuthenticateAsServer(serverCertificate, clientCertificateRequired, ServicePointManager.DefaultSslProtocols, checkCertificateRevocation, asyncCallback, asyncState); + } + // [HostProtection(ExternalThreading=true)] public virtual IAsyncResult BeginAuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired, @@ -217,6 +236,16 @@ public virtual void EndAuthenticateAsServer(IAsyncResult asyncResult) _SslState.EndProcessAuthentication(asyncResult); } + internal virtual IAsyncResult BeginShutdown(AsyncCallback asyncCallback, object asyncState) + { + return _SslState.BeginShutdown(asyncCallback, asyncState); + } + + internal virtual void EndShutdown(IAsyncResult asyncResult) + { + _SslState.EndShutdown(asyncResult); + } + public TransportContext TransportContext { get @@ -237,6 +266,12 @@ public virtual Task AuthenticateAsClientAsync(string targetHost) return Task.Factory.FromAsync(BeginAuthenticateAsClient, EndAuthenticateAsClient, targetHost, null); } + [HostProtection(ExternalThreading = true)] + public virtual Task AuthenticateAsClientAsync(string targetHost, X509CertificateCollection clientCertificates, bool checkCertificateRevocation) + { + return AuthenticateAsClientAsync(targetHost, clientCertificates, ServicePointManager.DefaultSslProtocols, checkCertificateRevocation); + } + [HostProtection(ExternalThreading = true)] public virtual Task AuthenticateAsClientAsync(string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation) { @@ -249,12 +284,26 @@ public virtual Task AuthenticateAsServerAsync(X509Certificate serverCertificate) return Task.Factory.FromAsync(BeginAuthenticateAsServer, EndAuthenticateAsServer, serverCertificate, null); } + [HostProtection(ExternalThreading = true)] + public virtual Task AuthenticateAsServerAsync(X509Certificate serverCertificate, bool clientCertificateRequired, bool checkCertificateRevocation) + { + return AuthenticateAsServerAsync(serverCertificate, clientCertificateRequired, ServicePointManager.DefaultSslProtocols, checkCertificateRevocation); + } + [HostProtection(ExternalThreading = true)] public virtual Task AuthenticateAsServerAsync(X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation) { return Task.Factory.FromAsync((callback, state) => BeginAuthenticateAsServer(serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation, callback, state), EndAuthenticateAsServer, null); } + [HostProtection(ExternalThreading = true)] + public virtual Task ShutdownAsync() + { + return Task.Factory.FromAsync( + (callback, state) => BeginShutdown(callback, state), + EndShutdown, + null); + } // // @@ -387,7 +436,7 @@ public override bool CanTimeout { // public override bool CanWrite { get { - return _SslState.IsAuthenticated && InnerStream.CanWrite; + return _SslState.IsAuthenticated && InnerStream.CanWrite && !_SslState.IsShutdown; } } // diff --git a/System/net/System/Net/SecureProtocols/_FixedSizeReader.cs b/System/net/System/Net/SecureProtocols/_FixedSizeReader.cs index db9d6aff1..2d676f9fa 100644 --- a/System/net/System/Net/SecureProtocols/_FixedSizeReader.cs +++ b/System/net/System/Net/SecureProtocols/_FixedSizeReader.cs @@ -8,7 +8,7 @@ Abstract: The class is a simple wrapper on top of a read stream. It will read the exact number of bytes requested. - It operates either [....] or async. + It operates either sync or async. Author: @@ -76,7 +76,7 @@ public void AsyncReadPacket(AsyncProtocolRequest request) StartReading(); } // - // Loops while subsequest completions are [....] + // Loops while subsequest completions are sync // private void StartReading() { diff --git a/System/net/System/Net/SecureProtocols/_NegoStream.cs b/System/net/System/Net/SecureProtocols/_NegoStream.cs index b8e698f07..91311238e 100644 --- a/System/net/System/Net/SecureProtocols/_NegoStream.cs +++ b/System/net/System/Net/SecureProtocols/_NegoStream.cs @@ -117,7 +117,7 @@ private void ValidateParameters(byte[] buffer, int offset, int count) throw new ArgumentOutOfRangeException("count", SR.GetString(SR.net_offset_plus_count)); } // - // Combined [....]/async write method. For [....] requet asyncRequest==null + // Combined sync/async write method. For sync requet asyncRequest==null // private void ProcessWrite(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { @@ -198,9 +198,9 @@ private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolReq } } // - // Combined [....]/async read method. For [....] requet asyncRequest==null - // There is a little overheader because we need to pass buffer/offset/count used only in [....]. - // Still the benefit is that we have a common [....]/async code path. + // Combined sync/async read method. For sync requet asyncRequest==null + // There is a little overheader because we need to pass buffer/offset/count used only in sync. + // Still the benefit is that we have a common sync/async code path. // private int ProcessRead(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { @@ -240,7 +240,7 @@ private int ProcessRead(byte[] buffer, int offset, int count, AsyncProtocolReque } finally { - // if [....] request or exception + // if sync request or exception if (asyncRequest == null || failed) { _NestedRead = 0; @@ -330,7 +330,7 @@ private int StartFrameBody(int readBytes, byte[] buffer, int offset, int count, } readBytes = asyncRequest.Result; } - else //[....] + else //Sync { readBytes = _FrameReader.ReadPacket(InternalBuffer, 0, readBytes); } diff --git a/System/net/System/Net/SecureProtocols/_SslState.cs b/System/net/System/Net/SecureProtocols/_SslState.cs index 2f9355f69..9fe6acf99 100644 --- a/System/net/System/Net/SecureProtocols/_SslState.cs +++ b/System/net/System/Net/SecureProtocols/_SslState.cs @@ -16,7 +16,7 @@ Alexei Vopilov 26-Jun-2002 Revision History: 22-Aug-2003 Adopted for new Ssl feature design. - 15-Sept-2003 Implemented concurent rehanshake + 15-Sept-2003 Implemented concurrent rehanshake --*/ @@ -58,6 +58,7 @@ internal class SslState { private bool _HandshakeCompleted; private bool _CertValidationFailed; + private bool _Shutdown; private SecurityStatus _SecurityStatus; private Exception _Exception; @@ -70,7 +71,7 @@ enum CachedSessionStatus: byte } private CachedSessionStatus _CachedSession; - // This block is used by rehandshake code to buffer data decryptred with the old key + // This block is used by rehandshake code to buffer data decrypted with the old key private byte[] _QueuedReadData; private int _QueuedReadCount; private bool _PendingReHandshake; @@ -132,8 +133,8 @@ internal void ValidateCreateContext(bool isServer, string targetHost, SslProtoco { // - // We don;t support SSL alerts right now, hence any exception is fatal and cannot be retried - // Consider: make use if SSL alerts to re-[....] SslStream on both sides for retrying. + // We don't support SSL alerts right now, hence any exception is fatal and cannot be retried + // Consider: make use if SSL alerts to re-sync SslStream on both sides for retrying. // if (_Exception != null && !_CanRetryAuthentication) { throw _Exception; @@ -151,7 +152,6 @@ internal void ValidateCreateContext(bool isServer, string targetHost, SslProtoco throw new ArgumentNullException("targetHost"); } - if (isServer ) { enabledSslProtocols &= (SslProtocols)SchProtocols.ServerMask; if (serverCertificate == null) @@ -161,7 +161,7 @@ internal void ValidateCreateContext(bool isServer, string targetHost, SslProtoco enabledSslProtocols &= (SslProtocols)SchProtocols.ClientMask; } - if ((int)enabledSslProtocols == 0) { + if (ServicePointManager.DisableSystemDefaultTlsVersions && ((int)enabledSslProtocols == 0)) { throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "SslProtocolType"), "sslProtocolType"); } @@ -264,6 +264,14 @@ internal bool IsCertValidationFailed { } } // + internal bool IsShutdown + { + get + { + return _Shutdown; + } + } + // internal bool DataAvailable { get { return IsAuthenticated && (SecureStream.DataAvailable || _QueuedReadCount != 0); @@ -438,14 +446,19 @@ private SecureChannel Context { // // - // - internal void CheckThrow(bool authSucessCheck) { + // + internal void CheckThrow(bool authSuccessCheck, bool shutdownCheck = false) { if (_Exception != null) { throw _Exception; } - if (authSucessCheck && !IsAuthenticated) { + + if (authSuccessCheck && !IsAuthenticated) { throw new InvalidOperationException(SR.GetString(SR.net_auth_noauth)); } + + if (shutdownCheck && _Shutdown && !LocalAppContextSwitches.DontEnableTlsAlerts) { + throw new InvalidOperationException(SR.net_ssl_io_already_shutdown); + } } // internal void Flush() @@ -631,7 +644,7 @@ private void ForceAuthentication(bool receiveFirst, byte[] buffer, AsyncProtocol // Async handshake is enqueued and will resume later return; } - // Either [....] handshake is ready to go or async handshake won the ---- over write. + // Either Sync handshake is ready to go or async handshake won the ---- over write. // This will tell that we don't know the framing yet (what SSL version is) _Framing = Framing.None; @@ -790,11 +803,14 @@ private void CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtoc } else if (message.Done && !_PendingReHandshake) { - if (!CompleteHandshake()) + ProtocolToken alertToken = null; + + if (!CompleteHandshake(ref alertToken)) { - StartSendAuthResetSignal(null, asyncRequest, new AuthenticationException(SR.GetString(SR.net_ssl_io_cert_validation), null)); + StartSendAuthResetSignal(alertToken, asyncRequest, new AuthenticationException(SR.GetString(SR.net_ssl_io_cert_validation), null)); return; } + // Release waiting IO if any. Presumably it should not throw. // Otheriwse application may get not expected type of the exception. FinishHandshake(null, asyncRequest); @@ -975,11 +991,11 @@ private void StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolReques // // - Returns false if failed to verify the Remote Cert // - private bool CompleteHandshake() { + private bool CompleteHandshake(ref ProtocolToken alertToken) { GlobalLog.Enter("CompleteHandshake"); Context.ProcessHandshakeSuccess(); - if (!Context.VerifyRemoteCertificate(_CertValidationDelegate)) + if (!Context.VerifyRemoteCertificate(_CertValidationDelegate, ref alertToken)) { _HandshakeCompleted = false; _CertValidationFailed = true; @@ -1296,7 +1312,7 @@ internal void FinishWrite() _QueuedWriteStateRequest = null; if (obj is LazyAsyncResult) { - // [....] handshake is waiting on other thread. + // sync handshake is waiting on other thread. ((LazyAsyncResult)obj).InvokeCallback(); } else @@ -1307,6 +1323,23 @@ internal void FinishWrite() } } } + + internal IAsyncResult BeginShutdown(AsyncCallback asyncCallback, object asyncState) + { + CheckThrow(authSuccessCheck: true, shutdownCheck: true); + + ProtocolToken message = Context.CreateShutdownToken(); + return InnerStream.BeginWrite(message.Payload, 0, message.Payload.Length, asyncCallback, asyncState); + } + + internal void EndShutdown(IAsyncResult result) + { + CheckThrow(authSuccessCheck: true, shutdownCheck: true); + + InnerStream.EndWrite(result); + _Shutdown = true; + } + // true - operation queued // false - operation can proceed private bool CheckEnqueueHandshake(byte[] buffer, AsyncProtocolRequest asyncRequest) @@ -1372,7 +1405,7 @@ private void FinishHandshake(Exception e, AsyncProtocolRequest asyncRequest) if (obj is LazyAsyncResult) { - // [....] write is waiting on other thread. + // sync write is waiting on other thread. ((LazyAsyncResult)obj).InvokeCallback(); } else @@ -1724,7 +1757,7 @@ private void RehandshakeCompleteCallback(IAsyncResult result) FinishHandshake(exception, null); } } - + #if TRAVE [System.Diagnostics.Conditional("TRAVE")] internal void DebugMembers() { diff --git a/System/net/System/Net/SecureProtocols/_SslStream.cs b/System/net/System/Net/SecureProtocols/_SslStream.cs index 6bb6bd71e..559be1d38 100644 --- a/System/net/System/Net/SecureProtocols/_SslStream.cs +++ b/System/net/System/Net/SecureProtocols/_SslStream.cs @@ -315,10 +315,12 @@ private void ValidateParameters(byte[] buffer, int offset, int count) throw new ArgumentOutOfRangeException("count", SR.GetString(SR.net_offset_plus_count)); } // - // Combined [....]/async write method. For [....] case asyncRequest==null + // Combined sync/async write method. For sync case asyncRequest==null // private void ProcessWrite(BufferOffsetSize[] buffers, SplitWriteAsyncProtocolRequest asyncRequest) { + _SslState.CheckThrow(authSuccessCheck: true, shutdownCheck: true); + foreach (BufferOffsetSize buffer in buffers) { ValidateParameters(buffer.Buffer, buffer.Offset, buffer.Size); @@ -357,7 +359,7 @@ private void ProcessWrite(BufferOffsetSize[] buffers, SplitWriteAsyncProtocolReq } } // - // Combined [....]/async write method. For [....] case asyncRequest==null + // Combined sync/async write method. For sync case asyncRequest==null // private void ProcessWrite(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { @@ -376,6 +378,7 @@ private void ProcessWrite(byte[] buffer, int offset, int count, AsyncProtocolReq } ValidateParameters(buffer, offset, count); + _SslState.CheckThrow(authSuccessCheck: true, shutdownCheck: true); if (Interlocked.Exchange(ref _NestedWrite, 1) == 1) { @@ -634,9 +637,9 @@ private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolReq } // - // Combined [....]/async read method. For [....] requet asyncRequest==null - // There is a little overheader because we need to pass buffer/offset/count used only in [....]. - // Still the benefit is that we have a common [....]/async code path. + // Combined sync/async read method. For sync requet asyncRequest==null + // There is a little overheader because we need to pass buffer/offset/count used only in sync. + // Still the benefit is that we have a common sync/async code path. // private int ProcessRead(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { @@ -678,7 +681,7 @@ private int ProcessRead(byte[] buffer, int offset, int count, AsyncProtocolReque } finally { - // if [....] request or exception + // if sync request or exception if (asyncRequest == null || failed) { _NestedRead = 0; @@ -793,7 +796,7 @@ private int StartFrameBody(int readBytes, byte[] buffer, int offset, int count, } readBytes = asyncRequest.Result; } - else //[....] + else //Sync { readBytes = _Reader.ReadPacket(InternalBuffer, SecureChannel.ReadHeaderSize, readBytes); } diff --git a/System/net/System/Net/ServicePoint.cs b/System/net/System/Net/ServicePoint.cs index 7f71c4ba8..89f94e570 100644 --- a/System/net/System/Net/ServicePoint.cs +++ b/System/net/System/Net/ServicePoint.cs @@ -251,7 +251,7 @@ internal Socket GetConnection(PooledStream PooledStream, object owner, bool asyn abortSocket6 = socket6; // - // Setup socket timeouts for [....] requests + // Setup socket timeouts for sync requests // // diff --git a/System/net/System/Net/ServicePointManager.cs b/System/net/System/Net/ServicePointManager.cs index d1ea370d2..34f3b4aa7 100644 --- a/System/net/System/Net/ServicePointManager.cs +++ b/System/net/System/Net/ServicePointManager.cs @@ -5,190 +5,15 @@ //------------------------------------------------------------------------------ namespace System.Net { + using Diagnostics; using System.Collections; - using System.Collections.Generic; - using System.Configuration; - using System.IO; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; using System.Net.Configuration; - using System.Net.Sockets; using System.Net.Security; - using System.Security; - using System.Security.Permissions; - using System.Security.Cryptography.X509Certificates; - using System.Threading; - using System.Globalization; using System.Runtime.CompilerServices; - using System.Diagnostics.CodeAnalysis; - using Microsoft.Win32; - - // This turned to be a legacy type name that is simply forwarded to System.Security.Authentication.SslProtocols defined values. -#if !FEATURE_PAL - [Flags] - public enum SecurityProtocolType - { - Ssl3 = System.Security.Authentication.SslProtocols.Ssl3, - Tls = System.Security.Authentication.SslProtocols.Tls, - Tls11 = System.Security.Authentication.SslProtocols.Tls11, - Tls12 = System.Security.Authentication.SslProtocols.Tls12, - } - - internal class CertPolicyValidationCallback - { - readonly ICertificatePolicy m_CertificatePolicy; - readonly ExecutionContext m_Context; - - internal CertPolicyValidationCallback() - { - m_CertificatePolicy = new DefaultCertPolicy(); - m_Context = null; - } - - internal CertPolicyValidationCallback(ICertificatePolicy certificatePolicy) - { - m_CertificatePolicy = certificatePolicy; - m_Context = ExecutionContext.Capture(); - } - - internal ICertificatePolicy CertificatePolicy { - get { return m_CertificatePolicy;} - } - - internal bool UsesDefault { - get { return m_Context == null;} - } - - internal void Callback(object state) - { - CallbackContext context = (CallbackContext) state; - context.result = context.policyWrapper.CheckErrors(context.hostName, - context.certificate, - context.chain, - context.sslPolicyErrors); - } - - internal bool Invoke(string hostName, - ServicePoint servicePoint, - X509Certificate certificate, - WebRequest request, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - PolicyWrapper policyWrapper = new PolicyWrapper(m_CertificatePolicy, - servicePoint, - (WebRequest) request); - - if (m_Context == null) - { - return policyWrapper.CheckErrors(hostName, - certificate, - chain, - sslPolicyErrors); - } - else - { - ExecutionContext execContext = m_Context.CreateCopy(); - CallbackContext callbackContext = new CallbackContext(policyWrapper, - hostName, - certificate, - chain, - sslPolicyErrors); - ExecutionContext.Run(execContext, Callback, callbackContext); - return callbackContext.result; - } - } - - private class CallbackContext - { - internal CallbackContext(PolicyWrapper policyWrapper, - string hostName, - X509Certificate certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - this.policyWrapper = policyWrapper; - this.hostName = hostName; - this.certificate = certificate; - this.chain = chain; - this.sslPolicyErrors = sslPolicyErrors; - } - - internal readonly PolicyWrapper policyWrapper; - internal readonly string hostName; - internal readonly X509Certificate certificate; - internal readonly X509Chain chain; - internal readonly SslPolicyErrors sslPolicyErrors; - - internal bool result; - } - } - - internal class ServerCertValidationCallback - { - readonly RemoteCertificateValidationCallback m_ValidationCallback; - readonly ExecutionContext m_Context; - - internal ServerCertValidationCallback(RemoteCertificateValidationCallback validationCallback) - { - m_ValidationCallback = validationCallback; - m_Context = ExecutionContext.Capture(); - } - - internal RemoteCertificateValidationCallback ValidationCallback { - get { return m_ValidationCallback;} - } - - internal void Callback(object state) - { - CallbackContext context = (CallbackContext) state; - context.result = m_ValidationCallback(context.request, - context.certificate, - context.chain, - context.sslPolicyErrors); - } - - internal bool Invoke(object request, - X509Certificate certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - if (m_Context == null) - { - return m_ValidationCallback(request, certificate, chain, sslPolicyErrors); - } - else - { - ExecutionContext execContext = m_Context.CreateCopy(); - CallbackContext callbackContext = new CallbackContext(request, - certificate, - chain, - sslPolicyErrors); - ExecutionContext.Run(execContext, Callback, callbackContext); - return callbackContext.result; - } - } - - private class CallbackContext - { - internal readonly Object request; - internal readonly X509Certificate certificate; - internal readonly X509Chain chain; - internal readonly SslPolicyErrors sslPolicyErrors; - - internal bool result; - - internal CallbackContext(Object request, - X509Certificate certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - this.request = request; - this.certificate = certificate; - this.chain = chain; - this.sslPolicyErrors = sslPolicyErrors; - } - } - } -#endif // !FEATURE_PAL + using System.Security.Authentication; + using System.Threading; // // The ServicePointManager class hands out ServicePoints (may exist or be created @@ -200,7 +25,7 @@ internal CallbackContext(Object request, /// <para>Manages the collection of <see cref='System.Net.ServicePoint'/> instances.</para> /// </devdoc> /// - public class ServicePointManager { + public partial class ServicePointManager { /// <devdoc> /// <para> @@ -245,24 +70,18 @@ public class ServicePointManager { private static volatile CertPolicyValidationCallback s_CertPolicyValidationCallback = new CertPolicyValidationCallback(); private static volatile ServerCertValidationCallback s_ServerCertValidationCallback = null; - private const string sendAuxRecordValueName = "SchSendAuxRecord"; - private const string sendAuxRecordAppSetting = "System.Net.ServicePointManager.SchSendAuxRecord"; - private const string strongCryptoValueName = "SchUseStrongCrypto"; - private const string secureProtocolAppSetting = "System.Net.ServicePointManager.SecurityProtocol"; + private static SecurityProtocolType s_SecurityProtocolType; - private static object configurationLoadedLock = new object(); - private static volatile bool configurationLoaded = false; - private static bool disableStrongCrypto = false; - private static bool disableSendAuxRecord = false; + private static bool s_reusePort; + private static bool? s_reusePortSupported = null; - private static SecurityProtocolType s_SecurityProtocolType = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3; + private static bool s_disableStrongCrypto; + private static bool s_disableSendAuxRecord; + private static bool s_disableSystemDefaultTlsVersions; + private static SslProtocols s_defaultSslProtocols; - private const string reusePortValueName = "HWRPortReuseOnSocketBind"; - private static object reusePortLock = new object(); - private static volatile bool reusePortSettingsInitialized = false; - private static bool reusePort = false; - private static bool? reusePortSupported = null; #endif // !FEATURE_PAL + private static volatile Hashtable s_ConfigTable = null; private static volatile int s_ConnectionLimit = PersistentConnectionLimit; @@ -440,10 +259,16 @@ public static SecurityProtocolType SecurityProtocol { private static void ValidateSecurityProtocol(SecurityProtocolType value) { - // Do not allow Ssl2 (and others) as explicit SSL version request + // Do not allow Ssl2 (and others) as explicit SSL version request. SecurityProtocolType allowed = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; + Debug.Assert((int)SecurityProtocolType.SystemDefault == (int)SslProtocols.None); + Debug.Assert((int)SecurityProtocolType.Ssl3 == (int)SslProtocols.Ssl3); + Debug.Assert((int)SecurityProtocolType.Tls == (int)SslProtocols.Tls); + Debug.Assert((int)SecurityProtocolType.Tls11 == (int)SslProtocols.Tls11); + Debug.Assert((int)SecurityProtocolType.Tls12 == (int)SslProtocols.Tls12); + if ((value & ~allowed) != 0) { throw new NotSupportedException(SR.GetString(SR.net_securityprotocolnotsupported)); @@ -451,6 +276,42 @@ private static void ValidateSecurityProtocol(SecurityProtocolType value) } #endif // !FEATURE_PAL + internal static bool DisableStrongCrypto + { + get + { + EnsureConfigurationLoaded(); + return s_disableStrongCrypto; + } + } + + internal static bool DisableSystemDefaultTlsVersions + { + get + { + EnsureConfigurationLoaded(); + return s_disableSystemDefaultTlsVersions; + } + } + + internal static bool DisableSendAuxRecord + { + get + { + EnsureConfigurationLoaded(); + return s_disableSendAuxRecord; + } + } + + internal static SslProtocols DefaultSslProtocols + { + get + { + EnsureConfigurationLoaded(); + return s_defaultSslProtocols; + } + } + // // accessors // @@ -639,171 +500,24 @@ internal static ServerCertValidationCallback ServerCertValidationCallback { } } - internal static bool DisableStrongCrypto { - get { - EnsureConfigurationLoaded(); - return disableStrongCrypto; - } - } - - internal static bool DisableSendAuxRecord { - get { - EnsureConfigurationLoaded(); - return disableSendAuxRecord; - } - } - - private static void EnsureConfigurationLoaded() { - if (configurationLoaded) { - return; - } - - lock (configurationLoadedLock) { - if (configurationLoaded) { - return; - } - - LoadDisableStrongCryptoConfiguration(); - LoadDisableSendAuxRecordConfiguration(); - - configurationLoaded = true; - } - } - - private static void LoadDisableStrongCryptoConfiguration() { - try { - bool disableStrongCryptoInternal = false; - int schUseStrongCryptoKeyValue = 0; - - if (LocalAppContextSwitches.DontEnableSchUseStrongCrypto) { - //.Net 4.5.2 and below will default to false unless the registry key is specifically set to 1. - schUseStrongCryptoKeyValue = - RegistryConfiguration.GlobalConfigReadInt(strongCryptoValueName, 0); - - disableStrongCryptoInternal = schUseStrongCryptoKeyValue != 1; - } - else { - // .Net 4.6 and above will default to true unless the registry key is specifically set to 0. - schUseStrongCryptoKeyValue = - RegistryConfiguration.GlobalConfigReadInt(strongCryptoValueName, 1); - - disableStrongCryptoInternal = schUseStrongCryptoKeyValue == 0; - } - - if (disableStrongCryptoInternal) { - // Revert the SecurityProtocol selection to the legacy combination. - s_SecurityProtocolType = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3; - } - else { - s_SecurityProtocolType = - SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; - - string appSetting = RegistryConfiguration.AppConfigReadString(secureProtocolAppSetting, null); - - SecurityProtocolType value; - try { - value = (SecurityProtocolType)Enum.Parse(typeof(SecurityProtocolType), appSetting); - ValidateSecurityProtocol(value); - s_SecurityProtocolType = value; - } - // Ignore all potential exceptions caused by Enum.Parse. - catch (ArgumentNullException) { } - catch (ArgumentException) { } - catch (NotSupportedException) { } - catch (OverflowException) { } - } - - disableStrongCrypto = disableStrongCryptoInternal; - } - catch (Exception e) - { - if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) - { - throw; - } - } - } - - private static void LoadDisableSendAuxRecordConfiguration() { - try { - if (LocalAppContextSwitches.DontEnableSchSendAuxRecord) { - disableSendAuxRecord = true; - return; - } - - int schSendAuxRecordKeyValue = 1; - schSendAuxRecordKeyValue = RegistryConfiguration.AppConfigReadInt(sendAuxRecordAppSetting, 1); - if (schSendAuxRecordKeyValue == 0) { - disableSendAuxRecord = true; - return; - } - - schSendAuxRecordKeyValue = RegistryConfiguration.GlobalConfigReadInt(sendAuxRecordValueName, 1); - if (schSendAuxRecordKeyValue == 0) { - disableSendAuxRecord = true; - return; - } - } - catch (Exception e) - { - if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) - { - throw; - } - } - } - public static bool ReusePort { get { - EnsureReusePortSettingsInitialized(); - return reusePort; + return s_reusePort; } set { - EnsureReusePortSettingsInitialized(); - reusePort = value; - } - } - - internal static bool? ReusePortSupported { - get { - return reusePortSupported; - } - set { - reusePortSupported = value; + s_reusePort = value; } } - private static void EnsureReusePortSettingsInitialized() { - - if (reusePortSettingsInitialized) { - return; + internal static bool? ReusePortSupported + { + get + { + return s_reusePortSupported; } - - lock (reusePortLock) { - if (reusePortSettingsInitialized) { - return; - } - - int reusePortKeyValue = 0; - try { - reusePortKeyValue = RegistryConfiguration.GlobalConfigReadInt(reusePortValueName, 0); - } - catch (Exception e) { - if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { - throw; - } - } - - bool reusePortInternal = false; - if (reusePortKeyValue == 1) { - if (Logging.On) { - Logging.PrintInfo(Logging.Web, typeof(ServicePointManager), SR.GetString(SR.net_log_set_socketoption_reuseport_default_on)); - } - reusePortInternal = true; - } - - reusePort = reusePortInternal; - reusePortSettingsInitialized = true; + set + { + s_reusePortSupported = value; } } #endif // !FEATURE_PAL diff --git a/System/net/System/Net/Sockets/NetworkStream.cs b/System/net/System/Net/Sockets/NetworkStream.cs index 7f46157be..cf21e9bfb 100644 --- a/System/net/System/Net/Sockets/NetworkStream.cs +++ b/System/net/System/Net/Sockets/NetworkStream.cs @@ -483,7 +483,7 @@ public override int Read([In, Out] byte[] buffer, int offset, int size) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif - bool canRead = CanRead; // Prevent race with Dispose. + bool canRead = CanRead; // Prevent ---- with Dispose. if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } @@ -557,7 +557,7 @@ public override void Write(byte[] buffer, int offset, int size) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif - bool canWrite = CanWrite; // Prevent race with Dispose. + bool canWrite = CanWrite; // Prevent ---- with Dispose. if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } @@ -717,7 +717,7 @@ public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, Asyn #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif - bool canRead = CanRead; // Prevent race with Dispose. + bool canRead = CanRead; // Prevent ---- with Dispose. if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } @@ -772,7 +772,7 @@ public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, Asyn internal virtual IAsyncResult UnsafeBeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { - bool canRead = CanRead; // Prevent race with Dispose. + bool canRead = CanRead; // Prevent ---- with Dispose. if (m_CleanedUp) { throw new ObjectDisposedException(GetType().FullName); @@ -902,7 +902,7 @@ public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, Asy #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif - bool canWrite = CanWrite; // Prevent race with Dispose. + bool canWrite = CanWrite; // Prevent ---- with Dispose. if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } @@ -964,7 +964,7 @@ internal virtual IAsyncResult UnsafeBeginWrite(byte[] buffer, int offset, int si #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif - bool canWrite = CanWrite; // Prevent race with Dispose. + bool canWrite = CanWrite; // Prevent ---- with Dispose. if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } @@ -1061,7 +1061,7 @@ public override void EndWrite(IAsyncResult asyncResult) { /// <devdoc> /// <para> - /// Performs a [....] Write of an array of buffers. + /// Performs a sync Write of an array of buffers. /// </para> /// </devdoc> internal virtual void MultipleWrite(BufferOffsetSize[] buffers) diff --git a/System/net/System/Net/Sockets/Socket.cs b/System/net/System/Net/Sockets/Socket.cs index 1d92faa54..56c66de41 100644 --- a/System/net/System/Net/Sockets/Socket.cs +++ b/System/net/System/Net/Sockets/Socket.cs @@ -64,7 +64,7 @@ public class Socket : IDisposable private SocketType socketType; private ProtocolType protocolType; - // These caches are one degree off of Socket since they're not used in the [....] case/when disabled in config. + // These caches are one degree off of Socket since they're not used in the sync case/when disabled in config. private CacheSet m_Caches; private class CacheSet @@ -6408,7 +6408,7 @@ internal unsafe void SetSocketOption(SocketOptionLevel optionLevel, SocketOption throw; } - // Keep the internal state in [....] if the user manually resets this + // Keep the internal state in sync if the user manually resets this if (optionName == SocketOptionName.PacketInformation && optionValue == 0 && errorCode == SocketError.Success) { @@ -7634,7 +7634,7 @@ public bool AcceptAsync(SocketAsyncEventArgs e) { e.StartOperationAccept(); BindToCompletionPort(); - // Local variables for [....] completion. + // Local variables for sync completion. int bytesTransferred; SocketError socketError = SocketError.Success; @@ -7899,7 +7899,7 @@ public bool ReceiveAsync(SocketAsyncEventArgs e) { e.StartOperationReceive(); BindToCompletionPort(); - // Local vars for [....] completion of native call. + // Local vars for sync completion of native call. SocketFlags flags = e.m_SocketFlags; int bytesTransferred; SocketError socketError; @@ -8142,7 +8142,7 @@ public bool SendAsync(SocketAsyncEventArgs e) { BindToCompletionPort(); - // Local vars for [....] completion of native call. + // Local vars for sync completion of native call. int bytesTransferred; SocketError socketError; @@ -8826,7 +8826,7 @@ private void SetBufferInternal(byte [] buffer, int offset, int count) { - // Method to update internal state after [....] or async completion. + // Method to update internal state after sync or async completion. internal void SetResults(SocketError socketError, int bytesTransferred, SocketFlags flags) { m_SocketError = socketError; m_ConnectByNameError = null; diff --git a/System/net/System/Net/UnsafeNativeMethods.cs b/System/net/System/Net/UnsafeNativeMethods.cs index 680ea9813..15e0dedae 100644 --- a/System/net/System/Net/UnsafeNativeMethods.cs +++ b/System/net/System/Net/UnsafeNativeMethods.cs @@ -598,6 +598,12 @@ internal unsafe static extern int CompleteAuthToken( [In, Out] SecurityBufferDescriptor inputBuffers ); + [DllImport(SECUR32, ExactSpelling = true, SetLastError = true)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + internal unsafe static extern int ApplyControlToken( + [In] void* inContextPtr, + [In, Out] SecurityBufferDescriptor inputBuffers + ); } #endif // !FEATURE_PAL @@ -2184,8 +2190,18 @@ internal static unsafe class HttpApi { internal static extern uint HttpCloseUrlGroup(ulong urlGroupId); [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")] - [DllImport(TOKENBINDING, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)] + [DllImport(TOKENBINDING, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint="TokenBindingVerifyMessage")] public static extern int TokenBindingVerifyMessage( + [In] byte* tokenBindingMessage, + [In] uint tokenBindingMessageSize, + [In] TOKENBINDING_KEY_PARAMETERS_TYPE keyType, + [In] byte* tlsUnique, + [In] uint tlsUniqueSize, + [Out] out HeapAllocHandle resultList); + + [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")] + [DllImport(TOKENBINDING, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint="TokenBindingVerifyMessage")] + public static extern int TokenBindingVerifyMessage_V1( [In] byte* tokenBindingMessage, [In] uint tokenBindingMessageSize, [In] IntPtr keyType, @@ -2236,6 +2252,7 @@ internal enum HTTP_REQUEST_INFO_TYPE { HttpRequestInfoTypeAuth, HttpRequestInfoTypeChannelBind, HttpRequestInfoTypeSslProtocol, + HttpRequestInfoTypeSslTokenBindingDraft, HttpRequestInfoTypeSslTokenBinding } @@ -2582,11 +2599,21 @@ internal struct HTTP_TIMEOUT_LIMIT_INFO { [StructLayout(LayoutKind.Sequential)] internal struct HTTP_BINDING_INFO { internal HTTP_FLAGS Flags; - internal IntPtr RequestQueueHandle; + internal IntPtr RequestQueueHandle; } [StructLayout(LayoutKind.Sequential)] internal unsafe struct HTTP_REQUEST_TOKEN_BINDING_INFO + { + public byte* TokenBinding; + public uint TokenBindingSize; + public byte* TlsUnique; + public uint TlsUniqueSize; + public TOKENBINDING_KEY_PARAMETERS_TYPE KeyType; + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct HTTP_REQUEST_TOKEN_BINDING_INFO_V1 { public byte* TokenBinding; public uint TokenBindingSize; @@ -2595,12 +2622,12 @@ internal unsafe struct HTTP_REQUEST_TOKEN_BINDING_INFO public IntPtr KeyType; } - internal enum TOKENBINDING_HASH_ALGORITHM : byte + internal enum TOKENBINDING_HASH_ALGORITHM_V1 : byte { TOKENBINDING_HASH_ALGORITHM_SHA256 = 4, } - internal enum TOKENBINDING_SIGNATURE_ALGORITHM : byte + internal enum TOKENBINDING_SIGNATURE_ALGORITHM_V1 : byte { TOKENBINDING_SIGNATURE_ALGORITHM_RSA = 1, TOKENBINDING_SIGNATURE_ALGORITHM_ECDSAP256 = 3, @@ -2617,17 +2644,31 @@ internal enum TOKENBINDING_EXTENSION_FORMAT TOKENBINDING_EXTENSION_FORMAT_UNDEFINED = 0, } + internal enum TOKENBINDING_KEY_PARAMETERS_TYPE : byte + { + TOKENBINDING_KEY_PARAMETERS_TYPE_RSA_PKCS_SHA256 = 0, + TOKENBINDING_KEY_PARAMETERS_TYPE_RSA_PSS_SHA256 = 1, + TOKENBINDING_KEY_PARAMETERS_TYPE_ECDSA_SHA256 = 2, + } + [StructLayout(LayoutKind.Sequential)] internal struct TOKENBINDING_IDENTIFIER { - public TOKENBINDING_TYPE bindingType; - public TOKENBINDING_HASH_ALGORITHM hashAlgorithm; - public TOKENBINDING_SIGNATURE_ALGORITHM signatureAlgorithm; + public TOKENBINDING_KEY_PARAMETERS_TYPE keyType; } + [StructLayout(LayoutKind.Sequential)] + internal struct TOKENBINDING_IDENTIFIER_V1 + { + public TOKENBINDING_TYPE bindingType; + public TOKENBINDING_HASH_ALGORITHM_V1 hashAlgorithm; + public TOKENBINDING_SIGNATURE_ALGORITHM_V1 signatureAlgorithm; + } + [StructLayout(LayoutKind.Sequential)] internal unsafe struct TOKENBINDING_RESULT_DATA { + public TOKENBINDING_TYPE bindingType; public uint identifierSize; public TOKENBINDING_IDENTIFIER* identifierData; public TOKENBINDING_EXTENSION_FORMAT extensionFormat; @@ -2635,12 +2676,29 @@ internal unsafe struct TOKENBINDING_RESULT_DATA public IntPtr extensionData; } + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct TOKENBINDING_RESULT_DATA_V1 + { + public uint identifierSize; + public TOKENBINDING_IDENTIFIER_V1* identifierData; + public TOKENBINDING_EXTENSION_FORMAT extensionFormat; + public uint extensionSize; + public IntPtr extensionData; + } + [StructLayout(LayoutKind.Sequential)] internal unsafe struct TOKENBINDING_RESULT_LIST { public uint resultCount; public TOKENBINDING_RESULT_DATA* resultData; } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct TOKENBINDING_RESULT_LIST_V1 + { + public uint resultCount; + public TOKENBINDING_RESULT_DATA_V1* resultData; + } // see http.w for definitions [Flags] @@ -3148,11 +3206,19 @@ internal static IPEndPoint GetLocalEndPoint(byte[] memoryBlob, IntPtr originalAd return endpoint; } - internal static HTTP_REQUEST_TOKEN_BINDING_INFO* GetTlsTokenBindingRequestInfo(byte[] memoryBlob, IntPtr originalAddress){ - + /// <summary> + /// Method to acquire the V2 token binding + /// We tell the difference between a V1 binding and a V2 binding by looking at the HTTP_REQUEST_INFO_TYPE returned from the HTTP request blob + /// If we negotiated the new binding type, the value 'HttpRequestInfoTypeSslTokenBinding' will be returned. + /// </summary> + /// <param name="memoryBlob"></param> + /// <param name="originalAddress"></param> + /// <returns></returns> + internal static HTTP_REQUEST_TOKEN_BINDING_INFO* GetTlsTokenBindingRequestInfo(byte[] memoryBlob, IntPtr originalAddress) + { fixed (byte* pMemoryBlob = memoryBlob) { - HTTP_REQUEST_V2* request = (HTTP_REQUEST_V2*)pMemoryBlob; + HTTP_REQUEST_V2* request = (HTTP_REQUEST_V2*)pMemoryBlob; long fixup = pMemoryBlob - (byte*) originalAddress; for (int i = 0; i < request->RequestInfoCount; i++) @@ -3160,7 +3226,35 @@ internal static IPEndPoint GetLocalEndPoint(byte[] memoryBlob, IntPtr originalAd HTTP_REQUEST_INFO* pThisInfo = (HTTP_REQUEST_INFO*)(fixup + (byte*)&request->pRequestInfo[i]); if (pThisInfo != null && pThisInfo->InfoType == HTTP_REQUEST_INFO_TYPE.HttpRequestInfoTypeSslTokenBinding) { - return (HTTP_REQUEST_TOKEN_BINDING_INFO*)pThisInfo->pInfo; + return (HTTP_REQUEST_TOKEN_BINDING_INFO*)((byte*)(pThisInfo->pInfo) + fixup); + } + } + } + return null; + } + + /// <summary> + /// Compat method to acquire the old V1 token binding + /// We tell the difference between a V1 binding and a V2 binding by looking at the HTTP_REQUEST_INFO_TYPE returned from the HTTP request blob + /// If we negotiated the old binding type, the value 'HttpRequestInfoTypeSslTokenBindingDraft' will be returned. + /// </summary> + /// <param name="memoryBlob"></param> + /// <param name="originalAddress"></param> + /// <returns></returns> + internal static HTTP_REQUEST_TOKEN_BINDING_INFO_V1* GetTlsTokenBindingRequestInfo_V1(byte[] memoryBlob, IntPtr originalAddress) + { + fixed (byte* pMemoryBlob = memoryBlob) + { + HTTP_REQUEST_V2* request = (HTTP_REQUEST_V2*)pMemoryBlob; + long fixup = pMemoryBlob - (byte*)originalAddress; + + for (int i = 0; i < request->RequestInfoCount; i++) + { + HTTP_REQUEST_INFO* pThisInfo = (HTTP_REQUEST_INFO*)(fixup + (byte*)&request->pRequestInfo[i]); + if (pThisInfo != null && pThisInfo->InfoType == HTTP_REQUEST_INFO_TYPE.HttpRequestInfoTypeSslTokenBindingDraft) + { + // Old V1 token binding protocol is being used, so we need to handle this data blob using the old behavior + return (HTTP_REQUEST_TOKEN_BINDING_INFO_V1*)((byte*)(pThisInfo->pInfo) + fixup); } } } diff --git a/System/net/System/Net/WebRequest.cs b/System/net/System/Net/WebRequest.cs index 1135be089..da5d0ed5f 100644 --- a/System/net/System/Net/WebRequest.cs +++ b/System/net/System/Net/WebRequest.cs @@ -981,7 +981,7 @@ public AuthenticationLevel AuthenticationLevel { // GetRequestStream() and the reading phase to GetResponse(), but if there's no request body, both phases // may happen inside GetResponse(). // - // Return null only on [....] (if we're on the [....] thread). Otherwise throw if no context is available. + // Return null only on Sync (if we're on the Sync thread). Otherwise throw if no context is available. internal virtual ContextAwareResult GetConnectingContext() { throw ExceptionHelper.MethodNotImplementedException; diff --git a/System/net/System/Net/WebSockets/WebSocketHttpListenerDuplexStream.cs b/System/net/System/Net/WebSockets/WebSocketHttpListenerDuplexStream.cs index da0acfe79..a0bb4575d 100644 --- a/System/net/System/Net/WebSockets/WebSocketHttpListenerDuplexStream.cs +++ b/System/net/System/Net/WebSockets/WebSocketHttpListenerDuplexStream.cs @@ -203,8 +203,8 @@ private async Task<int> ReadAsyncCore(byte[] buffer, int offset, int count, Canc return bytesRead; } - // return value indicates [....] vs async completion - // false: [....] completion + // return value indicates sync vs async completion + // false: sync completion // true: async completion private unsafe bool ReadAsyncFast(HttpListenerAsyncEventArgs eventArgs) { @@ -480,8 +480,8 @@ private async Task WriteAsyncCore(byte[] buffer, int offset, int count, Cancella } } - // return value indicates [....] vs async completion - // false: [....] completion + // return value indicates sync vs async completion + // false: sync completion // true: async completion private bool WriteAsyncFast(HttpListenerAsyncEventArgs eventArgs) { @@ -649,7 +649,7 @@ public async Task CloseNetworkConnectionAsync(CancellationToken cancellationToke } // throw OperationCancelledException when canceled by the caller - // otherwise ---- the exception + // otherwise swallow the exception cancellationToken.ThrowIfCancellationRequested(); } finally @@ -1198,7 +1198,7 @@ internal void Complete() } } - // Method to update internal state after [....] or async completion. + // Method to update internal state after sync or async completion. private void SetResults(Exception exception, int bytesTransferred) { m_Exception = exception; diff --git a/System/net/System/Net/WebUtility.cs b/System/net/System/Net/WebUtility.cs index 5c11e3efa..57731e3d2 100644 --- a/System/net/System/Net/WebUtility.cs +++ b/System/net/System/Net/WebUtility.cs @@ -330,7 +330,7 @@ private static UnicodeDecodingConformance HtmlDecodeConformance { catch { // DevDiv: 642025 // ASP.NET uses own ConfigurationManager which can throw in more situations than config errors (i.e. BadRequest) - // It's ok to ---- the exception here and continue using the default value + // It's ok to swallow the exception here and continue using the default value // Try to initialize again the next time return defaultDecodeConformance; } @@ -369,7 +369,7 @@ private static UnicodeEncodingConformance HtmlEncodeConformance { catch { // DevDiv: 642025 // ASP.NET uses own ConfigurationManager which can throw in more situations than config errors (i.e. BadRequest) - // It's ok to ---- the exception here and continue using the default value + // It's ok to swallow the exception here and continue using the default value // Try to initialize again the next time return defaultEncodeConformance; } diff --git a/System/net/System/Net/_AuthenticationState.cs b/System/net/System/Net/_AuthenticationState.cs index 0c79291da..f019dd018 100644 --- a/System/net/System/Net/_AuthenticationState.cs +++ b/System/net/System/Net/_AuthenticationState.cs @@ -325,7 +325,7 @@ internal void ClearAuthReq(HttpWebRequest httpWebRequest) { internal void Update(HttpWebRequest httpWebRequest) { // // RAID#86753 - // [....]: this is just a fix for redirection & kerberos. + // Microsoft: this is just a fix for redirection & kerberos. // we need to close the Context and call ISC() again with the final // blob returned from the server. to do this in general // we would probably need to change the IAuthenticationMdule interface and diff --git a/System/net/System/Net/_ChunkParser.cs b/System/net/System/Net/_ChunkParser.cs index 8b48cb8ca..47b3d4604 100644 --- a/System/net/System/Net/_ChunkParser.cs +++ b/System/net/System/Net/_ChunkParser.cs @@ -12,7 +12,7 @@ namespace System.Net { - // This class is a helper for parsing chunked HTTP responses. Usage is to either call Read() ([....]) or ReadAsync() + // This class is a helper for parsing chunked HTTP responses. Usage is to either call Read() (sync) or ReadAsync() // (async) methods to retrieve the response payload (without chunk metadata). // The buffer passed to the .ctor is owned by the ChunkParser until the whole response is read (i.e. Read/ // ReadAsync return 0 bytes) or an error occurs. diff --git a/System/net/System/Net/_CommandStream.cs b/System/net/System/Net/_CommandStream.cs index 859f87646..b98c090f2 100644 --- a/System/net/System/Net/_CommandStream.cs +++ b/System/net/System/Net/_CommandStream.cs @@ -271,7 +271,7 @@ private bool PostSendCommandProcessing(ref Stream stream) ** I don;t see how this code can be still relevant, remove it of no problems observed ** // - // This is a general race condition in [....] mode, if the server returns an error + // This is a general race condition in Sync mode, if the server returns an error // after we open the data connection, we will be off reading the data connection, // and not the control connection. The best we can do is try to poll, and in the // the worst case, we will timeout on establishing the data connection. @@ -300,7 +300,7 @@ private bool PostSendCommandProcessing(ref Stream stream) } catch { // If we get an exception on the QUIT command (which is // always the last command), ignore the final exception - // and continue with the pipeline regardlss of [....]/async + // and continue with the pipeline regardlss of sync/async if (index < 0 || index >= commands.Length || commands[index].Command != "QUIT\r\n") throw; @@ -423,7 +423,7 @@ protected virtual PipelineInstruction PipelineCallback(PipelineEntry entry, Resp // /// <summary> - /// <para>Provides a wrapper for the async operations, so that the code can be shared with [....]</para> + /// <para>Provides a wrapper for the async operations, so that the code can be shared with sync</para> /// </summary> private static void ReadCallback(IAsyncResult asyncResult) { ReceiveState state = (ReceiveState)asyncResult.AsyncState; @@ -502,7 +502,7 @@ protected virtual bool CheckValid(ResponseDescription response, ref int validThr } /// <summary> - /// Kicks off an asynchronous or [....] request to receive a response from the server. + /// Kicks off an asynchronous or sync request to receive a response from the server. /// Uses the Encoding <code>encoding</code> to transform the bytes received into a string to be /// returned in the GeneralResponseDescription's StatusDescription field. /// </summary> diff --git a/System/net/System/Net/_ConnectStream.cs b/System/net/System/Net/_ConnectStream.cs index 0b06f9343..8ecd19cc4 100644 --- a/System/net/System/Net/_ConnectStream.cs +++ b/System/net/System/Net/_ConnectStream.cs @@ -101,7 +101,7 @@ private ScatterGatherBuffers private const string responseDrainTimeoutAppSetting = "responseDrainTimeout"; // - // Timeout - timeout in ms for [....] reads & writes, passed in HttpWebRequest + // Timeout - timeout in ms for sync reads & writes, passed in HttpWebRequest // public override bool CanTimeout { @@ -430,7 +430,7 @@ internal void ProcessWriteCallDone(ConnectionReturnResult returnResult) if (returnResult == null) { m_Connection.WriteStartNextRequest(m_Request, ref returnResult); - // If the request is [....], then we do our Read here for data + // If the request is Sync, then we do our Read here for data if (!m_Request.Async) { object syncReaderResult = m_Request.ConnectionReaderAsyncResult.InternalWaitForCompletion(); @@ -439,7 +439,7 @@ internal void ProcessWriteCallDone(ConnectionReturnResult returnResult) //via poll when we handed back the request stream if (syncReaderResult == null && m_Request.NeedsToReadForResponse) #if DEBUG - // Remove once mixed [....]/async requests are supported. + // Remove once mixed sync/async requests are supported. using (GlobalLog.SetThreadKind(ThreadKinds.Sync)) #endif { @@ -891,7 +891,7 @@ public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, Asy } // - // Handles either async or [....] Writing for *public* stream API + // Handles either async or sync Writing for *public* stream API // private IAsyncResult InternalWrite(bool async, byte[] buffer, int offset, int size, AsyncCallback callback, object state ) { // @@ -952,7 +952,7 @@ private IAsyncResult InternalWrite(bool async, byte[] buffer, int offset, int si m_BytesLeftToWrite -= size; } - GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::InternalWrite() swallowing: size==0 || BufferOnly || IgnoreSocketErrors= " + (size==0) + BufferOnly + IgnoreSocketErrors); + GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::InternalWrite() ----ing: size==0 || BufferOnly || IgnoreSocketErrors= " + (size==0) + BufferOnly + IgnoreSocketErrors); if (async) { asyncResult = new LazyAsyncResult(this, state, callback); completeSync = true; @@ -1006,7 +1006,7 @@ private IAsyncResult InternalWrite(bool async, byte[] buffer, int offset, int si // IgnoreSocketErrors can be set at any time - need to check it again. if (IgnoreSocketErrors && !NclUtilities.IsFatal(exception)) { - GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::InternalWrite() swallowing: IgnoreSocketErrors set after throw."); + GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::InternalWrite() ----ing: IgnoreSocketErrors set after throw."); if (async) { completeSync = true; @@ -1109,7 +1109,7 @@ private IAsyncResult InternalWrite(bool async, byte[] buffer, int offset, int si // IgnoreSocketErrors can be set at any time - need to check it again. if (IgnoreSocketErrors && !NclUtilities.IsFatal(exception)) { - GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::InternalWrite() swallowing: IgnoreSocketErrors set after throw."); + GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::InternalWrite() ----ing: IgnoreSocketErrors set after throw."); if (async) { completeSync = true; @@ -1577,7 +1577,7 @@ private int ReadWithoutValidation([In, Out] byte[] buffer, int offset, int size, GlobalLog.Print("m_ReadBytes = "+m_ReadBytes); if (m_ReadBytes < 0) - throw new InternalException(); // TODO consider changing on Assert or a user exception when stress gets stable-stable + throw new InternalException(); // } @@ -2596,7 +2596,7 @@ private void CloseInternal(bool internalCall, bool aborting) { SafeSetSocketTimeout(SocketShutdown.Send); #if DEBUG - // Until there is an async version of this, we have to assert [....] privileges here. + // Until there is an async version of this, we have to assert Sync privileges here. using (GlobalLog.SetThreadKind(ThreadKinds.Sync)) { #endif m_Connection.Write(NclConstants.ChunkTerminator, 0, NclConstants.ChunkTerminator.Length); diff --git a/System/net/System/Net/_Connection.cs b/System/net/System/Net/_Connection.cs index b3e49c940..7b32af35d 100644 --- a/System/net/System/Net/_Connection.cs +++ b/System/net/System/Net/_Connection.cs @@ -702,7 +702,7 @@ internal bool SubmitRequest(HttpWebRequest request, bool forcedsubmit) if (startRequestResult != TriState.Unspecified) { CompleteStartRequest(true, request, startRequestResult); } - // On [....], we wait for the Connection to be come availble here, + // On Sync, we wait for the Connection to be come availble here, if (!request.Async) { object responseObject = request.ConnectionAsyncResult.InternalWaitForCompletion(); @@ -912,7 +912,7 @@ private void CompleteStartRequest(bool onSubmitThread, HttpWebRequest request, T // // From now on the request.SetRequestSubmitDone must be called or it may hang - // For a [....] request the write side reponse windowwas opened in HttpWebRequest.SubmitRequest + // For a sync request the write side reponse windowwas opened in HttpWebRequest.SubmitRequest if (request.Async) request.OpenWriteSideResponseWindow(); @@ -1078,7 +1078,7 @@ private void CompleteConnection(bool async, HttpWebRequest request) WebExceptionStatus ws = WebExceptionStatus.ConnectFailure; // // From now on the request.SetRequestSubmitDone must be called or it may hang - // For a [....] request the write side reponse windowwas opened in HttpWebRequest.SubmitRequest + // For a sync request the write side reponse windowwas opened in HttpWebRequest.SubmitRequest if (request.Async) request.OpenWriteSideResponseWindow(); @@ -1372,7 +1372,7 @@ internal void ReadStartNextRequest(WebRequest currentRequest, ref ConnectionRetu if (nextRequest != null ) { // We cannot have HeadersCompleted on the request that was not placed yet on the write list - if(nextRequest.HeadersCompleted) // TODO: change to be Assert but only when stress got stable-stable + if(nextRequest.HeadersCompleted) // throw new InternalException(); // This codepath doesn't handle the case where the server has closed the @@ -2124,7 +2124,7 @@ private long ProcessHeaderData(ref bool fHaveChunked, HttpWebRequest request, ou // IIS6 does not close the connection on 403 so all subsequent requests will fail to be authorized on THAT connection. //----------------------------------------------------------------------------------------------- //5/15/2006 - //[....] + //Microsoft //The DTS Issue 595216 claims that we are unnecessarily closing the //connection on 403 - even if it is a non SSL request. It seems //that the original intention is to close the request for SSL requests @@ -2153,7 +2153,7 @@ private long ProcessHeaderData(ref bool fHaveChunked, HttpWebRequest request, ou else { //QFE: 4599. - //Author: [....] + //Author: Microsoft //in v2.0, in case of SSL Requests through proxy that require NTLM authentication, //we are not honoring the Proxy-Connection: Keep-Alive header and //closing the connection. @@ -2928,7 +2928,7 @@ private void PrepareCloseConnectionSocket(ref ConnectionReturnResult returnResul { if (m_Error == WebExceptionStatus.Success) { - throw new InternalException(); // TODO: replace it with a generic error for the product bits + throw new InternalException(); // //m_Error = WebExceptionStatus.UnknownError; } @@ -3163,7 +3163,7 @@ internal void PollAndRead(HttpWebRequest request, bool userRetrievedStream) { } } // - // Peforms a [....] Read and calls the ReadComplete to process the result + // Peforms a Sync Read and calls the ReadComplete to process the result // The reads are done iteratively, until the Request has received enough // data to contruct a response, or a 100-Continue is read, allowing the HttpWebRequest // to return a write stream @@ -3272,7 +3272,7 @@ internal void SyncRead(HttpWebRequest request, bool userRetrievedStream, bool pr if (probeRead) { - // [....] 100-Continue wait only + // Sync 100-Continue wait only request.FinishContinueWait(); if (pollSuccess) { @@ -3468,7 +3468,7 @@ private bool ReadComplete(int bytesRead, WebExceptionStatus errorStatus) } // // Any exception is processed by HandleError() and ----ed to avoid throwing on a thread pool - // In the [....] case the HandleError() will abort the request so the caller will pick up the result. + // In the sync case the HandleError() will abort the request so the caller will pick up the result. // catch (Exception exception) { if (NclUtilities.IsFatal(exception)) throw; diff --git a/System/net/System/Net/_ContextAwareResult.cs b/System/net/System/Net/_ContextAwareResult.cs index c5c5dc428..b94e26e43 100644 --- a/System/net/System/Net/_ContextAwareResult.cs +++ b/System/net/System/Net/_ContextAwareResult.cs @@ -359,7 +359,7 @@ protected override void Cleanup() // to avoid flowing context. Even if the operation completes before this call, the callback won't have been // called. // - // Returns whether the operation completed [....] or not. + // Returns whether the operation completed sync or not. // private bool CaptureOrComplete(ref ExecutionContext cachedContext, bool returnContext) { diff --git a/System/net/System/Net/_DigestClient.cs b/System/net/System/Net/_DigestClient.cs index 04cf4ffdf..ae4d78026 100644 --- a/System/net/System/Net/_DigestClient.cs +++ b/System/net/System/Net/_DigestClient.cs @@ -28,7 +28,7 @@ internal class DigestClient : ISessionAuthenticationModule { private static PrefixLookup challengeCache = new PrefixLookup(); private static readonly char[] singleSpaceArray = new char[]{' '}; - // [....]: make sure WDigest fixes these bugs before we + // Microsoft: make sure WDigest fixes these bugs before we // enable this code ("Windows OS" Product Studio database): // // 921024 1 Wdigest should support MD5, at least for explicit (non-default) credentials. diff --git a/System/net/System/Net/_HTTPDateParse.cs b/System/net/System/Net/_HTTPDateParse.cs index 666ccf9a3..425f24222 100644 --- a/System/net/System/Net/_HTTPDateParse.cs +++ b/System/net/System/Net/_HTTPDateParse.cs @@ -42,7 +42,7 @@ internal static class HttpDateParse { private const int DATE_TOKEN_JANUARY = 1; private const int DATE_TOKEN_FEBRUARY = 2; - private const int DATE_TOKEN_MARCH = 3; + private const int DATE_TOKEN_Microsoft = 3; private const int DATE_TOKEN_APRIL = 4; private const int DATE_TOKEN_MAY = 5; private const int DATE_TOKEN_JUNE = 6; @@ -148,7 +148,7 @@ int index case 'A': switch (MAKE_UPPER(lpszDay[index+2])) { case 'R': - return DATE_TOKEN_MARCH; + return DATE_TOKEN_Microsoft; case 'Y': return DATE_TOKEN_MAY; } diff --git a/System/net/System/Net/_LazyAsyncResult.cs b/System/net/System/Net/_LazyAsyncResult.cs index bbf9ab822..17bd85e03 100644 --- a/System/net/System/Net/_LazyAsyncResult.cs +++ b/System/net/System/Net/_LazyAsyncResult.cs @@ -18,7 +18,7 @@ internal class LazyAsyncResult : IAsyncResult private const int c_ForceAsyncCount = 50; #if !NET_PERF - // This is to avoid user mistakes when they queue another async op from a callback the completes [....]. + // This is to avoid user mistakes when they queue another async op from a callback the completes sync. [ThreadStatic] private static ThreadContext t_ThreadContext; diff --git a/System/net/System/Net/_ListenerResponseStream.cs b/System/net/System/Net/_ListenerResponseStream.cs index 61c5adc6f..db4ba258c 100644 --- a/System/net/System/Net/_ListenerResponseStream.cs +++ b/System/net/System/Net/_ListenerResponseStream.cs @@ -463,7 +463,7 @@ internal void SwitchToOpaqueMode() } // The final Content-Length async write can only be cancelled by CancelIoEx. - // [....] can only be cancelled by CancelSynchronousIo, but we don't attempt this right now. + // Sync can only be cancelled by CancelSynchronousIo, but we don't attempt this right now. [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Justification = "It is safe to ignore the return value on a cancel operation because the connection is being closed")] internal void CancelLastWrite(CriticalHandle requestQueueHandle) diff --git a/System/net/System/Net/_NativeSSPI.cs b/System/net/System/Net/_NativeSSPI.cs index ec9b920dc..2aeb68176 100644 --- a/System/net/System/Net/_NativeSSPI.cs +++ b/System/net/System/Net/_NativeSSPI.cs @@ -40,6 +40,7 @@ internal interface SSPIInterface { int SetContextAttributes(SafeDeleteContext phContext, ContextAttribute attribute, byte[] buffer); int QuerySecurityContextToken(SafeDeleteContext phContext, out SafeCloseHandle phToken); int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers); + int ApplyControlToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers); } // For SSL connections: @@ -196,6 +197,11 @@ public int QuerySecurityContextToken(SafeDeleteContext phContext, out SafeCloseH public int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers) { throw new NotSupportedException(); } + + public int ApplyControlToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers) + { + return SafeDeleteContext.ApplyControlToken(Library, ref refContext, inputBuffers); + } } @@ -416,6 +422,11 @@ public int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] return SafeDeleteContext.CompleteAuthToken(Library, ref refContext, inputBuffers); } + public int ApplyControlToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers) + { + throw new NotSupportedException(); + } + private static int GetSecurityContextToken(SafeDeleteContext phContext, out SafeCloseHandle safeHandle) { int status = (int)SecurityStatus.InvalidHandle; diff --git a/System/net/System/Net/_SSPIWrapper.cs b/System/net/System/Net/_SSPIWrapper.cs index 6ea04a7d7..03ff30722 100644 --- a/System/net/System/Net/_SSPIWrapper.cs +++ b/System/net/System/Net/_SSPIWrapper.cs @@ -237,6 +237,15 @@ internal static int CompleteAuthToken(SSPIInterface SecModule, ref SafeDeleteCon return errorCode; } + internal static int ApplyControlToken(SSPIInterface SecModule, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers) + { + int errorCode = SecModule.ApplyControlToken(ref context, inputBuffers); + + if (Logging.On) Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_operation_returned_something, "ApplyControlToken()", (SecurityStatus)errorCode)); + + return errorCode; + } + public static int QuerySecurityContextToken(SSPIInterface SecModule, SafeDeleteContext context, out SafeCloseHandle token) { return SecModule.QuerySecurityContextToken(context, out token); } @@ -249,6 +258,52 @@ public static int DecryptMessage(SSPIInterface secModule, SafeDeleteContext cont return EncryptDecryptHelper(OP.Decrypt, secModule, context, input, sequenceNumber); } + public static int ApplyAlertToken( + SSPIInterface secModule, + ref SafeFreeCredentials credentialsHandle, + SafeDeleteContext securityContext, + TlsAlertType alertType, + TlsAlertMessage alertMessage) + { + Interop.SChannel.SCHANNEL_ALERT_TOKEN alertToken; + alertToken.dwTokenType = Interop.SChannel.SCHANNEL_ALERT; + alertToken.dwAlertType = (uint)alertType; + alertToken.dwAlertNumber = (uint)alertMessage; + + var bufferDesc = new SecurityBuffer[1]; + + int alertTokenByteSize = Marshal.SizeOf(typeof(Interop.SChannel.SCHANNEL_ALERT_TOKEN)); + IntPtr p = Marshal.AllocHGlobal(alertTokenByteSize); + + try + { + var buffer = new byte[alertTokenByteSize]; + Marshal.StructureToPtr(alertToken, p, false); + Marshal.Copy(p, buffer, 0, alertTokenByteSize); + + bufferDesc[0] = new SecurityBuffer(buffer, BufferType.Token); + return ApplyControlToken(secModule, ref securityContext, bufferDesc); + } + finally + { + Marshal.FreeHGlobal(p); + } + } + + public static int ApplyShutdownToken( + SSPIInterface secModule, + ref SafeFreeCredentials credentialsHandle, + SafeDeleteContext securityContext) + { + int shutdownToken = Interop.SChannel.SCHANNEL_SHUTDOWN; + + var bufferDesc = new SecurityBuffer[1]; + var buffer = BitConverter.GetBytes(shutdownToken); + + bufferDesc[0] = new SecurityBuffer(buffer, BufferType.Token); + return ApplyControlToken(secModule, ref securityContext, bufferDesc); + } + internal static int MakeSignature(SSPIInterface secModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) { return EncryptDecryptHelper(OP.MakeSignature, secModule, context, input, sequenceNumber); } @@ -711,6 +766,9 @@ internal enum Alg { NameMD5 = 3, NameSHA = 4, + NameSHA256 = 12, + NameSHA384 = 13, + NameSHA512 = 14, NameDH_Ephem = 2, } diff --git a/System/net/System/Net/_SafeNetHandles.cs b/System/net/System/Net/_SafeNetHandles.cs index 2a7463906..8fe388c03 100644 --- a/System/net/System/Net/_SafeNetHandles.cs +++ b/System/net/System/Net/_SafeNetHandles.cs @@ -2115,6 +2115,127 @@ internal unsafe static int CompleteAuthToken( return errorCode; } + + internal unsafe static int ApplyControlToken( + SecurDll dll, + ref SafeDeleteContext refContext, + SecurityBuffer[] inSecBuffers) + { + GlobalLog.Enter("SafeDeleteContext::ApplyControlToken"); + GlobalLog.Print(" DLL = " + dll); + GlobalLog.Print(" refContext = " + ValidationHelper.ToString(refContext)); +#if TRAVE + GlobalLog.Print(" inSecBuffers[] = length:" + inSecBuffers.Length); +// for (int index=0; index<inSecBuffers.Length; index++) { GlobalLog.Print(" inSecBuffers[" + index + "] = " + SecurityBuffer.ToString(inSecBuffers[index])); } +#endif + GlobalLog.Assert(inSecBuffers != null, "SafeDeleteContext::ApplyControlToken()|inSecBuffers == null"); + SecurityBufferDescriptor inSecurityBufferDescriptor = new SecurityBufferDescriptor(inSecBuffers.Length); + + int errorCode = (int)SecurityStatus.InvalidHandle; + + // these are pinned user byte arrays passed along with SecurityBuffers + GCHandle[] pinnedInBytes = null; + + SecurityBufferStruct[] inUnmanagedBuffer = new SecurityBufferStruct[inSecurityBufferDescriptor.Count]; + fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer) + { + // Fix Descriptor pointer that points to unmanaged SecurityBuffers + inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr; + pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count]; + SecurityBuffer securityBuffer; + for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index) + { + securityBuffer = inSecBuffers[index]; + if (securityBuffer != null) + { + inUnmanagedBuffer[index].count = securityBuffer.size; + inUnmanagedBuffer[index].type = securityBuffer.type; + + // use the unmanaged token if it's not null; otherwise use the managed buffer + if (securityBuffer.unmanagedToken != null) + { + inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle(); + } + else if (securityBuffer.token == null || securityBuffer.token.Length == 0) + { + inUnmanagedBuffer[index].token = IntPtr.Zero; + } + else + { + pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); + inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); + } +#if TRAVE + GlobalLog.Print("SecBuffer: cbBuffer:" + securityBuffer.size + " BufferType:" + securityBuffer.type); +// securityBuffer.DebugDump(); +#endif + } + } + + SSPIHandle contextHandle = new SSPIHandle(); + if (refContext != null) + { + contextHandle = refContext._handle; + } + try + { + if (dll == SecurDll.SECURITY) + { + if (refContext == null || refContext.IsInvalid) + { + refContext = new SafeDeleteContext_SECURITY(); + } + + bool b = false; + RuntimeHelpers.PrepareConstrainedRegions(); + try + { + refContext.DangerousAddRef(ref b); + } + catch (Exception e) + { + if (b) + { + refContext.DangerousRelease(); + b = false; + } + if (!(e is ObjectDisposedException)) + throw; + } + finally + { + if (b) + { + errorCode = UnsafeNclNativeMethods.SafeNetHandles_SECURITY.ApplyControlToken(contextHandle.IsZero ? null : &contextHandle, inSecurityBufferDescriptor); + refContext.DangerousRelease(); + } + } + + } + else + { + throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "SecurDll"), "Dll"); + } + } + finally + { + if (pinnedInBytes != null) + { + for (int index = 0; index < pinnedInBytes.Length; index++) + { + if (pinnedInBytes[index].IsAllocated) + { + pinnedInBytes[index].Free(); + } + } + } + } + } + + GlobalLog.Leave("SafeDeleteContext::ApplyControlToken() unmanaged ApplyControlToken()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + ValidationHelper.ToString(refContext)); + + return errorCode; + } } //====================================================================== diff --git a/System/net/System/Net/_SecureChannel.cs b/System/net/System/Net/_SecureChannel.cs index 82360ec49..a52e1d3d5 100644 --- a/System/net/System/Net/_SecureChannel.cs +++ b/System/net/System/Net/_SecureChannel.cs @@ -856,7 +856,7 @@ private bool AcquireServerCredentials(ref byte[] thumbPrint) // - // Security: we temporarily reset thread token to open the handle under process acount + // Security: we temporarily reset thread token to open the handle under process account // [SecurityPermissionAttribute(SecurityAction.Assert, Flags=SecurityPermissionFlag.ControlPrincipal)] SafeFreeCredentials AcquireCredentialsHandle(CredentialUse credUsage, ref SecureCredential secureCredential) @@ -894,7 +894,7 @@ internal ProtocolToken NextMessage(byte[] incoming, int offset, int count) { } /*++ - GenerateToken - Called after each sucessive state + GenerateToken - Called after each successive state in the Client - Server handshake. This function generates a set of bytes that will be sent next to the server. The server responds, each response, @@ -946,8 +946,8 @@ private SecurityStatus GenerateToken(byte[] input, int offset, int count, ref by bool cachedCreds = false; byte[] thumbPrint = null; // - // Looping through ASC or ISC with potenially cached credential that could have been - // already disposed from a different thread before ISC or ASC dir increemnt a cred ref count. + // Looping through ASC or ISC with potentially cached credential that could have been + // already disposed from a different thread before ISC or ASC dir increment a cred ref count. // try { @@ -1188,7 +1188,7 @@ internal SecurityStatus Decrypt(byte[] payload, ref int offset, ref int count) { count = 0; for (int i = 0; i < decspc.Length; i++) { - // Sucessfully decoded data and placed it at the following position in the buffer. + // Successfully decoded data and placed it at the following position in the buffer. if ((errorCode == SecurityStatus.OK && decspc[i].type == BufferType.Data) // or we failed to decode the data, here is the encoded data || (errorCode != SecurityStatus.OK && decspc[i].type == BufferType.Extra)) { @@ -1211,11 +1211,11 @@ internal SecurityStatus Decrypt(byte[] payload, ref int offset, ref int count) { --*/ //This method validates a remote certificate. - //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build - // A user callback has unique signature so it is safe to call it under permisison assert. + //SECURITY: The scenario is allowed in semi-trust StorePermission is asserted for Chain.Build + // A user callback has unique signature so it is safe to call it under permission assert. // [StorePermission(SecurityAction.Assert, Unrestricted=true)] - internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback) + internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback, ref ProtocolToken alertToken) { GlobalLog.Enter("SecureChannel#" + ValidationHelper.HashString(this) + "::VerifyRemoteCertificate"); SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; @@ -1287,35 +1287,24 @@ internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertVal success = (sslPolicyErrors == SslPolicyErrors.None); } - if (Logging.On) { - if (sslPolicyErrors != SslPolicyErrors.None) - { - Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_has_errors)); - if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) - Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString(SR.net_log_remote_cert_not_available)); - if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) - Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString(SR.net_log_remote_cert_name_mismatch)); - if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) - foreach (X509ChainStatus chainStatus in chain.ChainStatus) - Logging.PrintInfo(Logging.Web, this, "\t" + chainStatus.StatusInformation); - } - if (success) - { - if (remoteCertValidationCallback != null) - Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_user_declared_valid)); - else - Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_has_no_errors)); - } - else - { - if (remoteCertValidationCallback != null) - Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_user_declared_invalid)); - } + if (Logging.On) + { + LogCertificateValidation(remoteCertValidationCallback, sslPolicyErrors, success, chain); } + GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null? "<null>": remoteCertificateEx.ToString(true))); + + if (LocalAppContextSwitches.DontEnableTlsAlerts) + { + alertToken = null; + } + else if (!success) + { + alertToken = CreateFatalHandshakeAlertToken(sslPolicyErrors, chain); + } } finally { - // At least on Win2k server the chain is found to have dependancies on the original cert context. + // At least on Win2k server the chain is found to have dependencies on the original cert context. // So it should be closed first. if (chain != null) { chain.Reset(); @@ -1327,6 +1316,140 @@ internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertVal return success; } + public ProtocolToken CreateFatalHandshakeAlertToken(SslPolicyErrors sslPolicyErrors, X509Chain chain) + { + GlobalLog.Enter("SecureChannel#" + ValidationHelper.HashString(this) + "::CreateFatalHandshakeAlertToken"); + TlsAlertMessage alertMessage; + + switch (sslPolicyErrors) + { + case SslPolicyErrors.RemoteCertificateChainErrors: + alertMessage = GetAlertMessageFromChain(chain); + break; + case SslPolicyErrors.RemoteCertificateNameMismatch: + alertMessage = TlsAlertMessage.BadCertificate; + break; + case SslPolicyErrors.RemoteCertificateNotAvailable: + default: + alertMessage = TlsAlertMessage.CertificateUnknown; + break; + } + + GlobalLog.Print("SecureChannel#" + ValidationHelper.HashString(this) + "::CreateFatalHandshakeAlertToken() alertMessage: " + alertMessage.ToString()); + var status = (SecurityStatus)SSPIWrapper.ApplyAlertToken(GlobalSSPI.SSPISecureChannel, ref m_CredentialsHandle, m_SecurityContext, TlsAlertType.Fatal, alertMessage); + + if (status != SecurityStatus.OK) + { + GlobalLog.Print("SecureChannel#" + ValidationHelper.HashString(this) + "::ApplyAlertToken() returned " + status); + throw new Win32Exception((int)status); + } + + ProtocolToken token = GenerateAlertToken(); + GlobalLog.Leave("SecureChannel#" + ValidationHelper.HashString(this) + "::CreateFatalHandshakeAlertToken", token.ToString()); + return token; + } + + public ProtocolToken CreateShutdownToken() + { + GlobalLog.Enter("SecureChannel#" + ValidationHelper.HashString(this) + "::CreateShutdownToken"); + var status = (SecurityStatus)SSPIWrapper.ApplyShutdownToken(GlobalSSPI.SSPISecureChannel, ref m_CredentialsHandle, m_SecurityContext); + + if (status != SecurityStatus.OK) + { + GlobalLog.Print("SecureChannel#" + ValidationHelper.HashString(this) + "::ApplyAlertToken() returned " + status); + throw new Win32Exception((int)status); + } + + ProtocolToken token = GenerateAlertToken(); + GlobalLog.Leave("SecureChannel#" + ValidationHelper.HashString(this) + "::CreateShutdownToken", token.ToString()); + return token; + } + + private ProtocolToken GenerateAlertToken() + { + byte[] nextmsg = null; + SecurityStatus status = GenerateToken(null, 0, 0, ref nextmsg); + ProtocolToken token = new ProtocolToken(nextmsg, status); + return token; + } + + private static TlsAlertMessage GetAlertMessageFromChain(X509Chain chain) + { + foreach (X509ChainStatus chainStatus in chain.ChainStatus) + { + if (chainStatus.Status == X509ChainStatusFlags.NoError) + { + continue; + } + + if ((chainStatus.Status & + (X509ChainStatusFlags.UntrustedRoot | X509ChainStatusFlags.PartialChain | + X509ChainStatusFlags.Cyclic)) != 0) + { + return TlsAlertMessage.UnknownCA; + } + + if ((chainStatus.Status & + (X509ChainStatusFlags.Revoked | X509ChainStatusFlags.OfflineRevocation)) != 0) + { + return TlsAlertMessage.CertificateRevoked; + } + + if ((chainStatus.Status & + (X509ChainStatusFlags.CtlNotTimeValid | X509ChainStatusFlags.NotTimeNested | + X509ChainStatusFlags.NotTimeValid)) != 0) + { + return TlsAlertMessage.CertificateExpired; + } + + if ((chainStatus.Status & X509ChainStatusFlags.CtlNotValidForUsage) != 0) + { + return TlsAlertMessage.UnsupportedCert; + } + + if ((chainStatus.Status & + (X509ChainStatusFlags.CtlNotSignatureValid | X509ChainStatusFlags.InvalidExtension | + X509ChainStatusFlags.NotSignatureValid | X509ChainStatusFlags.InvalidPolicyConstraints) | + X509ChainStatusFlags.NoIssuanceChainPolicy | X509ChainStatusFlags.NotValidForUsage) != 0) + { + return TlsAlertMessage.BadCertificate; + } + + // All other errors: + return TlsAlertMessage.CertificateUnknown; + } + + Debug.Fail("GetAlertMessageFromChain was called but none of the chain elements had errors."); + return TlsAlertMessage.BadCertificate; + } + + private void LogCertificateValidation(RemoteCertValidationCallback remoteCertValidationCallback, SslPolicyErrors sslPolicyErrors, bool success, X509Chain chain) + { + if (sslPolicyErrors != SslPolicyErrors.None) + { + Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_has_errors)); + if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) + Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString(SR.net_log_remote_cert_not_available)); + if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) + Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString(SR.net_log_remote_cert_name_mismatch)); + if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) + foreach (X509ChainStatus chainStatus in chain.ChainStatus) + Logging.PrintInfo(Logging.Web, this, "\t" + chainStatus.StatusInformation); + } + if (success) + { + if (remoteCertValidationCallback != null) + Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_user_declared_valid)); + else + Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_has_no_errors)); + } + else + { + if (remoteCertValidationCallback != null) + Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_user_declared_invalid)); + } + } + /* From wincrypt.h diff --git a/System/net/System/Net/_TLSstream.cs b/System/net/System/Net/_TLSstream.cs index 3a418304f..50f5265f5 100644 --- a/System/net/System/Net/_TLSstream.cs +++ b/System/net/System/Net/_TLSstream.cs @@ -106,7 +106,7 @@ public override bool DataAvailable { } // - // [....] Read version + // Sync Read version // public override int Read(byte[] buffer, int offset, int size) { GlobalLog.Print("TlsStream#" + ValidationHelper.HashString(this) + "::Read() SecureWorker#" + ValidationHelper.HashString(m_Worker) + " offset:" + offset.ToString() + " size:" + size.ToString()); @@ -401,11 +401,11 @@ internal ChannelBinding GetChannelBinding(ChannelBindingKind kind) // // This methods ensures that IO is only issued when the handshake is completed in ether way - // The very first coming IO will initiate the handshake and define it's flavor ([....]/async). + // The very first coming IO will initiate the handshake and define it's flavor (sync/async). // // Returns false if the handshake was already done. // Returns true if the user IO is queued and the handshake is started. - // Return value is not applicable in [....] case. + // Return value is not applicable in sync case. // private ArrayList m_PendingIO = new ArrayList(); internal bool ProcessAuthentication(LazyAsyncResult result) @@ -483,7 +483,7 @@ internal bool ProcessAuthentication(LazyAsyncResult result) { if(m_PendingIO.Count > 1) { - // It was a real [....] handshake (now completed) and another IO came in. + // It was a real sync handshake (now completed) and another IO came in. // It's now waiting on us so resume. ThreadPool.QueueUserWorkItem(new WaitCallback(StartWakeupPendingIO), null); } @@ -496,7 +496,7 @@ internal bool ProcessAuthentication(LazyAsyncResult result) } else if (isSyncCall) { - GlobalLog.Assert(result != null, "TlsStream::ProcessAuthentication() this is a [....] call and it did not started the handshake hence null result must be wrapped into LazyAsyncResult"); + GlobalLog.Assert(result != null, "TlsStream::ProcessAuthentication() this is a Sync call and it did not started the handshake hence null result must be wrapped into LazyAsyncResult"); Exception e = result.InternalWaitForCompletion() as Exception; if (e != null) throw e; @@ -516,7 +516,7 @@ internal bool ProcessAuthentication(LazyAsyncResult result) } // Here in the async case a user IO has been queued (and may be already completed) - // For [....] case it does not matter since the caller will resume IO upon return + // For sync case it does not matter since the caller will resume IO upon return return true; } // @@ -581,7 +581,7 @@ private void WakeupPendingIO(IAsyncResult ar) } else { - //resume [....] IO waiting on other thread or signal waiting async handshake result. + //resume sync IO waiting on other thread or signal waiting async handshake result. try { lazyResult.InvokeCallback(exception); } diff --git a/System/net/System/Net/_TimerThread.cs b/System/net/System/Net/_TimerThread.cs index 059e88d5b..2d11591eb 100644 --- a/System/net/System/Net/_TimerThread.cs +++ b/System/net/System/Net/_TimerThread.cs @@ -13,7 +13,7 @@ namespace System.Net { using System.Runtime.InteropServices; /// <summary> - /// <para>Acts as countdown timer, used to measure elapsed time over a [....] operation.</para> + /// <para>Acts as countdown timer, used to measure elapsed time over a sync operation.</para> /// </summary> internal static class TimerThread { /// <summary> diff --git a/System/net/System/Net/mail/MailHeaderInfo.cs b/System/net/System/Net/mail/MailHeaderInfo.cs index cde8b0b45..eabb5954e 100644 --- a/System/net/System/Net/mail/MailHeaderInfo.cs +++ b/System/net/System/Net/mail/MailHeaderInfo.cs @@ -67,7 +67,7 @@ public HeaderInfo(MailHeaderID id, string name, bool isSingleton, bool isUserSet // Table of well-known mail headers. - // Keep the initializers in [....] with the enum above. + // Keep the initializers in sync with the enum above. private static readonly HeaderInfo[] m_HeaderInfo = { // ID NormalizedString IsSingleton IsUserSettable AllowsUnicode new HeaderInfo(MailHeaderID.Bcc, "Bcc", true, false, true), @@ -110,10 +110,10 @@ public HeaderInfo(MailHeaderID id, string name, bool isSingleton, bool isUserSet static MailHeaderInfo() { #if DEBUG - // Check that enum and header info array are in [....] + // Check that enum and header info array are in sync for(int i = 0; i < m_HeaderInfo.Length; i++) { if((int)m_HeaderInfo[i].ID != i) { - throw new Exception("Header info data structures are not in [....]"); + throw new Exception("Header info data structures are not in sync"); } } #endif diff --git a/System/net/System/Net/mail/SmtpClient.cs b/System/net/System/Net/mail/SmtpClient.cs index 38ccf0a7f..d1632685a 100644 --- a/System/net/System/Net/mail/SmtpClient.cs +++ b/System/net/System/Net/mail/SmtpClient.cs @@ -872,7 +872,7 @@ void SendMailCallback(IAsyncResult result) { try { writer = transport.EndSendMail(result); // If some recipients failed but not others, send the e-mail anyways, but then return the - // "Non-fatal" exception reporting the failures. The [....] code path does it this way. + // "Non-fatal" exception reporting the failures. The sync code path does it this way. // Fatal exceptions would have thrown above at transport.EndSendMail(...) SendMailAsyncResult sendResult = (SendMailAsyncResult)result; // Save these and throw them later in SendMessageCallback, after the message has sent. diff --git a/System/net/System/Net/mail/SmtpTransport.cs b/System/net/System/Net/mail/SmtpTransport.cs index 99c36b866..a6333e70e 100644 --- a/System/net/System/Net/mail/SmtpTransport.cs +++ b/System/net/System/Net/mail/SmtpTransport.cs @@ -235,7 +235,7 @@ internal IAsyncResult BeginGetConnection(ServicePoint servicePoint, ContextAware catch(Exception innerException){ throw new SmtpException(SR.GetString(SR.MailHostNotFound), innerException); } - GlobalLog.Leave("SmtpTransport#" + ValidationHelper.HashString(this) + "::BeginConnect [....] Completion"); + GlobalLog.Leave("SmtpTransport#" + ValidationHelper.HashString(this) + "::BeginConnect Sync Completion"); return result; } diff --git a/System/net/System/Net/mail/smtpconnection.cs b/System/net/System/Net/mail/smtpconnection.cs index a553312e2..ff9bddc77 100644 --- a/System/net/System/Net/mail/smtpconnection.cs +++ b/System/net/System/Net/mail/smtpconnection.cs @@ -417,7 +417,7 @@ internal void GetConnection(ServicePoint servicePoint) for (int i = 0; i < authenticationModules.Length; i++) { - //only authenticate if the auth protocol is supported - [....] + //only authenticate if the auth protocol is supported - Microsoft if (!AuthSupported(authenticationModules[i])) { continue; } @@ -650,7 +650,7 @@ internal static void End(IAsyncResult result) internal void GetConnection(bool synchronous) { - GlobalLog.Enter("ConnectAndHandshakeAsyncResult#" + ValidationHelper.HashString(this) + "::Connect: [....]=" + (synchronous ? "true" : "false")); + GlobalLog.Enter("ConnectAndHandshakeAsyncResult#" + ValidationHelper.HashString(this) + "::Connect: sync=" + (synchronous ? "true" : "false")); if (connection.isConnected) { throw new InvalidOperationException(SR.GetString(SR.SmtpAlreadyConnected)); diff --git a/System/net/System/URI.cs b/System/net/System/URI.cs index 4e565d324..50b5ba000 100644 --- a/System/net/System/URI.cs +++ b/System/net/System/URI.cs @@ -2057,7 +2057,7 @@ private unsafe ParsingError PrivateParseMinimal() ++length; } - // [....] codereview: + // Microsoft codereview: // Old Uri parser tries to figure out on a DosPath in all cases. // Hence http://c:/ is treated as as DosPath without the host while it should be a host "c", port 80 // @@ -2376,7 +2376,7 @@ private unsafe void CreateUriInfo(Flags cF) { // Note we already checked on general port syntax in ParseMinimal() // If iri parsing is on with unicode chars then the end of parsed host - // points to m_[....] string and not m_String + // points to m_orig string and not m_String bool UseOrigUnicodeStrOffset = ((cF& Flags.UseOrigUncdStrOffset) != 0); // This should happen only once. Reset it @@ -2555,7 +2555,7 @@ private static string CreateHostStringHelper(string str, ushort idx, ushort end, break; case Flags.IPv6HostType: - //[....] codereview + //Microsoft codereview // The helper will return [...] string that is not suited for Dns.Resolve() host = IPv6AddressHelper.ParseCanonicalName(str, idx, ref loopback, ref scopeId); break; @@ -2698,7 +2698,7 @@ internal string GetParts(UriComponents uriParts, UriFormat formatAs) // private string GetEscapedParts(UriComponents uriParts) { // Which Uri parts are not escaped canonically ? - // Notice that public UriPart and private Flags must me in [....] so below code can work + // Notice that public UriPart and private Flags must me in Sync so below code can work // ushort nonCanonical = (ushort)(((ushort)m_Flags & ((ushort)Flags.CannotDisplayCanonical<<7)) >> 6); if (InFact(Flags.SchemeNotCanonical)) { @@ -2728,7 +2728,7 @@ private string GetEscapedParts(UriComponents uriParts) { private string GetUnescapedParts(UriComponents uriParts, UriFormat formatAs) { // Which Uri parts are not escaped canonically ? - // Notice that public UriComponents and private Uri.Flags must me in [....] so below code can work + // Notice that public UriComponents and private Uri.Flags must me in Sync so below code can work // ushort nonCanonical = (ushort)((ushort)m_Flags & (ushort)Flags.CannotDisplayCanonical); @@ -3309,7 +3309,7 @@ private unsafe void ParseRemaining() { // Parsing the Path if any // - // For iri parsing if we found unicode the idx has offset into m_[....] string.. + // For iri parsing if we found unicode the idx has offset into m_orig string.. // so restart parsing from there and make m_Info.Offset.Path as m_string.length idx = m_Info.Offset.Path; @@ -5287,7 +5287,7 @@ public string MakeRelative(Uri toUri) [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] protected virtual void Parse() { - // [....] cr: In V1-Everett this method if suppressed by the derived class + // Microsoft cr: In V1-Everett this method if suppressed by the derived class // would lead to an unconstructed Uri instance. // It does not make any sense and violates Fxcop on calling a virtual method in the ctor. // Should be deprecated and removed asap. @@ -5296,7 +5296,7 @@ protected virtual void Parse() [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] protected virtual void Canonicalize() { - // [....] cr: In V1-Everett this method if suppressed by the derived class + // Microsoft cr: In V1-Everett this method if suppressed by the derived class // would lead to supressing of a path compression // It does not make much sense and violates Fxcop on calling a virtual method in the ctor. // Should be deprecated and removed asap. @@ -5305,7 +5305,7 @@ protected virtual void Canonicalize() [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] protected virtual void Escape() { - // [....] cr: In V1-Everett this method if suppressed by the derived class + // Microsoft cr: In V1-Everett this method if suppressed by the derived class // would lead to the same effect as dontEscape=true. // It does not make much sense and violates Fxcop on calling a virtual method in the ctor. // Should be deprecated and removed asap. @@ -5321,7 +5321,7 @@ protected virtual void Escape() [Obsolete("The method has been deprecated. Please use GetComponents() or static UnescapeDataString() to unescape a Uri component or a string. http://go.microsoft.com/fwlink/?linkid=14202")] protected virtual string Unescape(string path) { - // [....] cr: This method is dangerous since it gives path unescaping control + // Microsoft cr: This method is dangerous since it gives path unescaping control // to the derived class without any permission demand. // Should be deprecated and removed asap. @@ -5335,7 +5335,7 @@ protected virtual string Unescape(string path) { [Obsolete("The method has been deprecated. Please use GetComponents() or static EscapeUriString() to escape a Uri component or a string. http://go.microsoft.com/fwlink/?linkid=14202")] protected static string EscapeString(string str) { - // [....] cr: This method just does not make sense sa protected + // Microsoft cr: This method just does not make sense sa protected // It should go public static asap if ((object)str == null) { @@ -5358,7 +5358,7 @@ protected static string EscapeString(string str) { [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] protected virtual void CheckSecurity() { - // [....] cr: This method just does not make sense + // Microsoft cr: This method just does not make sense // Should be deprecated and removed asap. if (Scheme == "telnet") { @@ -5382,7 +5382,7 @@ protected virtual void CheckSecurity() { [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] protected virtual bool IsReservedCharacter(char character) { - // [....] cr: This method just does not make sense as virtual protected + // Microsoft cr: This method just does not make sense as virtual protected // It should go public static asap return (character == ';') @@ -5410,7 +5410,7 @@ protected virtual bool IsReservedCharacter(char character) { [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] protected static bool IsExcludedCharacter(char character) { - // [....] cr: This method just does not make sense sa protected + // Microsoft cr: This method just does not make sense sa protected // It should go public static asap // @@ -5453,7 +5453,7 @@ protected static bool IsExcludedCharacter(char character) { [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")] protected virtual bool IsBadFileSystemCharacter(char character) { - // [....] cr: This method just does not make sense sa protected virtual + // Microsoft cr: This method just does not make sense sa protected virtual // It should go public static asap return (character < 0x20) diff --git a/System/regex/system/text/regularexpressions/Regex.cs b/System/regex/system/text/regularexpressions/Regex.cs index 59c93a47a..63c4d0852 100644 --- a/System/regex/system/text/regularexpressions/Regex.cs +++ b/System/regex/system/text/regularexpressions/Regex.cs @@ -131,7 +131,7 @@ protected internal #else // desktop build still uses non-generic collections for AppCompat with .NET Framework 3.5 pre-compiled assemblies protected internal Hashtable caps; - protected internal Hashtable capnames; + protected internal Hashtable capnames; #endif protected internal String[] capslist; // if captures are sparse or named captures are used, this is the sorted list of names protected internal int capsize; // the size of the capture array @@ -436,7 +436,7 @@ public static String Escape(String str) { /// Unescapes any escaped characters in the input string. /// </para> /// </devdoc> - [SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="Unescape", Justification="[....]: already shipped since v1 - can't fix without causing a breaking change")] + [SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="Unescape", Justification="Microsoft: already shipped since v1 - can't fix without causing a breaking change")] public static String Unescape(String str) { if (str==null) throw new ArgumentNullException("str"); @@ -1189,7 +1189,7 @@ public String[] Split(String input, int count, int startat) { [HostProtection(MayLeakOnAbort=true)] [ResourceExposure(ResourceScope.Machine)] // The AssemblyName is interesting. [ResourceConsumption(ResourceScope.Machine)] - [SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="assemblyname", Justification="[....]: already shipped since v1 - can't fix without causing a breaking change")] + [SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="assemblyname", Justification="Microsoft: already shipped since v1 - can't fix without causing a breaking change")] public static void CompileToAssembly(RegexCompilationInfo[] regexinfos, AssemblyName assemblyname) { CompileToAssemblyInternal(regexinfos, assemblyname, null, null); @@ -1200,7 +1200,7 @@ public static void CompileToAssembly(RegexCompilationInfo[] regexinfos, Assembly [HostProtection(MayLeakOnAbort=true)] [ResourceExposure(ResourceScope.Machine)] // The AssemblyName is interesting. [ResourceConsumption(ResourceScope.Machine)] - [SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="assemblyname", Justification="[....]: already shipped since v1 - can't fix without causing a breaking change")] + [SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="assemblyname", Justification="Microsoft: already shipped since v1 - can't fix without causing a breaking change")] public static void CompileToAssembly(RegexCompilationInfo[] regexinfos, AssemblyName assemblyname, CustomAttributeBuilder[] attributes) { CompileToAssemblyInternal(regexinfos, assemblyname, attributes, null); } @@ -1208,7 +1208,7 @@ public static void CompileToAssembly(RegexCompilationInfo[] regexinfos, Assembly [HostProtection(MayLeakOnAbort=true)] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] - [SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="assemblyname", Justification="[....]: already shipped since v1 - can't fix without causing a breaking change")] + [SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="assemblyname", Justification="Microsoft: already shipped since v1 - can't fix without causing a breaking change")] public static void CompileToAssembly(RegexCompilationInfo[] regexinfos, AssemblyName assemblyname, CustomAttributeBuilder[] attributes, String resourceFile) { CompileToAssemblyInternal(regexinfos, assemblyname, attributes, resourceFile); } diff --git a/System/regex/system/text/regularexpressions/RegexCompiler.cs b/System/regex/system/text/regularexpressions/RegexCompiler.cs index 20be01664..d987a1181 100644 --- a/System/regex/system/text/regularexpressions/RegexCompiler.cs +++ b/System/regex/system/text/regularexpressions/RegexCompiler.cs @@ -208,7 +208,7 @@ internal static RegexRunnerFactory Compile(RegexCode code, RegexOptions options) */ [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] - [SuppressMessage("Microsoft.Security","CA2106:SecureAsserts", Justification="[....]: SECREVIEW : Regex only generates string manipulation, so this is OK")] + [SuppressMessage("Microsoft.Security","CA2106:SecureAsserts", Justification="Microsoft: SECREVIEW : Regex only generates string manipulation, so this is OK")] internal static void CompileToAssembly(RegexCompilationInfo[] regexes, AssemblyName an, CustomAttributeBuilder[] attribs, String resourceFile) { RegexTypeCompiler c = new RegexTypeCompiler(an, attribs, resourceFile); @@ -3024,7 +3024,7 @@ internal class RegexTypeCompiler : RegexCompiler { [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] - [SuppressMessage("Microsoft.Security","CA2106:SecureAsserts", Justification="[....]: SECREVIEW : Regex only generates string manipulation, so this is OK")] + [SuppressMessage("Microsoft.Security","CA2106:SecureAsserts", Justification="Microsoft: SECREVIEW : Regex only generates string manipulation, so this is OK")] internal RegexTypeCompiler(AssemblyName an, CustomAttributeBuilder[] attribs, String resourceFile) { // SECREVIEW : Regex only generates string manipulation, so this is // : ok. diff --git a/System/regex/system/text/regularexpressions/RegexGroup.cs b/System/regex/system/text/regularexpressions/RegexGroup.cs index 3f5b1d37e..207045958 100644 --- a/System/regex/system/text/regularexpressions/RegexGroup.cs +++ b/System/regex/system/text/regularexpressions/RegexGroup.cs @@ -10,6 +10,7 @@ namespace System.Text.RegularExpressions { using System.Security.Permissions; + using System.Runtime.Serialization; /// <devdoc> /// Group @@ -22,19 +23,24 @@ [ Serializable() ] #endif public class Group : Capture { // the empty group object - internal static Group _emptygroup = new Group(String.Empty, new int[0], 0); + internal static Group _emptygroup = new Group(String.Empty, new int[0], 0, string.Empty); internal int[] _caps; internal int _capcount; internal CaptureCollection _capcoll; +#if !SILVERLIGHT + [OptionalField] +#endif + internal string _name; - internal Group(String text, int[] caps, int capcount) + internal Group(String text, int[] caps, int capcount, string name) : base(text, capcount == 0 ? 0 : caps[(capcount - 1) * 2], capcount == 0 ? 0 : caps[(capcount * 2) - 1]) { _caps = caps; _capcount = capcount; + _name = name; } /* @@ -49,6 +55,17 @@ public bool Success { } } + /// <summary> + /// Provides the name of the group. + /// </summary> + public string Name + { + get + { + return _name; + } + } + /* * The collection of all captures for this group */ diff --git a/System/regex/system/text/regularexpressions/RegexGroupCollection.cs b/System/regex/system/text/regularexpressions/RegexGroupCollection.cs index c40858dcf..c2caf1254 100644 --- a/System/regex/system/text/regularexpressions/RegexGroupCollection.cs +++ b/System/regex/system/text/regularexpressions/RegexGroupCollection.cs @@ -147,7 +147,8 @@ internal Group GetGroupImpl(int groupnum) { if (_groups == null) { _groups = new Group[_match._matchcount.Length - 1]; for (int i = 0; i < _groups.Length; i++) { - _groups[i] = new Group(_match._text, _match._matches[i + 1], _match._matchcount[i + 1]); + string groupname = _match._regex.GroupNameFromNumber(i + 1); + _groups[i] = new Group(_match._text, _match._matches[i + 1], _match._matchcount[i + 1], groupname); } } diff --git a/System/regex/system/text/regularexpressions/RegexMatch.cs b/System/regex/system/text/regularexpressions/RegexMatch.cs index 5dfd3e804..3ab10bc82 100644 --- a/System/regex/system/text/regularexpressions/RegexMatch.cs +++ b/System/regex/system/text/regularexpressions/RegexMatch.cs @@ -77,7 +77,7 @@ public static Match Empty { */ internal Match(Regex regex, int capcount, String text, int begpos, int len, int startpos) - : base(text, new int[2], 0) { + : base(text, new int[2], 0, "0") { _regex = regex; _matchcount = new int[capcount]; diff --git a/System/services/monitoring/system/diagnosticts/EventLog.cs b/System/services/monitoring/system/diagnosticts/EventLog.cs index faa25dd5e..1c8e71440 100644 --- a/System/services/monitoring/system/diagnosticts/EventLog.cs +++ b/System/services/monitoring/system/diagnosticts/EventLog.cs @@ -150,8 +150,8 @@ public string LogDisplayName { [MonitoringDescription(SR.LogLog)] [DefaultValue("")] [SettingsBindable(true)] - [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "[....]: Safe, oldLog.machineName doesn't change")] - [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "[....]: By design, see justification above assert")] + [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "Microsoft: Safe, oldLog.machineName doesn't change")] + [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "Microsoft: By design, see justification above assert")] public string Log { get { return m_underlyingEventLog.Log; @@ -181,7 +181,7 @@ public string Log { [MonitoringDescription(SR.LogMachineName)] [DefaultValue(".")] [SettingsBindable(true)] - [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "[....]: By design, see justification above assert")] + [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "Microsoft: By design, see justification above assert")] public string MachineName { get { return m_underlyingEventLog.MachineName; @@ -292,8 +292,8 @@ public ISynchronizeInvoke SynchronizingObject { [MonitoringDescription(SR.LogSource)] [DefaultValue("")] [SettingsBindable(true)] - [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "[....]: Safe, oldLog.machineName doesn't change")] - [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "[....]: By design, see justification above assert")] + [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "Microsoft: Safe, oldLog.machineName doesn't change")] + [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "Microsoft: By design, see justification above assert")] public string Source { get { return m_underlyingEventLog.Source; @@ -1069,7 +1069,7 @@ public static bool SourceExists(string source, string machineName) { /// </devdoc> [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] - [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "[....]: Safe, machineName doesn't change")] + [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "Microsoft: Safe, machineName doesn't change")] internal static bool SourceExists(string source, string machineName, bool wantToCreate) { if (!SyntaxCheck.CheckMachineName(machineName)) { throw new ArgumentException(SR.GetString(SR.InvalidParameter, "machineName", machineName)); diff --git a/System/services/monitoring/system/diagnosticts/EventLogEntry.cs b/System/services/monitoring/system/diagnosticts/EventLogEntry.cs index 931faaa6a..cd19c7cc6 100644 --- a/System/services/monitoring/system/diagnosticts/EventLogEntry.cs +++ b/System/services/monitoring/system/diagnosticts/EventLogEntry.cs @@ -426,7 +426,7 @@ internal string ReplaceMessageParameters( String msg, string[] insertionStrings if ( percentIdx < 0 ) return msg; // no '%' at all - int startCopyIdx = 0; // start idx of last [....] msg chars to copy + int startCopyIdx = 0; // start idx of last orig msg chars to copy int msgLength = msg.Length; StringBuilder buf = new StringBuilder(); string paramDLLNames = GetMessageLibraryNames("ParameterMessageFile"); diff --git a/System/services/monitoring/system/diagnosticts/EventLogEntryCollection.cs b/System/services/monitoring/system/diagnosticts/EventLogEntryCollection.cs index 589a1d493..c095b3600 100644 --- a/System/services/monitoring/system/diagnosticts/EventLogEntryCollection.cs +++ b/System/services/monitoring/system/diagnosticts/EventLogEntryCollection.cs @@ -9,7 +9,7 @@ namespace System.Diagnostics { using System; using System.Collections; - //Consider, V2, [....]: Is there a way to implement Contains + //Consider, V2, Microsoft: Is there a way to implement Contains //and IndexOf, can we live withouth this part of the ReadOnly //collection pattern? /// <devdoc> diff --git a/System/services/monitoring/system/diagnosticts/EventLogInternal.cs b/System/services/monitoring/system/diagnosticts/EventLogInternal.cs index 754ae4cb0..d43d0a8df 100644 --- a/System/services/monitoring/system/diagnosticts/EventLogInternal.cs +++ b/System/services/monitoring/system/diagnosticts/EventLogInternal.cs @@ -160,7 +160,7 @@ public EventLogInternal(string logName, string machineName, string source) : thi /// <devdoc> /// <para>[To be supplied.]</para> /// </devdoc> - [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "[....]: Safe, oldLog.machineName doesn't change")] + [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "Microsoft: Safe, oldLog.machineName doesn't change")] public EventLogInternal(string logName, string machineName, string source, EventLog parent) { //look out for invalid log names if (logName == null) @@ -316,7 +316,7 @@ public string Log { } } - [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "[....]: Safe, machineName doesn't change")] + [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "Microsoft: Safe, machineName doesn't change")] private string GetLogName(string currentMachineName) { if ((logName == null || logName.Length == 0) && sourceName != null && sourceName.Length!=0) { @@ -347,7 +347,7 @@ public string MachineName { } [ComVisible(false)] - [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Justification = "[....]: MaximumKilobytes is the name of this property.")] + [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Justification = "Microsoft: MaximumKilobytes is the name of this property.")] public long MaximumKilobytes { get { string currentMachineName = this.machineName; @@ -653,7 +653,7 @@ public void Close() { Close(this.machineName); } - [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "[....]: Safe, currentMachineName doesn't change")] + [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "Microsoft: Safe, currentMachineName doesn't change")] private void Close(string currentMachineName) { EventLogPermission permission = new EventLogPermission(EventLogPermissionAccess.Write, currentMachineName); permission.Demand(); @@ -730,7 +730,7 @@ private void CompletionCallback(object context) { i = lastSeenCount; } - // NOTE, [....]: We have a double loop here so that we access the + // NOTE, Microsoft: We have a double loop here so that we access the // EntryCount property as infrequently as possible. (It may be expensive // to get the property.) Even though there are two loops, they will together // only execute as many times as (final value of EntryCount) - lastSeenCount. @@ -897,7 +897,7 @@ internal EventLogEntry[] GetAllEntries() { oldestEntry+idx, buf, buf.Length, out bytesRead, out minBytesNeeded); if (!success) { error = Marshal.GetLastWin32Error(); - // NOTE, [....]: ERROR_PROC_NOT_FOUND used to get returned, but I think that + // NOTE, Microsoft: ERROR_PROC_NOT_FOUND used to get returned, but I think that // was because I was calling GetLastError directly instead of GetLastWin32Error. // Making the buffer bigger and trying again seemed to work. I've removed the check // for ERROR_PROC_NOT_FOUND because I don't think it's necessary any more, but @@ -1090,7 +1090,7 @@ private EventLogEntry GetEntryWithOldest(int index) { cache, cache.Length, out bytesRead, out minBytesNeeded); if (!success) { int error = Marshal.GetLastWin32Error(); - // NOTE, [....]: ERROR_PROC_NOT_FOUND used to get returned, but I think that + // NOTE, Microsoft: ERROR_PROC_NOT_FOUND used to get returned, but I think that // was because I was calling GetLastError directly instead of GetLastWin32Error. // Making the buffer bigger and trying again seemed to work. I've removed the check // for ERROR_PROC_NOT_FOUND because I don't think it's necessary any more, but @@ -1270,7 +1270,7 @@ public void ModifyOverflowPolicy(OverflowAction action, int retentionDays) { /// </devdoc> [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] - [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "[....]: Safe, machineName doesn't change")] + [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "Microsoft: Safe, machineName doesn't change")] private void OpenForRead(string currentMachineName) { Debug.WriteLineIf(CompModSwitches.EventLog.TraceVerbose, "EventLog::OpenForRead"); @@ -1286,13 +1286,13 @@ private void OpenForRead(string currentMachineName) { if (logname == null || logname.Length==0) throw new ArgumentException(SR.GetString(SR.MissingLogProperty)); - if (!EventLog.Exists(logname, currentMachineName) ) // do not open non-existing Log [[....]] + if (!EventLog.Exists(logname, currentMachineName) ) // do not open non-existing Log [Microsoft] throw new InvalidOperationException( SR.GetString(SR.LogDoesNotExists, logname, currentMachineName) ); //Check environment before calling api SharedUtils.CheckEnvironment(); // Clean up cache variables. - // [[....]] The initilizing code is put here to guarantee, that first read of events + // [Microsoft] The initilizing code is put here to guarantee, that first read of events // from log file will start by filling up the cache buffer. lastSeenEntry = 0; lastSeenPos = 0; @@ -1506,7 +1506,7 @@ internal static bool ValidLogName(string logName, bool ignoreEmpty) { [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] - [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "[....]: Safe, machineName doesn't change")] + [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification = "Microsoft: Safe, machineName doesn't change")] private void VerifyAndCreateSource(string sourceName, string currentMachineName) { if (boolFlags[Flag_sourceVerified]) return; diff --git a/System/services/monitoring/system/diagnosticts/ProcessManager.cs b/System/services/monitoring/system/diagnosticts/ProcessManager.cs index 711debb3a..9c9d5e9e4 100644 --- a/System/services/monitoring/system/diagnosticts/ProcessManager.cs +++ b/System/services/monitoring/system/diagnosticts/ProcessManager.cs @@ -49,7 +49,7 @@ bool IsMainWindow(IntPtr handle) { if (NativeMethods.GetWindow(new HandleRef(this, handle), NativeMethods.GW_OWNER) != (IntPtr)0 || !NativeMethods.IsWindowVisible(new HandleRef(this, handle))) return false; - // [....]: should we use no window title to mean not a main window? (task man does) + // Microsoft: should we use no window title to mean not a main window? (task man does) /* int length = NativeMethods.GetWindowTextLength(handle) * 2; diff --git a/System/services/monitoring/system/diagnosticts/SharedUtils.cs b/System/services/monitoring/system/diagnosticts/SharedUtils.cs index b1c4a8601..5b664f60c 100644 --- a/System/services/monitoring/system/diagnosticts/SharedUtils.cs +++ b/System/services/monitoring/system/diagnosticts/SharedUtils.cs @@ -112,7 +112,7 @@ internal static void EnterMutex(string name, ref Mutex mutex) { [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] [SecurityPermission(SecurityAction.Assert, ControlPrincipal = true)] - [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "[....]: We pass fixed data into sec.AddAccessRule")] + [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "Microsoft: We pass fixed data into sec.AddAccessRule")] internal static void EnterMutexWithoutGlobal(string mutexName, ref Mutex mutex) { bool createdNew; MutexSecurity sec = new MutexSecurity(); diff --git a/System/services/timers/system/timers/Timer.cs b/System/services/timers/system/timers/Timer.cs index 7dc76d448..4202e7920 100644 --- a/System/services/timers/system/timers/Timer.cs +++ b/System/services/timers/system/timers/Timer.cs @@ -98,7 +98,7 @@ public bool AutoReset { /// is able /// to raise events at a defined interval.</para> /// </devdoc> - //[....] - The default value by design is false, don't change it. + //Microsoft - The default value by design is false, don't change it. [Category("Behavior"), TimersDescription(SR.TimerEnabled), DefaultValue(false)] public bool Enabled { get { diff --git a/System/sys/AppContextDefaultValues.Defaults.cs b/System/sys/AppContextDefaultValues.Defaults.cs index da13e1930..f9f41dee1 100644 --- a/System/sys/AppContextDefaultValues.Defaults.cs +++ b/System/sys/AppContextDefaultValues.Defaults.cs @@ -32,6 +32,13 @@ static partial void PopulateDefaultValuesPartial(string platformIdentifier, stri { LocalAppContext.DefineSwitchDefault(LocalAppContextSwitches.MemberDescriptorEqualsReturnsFalseIfEquivalentName, true); } + + if (version <= 40602) + { + LocalAppContext.DefineSwitchDefault(LocalAppContextSwitches.DontEnableSystemDefaultTlsVersionsName, true); + LocalAppContext.DefineSwitchDefault(LocalAppContextSwitches.DontEnableTlsAlertsName, true); + } + break; } case "WindowsPhone": @@ -39,7 +46,9 @@ static partial void PopulateDefaultValuesPartial(string platformIdentifier, stri { if (version <= 80100) { - LocalAppContext.DefineSwitchDefault(LocalAppContextSwitches.DontEnableSchUseStrongCryptoName, true); + LocalAppContext.DefineSwitchDefault(LocalAppContextSwitches.DontEnableSchUseStrongCryptoName, true); + LocalAppContext.DefineSwitchDefault(LocalAppContextSwitches.DontEnableSystemDefaultTlsVersionsName, true); + LocalAppContext.DefineSwitchDefault(LocalAppContextSwitches.DontEnableTlsAlertsName, true); } break; } diff --git a/System/sys/LocalAppContextSwitches.cs b/System/sys/LocalAppContextSwitches.cs index 0d28af159..f18360712 100644 --- a/System/sys/LocalAppContextSwitches.cs +++ b/System/sys/LocalAppContextSwitches.cs @@ -61,6 +61,31 @@ public static bool DontEnableSchSendAuxRecord return LocalAppContext.GetCachedSwitchValue(DontEnableSchSendAuxRecordName, ref _dontEnableSchSendAuxRecord); } } + + private static int _dontEnableSystemSystemDefaultTlsVersions; + internal const string DontEnableSystemDefaultTlsVersionsName = @"Switch.System.Net.DontEnableSystemDefaultTlsVersions"; + + public static bool DontEnableSystemDefaultTlsVersions + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return LocalAppContext.GetCachedSwitchValue(DontEnableSystemDefaultTlsVersionsName, ref _dontEnableSystemSystemDefaultTlsVersions); + } + } + + private static int _dontEnableTlsAlerts; + internal const string DontEnableTlsAlertsName = @"Switch.System.Net.DontEnableTlsAlerts"; + + public static bool DontEnableTlsAlerts + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return LocalAppContext.GetCachedSwitchValue(DontEnableTlsAlertsName, ref _dontEnableTlsAlerts); + } + } #endregion + } } diff --git a/System/sys/system/IO/ports/SerialStream.cs b/System/sys/system/IO/ports/SerialStream.cs index 02e2d4445..5848bb610 100644 --- a/System/sys/system/IO/ports/SerialStream.cs +++ b/System/sys/system/IO/ports/SerialStream.cs @@ -7,7 +7,7 @@ ** ** Class: SerialStream ** -** Purpose: Class for enabling low-level [....] and async control over a serial +** Purpose: Class for enabling low-level sync and async control over a serial ** : communications resource. ** ** Date: August, 2002 @@ -809,7 +809,8 @@ protected override void Dispose(bool disposing) // the SerialPort. A customer also reported seeing ERROR_BAD_COMMAND here. // Do not throw an exception on the finalizer thread - that's just rude, // since apps can't catch it and we may tear down the app. - if ((hr == NativeMethods.ERROR_ACCESS_DENIED || hr == NativeMethods.ERROR_BAD_COMMAND) && !disposing) { + const int ERROR_DEVICE_REMOVED = 1617; + if ((hr == NativeMethods.ERROR_ACCESS_DENIED || hr == NativeMethods.ERROR_BAD_COMMAND || hr == ERROR_DEVICE_REMOVED) && !disposing) { skipSPAccess = true; } else { @@ -1736,8 +1737,9 @@ internal unsafe void WaitForCommEvent() { int hr = Marshal.GetLastWin32Error(); // When a device is disconnected unexpectedly from a serial port, there appear to be - // at least two error codes Windows or drivers may return. - if (hr == NativeMethods.ERROR_ACCESS_DENIED || hr == NativeMethods.ERROR_BAD_COMMAND) { + // at least three error codes Windows or drivers may return. + const int ERROR_DEVICE_REMOVED = 1617; + if (hr == NativeMethods.ERROR_ACCESS_DENIED || hr == NativeMethods.ERROR_BAD_COMMAND || hr == ERROR_DEVICE_REMOVED) { doCleanup = true; break; } diff --git a/System/sys/system/Media/SoundPlayer.cs b/System/sys/system/Media/SoundPlayer.cs index 57e621ef4..03736293d 100644 --- a/System/sys/system/Media/SoundPlayer.cs +++ b/System/sys/system/Media/SoundPlayer.cs @@ -227,7 +227,7 @@ private void CleanupStreamData() { /// <include file='doc\SoundPlayer.uex' path='docs/doc[@for="SoundPlayer.Load"]/*' /> public void Load() { // if we have a file there is nothing to load - we just pass the file to the PlaySound function - // if we have a stream, then we start loading the stream [....] + // if we have a stream, then we start loading the stream sync // if (uri != null && uri.IsFile){ Debug.Assert(stream == null, "we can't have a stream and a path at the same time"); diff --git a/System/sys/system/collections/concurrent/BlockingCollection.cs b/System/sys/system/collections/concurrent/BlockingCollection.cs index ba8dac366..d252dced5 100644 --- a/System/sys/system/collections/concurrent/BlockingCollection.cs +++ b/System/sys/system/collections/concurrent/BlockingCollection.cs @@ -7,7 +7,7 @@ // // BlockingCollection.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A class that implements the bounding and blocking functionality while abstracting away // the underlying storage mechanism. This file also contains BlockingCollection's diff --git a/System/sys/system/collections/concurrent/ConcurrentBag.cs b/System/sys/system/collections/concurrent/ConcurrentBag.cs index 1f0d34927..0eac2aa19 100644 --- a/System/sys/system/collections/concurrent/ConcurrentBag.cs +++ b/System/sys/system/collections/concurrent/ConcurrentBag.cs @@ -7,7 +7,7 @@ // // ConcurrentBag.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // //An unordered collection that allows duplicates and that provides add and get operations. diff --git a/System/sys/system/threading/Barrier.cs b/System/sys/system/threading/Barrier.cs index 35db6d1f9..25c0ed599 100644 --- a/System/sys/system/threading/Barrier.cs +++ b/System/sys/system/threading/Barrier.cs @@ -7,7 +7,7 @@ // // Barrier.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A barrier allows multiple tasks to cooperatively work on some algorithm in parallel. // A group of tasks cooperate by moving through a series of phases, where each in the group signals it has arrived at diff --git a/System/sys/system/windows/markup/ValueSerializerAttribute.cs b/System/sys/system/windows/markup/ValueSerializerAttribute.cs index 2a0102e8c..083ec90e7 100644 --- a/System/sys/system/windows/markup/ValueSerializerAttribute.cs +++ b/System/sys/system/windows/markup/ValueSerializerAttribute.cs @@ -10,7 +10,7 @@ // an attached property by setting it on the static accessor // for the attachable property). // -// Created: 04/28/2005 [....] +// Created: 04/28/2005 Microsoft // //------------------------------------------------------------------------ diff --git a/mscorlib/InternalApis/NDP_Common/inc/StrongNameHelpers.cs b/mscorlib/InternalApis/NDP_Common/inc/StrongNameHelpers.cs index 262070c90..eca286141 100644 --- a/mscorlib/InternalApis/NDP_Common/inc/StrongNameHelpers.cs +++ b/mscorlib/InternalApis/NDP_Common/inc/StrongNameHelpers.cs @@ -20,7 +20,7 @@ internal static class StrongNameHelpers { [ThreadStatic] private static IClrStrongName s_StrongName; - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] private static IClrStrongName StrongName { [System.Security.SecurityCritical] get { @@ -33,7 +33,7 @@ private static IClrStrongName StrongName { } } - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] private static IClrStrongNameUsingIntPtr StrongNameUsingIntPtr { [System.Security.SecurityCritical] get { @@ -42,20 +42,20 @@ private static IClrStrongNameUsingIntPtr StrongNameUsingIntPtr { } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static int StrongNameErrorInfo() { return ts_LastStrongNameHR; } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "Microsoft.Runtime.Hosting.IClrStrongNameUsingIntPtr.StrongNameFreeBuffer(System.IntPtr)", Justification = "StrongNameFreeBuffer returns void but the new runtime wrappers return an HRESULT.")] public static void StrongNameFreeBuffer(IntPtr pbMemory) { StrongNameUsingIntPtr.StrongNameFreeBuffer(pbMemory); } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameGetPublicKey(string pwzKeyContainer, IntPtr pbKeyBlob, int cbKeyBlob, out IntPtr ppbPublicKeyBlob, out int pcbPublicKeyBlob) { int hr = StrongNameUsingIntPtr.StrongNameGetPublicKey(pwzKeyContainer, pbKeyBlob, cbKeyBlob, out ppbPublicKeyBlob, out pcbPublicKeyBlob); if( hr < 0 ) @@ -70,7 +70,7 @@ public static bool StrongNameGetPublicKey(string pwzKeyContainer, IntPtr pbKeyBl [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameKeyDelete(string pwzKeyContainer) { int hr = StrongName.StrongNameKeyDelete(pwzKeyContainer); if( hr < 0 ) @@ -82,7 +82,7 @@ public static bool StrongNameKeyDelete(string pwzKeyContainer) { } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameKeyGen(string pwzKeyContainer, int dwFlags, out IntPtr ppbKeyBlob, out int pcbKeyBlob) { int hr = StrongName.StrongNameKeyGen(pwzKeyContainer, dwFlags, out ppbKeyBlob, out pcbKeyBlob); if( hr < 0 ) @@ -96,7 +96,7 @@ public static bool StrongNameKeyGen(string pwzKeyContainer, int dwFlags, out Int } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameKeyInstall(string pwzKeyContainer, IntPtr pbKeyBlob, int cbKeyBlob) { int hr = StrongNameUsingIntPtr.StrongNameKeyInstall(pwzKeyContainer, pbKeyBlob, cbKeyBlob); if( hr < 0 ) @@ -108,7 +108,7 @@ public static bool StrongNameKeyInstall(string pwzKeyContainer, IntPtr pbKeyBlob } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzKeyContainer, IntPtr pbKeyBlob, int cbKeyBlob) { IntPtr ppbSignatureBlob = IntPtr.Zero; int cbSignatureBlob = 0; @@ -117,7 +117,7 @@ public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzK [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzKeyContainer, IntPtr pbKeyBlob, int cbKeyBlob, ref IntPtr ppbSignatureBlob, out int pcbSignatureBlob) { int hr = StrongNameUsingIntPtr.StrongNameSignatureGeneration(pwzFilePath, pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, out pcbSignatureBlob); if( hr < 0 ) @@ -130,7 +130,7 @@ public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzK } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureSize(IntPtr pbPublicKeyBlob, int cbPublicKeyBlob, out int pcbSize) { int hr = StrongNameUsingIntPtr.StrongNameSignatureSize(pbPublicKeyBlob, cbPublicKeyBlob, out pcbSize); if( hr < 0 ) @@ -143,7 +143,7 @@ public static bool StrongNameSignatureSize(IntPtr pbPublicKeyBlob, int cbPublicK } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureVerification(string pwzFilePath, int dwInFlags, out int pdwOutFlags) { int hr = StrongName.StrongNameSignatureVerification(pwzFilePath, dwInFlags, out pdwOutFlags); if( hr < 0 ) @@ -156,7 +156,7 @@ public static bool StrongNameSignatureVerification(string pwzFilePath, int dwInF } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureVerificationEx(string pwzFilePath, bool fForceVerification, out bool pfWasVerified) { int hr = StrongName.StrongNameSignatureVerificationEx(pwzFilePath, fForceVerification, out pfWasVerified); if( hr < 0 ) @@ -169,7 +169,7 @@ public static bool StrongNameSignatureVerificationEx(string pwzFilePath, bool fF } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameTokenFromPublicKey(IntPtr pbPublicKeyBlob, int cbPublicKeyBlob, out IntPtr ppbStrongNameToken, out int pcbStrongNameToken) { int hr = StrongNameUsingIntPtr.StrongNameTokenFromPublicKey(pbPublicKeyBlob, cbPublicKeyBlob, out ppbStrongNameToken, out pcbStrongNameToken); if( hr < 0 ) @@ -183,7 +183,7 @@ public static bool StrongNameTokenFromPublicKey(IntPtr pbPublicKeyBlob, int cbPu } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureSize(byte[] bPublicKeyBlob, int cbPublicKeyBlob, out int pcbSize) { int hr = StrongName.StrongNameSignatureSize(bPublicKeyBlob, cbPublicKeyBlob, out pcbSize); if( hr < 0 ) @@ -195,7 +195,7 @@ public static bool StrongNameSignatureSize(byte[] bPublicKeyBlob, int cbPublicKe return true; } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameTokenFromPublicKey(byte[] bPublicKeyBlob, int cbPublicKeyBlob, out IntPtr ppbStrongNameToken, out int pcbStrongNameToken) { int hr = StrongName.StrongNameTokenFromPublicKey(bPublicKeyBlob, cbPublicKeyBlob, out ppbStrongNameToken, out pcbStrongNameToken); if( hr < 0 ) @@ -209,7 +209,7 @@ public static bool StrongNameTokenFromPublicKey(byte[] bPublicKeyBlob, int cbPub } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameGetPublicKey(string pwzKeyContainer, byte[] bKeyBlob, int cbKeyBlob, out IntPtr ppbPublicKeyBlob, out int pcbPublicKeyBlob) { int hr = StrongName.StrongNameGetPublicKey(pwzKeyContainer, bKeyBlob, cbKeyBlob, out ppbPublicKeyBlob, out pcbPublicKeyBlob); if( hr < 0 ) @@ -223,7 +223,7 @@ public static bool StrongNameGetPublicKey(string pwzKeyContainer, byte[] bKeyBlo } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameKeyInstall(string pwzKeyContainer, byte[] bKeyBlob, int cbKeyBlob) { int hr = StrongName.StrongNameKeyInstall(pwzKeyContainer, bKeyBlob, cbKeyBlob); if( hr < 0 ) @@ -235,7 +235,7 @@ public static bool StrongNameKeyInstall(string pwzKeyContainer, byte[] bKeyBlob, } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzKeyContainer, byte[] bKeyBlob, int cbKeyBlob) { IntPtr ppbSignatureBlob = IntPtr.Zero; int cbSignatureBlob = 0; @@ -243,7 +243,7 @@ public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzK } [System.Security.SecurityCritical] - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "[....]: This file is included in a lot of projects some of which only use a subset of the functions.")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Microsoft: This file is included in a lot of projects some of which only use a subset of the functions.")] public static bool StrongNameSignatureGeneration(string pwzFilePath, string pwzKeyContainer, byte[] bKeyBlob, int cbKeyBlob, ref IntPtr ppbSignatureBlob, out int pcbSignatureBlob) { int hr = StrongName.StrongNameSignatureGeneration(pwzFilePath, pwzKeyContainer, bKeyBlob, cbKeyBlob, ppbSignatureBlob, out pcbSignatureBlob); if( hr < 0 ) diff --git a/mscorlib/microsoft/win32/oavariantlib.cs b/mscorlib/microsoft/win32/oavariantlib.cs index 8b8d0b1cb..96525f5cd 100644 --- a/mscorlib/microsoft/win32/oavariantlib.cs +++ b/mscorlib/microsoft/win32/oavariantlib.cs @@ -60,7 +60,7 @@ internal static class OAVariantLib typeof(DBNull), }; - // Keep these numbers in [....] w/ the above array. + // Keep these numbers in sync w/ the above array. private const int CV_OBJECT=0x12; #endregion diff --git a/mscorlib/microsoft/win32/safehandles/saferegistryhandle.cs b/mscorlib/microsoft/win32/safehandles/saferegistryhandle.cs index afe090120..c2b6730bb 100644 --- a/mscorlib/microsoft/win32/safehandles/saferegistryhandle.cs +++ b/mscorlib/microsoft/win32/safehandles/saferegistryhandle.cs @@ -6,7 +6,7 @@ // // File: SafeRegistryHandle.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Implements Microsoft.Win32.SafeHandles.SafeRegistryHandle // diff --git a/mscorlib/mscorlib.txt b/mscorlib/mscorlib.txt index e95c7ad15..35fac908a 100644 --- a/mscorlib/mscorlib.txt +++ b/mscorlib/mscorlib.txt @@ -46,12 +46,7 @@ Exception_EndStackTraceFromPreviousThrow = --- End of stack trace from previous Arg_ParamName_Name = Parameter name: {0} ArgumentOutOfRange_ActualValue = Actual value was {0}. -#if PLATFORM_UNIX -NoDebugResources = [{0}]\nArguments: {1}\nDebugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version={2}&File={3}&Key={4} -#endif -#if !PLATFORM_UNIX NoDebugResources = [{0}]\r\nArguments: {1}\r\nDebugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version={2}&File={3}&Key={4} -#endif // PLATFORM_UNIX else #endif // INCLUDE_RUNTIME #if !FEATURE_CORECLR @@ -73,12 +68,7 @@ PostconditionOnExceptionFailed = Postcondition failed after throwing an exceptio PostconditionOnExceptionFailed_Cnd = Postcondition failed after throwing an exception: {0} InvariantFailed = Invariant failed. InvariantFailed_Cnd = Invariant failed: {0} -#if PLATFORM_UNIX -StackTrace_Stack = Stack trace: \n{0} -#endif -#if !PLATFORM_UNIX StackTrace_Stack = Stack trace: \r\n{0} -#endif // PLATFORM_UNIX else MustUseCCRewrite = An assembly (probably "{1}") must be rewritten using the code contracts binary rewriter (CCRewrite) because it is calling Contract.{0} and the CONTRACTS_FULL symbol is defined. Remove any explicit definitions of the CONTRACTS_FULL symbol from your project and rebuild. CCRewrite can be downloaded from http://go.microsoft.com/fwlink/?LinkID=169180. \r\nAfter the rewriter is installed, it can be enabled in Visual Studio from the project's Properties page on the Code Contracts pane. Ensure that "Perform Runtime Contract Checking" is enabled, which will define CONTRACTS_FULL. ; Access Control @@ -319,7 +309,7 @@ Arg_EmptyOrNullArray = Array may not be empty or null. Arg_EmptyCollection = Collection must not be empty. Arg_EmptyOrNullString = String may not be empty or null. Argument_ItemNotExist = The specified item does not exist in this KeyedCollection. -Argument_EncodingNotSupported = '{0}' is not a supported encoding name. +Argument_EncodingNotSupported = '{0}' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method. Argument_FallbackBufferNotEmpty = Cannot change fallback when buffer is not empty. Previous Convert() call left data in the fallback buffer. Argument_InvalidCodePageConversionIndex = Unable to translate Unicode character \\u{0:X4} at index {1} to specified code page. Argument_InvalidCodePageBytesIndex = Unable to translate bytes {0} at index {1} from specified code page to Unicode. @@ -951,6 +941,7 @@ Cryptography_CSP_NoPrivateKey = Object contains only the public half of a key pa Cryptography_CSP_OFBNotSupported = Output feedback mode (OFB) is not supported by this implementation. Cryptography_CSP_WrongKeySpec = The specified cryptographic service provider (CSP) does not support this key algorithm. Cryptography_HashNameSet = Hash name cannot be changed after the first write to the stream. +Cryptography_HashAlgorithmNameNullOrEmpty = The hash algorithm name cannot be null or empty. Cryptography_InvalidHashSize = {0} algorithm hash size is {1} bytes. Cryptography_InvalidKey_Weak = Specified key is a known weak key for '{0}' and cannot be used. Cryptography_InvalidKey_SemiWeak = Specified key is a known semi-weak key for '{0}' and cannot be used. @@ -1008,6 +999,46 @@ EventSource_NeedGuid = The Guid of an EventSource must be non zero. EventSource_NeedName = The name of an EventSource must not be null. EventSource_EtwAlreadyRegistered = The provider has already been registered with the operating system. EventSource_ListenerWriteFailure = An error occurred when writing to a listener. +EventSource_TypeMustDeriveFromEventSource = Event source types must derive from EventSource. +EventSource_TypeMustBeSealedOrAbstract = Event source types must be sealed or abstract. +EventSource_TaskOpcodePairReused = Event {0} (with ID {1}) has the same task/opcode pair as event {2} (with ID {3}). +EventSource_EventMustHaveTaskIfNonDefaultOpcode = Event {0} (with ID {1}) has a non-default opcode but not a task. +EventSource_EventNameDoesNotEqualTaskPlusOpcode = Event {0} (with ID {1}) has a name that is not the concatenation of its task name and opcode. +EventSource_PeriodIllegalInProviderName = Period character ('.') is illegal in an ETW provider name ({0}). +EventSource_IllegalOpcodeValue = Opcode {0} has a value of {1} which is outside the legal range (11-238). +EventSource_OpcodeCollision = Opcodes {0} and {1} are defined with the same value ({2}). +EventSource_IllegalTaskValue = Task {0} has a value of {1} which is outside the legal range (1-65535). +EventSource_TaskCollision = Tasks {0} and {1} are defined with the same value ({2}). +EventSource_IllegalKeywordsValue = Keyword {0} has a value of {1} which is outside the legal range (0-0x0000080000000000). +EventSource_KeywordCollision = Keywords {0} and {1} are defined with the same value ({2}). +EventSource_EventChannelOutOfRange = Channel {0} has a value of {1} which is outside the legal range (16-254). +EventSource_ChannelTypeDoesNotMatchEventChannelValue = Channel {0} does not match event channel value {1}. +EventSource_MaxChannelExceeded = Attempt to define more than the maximum limit of 8 channels for a provider. +EventSource_DuplicateStringKey = Multiple definitions for string "{0}". +EventSource_EventWithAdminChannelMustHaveMessage = Event {0} specifies an Admin channel {1}. It must specify a Message property. +EventSource_UnsupportedMessageProperty = Event {0} specifies an illegal or unsupported formatting message ("{1}"). +EventSource_AbstractMustNotDeclareKTOC = Abstract event source must not declare {0} nested type. +EventSource_AbstractMustNotDeclareEventMethods = Abstract event source must not declare event methods ({0} with ID {1}). +EventSource_EventMustNotBeExplicitImplementation = Event method {0} (with ID {1}) is an explicit interface method implementation. Re-write method as implicit implementation. +EventSource_EventParametersMismatch = Event {0} was called with {1} argument(s) , but it is defined with {2} paramenter(s). +EventSource_InvalidCommand = Invalid command value. +EventSource_InvalidEventFormat = Can't specify both etw event format flags. +EventSource_AddScalarOutOfRange = Getting out of bounds during scalar addition. +EventSource_PinArrayOutOfRange = Pins are out of range. +EventSource_DataDescriptorsOutOfRange = Data descriptors are out of range. +EventSource_NotSupportedArrayOfNil = Arrays of Nil are not supported. +EventSource_NotSupportedArrayOfBinary = Arrays of Binary are not supported. +EventSource_NotSupportedArrayOfNullTerminatedString = Arrays of null-terminated string are not supported. +EventSource_TooManyFields = Too many fields in structure. +EventSource_RecursiveTypeDefinition = Recursive type definition is not supported. +EventSource_NotSupportedEnumType = Enum type {0} underlying type {1} is not supported for serialization. +EventSource_NonCompliantTypeError = The API supports only anonymous types or types decorated with the EventDataAttribute. Non-compliant type: {0} dataType. +EventSource_NotSupportedNestedArraysEnums = Nested arrays/enumerables are not supported. +EventSource_IncorrentlyAuthoredTypeInfo = Incorrectly-authored TypeInfo - a type should be serialized as one field or as one group +EventSource_NotSupportedCustomSerializedData = Enumerables of custom-serialized data are not supported +EventSource_StopsFollowStarts = An event with stop suffix must follow a corresponding event with a start suffix. +EventSource_NoRelatedActivityId = EventSource expects the first parameter of the Event method to be of type Guid and to be named "relatedActivityId" when calling WriteEventWithRelatedActivityId. +EventSource_VarArgsParameterMismatch = The parameters to the Event method do not match the parameters to the WriteEvent method. This may cause the event to be displayed incorrectly. ; ExecutionEngineException ExecutionEngine_InvalidAttribute = Attribute cannot have multiple definitions. @@ -1015,6 +1046,7 @@ ExecutionEngine_MissingSecurityDescriptor = Unable to retrieve security descript ;;ExecutionContext ExecutionContext_UndoFailed = Undo operation on a component context threw an exception +ExecutionContext_ExceptionInAsyncLocalNotification = An exception was not handled in an AsyncLocal<T> notification callback. ; FieldAccessException @@ -1094,8 +1126,6 @@ InvalidOperation_AddContextFrozen = Attempted to add properties to a frozen cont InvalidOperation_AppDomainSandboxAPINeedsExplicitAppBase = This API requires the ApplicationBase to be specified explicitly in the AppDomainSetup parameter. InvalidOperation_CantCancelCtrlBreak = Applications may not prevent control-break from terminating their process. InvalidOperation_CalledTwice = The method cannot be called twice on the same instance. -;InvalidOperation_CancellationRegionLeak = A nested cancellation region was not disposed of correctly. The thread's cancellation regions are now potentially invalid. -;InvalidOperation_CancellationSignalReuse = Cannot reuse a cancellation signal while it is still in use. InvalidOperation_CollectionCorrupted = A prior operation on this collection was interrupted by an exception. Collection's state is no longer trusted. InvalidOperation_CriticalTransparentAreMutuallyExclusive = SecurityTransparent and SecurityCritical attributes cannot be applied to the assembly scope at the same time. InvalidOperation_SubclassedObject = Cannot set sub-classed {0} object to {1} object. @@ -1192,7 +1222,6 @@ InvalidOperation_PIAMustBeStrongNamed = Primary interop assemblies must be stron InvalidOperation_HashInsertFailed = Hashtable insert failed. Load factor too high. The most common cause is multiple threads writing to the Hashtable simultaneously. InvalidOperation_UnknownEnumType = Unknown enum type. InvalidOperation_GetVersion = OSVersion's call to GetVersionEx failed. -InvalidOperation_InvalidPlatformID = Unrecognized OS PlatformId. InvalidOperation_DateTimeParsing = Internal Error in DateTime and Calendar operations. InvalidOperation_UserDomainName = UserDomainName native call failed. InvalidOperation_WaitOnTransparentProxy = Cannot wait on a transparent proxy. @@ -1379,7 +1408,7 @@ NotSupported_CreateInstanceWithTypeBuilder = CreateInstance cannot be used with NotSupported_NonUrlAttrOnMBR = UrlAttribute is the only attribute supported for MarshalByRefObject. NotSupported_ActivAttrOnNonMBR = Activation Attributes are not supported for types not deriving from MarshalByRefObject. NotSupported_ActivForCom = Activation Attributes not supported for COM Objects. -NotSupported_NoCodepageData = No data is available for encoding {0}. +NotSupported_NoCodepageData = No data is available for encoding {0}. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method. NotSupported_CodePage50229 = The ISO-2022-CN Encoding (Code page 50229) is not supported. NotSupported_DynamicAssemblyNoRunAccess = Cannot execute code on a dynamic assembly without run access. NotSupported_IDispInvokeDefaultMemberWithNamedArgs = Invoking default method with named arguments is not supported. @@ -1852,12 +1881,7 @@ PrivilegeNotHeld_Named = The process does not possess the '{0}' privilege which ; General strings used in the IO package IO_UnknownFileName = [Unknown] -#if PLATFORM_UNIX -IO_StreamWriterBufferedDataLost = A StreamWriter was not closed and all buffered data within that StreamWriter was not flushed to the underlying stream. (This was detected when the StreamWriter was finalized with data in its buffer.) A portion of the data was lost. Consider one of calling Close(), Flush(), setting the StreamWriter's AutoFlush property to true, or allocating the StreamWriter with a "using" statement. Stream type: {0}\nFile name: {1}\nAllocated from:\n {2} -#endif -#if !PLATFORM_UNIX IO_StreamWriterBufferedDataLost = A StreamWriter was not closed and all buffered data within that StreamWriter was not flushed to the underlying stream. (This was detected when the StreamWriter was finalized with data in its buffer.) A portion of the data was lost. Consider one of calling Close(), Flush(), setting the StreamWriter's AutoFlush property to true, or allocating the StreamWriter with a "using" statement. Stream type: {0}\r\nFile name: {1}\r\nAllocated from:\r\n {2} -#endif // PLATFORM_UNIX else IO_StreamWriterBufferedDataLostCaptureAllocatedFromCallstackNotEnabled = callstack information is not captured by default for performance reasons. Please enable captureAllocatedCallStack config switch for streamWriterBufferedDataLost MDA (refer to MSDN MDA documentation for how to do this). ; @@ -2217,6 +2241,10 @@ Loader_ContextPolicies = Context Policies: AppDomain_RequireApplicationName = ApplicationName must be set before the DynamicBase can be set. AppDomain_AppBaseNotSet = The ApplicationBase must be set before retrieving this property. +#if FEATURE_HOST_ASSEMBLY_RESOLVER +AppDomain_BindingModelIsLocked = Binding model is already locked for the AppDomain and cannot be reset. +Argument_CustomAssemblyLoadContextRequestedNameMismatch = Resolved assembly's simple name should be the same as of the requested assembly. +#endif // FEATURE_HOST_ASSEMBLY_RESOLVER ; ; XMLSyntaxExceptions XMLSyntax_UnexpectedEndOfFile = Unexpected end of file. @@ -2320,7 +2348,7 @@ TimeZoneNotFound_MissingRegistryData = The time zone ID '{0}' was not found on t ; Tuple ArgumentException_TupleIncorrectType=Argument must be of type {0}. ArgumentException_TupleNonIComparableElement=The tuple contains an element of type {0} which does not implement the IComparable interface. -ArgumentException_TupleLastArgumentNotATuple=The last element of an eight element tuple must be a Tuple. +ArgumentException_TupleLastArgumentNotATuple=The last element of an eight element Tuple must be a Tuple. ArgumentException_OtherNotArrayOfCorrectLength=Object is not a array with the same number of elements as the array to compare it to. ; WinRT collection adapters @@ -2339,60 +2367,106 @@ InvalidOperation_CannotRemoveLastFromEmptyCollection=Cannot remove the last elem Globalization.LegacyModifier = Legacy ; -;Total items: 393 +;Total items: 809 ; Globalization.ci_ = Invariant Language (Invariant Country) +Globalization.ci_aa = Afar +Globalization.ci_aa-DJ = Afar (Djibouti) +Globalization.ci_aa-ER = Afar (Eritrea) +Globalization.ci_aa-ET = Afar (Ethiopia) Globalization.ci_af = Afrikaans +Globalization.ci_af-NA = Afrikaans (Namibia) Globalization.ci_af-ZA = Afrikaans (South Africa) +Globalization.ci_agq = Aghem +Globalization.ci_agq-CM = Aghem (Cameroon) +Globalization.ci_ak = Akan +Globalization.ci_ak-GH = Akan (Ghana) Globalization.ci_am = Amharic Globalization.ci_am-ET = Amharic (Ethiopia) Globalization.ci_ar = Arabic +Globalization.ci_ar-001 = Arabic (World) Globalization.ci_ar-AE = Arabic (U.A.E.) Globalization.ci_ar-BH = Arabic (Bahrain) +Globalization.ci_ar-DJ = Arabic (Djibouti) Globalization.ci_ar-DZ = Arabic (Algeria) Globalization.ci_ar-EG = Arabic (Egypt) +Globalization.ci_ar-ER = Arabic (Eritrea) +Globalization.ci_ar-IL = Arabic (Israel) Globalization.ci_ar-IQ = Arabic (Iraq) Globalization.ci_ar-JO = Arabic (Jordan) +Globalization.ci_ar-KM = Arabic (Comoros) Globalization.ci_ar-KW = Arabic (Kuwait) Globalization.ci_ar-LB = Arabic (Lebanon) Globalization.ci_ar-LY = Arabic (Libya) Globalization.ci_ar-MA = Arabic (Morocco) +Globalization.ci_ar-MR = Arabic (Mauritania) Globalization.ci_ar-OM = Arabic (Oman) +Globalization.ci_ar-PS = Arabic (Palestinian Authority) Globalization.ci_ar-QA = Arabic (Qatar) Globalization.ci_ar-SA = Arabic (Saudi Arabia) +Globalization.ci_ar-SD = Arabic (Sudan) +Globalization.ci_ar-SO = Arabic (Somalia) +Globalization.ci_ar-SS = Arabic (South Sudan) Globalization.ci_ar-SY = Arabic (Syria) +Globalization.ci_ar-TD = Arabic (Chad) Globalization.ci_ar-TN = Arabic (Tunisia) Globalization.ci_ar-YE = Arabic (Yemen) Globalization.ci_arn = Mapudungun Globalization.ci_arn-CL = Mapudungun (Chile) Globalization.ci_as = Assamese Globalization.ci_as-IN = Assamese (India) -Globalization.ci_az = Azeri -Globalization.ci_az-Cyrl = Azeri (Cyrillic) -Globalization.ci_az-Cyrl-AZ = Azeri (Cyrillic, Azerbaijan) -Globalization.ci_az-Latn = Azeri (Latin) -Globalization.ci_az-Latn-AZ = Azeri (Latin, Azerbaijan) +Globalization.ci_asa = Asu +Globalization.ci_asa-TZ = Asu (Tanzania) +Globalization.ci_ast = Asturian +Globalization.ci_ast-ES = Asturian (Spain) +Globalization.ci_az = Azerbaijani +Globalization.ci_az-Cyrl = Azerbaijani (Cyrillic) +Globalization.ci_az-Cyrl-AZ = Azerbaijani (Cyrillic, Azerbaijan) +Globalization.ci_az-Latn = Azerbaijani (Latin) +Globalization.ci_az-Latn-AZ = Azerbaijani (Latin, Azerbaijan) Globalization.ci_ba = Bashkir Globalization.ci_ba-RU = Bashkir (Russia) +Globalization.ci_bas = Basaa +Globalization.ci_bas-CM = Basaa (Cameroon) Globalization.ci_be = Belarusian Globalization.ci_be-BY = Belarusian (Belarus) +Globalization.ci_bem = Bemba +Globalization.ci_bem-ZM = Bemba (Zambia) +Globalization.ci_bez = Bena +Globalization.ci_bez-TZ = Bena (Tanzania) Globalization.ci_bg = Bulgarian Globalization.ci_bg-BG = Bulgarian (Bulgaria) -Globalization.ci_bn = Bengali -Globalization.ci_bn-BD = Bengali (Bangladesh) -Globalization.ci_bn-IN = Bengali (India) +Globalization.ci_bin = Edo +Globalization.ci_bin-NG = Edo (Nigeria) +Globalization.ci_bm = Bambara +Globalization.ci_bm-Latn = Bambara (Latin) +Globalization.ci_bm-Latn-ML = Bambara (Latin, Mali) +Globalization.ci_bm-ML = Bamanankan (Latin, Mali) +Globalization.ci_bn = Bangla +Globalization.ci_bn-BD = Bangla (Bangladesh) +Globalization.ci_bn-IN = Bangla (India) Globalization.ci_bo = Tibetan Globalization.ci_bo-CN = Tibetan (PRC) +Globalization.ci_bo-IN = Tibetan (India) Globalization.ci_br = Breton Globalization.ci_br-FR = Breton (France) +Globalization.ci_brx = Bodo +Globalization.ci_brx-IN = Bodo (India) Globalization.ci_bs = Bosnian Globalization.ci_bs-Cyrl = Bosnian (Cyrillic) Globalization.ci_bs-Cyrl-BA = Bosnian (Cyrillic, Bosnia and Herzegovina) Globalization.ci_bs-Latn = Bosnian (Latin) Globalization.ci_bs-Latn-BA = Bosnian (Latin, Bosnia and Herzegovina) +Globalization.ci_byn = Blin +Globalization.ci_byn-ER = Blin (Eritrea) Globalization.ci_ca = Catalan +Globalization.ci_ca-AD = Catalan (Andorra) Globalization.ci_ca-ES = Catalan (Catalan) Globalization.ci_ca-ES-valencia = Valencian (Spain) +Globalization.ci_ca-FR = Catalan (France) +Globalization.ci_ca-IT = Catalan (Italy) +Globalization.ci_cgg = Chiga +Globalization.ci_cgg-UG = Chiga (Uganda) Globalization.ci_chr = Cherokee Globalization.ci_chr-Cher = Cherokee (Cherokee) Globalization.ci_chr-Cher-US = Cherokee (Cherokee) @@ -2404,52 +2478,154 @@ Globalization.ci_cy = Welsh Globalization.ci_cy-GB = Welsh (United Kingdom) Globalization.ci_da = Danish Globalization.ci_da-DK = Danish (Denmark) +Globalization.ci_da-GL = Danish (Greenland) +Globalization.ci_dav = Taita +Globalization.ci_dav-KE = Taita (Kenya) Globalization.ci_de = German Globalization.ci_de-AT = German (Austria) +Globalization.ci_de-BE = German (Belgium) Globalization.ci_de-CH = German (Switzerland) Globalization.ci_de-DE = German (Germany) Globalization.ci_de-DE_phoneb = German (Germany) Globalization.ci_de-LI = German (Liechtenstein) Globalization.ci_de-LU = German (Luxembourg) +Globalization.ci_dje = Zarma +Globalization.ci_dje-NE = Zarma (Niger) Globalization.ci_dsb = Lower Sorbian Globalization.ci_dsb-DE = Lower Sorbian (Germany) +Globalization.ci_dua = Duala +Globalization.ci_dua-CM = Duala (Cameroon) Globalization.ci_dv = Divehi Globalization.ci_dv-MV = Divehi (Maldives) +Globalization.ci_dyo = Jola-Fonyi +Globalization.ci_dyo-SN = Jola-Fonyi (Senegal) +Globalization.ci_dz = Dzongkha +Globalization.ci_dz-BT = Dzongkha (Bhutan) +Globalization.ci_ebu = Embu +Globalization.ci_ebu-KE = Embu (Kenya) +Globalization.ci_ee = Ewe +Globalization.ci_ee-GH = Ewe (Ghana) +Globalization.ci_ee-TG = Ewe (Togo) Globalization.ci_el = Greek +Globalization.ci_el-CY = Greek (Cyprus) Globalization.ci_el-GR = Greek (Greece) Globalization.ci_en = English +Globalization.ci_en-001 = English (World) Globalization.ci_en-029 = English (Caribbean) +Globalization.ci_en-150 = English (Europe) +Globalization.ci_en-AG = English (Antigua and Barbuda) +Globalization.ci_en-AI = English (Anguilla) +Globalization.ci_en-AS = English (American Samoa) Globalization.ci_en-AU = English (Australia) +Globalization.ci_en-BB = English (Barbados) +Globalization.ci_en-BE = English (Belgium) +Globalization.ci_en-BM = English (Bermuda) +Globalization.ci_en-BS = English (Bahamas) +Globalization.ci_en-BW = English (Botswana) Globalization.ci_en-BZ = English (Belize) Globalization.ci_en-CA = English (Canada) +Globalization.ci_en-CC = English (Cocos [Keeling] Islands) +Globalization.ci_en-CK = English (Cook Islands) +Globalization.ci_en-CM = English (Cameroon) +Globalization.ci_en-CX = English (Christmas Island) +Globalization.ci_en-DM = English (Dominica) +Globalization.ci_en-ER = English (Eritrea) +Globalization.ci_en-FJ = English (Fiji) +Globalization.ci_en-FK = English (Falkland Islands) +Globalization.ci_en-FM = English (Micronesia) Globalization.ci_en-GB = English (United Kingdom) +Globalization.ci_en-GD = English (Grenada) +Globalization.ci_en-GG = English (Guernsey) +Globalization.ci_en-GH = English (Ghana) +Globalization.ci_en-GI = English (Gibraltar) +Globalization.ci_en-GM = English (Gambia) +Globalization.ci_en-GU = English (Guam) +Globalization.ci_en-GY = English (Guyana) +Globalization.ci_en-HK = English (Hong Kong SAR) +Globalization.ci_en-ID = English (Indonesia) Globalization.ci_en-IE = English (Ireland) +Globalization.ci_en-IM = English (Isle of Man) Globalization.ci_en-IN = English (India) +Globalization.ci_en-IO = English (British Indian Ocean Territory) +Globalization.ci_en-JE = English (Jersey) Globalization.ci_en-JM = English (Jamaica) +Globalization.ci_en-KE = English (Kenya) +Globalization.ci_en-KI = English (Kiribati) +Globalization.ci_en-KN = English (Saint Kitts and Nevis) +Globalization.ci_en-KY = English (Cayman Islands) +Globalization.ci_en-LC = English (Saint Lucia) +Globalization.ci_en-LR = English (Liberia) +Globalization.ci_en-LS = English (Lesotho) +Globalization.ci_en-MG = English (Madagascar) +Globalization.ci_en-MH = English (Marshall Islands) +Globalization.ci_en-MO = English (Macao SAR) +Globalization.ci_en-MP = English (Northern Mariana Islands) +Globalization.ci_en-MS = English (Montserrat) +Globalization.ci_en-MT = English (Malta) +Globalization.ci_en-MU = English (Mauritius) +Globalization.ci_en-MW = English (Malawi) Globalization.ci_en-MY = English (Malaysia) +Globalization.ci_en-NA = English (Namibia) +Globalization.ci_en-NF = English (Norfolk Island) +Globalization.ci_en-NG = English (Nigeria) +Globalization.ci_en-NR = English (Nauru) +Globalization.ci_en-NU = English (Niue) Globalization.ci_en-NZ = English (New Zealand) +Globalization.ci_en-PG = English (Papua New Guinea) Globalization.ci_en-PH = English (Republic of the Philippines) +Globalization.ci_en-PK = English (Pakistan) +Globalization.ci_en-PN = English (Pitcairn Islands) +Globalization.ci_en-PR = English (Puerto Rico) +Globalization.ci_en-PW = English (Palau) +Globalization.ci_en-RW = English (Rwanda) +Globalization.ci_en-SB = English (Solomon Islands) +Globalization.ci_en-SC = English (Seychelles) +Globalization.ci_en-SD = English (Sudan) Globalization.ci_en-SG = English (Singapore) +Globalization.ci_en-SH = English (St Helena, Ascension, Tristan da Cunha) +Globalization.ci_en-SL = English (Sierra Leone) +Globalization.ci_en-SS = English (South Sudan) +Globalization.ci_en-SX = English (Sint Maarten) +Globalization.ci_en-SZ = English (Swaziland) +Globalization.ci_en-TC = English (Turks and Caicos Islands) +Globalization.ci_en-TK = English (Tokelau) +Globalization.ci_en-TO = English (Tonga) Globalization.ci_en-TT = English (Trinidad and Tobago) +Globalization.ci_en-TV = English (Tuvalu) +Globalization.ci_en-TZ = English (Tanzania) +Globalization.ci_en-UG = English (Uganda) +Globalization.ci_en-UM = English (US Minor Outlying Islands) Globalization.ci_en-US = English (United States) +Globalization.ci_en-VC = English (Saint Vincent and the Grenadines) +Globalization.ci_en-VG = English (British Virgin Islands) +Globalization.ci_en-VI = English (US Virgin Islands) +Globalization.ci_en-VU = English (Vanuatu) +Globalization.ci_en-WS = English (Samoa) Globalization.ci_en-ZA = English (South Africa) +Globalization.ci_en-ZM = English (Zambia) Globalization.ci_en-ZW = English (Zimbabwe) +Globalization.ci_eo = Esperanto +Globalization.ci_eo-001 = Esperanto (World) Globalization.ci_es = Spanish +Globalization.ci_es-419 = Spanish (Latin America) Globalization.ci_es-AR = Spanish (Argentina) Globalization.ci_es-BO = Spanish (Bolivia) Globalization.ci_es-CL = Spanish (Chile) Globalization.ci_es-CO = Spanish (Colombia) Globalization.ci_es-CR = Spanish (Costa Rica) +Globalization.ci_es-CU = Spanish (Cuba) Globalization.ci_es-DO = Spanish (Dominican Republic) Globalization.ci_es-EC = Spanish (Ecuador) Globalization.ci_es-ES = Spanish (Spain) Globalization.ci_es-ES_tradnl = Spanish (Spain) +Globalization.ci_es-GQ = Spanish (Equatorial Guinea) Globalization.ci_es-GT = Spanish (Guatemala) Globalization.ci_es-HN = Spanish (Honduras) Globalization.ci_es-MX = Spanish (Mexico) Globalization.ci_es-NI = Spanish (Nicaragua) Globalization.ci_es-PA = Spanish (Panama) Globalization.ci_es-PE = Spanish (Peru) +Globalization.ci_es-PH = Spanish (Philippines) Globalization.ci_es-PR = Spanish (Puerto Rico) Globalization.ci_es-PY = Spanish (Paraguay) Globalization.ci_es-SV = Spanish (El Salvador) @@ -2460,11 +2636,18 @@ Globalization.ci_et = Estonian Globalization.ci_et-EE = Estonian (Estonia) Globalization.ci_eu = Basque Globalization.ci_eu-ES = Basque (Basque) +Globalization.ci_ewo = Ewondo +Globalization.ci_ewo-CM = Ewondo (Cameroon) Globalization.ci_fa = Persian -Globalization.ci_fa-IR = Persian +Globalization.ci_fa-AF = Persian (Afghanistan) +Globalization.ci_fa-IR = Persian (Iran) Globalization.ci_ff = Fulah +Globalization.ci_ff-CM = Fulah (Cameroon) +Globalization.ci_ff-GN = Fulah (Guinea) Globalization.ci_ff-Latn = Fulah (Latin) Globalization.ci_ff-Latn-SN = Fulah (Latin, Senegal) +Globalization.ci_ff-MR = Fulah (Mauritania) +Globalization.ci_ff-NG = Fulah (Nigeria) Globalization.ci_fi = Finnish Globalization.ci_fi-FI = Finnish (Finland) Globalization.ci_fil = Filipino @@ -2472,12 +2655,55 @@ Globalization.ci_fil-PH = Filipino (Philippines) Globalization.ci_fo = Faroese Globalization.ci_fo-FO = Faroese (Faroe Islands) Globalization.ci_fr = French +Globalization.ci_fr-029 = French (Caribbean) Globalization.ci_fr-BE = French (Belgium) +Globalization.ci_fr-BF = French (Burkina Faso) +Globalization.ci_fr-BI = French (Burundi) +Globalization.ci_fr-BJ = French (Benin) +Globalization.ci_fr-BL = French (Saint Barthélemy) Globalization.ci_fr-CA = French (Canada) +Globalization.ci_fr-CD = French (Congo DRC) +Globalization.ci_fr-CF = French (Central African Republic) +Globalization.ci_fr-CG = French (Congo) Globalization.ci_fr-CH = French (Switzerland) +Globalization.ci_fr-CI = French (Côte d’Ivoire) +Globalization.ci_fr-CM = French (Cameroon) +Globalization.ci_fr-DJ = French (Djibouti) +Globalization.ci_fr-DZ = French (Algeria) Globalization.ci_fr-FR = French (France) +Globalization.ci_fr-GA = French (Gabon) +Globalization.ci_fr-GF = French (French Guiana) +Globalization.ci_fr-GN = French (Guinea) +Globalization.ci_fr-GP = French (Guadeloupe) +Globalization.ci_fr-GQ = French (Equatorial Guinea) +Globalization.ci_fr-HT = French (Haiti) +Globalization.ci_fr-KM = French (Comoros) Globalization.ci_fr-LU = French (Luxembourg) +Globalization.ci_fr-MA = French (Morocco) Globalization.ci_fr-MC = French (Monaco) +Globalization.ci_fr-MF = French (Saint Martin) +Globalization.ci_fr-MG = French (Madagascar) +Globalization.ci_fr-ML = French (Mali) +Globalization.ci_fr-MQ = French (Martinique) +Globalization.ci_fr-MR = French (Mauritania) +Globalization.ci_fr-MU = French (Mauritius) +Globalization.ci_fr-NC = French (New Caledonia) +Globalization.ci_fr-NE = French (Niger) +Globalization.ci_fr-PF = French (French Polynesia) +Globalization.ci_fr-PM = French (Saint Pierre and Miquelon) +Globalization.ci_fr-RE = French (Reunion) +Globalization.ci_fr-RW = French (Rwanda) +Globalization.ci_fr-SC = French (Seychelles) +Globalization.ci_fr-SN = French (Senegal) +Globalization.ci_fr-SY = French (Syria) +Globalization.ci_fr-TD = French (Chad) +Globalization.ci_fr-TG = French (Togo) +Globalization.ci_fr-TN = French (Tunisia) +Globalization.ci_fr-VU = French (Vanuatu) +Globalization.ci_fr-WF = French (Wallis and Futuna) +Globalization.ci_fr-YT = French (Mayotte) +Globalization.ci_fur = Friulian +Globalization.ci_fur-IT = Friulian (Italy) Globalization.ci_fy = Frisian Globalization.ci_fy-NL = Frisian (Netherlands) Globalization.ci_ga = Irish @@ -2486,12 +2712,22 @@ Globalization.ci_gd = Scottish Gaelic Globalization.ci_gd-GB = Scottish Gaelic (United Kingdom) Globalization.ci_gl = Galician Globalization.ci_gl-ES = Galician (Galician) +Globalization.ci_gn = Guarani +Globalization.ci_gn-PY = Guarani (Paraguay) Globalization.ci_gsw = Alsatian +Globalization.ci_gsw-CH = Alsatian (Switzerland) Globalization.ci_gsw-FR = Alsatian (France) +Globalization.ci_gsw-LI = Alsatian (Liechtenstein) Globalization.ci_gu = Gujarati Globalization.ci_gu-IN = Gujarati (India) +Globalization.ci_guz = Gusii +Globalization.ci_guz-KE = Gusii (Kenya) +Globalization.ci_gv = Manx +Globalization.ci_gv-IM = Manx (Isle of Man) Globalization.ci_ha = Hausa Globalization.ci_ha-Latn = Hausa (Latin) +Globalization.ci_ha-Latn-GH = Hausa (Latin, Ghana) +Globalization.ci_ha-Latn-NE = Hausa (Latin, Niger) Globalization.ci_ha-Latn-NG = Hausa (Latin, Nigeria) Globalization.ci_haw = Hawaiian Globalization.ci_haw-US = Hawaiian (United States) @@ -2509,6 +2745,11 @@ Globalization.ci_hu-HU = Hungarian (Hungary) Globalization.ci_hu-HU_technl = Hungarian (Hungary) Globalization.ci_hy = Armenian Globalization.ci_hy-AM = Armenian (Armenia) +Globalization.ci_ia = Interlingua +Globalization.ci_ia-001 = Interlingua (World) +Globalization.ci_ia-FR = Interlingua (France) +Globalization.ci_ibb = Ibibio +Globalization.ci_ibb-NG = Ibibio (Nigeria) Globalization.ci_id = Indonesian Globalization.ci_id-ID = Indonesian (Indonesia) Globalization.ci_ig = Igbo @@ -2520,6 +2761,7 @@ Globalization.ci_is-IS = Icelandic (Iceland) Globalization.ci_it = Italian Globalization.ci_it-CH = Italian (Switzerland) Globalization.ci_it-IT = Italian (Italy) +Globalization.ci_it-SM = Italian (San Marino) Globalization.ci_iu = Inuktitut Globalization.ci_iu-Cans = Inuktitut (Syllabics) Globalization.ci_iu-Cans-CA = Inuktitut (Syllabics, Canada) @@ -2528,13 +2770,38 @@ Globalization.ci_iu-Latn-CA = Inuktitut (Latin, Canada) Globalization.ci_ja = Japanese Globalization.ci_ja-JP = Japanese (Japan) Globalization.ci_ja-JP_radstr = Japanese (Japan) +Globalization.ci_jgo = Ngomba +Globalization.ci_jgo-CM = Ngomba (Cameroon) +Globalization.ci_jmc = Machame +Globalization.ci_jmc-TZ = Machame (Tanzania) +Globalization.ci_jv = Javanese +Globalization.ci_jv-Java = Javanese (Javanese) +Globalization.ci_jv-Java-ID = Javanese (Javanese, Indonesia) +Globalization.ci_jv-Latn = Javanese +Globalization.ci_jv-Latn-ID = Javanese (Indonesia) Globalization.ci_ka = Georgian Globalization.ci_ka-GE = Georgian (Georgia) Globalization.ci_ka-GE_modern = Georgian (Georgia) +Globalization.ci_kab = Kabyle +Globalization.ci_kab-DZ = Kabyle (Algeria) +Globalization.ci_kam = Kamba +Globalization.ci_kam-KE = Kamba (Kenya) +Globalization.ci_kde = Makonde +Globalization.ci_kde-TZ = Makonde (Tanzania) +Globalization.ci_kea = Kabuverdianu +Globalization.ci_kea-CV = Kabuverdianu (Cabo Verde) +Globalization.ci_khq = Koyra Chiini +Globalization.ci_khq-ML = Koyra Chiini (Mali) +Globalization.ci_ki = Kikuyu +Globalization.ci_ki-KE = Kikuyu (Kenya) Globalization.ci_kk = Kazakh Globalization.ci_kk-KZ = Kazakh (Kazakhstan) +Globalization.ci_kkj = Kako +Globalization.ci_kkj-CM = Kako (Cameroon) Globalization.ci_kl = Greenlandic Globalization.ci_kl-GL = Greenlandic (Greenland) +Globalization.ci_kln = Kalenjin +Globalization.ci_kln-KE = Kalenjin (Kenya) Globalization.ci_km = Khmer Globalization.ci_km-KH = Khmer (Cambodia) Globalization.ci_kn = Kannada @@ -2543,19 +2810,66 @@ Globalization.ci_ko = Korean Globalization.ci_ko-KR = Korean (Korea) Globalization.ci_kok = Konkani Globalization.ci_kok-IN = Konkani (India) +Globalization.ci_kr = Kanuri +Globalization.ci_kr-NG = Kanuri (Nigeria) +Globalization.ci_ks = Kashmiri +Globalization.ci_ks-Arab = Kashmiri (Perso-Arabic) +Globalization.ci_ks-Arab-IN = Kashmiri (Perso-Arabic) +Globalization.ci_ks-Deva = Kashmiri (Devanagari) +Globalization.ci_ks-Deva-IN = Kashmiri (Devanagari, India) +Globalization.ci_ksb = Shambala +Globalization.ci_ksb-TZ = Shambala (Tanzania) +Globalization.ci_ksf = Bafia +Globalization.ci_ksf-CM = Bafia (Cameroon) +Globalization.ci_ksh = Colognian +Globalization.ci_ksh-DE = Ripuarian (Germany) Globalization.ci_ku = Central Kurdish Globalization.ci_ku-Arab = Central Kurdish (Arabic) Globalization.ci_ku-Arab-IQ = Central Kurdish (Iraq) +Globalization.ci_kw = Cornish +Globalization.ci_kw-GB = Cornish (United Kingdom) Globalization.ci_ky = Kyrgyz Globalization.ci_ky-KG = Kyrgyz (Kyrgyzstan) +Globalization.ci_la = Latin +Globalization.ci_la-001 = Latin (World) +Globalization.ci_lag = Langi +Globalization.ci_lag-TZ = Langi (Tanzania) Globalization.ci_lb = Luxembourgish Globalization.ci_lb-LU = Luxembourgish (Luxembourg) +Globalization.ci_lg = Ganda +Globalization.ci_lg-UG = Ganda (Uganda) +Globalization.ci_lkt = Lakota +Globalization.ci_lkt-US = Lakota (United States) +Globalization.ci_ln = Lingala +Globalization.ci_ln-AO = Lingala (Angola) +Globalization.ci_ln-CD = Lingala (Congo DRC) +Globalization.ci_ln-CF = Lingala (Central African Republic) +Globalization.ci_ln-CG = Lingala (Congo) Globalization.ci_lo = Lao Globalization.ci_lo-LA = Lao (Lao P.D.R.) Globalization.ci_lt = Lithuanian Globalization.ci_lt-LT = Lithuanian (Lithuania) +Globalization.ci_lu = Luba-Katanga +Globalization.ci_lu-CD = Luba-Katanga (Congo DRC) +Globalization.ci_luo = Luo +Globalization.ci_luo-KE = Luo (Kenya) +Globalization.ci_luy = Luyia +Globalization.ci_luy-KE = Luyia (Kenya) Globalization.ci_lv = Latvian Globalization.ci_lv-LV = Latvian (Latvia) +Globalization.ci_mas = Masai +Globalization.ci_mas-KE = Masai (Kenya) +Globalization.ci_mas-TZ = Masai (Tanzania) +Globalization.ci_mer = Meru +Globalization.ci_mer-KE = Meru (Kenya) +Globalization.ci_mfe = Morisyen +Globalization.ci_mfe-MU = Morisyen (Mauritius) +Globalization.ci_mg = Malagasy +Globalization.ci_mg-MG = Malagasy (Madagascar) +Globalization.ci_mgh = Makhuwa-Meetto +Globalization.ci_mgh-MZ = Makhuwa-Meetto (Mozambique) +Globalization.ci_mgo = Meta' +Globalization.ci_mgo-CM = Meta' (Cameroon) Globalization.ci_mi = Maori Globalization.ci_mi-NZ = Maori (New Zealand) Globalization.ci_mk = Macedonian (FYROM) @@ -2567,6 +2881,9 @@ Globalization.ci_mn-Cyrl = Mongolian (Cyrillic) Globalization.ci_mn-MN = Mongolian (Cyrillic, Mongolia) Globalization.ci_mn-Mong = Mongolian (Traditional Mongolian) Globalization.ci_mn-Mong-CN = Mongolian (Traditional Mongolian, PRC) +Globalization.ci_mn-Mong-MN = Mongolian (Traditional Mongolian, Mongolia) +Globalization.ci_mni = Manipuri +Globalization.ci_mni-IN = Manipuri (India) Globalization.ci_moh = Mohawk Globalization.ci_moh-CA = Mohawk (Mohawk) Globalization.ci_mr = Marathi @@ -2574,28 +2891,65 @@ Globalization.ci_mr-IN = Marathi (India) Globalization.ci_ms = Malay Globalization.ci_ms-BN = Malay (Brunei Darussalam) Globalization.ci_ms-MY = Malay (Malaysia) +Globalization.ci_ms-SG = Malay (Latin, Singapore) Globalization.ci_mt = Maltese Globalization.ci_mt-MT = Maltese (Malta) +Globalization.ci_mua = Mundang +Globalization.ci_mua-CM = Mundang (Cameroon) +Globalization.ci_my = Burmese +Globalization.ci_my-MM = Burmese (Myanmar) +Globalization.ci_naq = Nama +Globalization.ci_naq-NA = Nama (Namibia) Globalization.ci_nb = Norwegian (Bokmål) Globalization.ci_nb-NO = Norwegian, Bokmål (Norway) +Globalization.ci_nb-SJ = Norwegian, Bokmål (Svalbard and Jan Mayen) +Globalization.ci_nd = North Ndebele +Globalization.ci_nd-ZW = North Ndebele (Zimbabwe) Globalization.ci_ne = Nepali +Globalization.ci_ne-IN = Nepali (India) Globalization.ci_ne-NP = Nepali (Nepal) Globalization.ci_nl = Dutch +Globalization.ci_nl-AW = Dutch (Aruba) Globalization.ci_nl-BE = Dutch (Belgium) +Globalization.ci_nl-BQ = Dutch (Bonaire, Sint Eustatius and Saba) +Globalization.ci_nl-CW = Dutch (Curaçao) Globalization.ci_nl-NL = Dutch (Netherlands) +Globalization.ci_nl-SR = Dutch (Suriname) +Globalization.ci_nl-SX = Dutch (Sint Maarten) +Globalization.ci_nmg = Kwasio +Globalization.ci_nmg-CM = Kwasio (Cameroon) Globalization.ci_nn = Norwegian (Nynorsk) Globalization.ci_nn-NO = Norwegian, Nynorsk (Norway) +Globalization.ci_nnh = Ngiemboon +Globalization.ci_nnh-CM = Ngiemboon (Cameroon) Globalization.ci_no = Norwegian +Globalization.ci_nqo = N'ko +Globalization.ci_nqo-GN = N'ko (Guinea) +Globalization.ci_nr = South Ndebele +Globalization.ci_nr-ZA = South Ndebele (South Africa) Globalization.ci_nso = Sesotho sa Leboa Globalization.ci_nso-ZA = Sesotho sa Leboa (South Africa) +Globalization.ci_nus = Nuer +Globalization.ci_nus-SD = Nuer (Sudan) +Globalization.ci_nus-SS = Nuer (South Sudan) +Globalization.ci_nyn = Nyankole +Globalization.ci_nyn-UG = Nyankole (Uganda) Globalization.ci_oc = Occitan Globalization.ci_oc-FR = Occitan (France) -Globalization.ci_or = Oriya -Globalization.ci_or-IN = Oriya (India) +Globalization.ci_om = Oromo +Globalization.ci_om-ET = Oromo (Ethiopia) +Globalization.ci_om-KE = Oromo (Kenya) +Globalization.ci_or = Odia +Globalization.ci_or-IN = Odia (India) +Globalization.ci_os = Ossetic +Globalization.ci_os-GE = Ossetian (Cyrillic, Georgia) +Globalization.ci_os-RU = Ossetian (Cyrillic, Russia) Globalization.ci_pa = Punjabi -Globalization.ci_oa-Arab = Punjabi (Arabic) +Globalization.ci_pa-Arab = Punjabi (Arabic) Globalization.ci_pa-Arab-PK = Punjabi (Islamic Republic of Pakistan) Globalization.ci_pa-IN = Punjabi (India) +Globalization.ci_pap = Papiamento +Globalization.ci_pap-029 = Papiamento (Caribbean) Globalization.ci_pl = Polish Globalization.ci_pl-PL = Polish (Poland) Globalization.ci_prs = Dari @@ -2603,11 +2957,25 @@ Globalization.ci_prs-AF = Dari (Afghanistan) Globalization.ci_ps = Pashto Globalization.ci_ps-AF = Pashto (Afghanistan) Globalization.ci_pt = Portuguese +Globalization.ci_pt-AO = Portuguese (Angola) Globalization.ci_pt-BR = Portuguese (Brazil) +Globalization.ci_pt-CV = Portuguese (Cabo Verde) +Globalization.ci_pt-GW = Portuguese (Guinea-Bissau) +Globalization.ci_pt-MO = Portuguese (Macao SAR) +Globalization.ci_pt-MZ = Portuguese (Mozambique) Globalization.ci_pt-PT = Portuguese (Portugal) +Globalization.ci_pt-ST = Portuguese (São Tomé and Príncipe) +Globalization.ci_pt-TL = Portuguese (Timor-Leste) Globalization.ci_qps-ploc = Pseudo Language (Pseudo) Globalization.ci_qps-ploca = Pseudo Language (Pseudo Asia) Globalization.ci_qps-plocm = Pseudo Language (Pseudo Mirrored) +Globalization.ci_qu = Quechua +Globalization.ci_qu-BO = Quechua (Bolivia) +Globalization.ci_qu-EC = Quechua (Ecuador) +Globalization.ci_qu-PE = Quechua (Peru) +Globalization.ci_quc = K'iche' +Globalization.ci_quc-Latn = K'iche' +Globalization.ci_quc-Latn-GT = K'iche' (Guatemala) Globalization.ci_qut = K'iche Globalization.ci_qut-GT = K'iche (Guatemala) Globalization.ci_quz = Quechua @@ -2616,23 +2984,52 @@ Globalization.ci_quz-EC = Quechua (Ecuador) Globalization.ci_quz-PE = Quechua (Peru) Globalization.ci_rm = Romansh Globalization.ci_rm-CH = Romansh (Switzerland) +Globalization.ci_rn = Rundi +Globalization.ci_rn-BI = Rundi (Burundi) Globalization.ci_ro = Romanian +Globalization.ci_ro-MD = Romanian (Moldova) Globalization.ci_ro-RO = Romanian (Romania) +Globalization.ci_rof = Rombo +Globalization.ci_rof-TZ = Rombo (Tanzania) Globalization.ci_ru = Russian +Globalization.ci_ru-BY = Russian (Belarus) +Globalization.ci_ru-KG = Russian (Kyrgyzstan) +Globalization.ci_ru-KZ = Russian (Kazakhstan) +Globalization.ci_ru-MD = Russian (Moldova) Globalization.ci_ru-RU = Russian (Russia) +Globalization.ci_ru-UA = Russian (Ukraine) Globalization.ci_rw = Kinyarwanda Globalization.ci_rw-RW = Kinyarwanda (Rwanda) +Globalization.ci_rwk = Rwa +Globalization.ci_rwk-TZ = Rwa (Tanzania) Globalization.ci_sa = Sanskrit Globalization.ci_sa-IN = Sanskrit (India) Globalization.ci_sah = Sakha Globalization.ci_sah-RU = Sakha (Russia) +Globalization.ci_saq = Samburu +Globalization.ci_saq-KE = Samburu (Kenya) +Globalization.ci_sbp = Sangu +Globalization.ci_sbp-TZ = Sangu (Tanzania) +Globalization.ci_sd = Sindhi +Globalization.ci_sd-Arab = Sindhi (Arabic) +Globalization.ci_sd-Arab-PK = Sindhi (Islamic Republic of Pakistan) +Globalization.ci_sd-Deva = Sindhi (Devanagari) +Globalization.ci_sd-Deva-IN = Sindhi (Devanagari, India) Globalization.ci_se = Sami (Northern) Globalization.ci_se-FI = Sami, Northern (Finland) Globalization.ci_se-NO = Sami, Northern (Norway) Globalization.ci_se-SE = Sami, Northern (Sweden) -Globalization.ci_sd = Sindhi -Globalization.ci_sd-Arab = Sindhi (Arabic) -Globalization.ci_sd-Arab-PK = Sindhi (Islamic Republic of Pakistan) +Globalization.ci_seh = Sena +Globalization.ci_seh-MZ = Sena (Mozambique) +Globalization.ci_ses = Koyraboro Senni +Globalization.ci_ses-ML = Koyraboro Senni (Mali) +Globalization.ci_sg = Sango +Globalization.ci_sg-CF = Sango (Central African Republic) +Globalization.ci_shi = Tachelhit +Globalization.ci_shi-Latn = Tachelhit (Latin) +Globalization.ci_shi-Latn-MA = Tachelhit (Latin, Morocco) +Globalization.ci_shi-Tfng = Tachelhit (Tifinagh) +Globalization.ci_shi-Tfng-MA = Tachelhit (Tifinagh, Morocco) Globalization.ci_si = Sinhala Globalization.ci_si-LK = Sinhala (Sri Lanka) Globalization.ci_sk = Slovak @@ -2649,8 +3046,19 @@ Globalization.ci_smn = Sami (Inari) Globalization.ci_smn-FI = Sami, Inari (Finland) Globalization.ci_sms = Sami (Skolt) Globalization.ci_sms-FI = Sami, Skolt (Finland) +Globalization.ci_sn = Shona +Globalization.ci_sn-Latn = Shona (Latin) +Globalization.ci_sn-Latn-ZW = Shona (Latin, Zimbabwe) +Globalization.ci_so = Somali +Globalization.ci_so-DJ = Somali (Djibouti) +Globalization.ci_so-ET = Somali (Ethiopia) +Globalization.ci_so-KE = Somali (Kenya) +Globalization.ci_so-SO = Somali (Somalia) Globalization.ci_sq = Albanian Globalization.ci_sq-AL = Albanian (Albania) +Globalization.ci_sq-MK = Albanian (Macedonia, FYRO) +Globalization.ci_sq-XK = Albanian (Kosovo) +Globalization.ci_sr-Cyrl-XK = Serbian (Cyrillic, Kosovo) Globalization.ci_sr = Serbian Globalization.ci_sr-Cyrl = Serbian (Cyrillic) Globalization.ci_sr-Cyrl-BA = Serbian (Cyrillic, Bosnia and Herzegovina) @@ -2662,18 +3070,38 @@ Globalization.ci_sr-Latn-BA = Serbian (Latin, Bosnia and Herzegovina) Globalization.ci_sr-Latn-CS = Serbian (Latin, Serbia and Montenegro (Former)) Globalization.ci_sr-Latn-ME = Serbian (Latin, Montenegro) Globalization.ci_sr-Latn-RS = Serbian (Latin, Serbia) +Globalization.ci_sr-Latn-XK = Serbian (Latin, Kosovo) +Globalization.ci_ss = Swati +Globalization.ci_ss-SZ = Swati (Swaziland) +Globalization.ci_ss-ZA = Swati (South Africa) +Globalization.ci_ssy = Saho +Globalization.ci_ssy-ER = Saho (Eritrea) +Globalization.ci_st = Southern Sotho +Globalization.ci_st-LS = Sesotho (Lesotho) +Globalization.ci_st-ZA = Southern Sotho (South Africa) Globalization.ci_sv = Swedish +Globalization.ci_sv-AX = Swedish (Åland Islands) Globalization.ci_sv-FI = Swedish (Finland) Globalization.ci_sv-SE = Swedish (Sweden) Globalization.ci_sw = Kiswahili +Globalization.ci_sw-CD = Kiswahili (Congo DRC) Globalization.ci_sw-KE = Kiswahili (Kenya) +Globalization.ci_sw-TZ = Kiswahili (Tanzania) +Globalization.ci_sw-UG = Kiswahili (Uganda) +Globalization.ci_swc = Congo Swahili +Globalization.ci_swc-CD = Congo Swahili (Congo DRC) Globalization.ci_syr = Syriac Globalization.ci_syr-SY = Syriac (Syria) Globalization.ci_ta = Tamil Globalization.ci_ta-IN = Tamil (India) Globalization.ci_ta-LK = Tamil (Sri Lanka) +Globalization.ci_ta-MY = Tamil (Malaysia) +Globalization.ci_ta-SG = Tamil (Singapore) Globalization.ci_te = Telugu Globalization.ci_te-IN = Telugu (India) +Globalization.ci_teo = Teso +Globalization.ci_teo-KE = Teso (Kenya) +Globalization.ci_teo-UG = Teso (Uganda) Globalization.ci_tg = Tajik Globalization.ci_tg-Cyrl = Tajik (Cyrillic) Globalization.ci_tg-Cyrl-TJ = Tajik (Cyrillic, Tajikistan) @@ -2682,18 +3110,30 @@ Globalization.ci_th-TH = Thai (Thailand) Globalization.ci_ti = Tigrinya Globalization.ci_ti-ER = Tigrinya (Eritrea) Globalization.ci_ti-ET = Tigrinya (Ethiopia) +Globalization.ci_tig = Tigre +Globalization.ci_tig-ER = Tigre (Eritrea) Globalization.ci_tk = Turkmen Globalization.ci_tk-TM = Turkmen (Turkmenistan) Globalization.ci_tn = Setswana Globalization.ci_tn-BW = Setswana (Botswana) Globalization.ci_tn-ZA = Setswana (South Africa) +Globalization.ci_to = Tongan +Globalization.ci_to-TO = Tongan (Tonga) Globalization.ci_tr = Turkish +Globalization.ci_tr-CY = Turkish (Cyprus) Globalization.ci_tr-TR = Turkish (Turkey) +Globalization.ci_ts = Tsonga +Globalization.ci_ts-ZA = Tsonga (South Africa) Globalization.ci_tt = Tatar Globalization.ci_tt-RU = Tatar (Russia) +Globalization.ci_twq = Tasawaq +Globalization.ci_twq-NE = Tasawaq (Niger) Globalization.ci_tzm = Tamazight +Globalization.ci_tzm-Arab = Central Atlas Tamazight (Arabic) +Globalization.ci_tzm-Arab-MA = Central Atlas Tamazight (Arabic, Morocco) Globalization.ci_tzm-Latn = Tamazight (Latin) Globalization.ci_tzm-Latn-DZ = Tamazight (Latin, Algeria) +Globalization.ci_tzm-Latn-MA = Central Atlas Tamazight (Latin, Morocco) Globalization.ci_tzm-Tfng = Tamazight (Tifinagh) Globalization.ci_tzm-Tfng-MA = Central Atlas Tamazight (Tifinagh, Morocco) Globalization.ci_ug = Uyghur @@ -2701,31 +3141,61 @@ Globalization.ci_ug-CN = Uyghur (PRC) Globalization.ci_uk = Ukrainian Globalization.ci_uk-UA = Ukrainian (Ukraine) Globalization.ci_ur = Urdu +Globalization.ci_ur-IN = Urdu (India) Globalization.ci_ur-PK = Urdu (Islamic Republic of Pakistan) Globalization.ci_uz = Uzbek +Globalization.ci_uz-Arab = Uzbek (Perso-Arabic) +Globalization.ci_uz-Arab-AF = Uzbek (Perso-Arabic, Afghanistan) Globalization.ci_uz-Cyrl = Uzbek (Cyrillic) Globalization.ci_uz-Cyrl-UZ = Uzbek (Cyrillic, Uzbekistan) Globalization.ci_uz-Latn = Uzbek (Latin) Globalization.ci_uz-Latn-UZ = Uzbek (Latin, Uzbekistan) +Globalization.ci_vai = Vai +Globalization.ci_vai-Latn = Vai (Latin) +Globalization.ci_vai-Latn-LR = Vai (Latin, Liberia) +Globalization.ci_vai-Vaii = Vai (Vai) +Globalization.ci_vai-Vaii-LR = Vai (Vai, Liberia) +Globalization.ci_ve = Venda +Globalization.ci_ve-ZA = Venda (South Africa) Globalization.ci_vi = Vietnamese Globalization.ci_vi-VN = Vietnamese (Vietnam) +Globalization.ci_vo = Volapük +Globalization.ci_vo-001 = Volapük (World) +Globalization.ci_vun = Vunjo +Globalization.ci_vun-TZ = Vunjo (Tanzania) +Globalization.ci_wae = Walser +Globalization.ci_wae-CH = Walser (Switzerland) +Globalization.ci_wal = Wolaytta +Globalization.ci_wal-ET = Wolaytta (Ethiopia) Globalization.ci_wo = Wolof Globalization.ci_wo-SN = Wolof (Senegal) Globalization.ci_x-IV = Invariant Language (Invariant Country) Globalization.ci_x-IV_mathan = Invariant Language (Invariant Country) Globalization.ci_xh = isiXhosa Globalization.ci_xh-ZA = isiXhosa (South Africa) +Globalization.ci_xog = Soga +Globalization.ci_xog-UG = Soga (Uganda) +Globalization.ci_yav = Yangben +Globalization.ci_yav-CM = Yangben (Cameroon) +Globalization.ci_yi = Yiddish +Globalization.ci_yi-001 = Yiddish (World) Globalization.ci_yo = Yoruba +Globalization.ci_yo-BJ = Yoruba (Benin) Globalization.ci_yo-NG = Yoruba (Nigeria) +Globalization.ci_zgh = Standard Moroccan Tamazight +Globalization.ci_zgh-Tfng = Standard Moroccan Tamazight (Tifinagh) +Globalization.ci_zgh-Tfng-MA = Standard Moroccan Tamazight (Tifinagh, Morocco) Globalization.ci_zh = Chinese Globalization.ci_zh-CHS = Chinese (Simplified) Legacy Globalization.ci_zh-CHT = Chinese (Traditional) Legacy Globalization.ci_zh-CN = Chinese (Simplified, PRC) Globalization.ci_zh-CN_stroke = Chinese (Simplified, PRC) -Globalization.ci_zh-HK = Chinese (Traditional, Hong Kong S.A.R.) -Globalization.ci_zh-HK_radstr = Chinese (Traditional, Hong Kong S.A.R.) Globalization.ci_zh-Hans = Chinese (Simplified) +Globalization.ci_zh-Hans-HK = Chinese (Simplified Han, Hong Kong SAR) +Globalization.ci_zh-Hans-MO = Chinese (Simplified Han, Macao SAR) Globalization.ci_zh-Hant = Chinese (Traditional) +Globalization.ci_zh-HK = Chinese (Traditional, Hong Kong S.A.R.) +Globalization.ci_zh-HK_radstr = Chinese (Traditional, Hong Kong S.A.R.) Globalization.ci_zh-MO = Chinese (Traditional, Macao S.A.R.) Globalization.ci_zh-MO_radstr = Chinese (Traditional, Macao S.A.R.) Globalization.ci_zh-MO_stroke = Chinese (Traditional, Macao S.A.R.) @@ -2740,35 +3210,69 @@ Globalization.ci_zu-ZA = isiZulu (South Africa) ; ;Total items: 129 ; +Globalization.ri_001 = World Globalization.ri_029 = Caribbean +Globalization.ri_150 = Europe +Globalization.ri_419 = Latin America +Globalization.ri_AD = Andorra Globalization.ri_AE = U.A.E. Globalization.ri_AF = Afghanistan +Globalization.ri_AG = Antigua and Barbuda +Globalization.ri_AI = Anguilla Globalization.ri_AL = Albania Globalization.ri_AM = Armenia +Globalization.ri_AO = Angola Globalization.ri_AR = Argentina +Globalization.ri_AS = American Samoa Globalization.ri_AT = Austria Globalization.ri_AU = Australia +Globalization.ri_AW = Aruba +Globalization.ri_AX = Åland Islands Globalization.ri_AZ = Azerbaijan Globalization.ri_BA = Bosnia and Herzegovina +Globalization.ri_BB = Barbados Globalization.ri_BD = Bangladesh Globalization.ri_BE = Belgium +Globalization.ri_BF = Burkina Faso Globalization.ri_BG = Bulgaria Globalization.ri_BH = Bahrain +Globalization.ri_BI = Burundi +Globalization.ri_BJ = Benin +Globalization.ri_BL = Saint Barthélemy +Globalization.ri_BM = Bermuda Globalization.ri_BN = Brunei Darussalam Globalization.ri_BO = Bolivia +Globalization.ri_BQ = Bonaire, Sint Eustatius and Saba Globalization.ri_BR = Brazil +Globalization.ri_BS = Bahamas +Globalization.ri_BT = Bhutan +Globalization.ri_BW = Botswana Globalization.ri_BY = Belarus Globalization.ri_BZ = Belize Globalization.ri_CA = Canada +Globalization.ri_CC = Cocos (Keeling) Islands +Globalization.ri_CD = Congo (DRC) +Globalization.ri_CF = Central African Republic +Globalization.ri_CG = Congo Globalization.ri_CH = Switzerland +Globalization.ri_CI = Côte d’Ivoire +Globalization.ri_CK = Cook Islands Globalization.ri_CL = Chile +Globalization.ri_CM = Cameroon Globalization.ri_CN = People's Republic of China Globalization.ri_CO = Colombia Globalization.ri_CR = Costa Rica Globalization.ri_CS = Serbia and Montenegro (Former) +Globalization.ri_CU = Cuba +Globalization.ri_CV = Cabo Verde +Globalization.ri_CW = Curaçao +Globalization.ri_CX = Christmas Island +Globalization.ri_CY = Cyprus Globalization.ri_CZ = Czech Republic Globalization.ri_DE = Germany +Globalization.ri_DJ = Djibouti Globalization.ri_DK = Denmark +Globalization.ri_DM = Dominica Globalization.ri_DO = Dominican Republic Globalization.ri_DZ = Algeria Globalization.ri_EC = Ecuador @@ -2778,96 +3282,181 @@ Globalization.ri_ER = Eritrea Globalization.ri_ES = Spain Globalization.ri_ET = Ethiopia Globalization.ri_FI = Finland +Globalization.ri_FJ = Fiji +Globalization.ri_FK = Falkland Islands +Globalization.ri_FM = Micronesia Globalization.ri_FO = Faroe Islands Globalization.ri_FR = France +Globalization.ri_GA = Gabon Globalization.ri_GB = United Kingdom +Globalization.ri_GD = Grenada Globalization.ri_GE = Georgia +Globalization.ri_GF = French Guiana +Globalization.ri_GG = Guernsey +Globalization.ri_GH = Ghana +Globalization.ri_GI = Gibraltar Globalization.ri_GL = Greenland +Globalization.ri_GM = Gambia +Globalization.ri_GN = Guinea +Globalization.ri_GP = Guadeloupe +Globalization.ri_GQ = Equatorial Guinea Globalization.ri_GR = Greece Globalization.ri_GT = Guatemala +Globalization.ri_GU = Guam +Globalization.ri_GW = Guinea-Bissau +Globalization.ri_GY = Guyana Globalization.ri_HK = Hong Kong S.A.R. Globalization.ri_HN = Honduras Globalization.ri_HR = Croatia +Globalization.ri_HT = Haiti Globalization.ri_HU = Hungary Globalization.ri_ID = Indonesia Globalization.ri_IE = Ireland Globalization.ri_IL = Israel Globalization.ri_IN = India +Globalization.ri_IM = Isle of Man +Globalization.ri_IO = British Indian Ocean Territory Globalization.ri_IQ = Iraq Globalization.ri_IR = Iran Globalization.ri_IS = Iceland Globalization.ri_IT = Italy Globalization.ri_IV = Invariant Country +Globalization.ri_JE = Jersey Globalization.ri_JM = Jamaica Globalization.ri_JO = Jordan Globalization.ri_JP = Japan Globalization.ri_KE = Kenya Globalization.ri_KG = Kyrgyzstan Globalization.ri_KH = Cambodia +Globalization.ri_KI = Kiribati +Globalization.ri_KM = Comoros +Globalization.ri_KN = Saint Kitts and Nevis Globalization.ri_KR = Korea Globalization.ri_KW = Kuwait +Globalization.ri_KY = Cayman Islands Globalization.ri_KZ = Kazakhstan Globalization.ri_LA = Lao P.D.R. Globalization.ri_LB = Lebanon +Globalization.ri_LC = Saint Lucia Globalization.ri_LI = Liechtenstein Globalization.ri_LK = Sri Lanka +Globalization.ri_LR = Liberia +Globalization.ri_LS = Lesotho Globalization.ri_LT = Lithuania Globalization.ri_LU = Luxembourg Globalization.ri_LV = Latvia Globalization.ri_LY = Libya Globalization.ri_MA = Morocco Globalization.ri_MC = Principality of Monaco +Globalization.ri_MD = Moldova Globalization.ri_ME = Montenegro +Globalization.ri_MF = Saint Martin +Globalization.ri_MG = Madagascar +Globalization.ri_MH = Marshall Islands Globalization.ri_MK = Macedonia (FYROM) +Globalization.ri_ML = Mali +Globalization.ri_MM = Myanmar Globalization.ri_MN = Mongolia Globalization.ri_MO = Macao S.A.R. +Globalization.ri_MP = Northern Mariana Islands +Globalization.ri_MQ = Martinique +Globalization.ri_MR = Mauritania +Globalization.ri_MS = Montserrat Globalization.ri_MT = Malta +Globalization.ri_MU = Mauritius Globalization.ri_MV = Maldives +Globalization.ri_MW = Malawi Globalization.ri_MX = Mexico Globalization.ri_MY = Malaysia +Globalization.ri_MZ = Mozambique +Globalization.ri_NA = Namibia +Globalization.ri_NC = New Caledonia +Globalization.ri_NE = Niger +Globalization.ri_NF = Norfolk Island Globalization.ri_NG = Nigeria Globalization.ri_NI = Nicaragua Globalization.ri_NL = Netherlands Globalization.ri_NO = Norway Globalization.ri_NP = Nepal +Globalization.ri_NR = Nauru +Globalization.ri_NU = Niue Globalization.ri_NZ = New Zealand Globalization.ri_OM = Oman Globalization.ri_PA = Panama Globalization.ri_PE = Peru +Globalization.ri_PF = French Polynesia +Globalization.ri_PG = Papua New Guinea Globalization.ri_PH = Philippines Globalization.ri_PK = Islamic Republic of Pakistan Globalization.ri_PL = Poland +Globalization.ri_PM = Saint Pierre and Miquelon +Globalization.ri_PN = Pitcairn Islands Globalization.ri_PR = Puerto Rico +Globalization.ri_PS = Palestinian Authority Globalization.ri_PT = Portugal +Globalization.ri_PW = Palau Globalization.ri_PY = Paraguay Globalization.ri_QA = Qatar +Globalization.ri_RE = Réunion Globalization.ri_RO = Romania Globalization.ri_RS = Serbia Globalization.ri_RU = Russia Globalization.ri_RW = Rwanda Globalization.ri_SA = Saudi Arabia +Globalization.ri_SB = Solomon Islands +Globalization.ri_SC = Seychelles +Globalization.ri_SD = Sudan Globalization.ri_SE = Sweden Globalization.ri_SG = Singapore +Globalization.ri_SH = St Helena, Ascension, Tristan da Cunha Globalization.ri_SI = Slovenia +Globalization.ri_SJ = Svalbard and Jan Mayen Globalization.ri_SK = Slovakia +Globalization.ri_SL = Sierra Leone +Globalization.ri_SM = San Marino Globalization.ri_SN = Senegal +Globalization.ri_SO = Somalia +Globalization.ri_SR = Suriname +Globalization.ri_SS = South Sudan +Globalization.ri_ST = São Tomé and Príncipe Globalization.ri_SV = El Salvador +Globalization.ri_SX = Sint Maarten Globalization.ri_SY = Syria +Globalization.ri_SZ = Swaziland +Globalization.ri_TC = Turks and Caicos Islands +Globalization.ri_TD = Chad +Globalization.ri_TG = Togo Globalization.ri_TH = Thailand Globalization.ri_TJ = Tajikistan +Globalization.ri_TK = Tokelau +Globalization.ri_TL = Timor-Leste Globalization.ri_TM = Turkmenistan Globalization.ri_TN = Tunisia +Globalization.ri_TO = Tonga Globalization.ri_TR = Turkey Globalization.ri_TT = Trinidad and Tobago +Globalization.ri_TV = Tuvalu Globalization.ri_TW = Taiwan +Globalization.ri_TZ = Tanzania Globalization.ri_UA = Ukraine +Globalization.ri_UG = Uganda +Globalization.ri_UM = U.S. Outlying Islands Globalization.ri_US = United States Globalization.ri_UY = Uruguay Globalization.ri_UZ = Uzbekistan +Globalization.ri_VC = Saint Vincent and the Grenadines Globalization.ri_VE = Bolivarian Republic of Venezuela +Globalization.ri_VG = British Virgin Islands +Globalization.ri_VI = U.S. Virgin Islands Globalization.ri_VN = Vietnam +Globalization.ri_VU = Vanuatu +Globalization.ri_WF = Wallis and Futuna +Globalization.ri_WS = Samoa +Globalization.ri_XK = Kosovo Globalization.ri_YE = Yemen +Globalization.ri_YT = Mayotte Globalization.ri_ZA = South Africa +Globalization.ri_ZM = Zambia Globalization.ri_ZW = Zimbabwe #endif //!FEATURE_CORECLR @@ -2879,6 +3468,12 @@ Globalization.ri_ZW = Zimbabwe Globalization.cp_1200 = Unicode Globalization.cp_1201 = Unicode (Big-Endian) Globalization.cp_65001 = Unicode (UTF-8) +Globalization.cp_65000 = Unicode (UTF-7) +Globalization.cp_12000 = Unicode (UTF-32) +Globalization.cp_12001 = Unicode (UTF-32 Big-Endian) +Globalization.cp_20127 = US-ASCII +Globalization.cp_28591 = Western European (ISO) + #if FEATURE_NON_UNICODE_CODE_PAGES Globalization.cp_37 = IBM EBCDIC (US-Canada) Globalization.cp_437 = OEM United States @@ -2945,8 +3540,6 @@ Globalization.cp_10029 = Central European (Mac) Globalization.cp_10079 = Icelandic (Mac) Globalization.cp_10081 = Turkish (Mac) Globalization.cp_10082 = Croatian (Mac) -Globalization.cp_12000 = Unicode (UTF-32) -Globalization.cp_12001 = Unicode (UTF-32 Big-Endian) Globalization.cp_20000 = Chinese Traditional (CNS) Globalization.cp_20001 = TCA Taiwan Globalization.cp_20002 = Chinese Traditional (Eten) @@ -2957,7 +3550,6 @@ Globalization.cp_20105 = Western European (IA5) Globalization.cp_20106 = German (IA5) Globalization.cp_20107 = Swedish (IA5) Globalization.cp_20108 = Norwegian (IA5) -Globalization.cp_20127 = US-ASCII Globalization.cp_20261 = T.61 Globalization.cp_20269 = ISO-6937 Globalization.cp_20273 = IBM EBCDIC (Germany) @@ -2984,7 +3576,6 @@ Globalization.cp_20949 = Korean Wansung Globalization.cp_21025 = IBM EBCDIC (Cyrillic Serbian-Bulgarian) Globalization.cp_21027 = Ext Alpha Lowercase Globalization.cp_21866 = Cyrillic (KOI8-U) -Globalization.cp_28591 = Western European (ISO) Globalization.cp_28592 = Central European (ISO) Globalization.cp_28593 = Latin 3 (ISO) Globalization.cp_28594 = Baltic (ISO) @@ -3025,9 +3616,12 @@ Globalization.cp_57008 = ISCII Kannada Globalization.cp_57009 = ISCII Malayalam Globalization.cp_57010 = ISCII Gujarati Globalization.cp_57011 = ISCII Punjabi -Globalization.cp_65000 = Unicode (UTF-7) #endif // FEATURE_NON_UNICODE_CODE_PAGES #endif // INCLUDE_DEBUG ;------------------ +; ValueTuple +ArgumentException_ValueTupleIncorrectType=Argument must be of type {0}. +ArgumentException_ValueTupleLastArgumentNotAValueTuple=The last element of an eight element ValueTuple must be a ValueTuple. + diff --git a/mscorlib/system/AggregateException.cs b/mscorlib/system/AggregateException.cs index 2a2561b05..5b442f254 100644 --- a/mscorlib/system/AggregateException.cs +++ b/mscorlib/system/AggregateException.cs @@ -7,7 +7,7 @@ // // AggregateException.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Public type to communicate multiple failures to an end-user. // diff --git a/mscorlib/system/AppContext/AppContext.cs b/mscorlib/system/AppContext/AppContext.cs index 0f8a02ac9..17d65f8db 100644 --- a/mscorlib/system/AppContext/AppContext.cs +++ b/mscorlib/system/AppContext/AppContext.cs @@ -8,6 +8,19 @@ namespace System { + + // + // The AppContext class consists of a collection of APIs that applications can use to reason about the context + // in which they are running. + // + // One of the APIs that are available to the application (and the framework) are the ones related to the + // configuration switches (SetSwitch, TryGetSwitch). Those APIs are used to set and retrieve the value of a switch. + // + // Inside the framework we use those APIs to provide backward compatibility for our in-place updates. In order for + // that to work in as many cases as possible we have intentionally coded the APIs to use very low level concepts. + // For instance, we are directly P/Invoking into the Registry calls and so that we don't initialize the infrastructure + // for accessing registry. Doing that would allow us to use AppContext switches inside the Registry code. + // public static class AppContext { [Flags] @@ -18,7 +31,13 @@ private enum SwitchValueState HasLookedForOverride = 0x4, UnknownValue = 0x8 // Has no default and could not find an override } + + // The Dictionary is intentionally left without specifying the comparer. StringComparer.Ordinal for instance will + // end up pulling in Globalization since all StringComparers are initialized in the static constructor (including the + // ones that use CultureInfo). + // Not specifying a comparer means that the dictionary will end up with a GenericEqualityComparer<string> comparer private static readonly Dictionary<string, SwitchValueState> s_switchMap = new Dictionary<string, SwitchValueState>(); + private static volatile bool s_defaultsInitialized = false; public static string BaseDirectory { @@ -33,12 +52,38 @@ public static string BaseDirectory } } + public static string TargetFrameworkName + { + get + { + // Forward the value that is set on the current domain. + return AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName; + } + } + +#if FEATURE_CORECLR + [System.Security.SecuritySafeCritical] +#endif + public static object GetData(string name) + { + return AppDomain.CurrentDomain.GetData(name); + } + #region Switch APIs - static AppContext() + private static void InitializeDefaultSwitchValues() { - // populate the AppContext with the default set of values - AppContextDefaultValues.PopulateDefaultValues(); + // To save a method call into this method, we are first checking + // the value of s_defaultsInitialized in the caller. + lock (s_switchMap) + { + if (s_defaultsInitialized == false) + { + // populate the AppContext with the default set of values + AppContextDefaultValues.PopulateDefaultValues(); + s_defaultsInitialized = true; + } + } } /// <summary> @@ -54,6 +99,14 @@ public static bool TryGetSwitch(string switchName, out bool isEnabled) if (switchName.Length == 0) throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "switchName"); + if (s_defaultsInitialized == false) + { + InitializeDefaultSwitchValues(); + } +#if DEBUG + BCLDebug.Assert(s_defaultsInitialized == true, "AppContext defaults should have been initialized."); +#endif + // By default, the switch is not enabled. isEnabled = false; @@ -150,6 +203,14 @@ public static void SetSwitch(string switchName, bool isEnabled) if (switchName.Length == 0) throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "switchName"); + if (s_defaultsInitialized == false) + { + InitializeDefaultSwitchValues(); + } +#if DEBUG + BCLDebug.Assert(s_defaultsInitialized == true, "AppContext defaults should have been initialized."); +#endif + SwitchValueState switchValue = (isEnabled ? SwitchValueState.HasTrueValue : SwitchValueState.HasFalseValue) | SwitchValueState.HasLookedForOverride; lock (s_switchMap) @@ -161,13 +222,30 @@ public static void SetSwitch(string switchName, bool isEnabled) /// <summary> /// This method is going to be called from the AppContextDefaultValues class when setting up the - /// default values for the switches. !!!! This method is called during the static constructor so it does not - /// take a lock !!!! If you are planning to use this outside of that, please ensure proper locking. + /// default values for the switches. /// </summary> internal static void DefineSwitchDefault(string switchName, bool isEnabled) { +#if DEBUG + BCLDebug.Assert(System.Threading.Monitor.IsEntered(s_switchMap), "Expected the method to be called within a lock"); +#endif + s_switchMap[switchName] = isEnabled ? SwitchValueState.HasTrueValue : SwitchValueState.HasFalseValue; } + + /// <summary> + /// This method is going to be called from the AppContextDefaultValues class when setting up the + /// override default values for the switches. + /// </summary> + internal static void DefineSwitchOverride(string switchName, bool isEnabled) + { +#if DEBUG + BCLDebug.Assert(System.Threading.Monitor.IsEntered(s_switchMap), "Expected the method to be called within a lock"); +#endif + + s_switchMap[switchName] = (isEnabled ? SwitchValueState.HasTrueValue : SwitchValueState.HasFalseValue) + | SwitchValueState.HasLookedForOverride; + } #endregion } } diff --git a/mscorlib/system/AppContext/AppContextDefaultValues.Defaults.cs b/mscorlib/system/AppContext/AppContextDefaultValues.Defaults.cs index d934f6ac1..90819c4c8 100644 --- a/mscorlib/system/AppContext/AppContextDefaultValues.Defaults.cs +++ b/mscorlib/system/AppContext/AppContextDefaultValues.Defaults.cs @@ -1,4 +1,4 @@ -// ==++== +// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // @@ -15,9 +15,9 @@ internal static partial class AppContextDefaultValues internal static readonly string SwitchPreserveEventListnerObjectIdentity = "Switch.System.Diagnostics.EventSource.PreserveEventListnerObjectIdentity"; internal static readonly string SwitchUseLegacyPathHandling = "Switch.System.IO.UseLegacyPathHandling"; internal static readonly string SwitchBlockLongPaths = "Switch.System.IO.BlockLongPaths"; + internal static readonly string SwitchDoNotAddrOfCspParentWindowHandle = "Switch.System.Security.Cryptography.DoNotAddrOfCspParentWindowHandle"; internal static readonly string SwitchSetActorAsReferenceWhenCopyingClaimsIdentity = "Switch.System.Security.ClaimsIdentity.SetActorAsReferenceWhenCopyingClaimsIdentity"; - // This is a partial method. Platforms can provide an implementation of it that will set override values // from whatever mechanism is available on that platform. If no implementation is provided, the compiler is going to remove the calls // to it from the code @@ -52,6 +52,11 @@ static partial void PopulateDefaultValuesPartial(string platformIdentifier, stri AppContext.DefineSwitchDefault(SwitchSetActorAsReferenceWhenCopyingClaimsIdentity, true); } + if (version <= 40602) + { + AppContext.DefineSwitchDefault(SwitchDoNotAddrOfCspParentWindowHandle, true); + } + break; } case "WindowsPhone": @@ -63,6 +68,7 @@ static partial void PopulateDefaultValuesPartial(string platformIdentifier, stri AppContext.DefineSwitchDefault(SwitchThrowExceptionIfDisposedCancellationTokenSource, true); AppContext.DefineSwitchDefault(SwitchUseLegacyPathHandling, true); AppContext.DefineSwitchDefault(SwitchBlockLongPaths, true); + AppContext.DefineSwitchDefault(SwitchDoNotAddrOfCspParentWindowHandle, true); } break; } diff --git a/mscorlib/system/AppContext/AppContextDefaultValues.DesktopOverrides.cs b/mscorlib/system/AppContext/AppContextDefaultValues.DesktopOverrides.cs index 56e7e7873..2b5055ddc 100644 --- a/mscorlib/system/AppContext/AppContextDefaultValues.DesktopOverrides.cs +++ b/mscorlib/system/AppContext/AppContextDefaultValues.DesktopOverrides.cs @@ -5,6 +5,7 @@ // ==--== using Microsoft.Win32; +using Microsoft.Win32.SafeHandles; using System; using System.Collections.Generic; using System.Diagnostics; @@ -55,7 +56,7 @@ static partial void PopulateOverrideValuesPartial() if (bool.TryParse(value, out switchValue)) { // If multiple switches have the same name, the last value that we find will win. - AppContext.SetSwitch(name, switchValue); + AppContext.DefineSwitchOverride(name, switchValue); } } previousSemicolonPos = currentPos; @@ -96,10 +97,10 @@ static partial void TryGetSwitchOverridePartial(string switchName, ref bool over overrideFound = false; // Read the value from the registry if we can (ie. the key exists) - if (s_switchesRegKey != null) + if (s_errorReadingRegistry != true) { // try to read it from the registry key and return null if the switch name is not found - valueFromConfig = s_switchesRegKey.GetValue(switchName, (string)null) as string; + valueFromConfig = GetSwitchValueFromRegistry(switchName); } // Note: valueFromConfig will be null only if the key is not found. @@ -118,19 +119,44 @@ static partial void TryGetSwitchOverridePartial(string switchName, ref bool over } } - // Cached registry key used to read value overrides from the registry - private static RegistryKey s_switchesRegKey = OpenRegKeyNoThrow(); - - /// <summary> - /// Opens the registry key where the switches are stored and returns null if there is an issue opening the key - /// </summary> - private static RegistryKey OpenRegKeyNoThrow() + private volatile static bool s_errorReadingRegistry; + [SecuritySafeCritical] + private static string GetSwitchValueFromRegistry(string switchName) { + // + // We are using P/Invokes directly instead of using the RegistryKey class to avoid pulling in the + // globalization stack that is required by RegistryKey. + // + const string REG_KEY_APPCONTEXT = @"SOFTWARE\Microsoft\.NETFramework\AppContext"; try { - return Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework\AppContext"); + using (SafeRegistryHandle hklm = new SafeRegistryHandle((IntPtr)RegistryHive.LocalMachine, true)) + { + SafeRegistryHandle hkey = null; + + if (Win32Native.RegOpenKeyEx(hklm, REG_KEY_APPCONTEXT, 0, Win32Native.KEY_READ, out hkey) == 0) + { + int size = 6; // "false".Length+1 + int type = 0; + System.Text.StringBuilder keyBuffer = new System.Text.StringBuilder((int)size); + if (Win32Native.RegQueryValueEx(hkey, switchName, null, ref type, keyBuffer, ref size) == 0) + { + return keyBuffer.ToString(); + } + } + else + { + // If we could not open the AppContext key, don't try it again. + s_errorReadingRegistry = true; + } + } } - catch { return null; } + catch + { + // If there was an error, flag it so that we don't try this again. + s_errorReadingRegistry = true; + } + return null; } } } diff --git a/mscorlib/system/AppContext/AppContextSwitches.cs b/mscorlib/system/AppContext/AppContextSwitches.cs index 72eb1cccb..8a4018b39 100644 --- a/mscorlib/system/AppContext/AppContextSwitches.cs +++ b/mscorlib/system/AppContext/AppContextSwitches.cs @@ -83,6 +83,16 @@ public static bool SetActorAsReferenceWhenCopyingClaimsIdentity } } + private static int _doNotAddrOfCspParentWindowHandle; + public static bool DoNotAddrOfCspParentWindowHandle + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return GetCachedSwitchValue(AppContextDefaultValues.SwitchDoNotAddrOfCspParentWindowHandle, ref _doNotAddrOfCspParentWindowHandle); + } + } + // // Implementation details // diff --git a/mscorlib/system/Lazy.cs b/mscorlib/system/Lazy.cs index 41de24814..edb3f9e93 100644 --- a/mscorlib/system/Lazy.cs +++ b/mscorlib/system/Lazy.cs @@ -8,7 +8,7 @@ // // Lazy.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // -------------------------------------------------------------------------------------- // @@ -431,7 +431,7 @@ private Boxed CreateValue() } else if (factory == ALREADY_INVOKED_SENTINEL) { - // Another thread ----d with us and beat us to successfully invoke the factory. + // Another thread raced with us and beat us to successfully invoke the factory. return null; } boxed = new Boxed(factory()); diff --git a/mscorlib/system/appdomain.cs b/mscorlib/system/appdomain.cs index 2a704e830..0b475ce30 100644 --- a/mscorlib/system/appdomain.cs +++ b/mscorlib/system/appdomain.cs @@ -7,7 +7,7 @@ ** ** Class: AppDomain ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Domains represent an application within the runtime. Objects can @@ -643,6 +643,16 @@ internal String GetTargetFrameworkName() return targetFrameworkName; } + [SecuritySafeCritical] + private void SetTargetFrameworkName(string targetFrameworkName) + { + if (!_FusionStore.CheckedForTargetFrameworkName) + { + _FusionStore.TargetFrameworkName = targetFrameworkName; + _FusionStore.CheckedForTargetFrameworkName = true; + } + } + /// <summary> /// Returns the setting of the corresponding compatibility config switch (see CreateAppDomainManager for the impact). /// </summary> @@ -3503,6 +3513,10 @@ private void SetupFusionStore(AppDomainSetup info, AppDomainSetup oldInfo) { Contract.Requires(info != null); + // Setup the fusion store so that further calls can use the information stored there + // Changes to info should persist to _FusionStore as this is a reference assignment + _FusionStore = info; + #if FEATURE_FUSION if (oldInfo == null) { @@ -3565,11 +3579,6 @@ private void SetupFusionStore(AppDomainSetup info, AppDomainSetup oldInfo) if (info.LoaderOptimization != LoaderOptimization.NotSpecified || (oldInfo != null && info.LoaderOptimization != oldInfo.LoaderOptimization)) UpdateLoaderOptimization(info.LoaderOptimization); #endif - - - - // This must be the last action taken - _FusionStore = info; } // used to package up evidence, so it can be serialized @@ -3740,7 +3749,7 @@ private static Object Setup(Object arg) for (int i=0; i<propertyNames.Length; i++) { - if(propertyNames[i]=="APPBASE") // make sure in [....] with Fusion + if(propertyNames[i]=="APPBASE") // make sure in sync with Fusion { if(propertyValues[i]==null) throw new ArgumentNullException("APPBASE"); @@ -4171,7 +4180,7 @@ private void SetupDomain(bool allowRedirects, String path, String configFile, St // in via the default domain properties. That restriction could be lifted // in a future release, at which point this assert should be removed. // - // This should be kept in [....] with the real externally facing filter code + // This should be kept in sync with the real externally facing filter code // in CorHost2::SetPropertiesForDefaultAppDomain BCLDebug.Assert(false, "Unexpected default domain property"); } diff --git a/mscorlib/system/appdomainattributes.cs b/mscorlib/system/appdomainattributes.cs index 52abb4ce8..ec913e797 100644 --- a/mscorlib/system/appdomainattributes.cs +++ b/mscorlib/system/appdomainattributes.cs @@ -7,7 +7,7 @@ ** ** File: AppDomainAttributes ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: For AppDomain-related custom attributes. diff --git a/mscorlib/system/appdomainunloadedexception.cs b/mscorlib/system/appdomainunloadedexception.cs index 6c21cf0ba..b0518f6ed 100644 --- a/mscorlib/system/appdomainunloadedexception.cs +++ b/mscorlib/system/appdomainunloadedexception.cs @@ -7,7 +7,7 @@ ** ** Class: AppDomainUnloadedException ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception class for attempt to access an unloaded AppDomain diff --git a/mscorlib/system/argiterator.cs b/mscorlib/system/argiterator.cs index 9edb731f1..56b67d05c 100644 --- a/mscorlib/system/argiterator.cs +++ b/mscorlib/system/argiterator.cs @@ -13,7 +13,7 @@ namespace System { // This class will not be marked serializable // Note: This type must have the same layout as the CLR's VARARGS type in CLRVarArgs.h. - // It also contains an inline SigPointer data structure - must keep those fields in [....]. + // It also contains an inline SigPointer data structure - must keep those fields in sync. [StructLayout(LayoutKind.Sequential)] public struct ArgIterator { diff --git a/mscorlib/system/array.cs b/mscorlib/system/array.cs index 7c767692f..3c678360d 100644 --- a/mscorlib/system/array.cs +++ b/mscorlib/system/array.cs @@ -618,7 +618,7 @@ private static int GetMedian(int low, int hi) { // We impose limits on maximum array lenght in each dimension to allow efficient // implementation of advanced range check elimination in future. - // Keep in [....] with vm\gcscan.cpp and HashHelpers.MaxPrimeArrayLength. + // Keep in sync with vm\gcscan.cpp and HashHelpers.MaxPrimeArrayLength. // The constants are defined in this method: inline SIZE_T MaxArrayLength(SIZE_T componentSize) from gcscan // We have different max sizes for arrays with elements of size 1 for backwards compatibility internal const int MaxArrayLength = 0X7FEFFFFF; diff --git a/mscorlib/system/badimageformatexception.cs b/mscorlib/system/badimageformatexception.cs index 442639c09..19783eb44 100644 --- a/mscorlib/system/badimageformatexception.cs +++ b/mscorlib/system/badimageformatexception.cs @@ -12,7 +12,7 @@ ** ** ===========================================================*/ -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System { diff --git a/mscorlib/system/cannotunloadappdomainexception.cs b/mscorlib/system/cannotunloadappdomainexception.cs index 1f3b6ff37..6c9df903f 100644 --- a/mscorlib/system/cannotunloadappdomainexception.cs +++ b/mscorlib/system/cannotunloadappdomainexception.cs @@ -7,7 +7,7 @@ ** ** Class: CannotUnloadAppDomainException ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception class for failed attempt to unload an AppDomain. diff --git a/mscorlib/system/collections/Concurrent/CDSCollectionETWBCLProvider.cs b/mscorlib/system/collections/Concurrent/CDSCollectionETWBCLProvider.cs index 318794b7f..793a0d9f1 100644 --- a/mscorlib/system/collections/Concurrent/CDSCollectionETWBCLProvider.cs +++ b/mscorlib/system/collections/Concurrent/CDSCollectionETWBCLProvider.cs @@ -7,7 +7,7 @@ // // CDSCollectionETWBCLProvider.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A helper class for firing ETW events related to the Coordination Data Structure // collection types. This provider is used by CDS collections in both mscorlib.dll diff --git a/mscorlib/system/collections/Concurrent/ConcurrentDictionary.cs b/mscorlib/system/collections/Concurrent/ConcurrentDictionary.cs index 61a88f102..90f183261 100644 --- a/mscorlib/system/collections/Concurrent/ConcurrentDictionary.cs +++ b/mscorlib/system/collections/Concurrent/ConcurrentDictionary.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================ ** ** Class: ConcurrentDictionary diff --git a/mscorlib/system/collections/Concurrent/ConcurrentQueue.cs b/mscorlib/system/collections/Concurrent/ConcurrentQueue.cs index eb7aeb2d7..9a17c4436 100644 --- a/mscorlib/system/collections/Concurrent/ConcurrentQueue.cs +++ b/mscorlib/system/collections/Concurrent/ConcurrentQueue.cs @@ -9,7 +9,7 @@ // // ConcurrentQueue.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A lock-free, concurrent queue primitive, and its associated debugger view type. // diff --git a/mscorlib/system/collections/Concurrent/ConcurrentStack.cs b/mscorlib/system/collections/Concurrent/ConcurrentStack.cs index dbadcc311..8e5821f55 100644 --- a/mscorlib/system/collections/Concurrent/ConcurrentStack.cs +++ b/mscorlib/system/collections/Concurrent/ConcurrentStack.cs @@ -9,7 +9,7 @@ // // ConcurrentStack.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A lock-free, concurrent stack primitive, and its associated debugger view type. // diff --git a/mscorlib/system/collections/Concurrent/IProducerConsumerCollection.cs b/mscorlib/system/collections/Concurrent/IProducerConsumerCollection.cs index d8b1a0bf1..6ed2935c8 100644 --- a/mscorlib/system/collections/Concurrent/IProducerConsumerCollection.cs +++ b/mscorlib/system/collections/Concurrent/IProducerConsumerCollection.cs @@ -7,7 +7,7 @@ // // IProducerConsumerCollection.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A common interface for all concurrent collections. // diff --git a/mscorlib/system/collections/Concurrent/OrderablePartitioner.cs b/mscorlib/system/collections/Concurrent/OrderablePartitioner.cs index 82419f629..aaf92c0fc 100644 --- a/mscorlib/system/collections/Concurrent/OrderablePartitioner.cs +++ b/mscorlib/system/collections/Concurrent/OrderablePartitioner.cs @@ -7,7 +7,7 @@ // // OrderablePartitioner.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // // diff --git a/mscorlib/system/collections/Concurrent/Partitioner.cs b/mscorlib/system/collections/Concurrent/Partitioner.cs index 7b683d247..095777506 100644 --- a/mscorlib/system/collections/Concurrent/Partitioner.cs +++ b/mscorlib/system/collections/Concurrent/Partitioner.cs @@ -7,7 +7,7 @@ // // Partitioner.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Represents a particular way of splitting a collection into multiple partitions. // diff --git a/mscorlib/system/collections/Concurrent/PartitionerStatic.cs b/mscorlib/system/collections/Concurrent/PartitionerStatic.cs index a0c3d19c8..20c1ac593 100644 --- a/mscorlib/system/collections/Concurrent/PartitionerStatic.cs +++ b/mscorlib/system/collections/Concurrent/PartitionerStatic.cs @@ -8,7 +8,7 @@ // // PartitionerStatic.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A class of default partitioners for Partitioner<TSource> // diff --git a/mscorlib/system/collections/arraylist.cs b/mscorlib/system/collections/arraylist.cs index ac2b660cf..c980dc136 100644 --- a/mscorlib/system/collections/arraylist.cs +++ b/mscorlib/system/collections/arraylist.cs @@ -7,7 +7,7 @@ ** ** Class: ArrayList ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Implements a dynamically sized List as an array, diff --git a/mscorlib/system/collections/bitarray.cs b/mscorlib/system/collections/bitarray.cs index dfe421f31..67acd6a07 100644 --- a/mscorlib/system/collections/bitarray.cs +++ b/mscorlib/system/collections/bitarray.cs @@ -7,7 +7,7 @@ ** ** Class: BitArray ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: The BitArray class manages a compact array of bit values. diff --git a/mscorlib/system/collections/caseinsensitivecomparer.cs b/mscorlib/system/collections/caseinsensitivecomparer.cs index c6d46c109..9e584ea82 100644 --- a/mscorlib/system/collections/caseinsensitivecomparer.cs +++ b/mscorlib/system/collections/caseinsensitivecomparer.cs @@ -7,7 +7,7 @@ ** ** Class: CaseInsensitiveComparer ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** diff --git a/mscorlib/system/collections/caseinsensitivehashcodeprovider.cs b/mscorlib/system/collections/caseinsensitivehashcodeprovider.cs index c9a9fd5c9..e9d24edc9 100644 --- a/mscorlib/system/collections/caseinsensitivehashcodeprovider.cs +++ b/mscorlib/system/collections/caseinsensitivehashcodeprovider.cs @@ -7,7 +7,7 @@ ** ** Class: CaseInsensitiveHashCodeProvider ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Designed to support hashtables which require diff --git a/mscorlib/system/collections/collectionbase.cs b/mscorlib/system/collections/collectionbase.cs index 52355ea4c..02ea374d2 100644 --- a/mscorlib/system/collections/collectionbase.cs +++ b/mscorlib/system/collections/collectionbase.cs @@ -5,7 +5,7 @@ // ==--== //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Collections { diff --git a/mscorlib/system/collections/comparer.cs b/mscorlib/system/collections/comparer.cs index 89a67deff..4509457f8 100644 --- a/mscorlib/system/collections/comparer.cs +++ b/mscorlib/system/collections/comparer.cs @@ -7,7 +7,7 @@ ** ** Class: Comparer ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Default IComparer implementation. diff --git a/mscorlib/system/collections/compatiblecomparer.cs b/mscorlib/system/collections/compatiblecomparer.cs index a19337c90..92760855b 100644 --- a/mscorlib/system/collections/compatiblecomparer.cs +++ b/mscorlib/system/collections/compatiblecomparer.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System.Diagnostics.Contracts; diff --git a/mscorlib/system/collections/dictionarybase.cs b/mscorlib/system/collections/dictionarybase.cs index 022cc7355..a8bfc680c 100644 --- a/mscorlib/system/collections/dictionarybase.cs +++ b/mscorlib/system/collections/dictionarybase.cs @@ -5,7 +5,7 @@ // ==--== //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Collections { diff --git a/mscorlib/system/collections/dictionaryentry.cs b/mscorlib/system/collections/dictionaryentry.cs index fe2e34148..34ccbc28c 100644 --- a/mscorlib/system/collections/dictionaryentry.cs +++ b/mscorlib/system/collections/dictionaryentry.cs @@ -7,7 +7,7 @@ ** ** Interface: DictionaryEntry ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Return Value for IDictionaryEnumerator::GetEntry diff --git a/mscorlib/system/collections/emptyreadonlydictionaryinternal.cs b/mscorlib/system/collections/emptyreadonlydictionaryinternal.cs index da84bb45f..5fab81ba4 100644 --- a/mscorlib/system/collections/emptyreadonlydictionaryinternal.cs +++ b/mscorlib/system/collections/emptyreadonlydictionaryinternal.cs @@ -7,7 +7,7 @@ ** ** Class: EmptyReadOnlyDictionaryInternal ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: List for exceptions. diff --git a/mscorlib/system/collections/generic/arraysorthelper.cs b/mscorlib/system/collections/generic/arraysorthelper.cs index 961482b65..6fa9b12e3 100644 --- a/mscorlib/system/collections/generic/arraysorthelper.cs +++ b/mscorlib/system/collections/generic/arraysorthelper.cs @@ -7,7 +7,7 @@ ** ** Class: ArraySortHelper ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: class to sort arrays diff --git a/mscorlib/system/collections/generic/comparer.cs b/mscorlib/system/collections/generic/comparer.cs index ec1fcd681..275b0c496 100644 --- a/mscorlib/system/collections/generic/comparer.cs +++ b/mscorlib/system/collections/generic/comparer.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/collections/generic/debugview.cs b/mscorlib/system/collections/generic/debugview.cs index e82dda98c..ac847ec06 100644 --- a/mscorlib/system/collections/generic/debugview.cs +++ b/mscorlib/system/collections/generic/debugview.cs @@ -9,7 +9,7 @@ ** ** Purpose: DebugView class for generic collections ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** =============================================================================*/ diff --git a/mscorlib/system/collections/generic/dictionary.cs b/mscorlib/system/collections/generic/dictionary.cs index 74859fa7f..92b7c2ac5 100644 --- a/mscorlib/system/collections/generic/dictionary.cs +++ b/mscorlib/system/collections/generic/dictionary.cs @@ -7,7 +7,7 @@ ** ** Class: Dictionary ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: Generic hash table implementation ** diff --git a/mscorlib/system/collections/generic/equalitycomparer.cs b/mscorlib/system/collections/generic/equalitycomparer.cs index 7064b3978..f3118216f 100644 --- a/mscorlib/system/collections/generic/equalitycomparer.cs +++ b/mscorlib/system/collections/generic/equalitycomparer.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/collections/generic/keynotfoundexception.cs b/mscorlib/system/collections/generic/keynotfoundexception.cs index 10477931a..c8afceb30 100644 --- a/mscorlib/system/collections/generic/keynotfoundexception.cs +++ b/mscorlib/system/collections/generic/keynotfoundexception.cs @@ -7,7 +7,7 @@ ** ** Class: KeyNotFoundException ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception class for Hashtable and Dictionary. diff --git a/mscorlib/system/collections/generic/keyvaluepair.cs b/mscorlib/system/collections/generic/keyvaluepair.cs index 24baeb3f2..d6e298ee5 100644 --- a/mscorlib/system/collections/generic/keyvaluepair.cs +++ b/mscorlib/system/collections/generic/keyvaluepair.cs @@ -7,7 +7,7 @@ ** ** Interface: KeyValuePair ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Generic key-value pair for dictionary enumerators. diff --git a/mscorlib/system/collections/generic/list.cs b/mscorlib/system/collections/generic/list.cs index 5803c382d..fbf8b5020 100644 --- a/mscorlib/system/collections/generic/list.cs +++ b/mscorlib/system/collections/generic/list.cs @@ -7,7 +7,7 @@ ** ** Class: List ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: Implements a generic, dynamically sized list as an ** array. diff --git a/mscorlib/system/collections/hashtable.cs b/mscorlib/system/collections/hashtable.cs index 6998dde77..162d92172 100644 --- a/mscorlib/system/collections/hashtable.cs +++ b/mscorlib/system/collections/hashtable.cs @@ -7,7 +7,7 @@ ** ** Class: Hashtable ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Hash table implementation diff --git a/mscorlib/system/collections/keyvaluepairs.cs b/mscorlib/system/collections/keyvaluepairs.cs index 345e2b506..06aeb0975 100644 --- a/mscorlib/system/collections/keyvaluepairs.cs +++ b/mscorlib/system/collections/keyvaluepairs.cs @@ -7,7 +7,7 @@ ** ** Class: KeyValuePairs ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: KeyValuePairs to display items in collection class under debugger diff --git a/mscorlib/system/collections/listdictionaryinternal.cs b/mscorlib/system/collections/listdictionaryinternal.cs index db4fe1d05..b24b03ba7 100644 --- a/mscorlib/system/collections/listdictionaryinternal.cs +++ b/mscorlib/system/collections/listdictionaryinternal.cs @@ -8,7 +8,7 @@ ** ** Class: ListDictionaryInternal ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: List for exceptions. diff --git a/mscorlib/system/collections/objectmodel/collection.cs b/mscorlib/system/collections/objectmodel/collection.cs index 6f8b53c88..81eda7eda 100644 --- a/mscorlib/system/collections/objectmodel/collection.cs +++ b/mscorlib/system/collections/objectmodel/collection.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Collections.ObjectModel diff --git a/mscorlib/system/collections/objectmodel/keyedcollection.cs b/mscorlib/system/collections/objectmodel/keyedcollection.cs index 014d889c4..6fb157925 100644 --- a/mscorlib/system/collections/objectmodel/keyedcollection.cs +++ b/mscorlib/system/collections/objectmodel/keyedcollection.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Collections.ObjectModel diff --git a/mscorlib/system/collections/objectmodel/readonlycollection.cs b/mscorlib/system/collections/objectmodel/readonlycollection.cs index 760349f81..30ab5372f 100644 --- a/mscorlib/system/collections/objectmodel/readonlycollection.cs +++ b/mscorlib/system/collections/objectmodel/readonlycollection.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Collections.ObjectModel diff --git a/mscorlib/system/collections/queue.cs b/mscorlib/system/collections/queue.cs index ba67a2a31..edfcd0873 100644 --- a/mscorlib/system/collections/queue.cs +++ b/mscorlib/system/collections/queue.cs @@ -7,7 +7,7 @@ ** ** Class: Queue ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: A circular-array implementation of a queue. ** diff --git a/mscorlib/system/collections/readonlycollectionbase.cs b/mscorlib/system/collections/readonlycollectionbase.cs index cf07d664e..c83271d24 100644 --- a/mscorlib/system/collections/readonlycollectionbase.cs +++ b/mscorlib/system/collections/readonlycollectionbase.cs @@ -5,7 +5,7 @@ // ==--== //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Collections { diff --git a/mscorlib/system/collections/sortedlist.cs b/mscorlib/system/collections/sortedlist.cs index bb7b853fa..6e50be2d2 100644 --- a/mscorlib/system/collections/sortedlist.cs +++ b/mscorlib/system/collections/sortedlist.cs @@ -7,7 +7,7 @@ ** ** Class: SortedList ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: A sorted dictionary. ** diff --git a/mscorlib/system/collections/stack.cs b/mscorlib/system/collections/stack.cs index 158089a62..de575ffbd 100644 --- a/mscorlib/system/collections/stack.cs +++ b/mscorlib/system/collections/stack.cs @@ -7,7 +7,7 @@ ** ** Class: Stack ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: An array implementation of a stack. ** @@ -30,7 +30,7 @@ public class Stack : ICollection, ICloneable { private Object[] _array; // Storage for stack elements [ContractPublicPropertyName("Count")] private int _size; // Number of items in the stack. - private int _version; // Used to keep enumerator in [....] w/ collection. + private int _version; // Used to keep enumerator in sync w/ collection. [NonSerialized] private Object _syncRoot; diff --git a/mscorlib/system/collections/structuralcomparisons.cs b/mscorlib/system/collections/structuralcomparisons.cs index 4d4252aaa..e5a1aa556 100644 --- a/mscorlib/system/collections/structuralcomparisons.cs +++ b/mscorlib/system/collections/structuralcomparisons.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/delegate.cs b/mscorlib/system/delegate.cs index 998b13fbd..3bc7e77bd 100644 --- a/mscorlib/system/delegate.cs +++ b/mscorlib/system/delegate.cs @@ -796,7 +796,7 @@ internal virtual Object GetTarget() } // These flags effect the way BindToMethodInfo and BindToMethodName are allowed to bind a delegate to a target method. Their - // values must be kept in [....] with the definition in vm\comdelegate.h. + // values must be kept in sync with the definition in vm\comdelegate.h. internal enum DelegateBindingFlags { StaticMethodOnly = 0x00000001, // Can only bind to static target methods diff --git a/mscorlib/system/diagnostics/contracts/contracts.cs b/mscorlib/system/diagnostics/contracts/contracts.cs index fe943007d..e2fc7888f 100644 --- a/mscorlib/system/diagnostics/contracts/contracts.cs +++ b/mscorlib/system/diagnostics/contracts/contracts.cs @@ -7,7 +7,7 @@ ** ** Class: Contract ** -** <OWNER>[....],mbarnett</OWNER> +** <OWNER>Microsoft,mbarnett</OWNER> ** ** Purpose: The contract class allows for expressing preconditions, ** postconditions, and object invariants about methods in source diff --git a/mscorlib/system/diagnostics/contracts/contractsbcl.cs b/mscorlib/system/diagnostics/contracts/contractsbcl.cs index 644e05605..d021a995d 100644 --- a/mscorlib/system/diagnostics/contracts/contractsbcl.cs +++ b/mscorlib/system/diagnostics/contracts/contractsbcl.cs @@ -7,7 +7,7 @@ ** ** Class: Contract ** -** <OWNER>maf,mbarnett,[....]</OWNER> +** <OWNER>maf,mbarnett,Microsoft</OWNER> ** ** Implementation details of CLR Contracts. ** diff --git a/mscorlib/system/diagnostics/eventing/TraceLogging/EventPayload.cs b/mscorlib/system/diagnostics/eventing/TraceLogging/EventPayload.cs index 3240a8d73..d3f21680c 100644 --- a/mscorlib/system/diagnostics/eventing/TraceLogging/EventPayload.cs +++ b/mscorlib/system/diagnostics/eventing/TraceLogging/EventPayload.cs @@ -95,7 +95,10 @@ public bool ContainsKey(string key) public IEnumerator<KeyValuePair<string, object>> GetEnumerator() { - throw new System.NotSupportedException(); + for (int i = 0; i < Keys.Count; i++) + { + yield return new KeyValuePair<string, object>(this.m_names[i], this.m_values[i]); + } } IEnumerator IEnumerable.GetEnumerator() diff --git a/mscorlib/system/diagnostics/eventing/activitytracker.cs b/mscorlib/system/diagnostics/eventing/activitytracker.cs index bdfa364fe..22be307d6 100644 --- a/mscorlib/system/diagnostics/eventing/activitytracker.cs +++ b/mscorlib/system/diagnostics/eventing/activitytracker.cs @@ -549,7 +549,7 @@ private static unsafe void WriteNibble(ref byte* ptr, byte* endPtr, uint value) } // This callback is used to initialize the m_current AsyncLocal Variable. - // Its job is to keep the ETW Activity ID (part of thread local storage) in [....] + // Its job is to keep the ETW Activity ID (part of thread local storage) in sync // with m_current.ActivityID void ActivityChanging(AsyncLocalValueChangedArgs<ActivityInfo> args) { diff --git a/mscorlib/system/diagnostics/eventing/eventdescriptor.cs b/mscorlib/system/diagnostics/eventing/eventdescriptor.cs index f8f4afe95..60eae4d2d 100644 --- a/mscorlib/system/diagnostics/eventing/eventdescriptor.cs +++ b/mscorlib/system/diagnostics/eventing/eventdescriptor.cs @@ -2,7 +2,7 @@ // <copyright file="etwprovider.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> //------------------------------------------------------------------------------ using System; using System.Runtime.InteropServices; diff --git a/mscorlib/system/diagnostics/eventing/eventsource.cs b/mscorlib/system/diagnostics/eventing/eventsource.cs index 9ae566937..6bc1f7685 100644 --- a/mscorlib/system/diagnostics/eventing/eventsource.cs +++ b/mscorlib/system/diagnostics/eventing/eventsource.cs @@ -1207,7 +1207,7 @@ protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, Guid* rel } #if FEATURE_ACTIVITYSAMPLING - // this code should be kept in [....] with WriteEventVarargs(). + // this code should be kept in sync with WriteEventVarargs(). SessionMask etwSessions = SessionMask.All; // only compute etwSessions if there are *any* ETW filters enabled... if ((ulong)m_curLiveSessions != 0) @@ -1938,7 +1938,7 @@ private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object } #if FEATURE_ACTIVITYSAMPLING - // this code should be kept in [....] with WriteEventWithRelatedActivityIdCore(). + // this code should be kept in sync with WriteEventWithRelatedActivityIdCore(). SessionMask etwSessions = SessionMask.All; // only compute etwSessions if there are *any* ETW filters enabled... if ((ulong)m_curLiveSessions != 0) @@ -1968,7 +1968,7 @@ private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object m_eventData[eventId].Descriptor.Level, m_eventData[eventId].Descriptor.Opcode, m_eventData[eventId].Descriptor.Task, - unchecked((long)(ulong)etwSessions | origKwd)); + unchecked((long)etwSessions.ToEventKeywords() | origKwd)); if (!m_provider.WriteEvent(ref desc, pActivityId, childActivityID, args)) ThrowEventSourceException(m_eventData[eventId].Name); @@ -1989,7 +1989,7 @@ private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object // EventSourceOptions opt = new EventSourceOptions { - Keywords = (EventKeywords)unchecked((long)(ulong)etwSessions | origKwd), + Keywords = (EventKeywords)unchecked((long)etwSessions.ToEventKeywords() | origKwd), Level = (EventLevel)m_eventData[eventId].Descriptor.Level, Opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode }; @@ -3109,6 +3109,11 @@ private unsafe bool SendManifest(byte[] rawManifest) dataLeft -= chunkSize; dataDescrs[1].Ptr += (uint)chunkSize; envelope.ChunkNumber++; + + // For large manifests we want to not overflow any receiver's buffer. Most manifests will fit within + // 5 chunks, so only the largest manifests will hit the pause. + if((envelope.ChunkNumber % 5) == 0) + Thread.Sleep(15); } } #endif @@ -4329,6 +4334,15 @@ public void DisableEvents(EventSource eventSource) eventSource.SendCommand(this, 0, 0, EventCommand.Update, false, EventLevel.LogAlways, EventKeywords.None, null); } + /// <summary> + /// EventSourceIndex is small non-negative integer (suitable for indexing in an array) + /// identifying EventSource. It is unique per-appdomain. Some EventListeners might find + /// it useful to store additional information about each eventSource connected to it, + /// and EventSourceIndex allows this extra information to be efficiently stored in a + /// (growable) array (eg List(T)). + /// </summary> + public static int EventSourceIndex(EventSource eventSource) { return eventSource.m_id; } + /// <summary> /// This method is called whenever a new eventSource is 'attached' to the dispatcher. /// This can happen for all existing EventSources when the EventListener is created @@ -4367,15 +4381,6 @@ internal protected virtual void OnEventWritten(EventWrittenEventArgs eventData) } } - /// <summary> - /// EventSourceIndex is small non-negative integer (suitable for indexing in an array) - /// identifying EventSource. It is unique per-appdomain. Some EventListeners might find - /// it useful to store additional information about each eventSource connected to it, - /// and EventSourceIndex allows this extra information to be efficiently stored in a - /// (growable) array (eg List(T)). - /// </summary> - static protected int EventSourceIndex(EventSource eventSource) { return eventSource.m_id; } - #region private /// <summary> /// This routine adds newEventSource to the global list of eventSources, it also assigns the diff --git a/mscorlib/system/diagnostics/eventing/frameworkeventsource.cs b/mscorlib/system/diagnostics/eventing/frameworkeventsource.cs index fbd51c70f..f20eaa19b 100644 --- a/mscorlib/system/diagnostics/eventing/frameworkeventsource.cs +++ b/mscorlib/system/diagnostics/eventing/frameworkeventsource.cs @@ -6,8 +6,8 @@ // // ResourcesEtwProvider.cs // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> // // Managed event source for things that can version with MSCORLIB. // diff --git a/mscorlib/system/exception.cs b/mscorlib/system/exception.cs index c1e9a3fad..bae8755d5 100644 --- a/mscorlib/system/exception.cs +++ b/mscorlib/system/exception.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // ==--== /*============================================================================= diff --git a/mscorlib/system/executionengineexception.cs b/mscorlib/system/executionengineexception.cs index 493228346..6e928d517 100644 --- a/mscorlib/system/executionengineexception.cs +++ b/mscorlib/system/executionengineexception.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // /*============================================================================= ** diff --git a/mscorlib/system/globalization/Persiancalendar.cs b/mscorlib/system/globalization/Persiancalendar.cs index cdcbe04a2..5eb368bac 100644 --- a/mscorlib/system/globalization/Persiancalendar.cs +++ b/mscorlib/system/globalization/Persiancalendar.cs @@ -13,7 +13,7 @@ namespace System.Globalization { // //////////////////////////////////////////////////////////////////////////// // Modern Persian calendar is a solar observation based calendar. Each new year begins on the day when the vernal equinox occurs before noon. - // The epoch is the date of the vernal equinox prior to the epoch of the Islamic calendar ([....] 19, 622 Julian or [....] 22, 622 Gregorian) + // The epoch is the date of the vernal equinox prior to the epoch of the Islamic calendar (Microsoft 19, 622 Julian or Microsoft 22, 622 Gregorian) // There is no Persian year 0. Ordinary years have 365 days. Leap years have 366 days with the last month (Esfand) gaining the extra day. /* diff --git a/mscorlib/system/globalization/calendar.cs b/mscorlib/system/globalization/calendar.cs index 44840fdca..9b0ca90b5 100644 --- a/mscorlib/system/globalization/calendar.cs +++ b/mscorlib/system/globalization/calendar.cs @@ -19,7 +19,7 @@ namespace System.Globalization { // , 46, 8, 20, 3, 1999) in the Gregorian calendar. An implementation of // Calendar can map any DateTime value to such an n-tuple and vice versa. The // DateTimeFormat class can map between such n-tuples and a textual - // representation such as "8:46 AM [....] 20th 1999 AD". + // representation such as "8:46 AM Microsoft 20th 1999 AD". // // Most calendars identify a year which begins the current era. There may be any // number of previous eras. The Calendar class identifies the eras as enumerated diff --git a/mscorlib/system/globalization/calendardata.cs b/mscorlib/system/globalization/calendardata.cs index 85d21351a..bc1761915 100644 --- a/mscorlib/system/globalization/calendardata.cs +++ b/mscorlib/system/globalization/calendardata.cs @@ -24,7 +24,7 @@ namespace System.Globalization // properties are available without locales using CalendarData.GetCalendar(int) // StructLayout is needed here otherwise compiler can re-arrange the fields. - // We have to keep this in-[....] with the definition in calendardata.h + // We have to keep this in-sync with the definition in calendardata.h // // WARNING WARNING WARNING // diff --git a/mscorlib/system/globalization/culturedata.cs b/mscorlib/system/globalization/culturedata.cs index b128980d0..ee166fccb 100644 --- a/mscorlib/system/globalization/culturedata.cs +++ b/mscorlib/system/globalization/culturedata.cs @@ -55,7 +55,7 @@ namespace System.Globalization // // StructLayout is needed here otherwise compiler can re-arrange the fields. - // We have to keep this in-[....] with the definition in comnlsinfo.h + // We have to keep this in-sync with the definition in comnlsinfo.h // // WARNING WARNING WARNING // diff --git a/mscorlib/system/globalization/cultureinfo.cs b/mscorlib/system/globalization/cultureinfo.cs index 07c0f1472..b3cf1c0cb 100644 --- a/mscorlib/system/globalization/cultureinfo.cs +++ b/mscorlib/system/globalization/cultureinfo.cs @@ -14,7 +14,7 @@ // as well as methods for common operations such as printing // dates and sorting strings. // -// Date: [....] 31, 1999 +// Date: Microsoft 31, 1999 // // // !!!! NOTE WHEN CHANGING THIS CLASS !!!! diff --git a/mscorlib/system/globalization/datetimeparse.cs b/mscorlib/system/globalization/datetimeparse.cs index c521139c1..95d5a81e2 100644 --- a/mscorlib/system/globalization/datetimeparse.cs +++ b/mscorlib/system/globalization/datetimeparse.cs @@ -5057,7 +5057,7 @@ internal enum TokenType { YearNumberToken = 2, // The number which is considered as year number, which has 3 or more digits. E.g. "2003" Am = 3, // AM timemark. E.g. "AM" Pm = 4, // PM timemark. E.g. "PM" - MonthToken = 5, // A word (or words) that represents a month name. E.g. "[....]" + MonthToken = 5, // A word (or words) that represents a month name. E.g. "Microsoft" EndOfString = 6, // End of string DayOfWeekToken = 7, // A word (or words) that represents a day of week name. E.g. "Monday" or "Mon" TimeZoneToken = 8, // A word that represents a timezone name. E.g. "GMT" diff --git a/mscorlib/system/globalization/eastasianlunisolarcalendar.cs b/mscorlib/system/globalization/eastasianlunisolarcalendar.cs index cab202119..893503413 100644 --- a/mscorlib/system/globalization/eastasianlunisolarcalendar.cs +++ b/mscorlib/system/globalization/eastasianlunisolarcalendar.cs @@ -303,7 +303,7 @@ internal void GregorianToLunar(int nSYear, int nSMonth, int nSDate, ref int nLYe // convert solar day into lunar day. // subtract off the beginning part of the solar year which is not // part of the lunar year. since this part is always in Jan or Feb, - // we don't need to handle Leap Year (LY only affects [....] + // we don't need to handle Leap Year (LY only affects Microsoft // and later). nLunarDay -= DaysToMonth365[nJan1Month-1]; nLunarDay -= (nJan1Date - 1); diff --git a/mscorlib/system/globalization/hebrewnumber.cs b/mscorlib/system/globalization/hebrewnumber.cs index 8c96b12e3..4bb6202e6 100644 --- a/mscorlib/system/globalization/hebrewnumber.cs +++ b/mscorlib/system/globalization/hebrewnumber.cs @@ -140,7 +140,7 @@ internal static String ToString(int Number) { cTens = '\x05db'; // Hebrew Letter Kaf break; case ( 3 ) : - cTens = '\x05dc'; // Hebrew Letter ----d + cTens = '\x05dc'; // Hebrew Letter Lamed break; case ( 4 ) : cTens = '\x05de'; // Hebrew Letter Mem @@ -256,7 +256,7 @@ internal HebrewValue(HebrewToken token, int value) { new HebrewValue(HebrewToken.Digit10, 10) , // '\x05d9; // Hebrew Letter Yod new HebrewValue(HebrewToken.Invalid, -1) , // '\x05da; new HebrewValue(HebrewToken.Digit10, 20) , // '\x05db; // Hebrew Letter Kaf - new HebrewValue(HebrewToken.Digit10, 30) , // '\x05dc; // Hebrew Letter ----d + new HebrewValue(HebrewToken.Digit10, 30) , // '\x05dc; // Hebrew Letter Lamed new HebrewValue(HebrewToken.Invalid, -1) , // '\x05dd; new HebrewValue(HebrewToken.Digit10, 40) , // '\x05de; // Hebrew Letter Mem new HebrewValue(HebrewToken.Invalid, -1) , // '\x05df; diff --git a/mscorlib/system/globalization/regioninfo.cs b/mscorlib/system/globalization/regioninfo.cs index c27177b8e..16503897c 100644 --- a/mscorlib/system/globalization/regioninfo.cs +++ b/mscorlib/system/globalization/regioninfo.cs @@ -14,7 +14,7 @@ // preferences of the user and does not depend on the user's // language or culture. // -// Date: [....] 31, 1999 +// Date: Microsoft 31, 1999 // //////////////////////////////////////////////////////////////////////////// diff --git a/mscorlib/system/globalization/stringinfo.cs b/mscorlib/system/globalization/stringinfo.cs index efd5cada4..f39ac8c43 100644 --- a/mscorlib/system/globalization/stringinfo.cs +++ b/mscorlib/system/globalization/stringinfo.cs @@ -11,7 +11,7 @@ // A writing system is the collection of scripts and // orthographic rules required to represent a language as text. // -// Date: [....] 31, 1999 +// Date: Microsoft 31, 1999 // //////////////////////////////////////////////////////////////////////////// diff --git a/mscorlib/system/globalization/taiwancalendar.cs b/mscorlib/system/globalization/taiwancalendar.cs index e2f2f3055..6ba1a3929 100644 --- a/mscorlib/system/globalization/taiwancalendar.cs +++ b/mscorlib/system/globalization/taiwancalendar.cs @@ -21,7 +21,7 @@ namespace System.Globalization { ** Gregorian 1912/01/01 9999/12/31 ** Taiwan 01/01/01 8088/12/31 ============================================================================*/ - + [System.Runtime.InteropServices.ComVisible(true)] [Serializable] public class TaiwanCalendar: Calendar { diff --git a/mscorlib/system/globalization/textelementenumerator.cs b/mscorlib/system/globalization/textelementenumerator.cs index 503a249df..57b17ae07 100644 --- a/mscorlib/system/globalization/textelementenumerator.cs +++ b/mscorlib/system/globalization/textelementenumerator.cs @@ -9,7 +9,7 @@ // // Purpose: // -// Date: [....] 31, 1999 +// Date: Microsoft 31, 1999 // //////////////////////////////////////////////////////////////////////////// diff --git a/mscorlib/system/globalization/textinfo.cs b/mscorlib/system/globalization/textinfo.cs index afef11223..783e2a1fc 100644 --- a/mscorlib/system/globalization/textinfo.cs +++ b/mscorlib/system/globalization/textinfo.cs @@ -11,7 +11,7 @@ // A writing system is the collection of scripts and // orthographic rules required to represent a language as text. // -// Date: [....] 31, 1999 +// Date: Microsoft 31, 1999 // //////////////////////////////////////////////////////////////////////////// diff --git a/mscorlib/system/globalization/timespanformat.cs b/mscorlib/system/globalization/timespanformat.cs index ae14266ab..23928c8e2 100644 --- a/mscorlib/system/globalization/timespanformat.cs +++ b/mscorlib/system/globalization/timespanformat.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Globalization { using System.Text; diff --git a/mscorlib/system/globalization/timespanparse.cs b/mscorlib/system/globalization/timespanparse.cs index 5ff183b7c..3e15ad940 100644 --- a/mscorlib/system/globalization/timespanparse.cs +++ b/mscorlib/system/globalization/timespanparse.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // //////////////////////////////////////////////////////////////////////////// // diff --git a/mscorlib/system/globalization/umalquracalendar.cs b/mscorlib/system/globalization/umalquracalendar.cs index d7ca8056a..7e8a4dde5 100644 --- a/mscorlib/system/globalization/umalquracalendar.cs +++ b/mscorlib/system/globalization/umalquracalendar.cs @@ -43,7 +43,7 @@ internal DateMapping(int MonthsLengthFlags, int GYear, int GMonth, int GDay) static DateMapping[] InitDateMapping() { short[] rawData = new short[] { -//These data is taken from Tables/Excel/UmAlQura.xls please make sure that the two places are in [....] +//These data is taken from Tables/Excel/UmAlQura.xls please make sure that the two places are in sync /* DaysPerM GY GM GD D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 1318*/0x02EA, 1900, 4, 30,/* 0 1 0 1 0 1 1 1 0 1 0 0 4/30/1900 1319*/0x06E9, 1901, 4, 19,/* 1 0 0 1 0 1 1 1 0 1 1 0 4/19/1901 diff --git a/mscorlib/system/io/__consolestream.cs b/mscorlib/system/io/__consolestream.cs index 505f30675..a877feabd 100644 --- a/mscorlib/system/io/__consolestream.cs +++ b/mscorlib/system/io/__consolestream.cs @@ -5,7 +5,7 @@ // ==--== /*============================================================ ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Class: ConsoleStream ** diff --git a/mscorlib/system/io/__error.cs b/mscorlib/system/io/__error.cs index f4a47d4a6..0f803ce9b 100644 --- a/mscorlib/system/io/__error.cs +++ b/mscorlib/system/io/__error.cs @@ -7,7 +7,7 @@ ** ** Class: __Error ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Centralized error methods for the IO package. diff --git a/mscorlib/system/io/bufferedstream.cs b/mscorlib/system/io/bufferedstream.cs index 1cdc72037..963365e67 100644 --- a/mscorlib/system/io/bufferedstream.cs +++ b/mscorlib/system/io/bufferedstream.cs @@ -395,7 +395,7 @@ private static async Task FlushAsyncInternal(CancellationToken cancellationToken // Reading is done in blocks, but someone could read 1 byte from the buffer then write. - // At that point, the underlying stream's pointer is out of [....] with this stream's position. + // At that point, the underlying stream's pointer is out of sync with this stream's position. // All write functions should call this function to ensure that the buffered data is not lost. private void FlushRead() { @@ -1158,7 +1158,7 @@ private async Task WriteToUnderlyingStreamAsync(Byte[] array, Int32 offset, Int3 try { // The buffer might have been changed by another async task while we were waiting on the semaphore. - // However, note that if we recalculate the [....] completion condition to TRUE, then useBuffer will also be TRUE. + // However, note that if we recalculate the sync completion condition to TRUE, then useBuffer will also be TRUE. if (_writePos == 0) ClearReadBufferBeforeWrite(); diff --git a/mscorlib/system/io/directory.cs b/mscorlib/system/io/directory.cs index 943e8ff52..7dc48de05 100644 --- a/mscorlib/system/io/directory.cs +++ b/mscorlib/system/io/directory.cs @@ -7,7 +7,7 @@ ** ** Class: Directory ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exposes routines for enumerating through a @@ -102,53 +102,70 @@ internal static DirectoryInfo UnsafeCreateDirectory(String path) [System.Security.SecurityCritical] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] - internal static DirectoryInfo InternalCreateDirectoryHelper(String path, bool checkHost) + internal static DirectoryInfo InternalCreateDirectoryHelper(string path, bool checkHost) { Contract.Requires(path != null); Contract.Requires(path.Length != 0); + string fullPath = GetFullPathAndCheckPermissions(path, checkHost: checkHost); + + InternalCreateDirectory(fullPath, path, dirSecurityObj: null, checkHost: checkHost); + + // Call the internal DirectoryInfo constructor + return new DirectoryInfo(fullPath, junk: false); + } + + internal static string GetFullPathAndCheckPermissions(string path, bool checkHost, FileSecurityStateAccess access = FileSecurityStateAccess.Read) + { String fullPath = Path.GetFullPathInternal(path); + CheckPermissions(path, fullPath, checkHost: checkHost, access: access); + return fullPath; + } + [SecuritySafeCritical] + internal static void CheckPermissions(string displayPath, string fullPath, bool checkHost, FileSecurityStateAccess access = FileSecurityStateAccess.Read) + { // You need read access to the directory to be returned back and write access to all the directories // that you need to create. If we fail any security checks we will not create any directories at all. // We attempt to create directories only after all the security checks have passed. This is avoid doing // a demand at every level. - String demandDir = GetDemandDir(fullPath, true); #if FEATURE_CORECLR if (checkHost) { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, demandDir); - state.EnsureState(); // do the check on the AppDomainManager to make sure this is allowed + FileSecurityState state = new FileSecurityState( + access, + path: displayPath, + canonicalizedPath: GetDemandDir(fullPath, thisDirOnly: true)); + state.EnsureState(); // do the check on the AppDomainManager to make sure this is allowed } #else - FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandDir, false, false); + // In full trust we want to avoid allocating another string via GetDemandDir() + if (CodeAccessSecurityEngine.QuickCheckForAllDemands()) + FileIOPermission.EmulateFileIOPermissionChecks(fullPath); + else + FileIOPermission.QuickDemand( + (FileIOPermissionAccess)access, + GetDemandDir(fullPath, thisDirOnly: true), + checkForDuplicates: false, + needFullPath: false); #endif - - InternalCreateDirectory(fullPath, path, null, checkHost); - - return new DirectoryInfo(fullPath, false); } + #if FEATURE_MACL [System.Security.SecuritySafeCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] - public static DirectoryInfo CreateDirectory(String path, DirectorySecurity directorySecurity) { + public static DirectoryInfo CreateDirectory(String path, DirectorySecurity directorySecurity) + { if (path==null) throw new ArgumentNullException("path"); if (path.Length == 0) throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty")); Contract.EndContractBlock(); - - String fullPath = Path.GetFullPathInternal(path); - // You need read access to the directory to be returned back and write access to all the directories - // that you need to create. If we fail any security checks we will not create any directories at all. - // We attempt to create directories only after all the security checks have passed. This is avoid doing - // a demand at every level. - String demandDir = GetDemandDir(fullPath, true); - FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandDir, false, false ); + string fullPath = GetFullPathAndCheckPermissions(path, checkHost: true); InternalCreateDirectory(fullPath, path, directorySecurity); @@ -322,21 +339,16 @@ internal unsafe static void InternalCreateDirectory(String fullPath, String path // fail because the target does exist, but is a file. if (currentError != Win32Native.ERROR_ALREADY_EXISTS) firstError = currentError; - else { + else + { // If there's a file in this directory's place, or if we have ERROR_ACCESS_DENIED when checking if the directory already exists throw. - if (File.InternalExists(name) || (!InternalExists(name, out currentError) && currentError == Win32Native.ERROR_ACCESS_DENIED)) { + if (File.InternalExists(name) || (!InternalExists(name, out currentError) && currentError == Win32Native.ERROR_ACCESS_DENIED)) + { firstError = currentError; // Give the user a nice error message, but don't leak path information. - try { -#if FEATURE_CORECLR - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, GetDemandDir(name, true)); - state.EnsureState(); - } -#else - FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, GetDemandDir(name, true)); -#endif // FEATURE_CORECLR + try + { + CheckPermissions(string.Empty, name, checkHost: checkHost, access: FileSecurityStateAccess.PathDiscovery); errorString = name; } catch(SecurityException) {} @@ -374,7 +386,7 @@ internal unsafe static void InternalCreateDirectory(String fullPath, String path [ResourceConsumption(ResourceScope.Machine)] public static bool Exists(String path) { - return InternalExistsHelper(path, true); + return InternalExistsHelper(path, checkHost: true); } [System.Security.SecurityCritical] @@ -382,36 +394,22 @@ public static bool Exists(String path) [ResourceConsumption(ResourceScope.Machine)] internal static bool UnsafeExists(String path) { - return InternalExistsHelper(path, false); + return InternalExistsHelper(path, checkHost: false); } [System.Security.SecurityCritical] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] - internal static bool InternalExistsHelper(String path, bool checkHost) { + internal static bool InternalExistsHelper(String path, bool checkHost) + { + if (path == null || path.Length == 0) + return false; + try { - if (path == null) - return false; - if (path.Length == 0) - return false; - - // Get fully qualified file name ending in \* for security check - - String fullPath = Path.GetFullPathInternal(path); - String demandPath = GetDemandDir(fullPath, true); - -#if FEATURE_CORECLR - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, demandPath); - state.EnsureState(); - } -#else - FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandPath, false, false); -#endif - - + // This could be further optimized- there is no need to get the full path if we aren't checking our + // own permissions- Windows will normalize it when we get the attributes. + string fullPath = GetFullPathAndCheckPermissions(path, checkHost: checkHost); return InternalExists(fullPath); } catch (ArgumentException) { } @@ -421,7 +419,7 @@ internal static bool InternalExistsHelper(String path, bool checkHost) { catch (UnauthorizedAccessException) { #if !FEATURE_PAL - Contract.Assert(false, "Ignore this assert and send a repro to [....]. This assert was tracking purposes only."); + Contract.Assert(false, "Ignore this assert and send a repro to Microsoft. This assert was tracking purposes only."); #endif //!FEATURE_PAL } return false; @@ -1047,27 +1045,23 @@ public static String[] GetLogicalDrives() [System.Security.SecuritySafeCritical] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] - public static String GetDirectoryRoot(String path) { + public static string GetDirectoryRoot(string path) + { if (path==null) throw new ArgumentNullException("path"); Contract.EndContractBlock(); - - String fullPath = Path.GetFullPathInternal(path); - String root = fullPath.Substring(0, Path.GetRootLength(fullPath)); - String demandPath = GetDemandDir(root, true); -#if FEATURE_CORECLR - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, path, demandPath); - state.EnsureState(); -#else - FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandPath, false, false); -#endif - + string fullPath = Path.GetFullPathInternal(path); + string root = fullPath.Substring(0, Path.GetRootLength(fullPath)); + + CheckPermissions(path, root, checkHost: true, access: FileSecurityStateAccess.PathDiscovery); + return root; } - internal static String InternalGetDirectoryRoot(String path) { - if (path == null) return null; + internal static string InternalGetDirectoryRoot(string path) + { + if (path == null) return null; return path.Substring(0, Path.GetRootLength(path)); } @@ -1100,17 +1094,9 @@ internal static String UnsafeGetCurrentDirectory() private static string InternalGetCurrentDirectory(bool checkHost) { string currentDirectory = AppContextSwitches.UseLegacyPathHandling ? LegacyGetCurrentDirectory() : NewGetCurrentDirectory(); - string demandPath = GetDemandDir(currentDirectory, true); -#if FEATURE_CORECLR - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPath); - state.EnsureState(); - } -#else - FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandPath, false, false); -#endif + CheckPermissions(string.Empty, currentDirectory, checkHost: true, access: FileSecurityStateAccess.PathDiscovery); + return currentDirectory; } @@ -1324,11 +1310,11 @@ internal static void UnsafeDelete(String path, bool recursive) internal static void Delete(String fullPath, String userPath, bool recursive, bool checkHost) { String demandPath; - + // If not recursive, do permission check only on this directory // else check for the whole directory structure rooted below - demandPath = GetDemandDir(fullPath, !recursive); - + demandPath = GetDemandDir(fullPath, thisDirOnly: !recursive); + #if FEATURE_CORECLR if (checkHost) { @@ -1502,7 +1488,6 @@ private static void DeleteHelper(String fullPath, String userPath, bool recursiv } } - // WinNT only. Win9x this code will not work. [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] diff --git a/mscorlib/system/io/directoryinfo.cs b/mscorlib/system/io/directoryinfo.cs index 4a5d733a5..b53c60893 100644 --- a/mscorlib/system/io/directoryinfo.cs +++ b/mscorlib/system/io/directoryinfo.cs @@ -7,7 +7,7 @@ ** ** Class: DirectoryInfo ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exposes routines for enumerating through a @@ -33,14 +33,19 @@ using System.Runtime.Versioning; using System.Diagnostics.Contracts; -namespace System.IO { +namespace System.IO +{ [Serializable] [ComVisible(true)] - public sealed class DirectoryInfo : FileSystemInfo { - private String[] demandDir; + public sealed class DirectoryInfo : FileSystemInfo + { +#pragma warning disable CS0169 + // This member isn't used anymore but must be maintained for binary serialization compatibility + private string[] demandDir; +#pragma warning restore CS0169 #if FEATURE_CORECLR - // Migrating InheritanceDemands requires this default ctor, so we can annotate it. + // Migrating InheritanceDemands requires this default ctor, so we can annotate it. #if FEATURE_CORESYSTEM [System.Security.SecurityCritical] #else @@ -79,7 +84,7 @@ public DirectoryInfo(String path) [System.Security.SecurityCritical] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] - private void Init(String path, bool checkHost) + private void Init(string path, bool checkHost) { // Special case "<DriveLetter>:" to point to "<CurrentDirectory>" instead if ((path.Length == 2) && (path[1] == ':')) @@ -92,18 +97,7 @@ private void Init(String path, bool checkHost) } // Must fully qualify the path for the security check - String fullPath = Path.GetFullPathInternal(path); - - demandDir = new String[] {Directory.GetDemandDir(fullPath, true)}; -#if FEATURE_CORECLR - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, OriginalPath, fullPath); - state.EnsureState(); - } -#else - FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandDir, false, false); -#endif + string fullPath = Directory.GetFullPathAndCheckPermissions(path, checkHost: checkHost); FullPath = fullPath; DisplayPath = GetDisplayName(OriginalPath, FullPath); @@ -122,20 +116,17 @@ internal DirectoryInfo(String fullPath, bool junk) FullPath = fullPath; DisplayPath = GetDisplayName(OriginalPath, FullPath); - demandDir = new String[] {Directory.GetDemandDir(fullPath, true)}; } [System.Security.SecurityCritical] // auto-generated private DirectoryInfo(SerializationInfo info, StreamingContext context) : base(info, context) { -#if !FEATURE_CORECLR - demandDir = new String[] {Directory.GetDemandDir(FullPath, true)}; - FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandDir, false, false ); -#endif + Directory.CheckPermissions(string.Empty, FullPath, checkHost: false); DisplayPath = GetDisplayName(OriginalPath, FullPath); } - public override String Name { + public override string Name + { [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] get @@ -150,32 +141,49 @@ public override String Name { } } - public DirectoryInfo Parent { + public override string FullName + { + [SecuritySafeCritical] + get + { + Directory.CheckPermissions(string.Empty, FullPath, checkHost: true, access: FileSecurityStateAccess.PathDiscovery); + return FullPath; + } + } + + internal override string UnsafeGetFullName + { + [SecurityCritical] + get + { + Directory.CheckPermissions(string.Empty, FullPath, checkHost: false, access: FileSecurityStateAccess.PathDiscovery); + return FullPath; + } + } + + public DirectoryInfo Parent + { [System.Security.SecuritySafeCritical] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] - get { - String parentName; + get + { + string parentName; // FullPath might be either "c:\bar" or "c:\bar\". Handle // those cases, as well as avoiding mangling "c:\". - String s = FullPath; + string s = FullPath; if (s.Length > 3 && s.EndsWith(Path.DirectorySeparatorChar)) - s = FullPath.Substring(0, FullPath.Length - 1); + s = FullPath.Substring(0, FullPath.Length - 1); parentName = Path.GetDirectoryName(s); if (parentName==null) return null; - DirectoryInfo dir = new DirectoryInfo(parentName,false); -#if FEATURE_CORECLR - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery | FileSecurityStateAccess.Read, String.Empty, dir.demandDir[0]); - state.EnsureState(); -#else - FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, dir.demandDir, false, false); -#endif + + DirectoryInfo dir = new DirectoryInfo(parentName, false); + Directory.CheckPermissions(string.Empty, dir.FullPath, checkHost: true, access: FileSecurityStateAccess.PathDiscovery | FileSecurityStateAccess.Read); return dir; } } - [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] #if FEATURE_CORECLR @@ -618,38 +626,28 @@ public DirectoryInfo Root { [System.Security.SecuritySafeCritical] [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] - public void MoveTo(String destDirName) { + public void MoveTo(string destDirName) + { if (destDirName==null) throw new ArgumentNullException("destDirName"); if (destDirName.Length==0) throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destDirName"); Contract.EndContractBlock(); - -#if FEATURE_CORECLR - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, DisplayPath, Directory.GetDemandDir(FullPath, true)); - sourceState.EnsureState(); -#else - FileIOPermission.QuickDemand(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, demandDir, false, false); -#endif - String fullDestDirName = Path.GetFullPathInternal(destDirName); - String demandPath; + + Directory.CheckPermissions(DisplayPath, FullPath, checkHost: true, access: FileSecurityStateAccess.Write | FileSecurityStateAccess.Read); + + string fullDestDirName = Path.GetFullPathInternal(destDirName); if (!fullDestDirName.EndsWith(Path.DirectorySeparatorChar)) fullDestDirName = fullDestDirName + Path.DirectorySeparatorChar; - demandPath = fullDestDirName + '.'; - // Demand read & write permission to destination. The reason is // we hand back a DirectoryInfo to the destination that would allow // you to read a directory listing from that directory. Sure, you // had the ability to read the file contents in the old location, // but you technically also need read permissions to the new // location as well, and write is not a true superset of read. -#if FEATURE_CORECLR - FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destDirName, demandPath); - destState.EnsureState(); -#else - FileIOPermission.QuickDemand(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, demandPath); -#endif + + Directory.CheckPermissions(destDirName, fullDestDirName, checkHost: true, access: FileSecurityStateAccess.Write | FileSecurityStateAccess.Read); String fullSourcePath; if (FullPath.EndsWith(Path.DirectorySeparatorChar)) @@ -674,16 +672,15 @@ public void MoveTo(String destDirName) { hr = Win32Native.ERROR_PATH_NOT_FOUND; __Error.WinIOError(hr, DisplayPath); } - + if (hr == Win32Native.ERROR_ACCESS_DENIED) // We did this for Win9x. We can't change it for backcomp. throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", DisplayPath)); - - __Error.WinIOError(hr,String.Empty); + + __Error.WinIOError(hr, string.Empty); } FullPath = fullDestDirName; OriginalPath = destDirName; DisplayPath = GetDisplayName(OriginalPath, FullPath); - demandDir = new String[] { Directory.GetDemandDir(FullPath, true) }; // Flush any cached information about the directory. _dataInitialised = -1; diff --git a/mscorlib/system/io/directorynotfoundexception.cs b/mscorlib/system/io/directorynotfoundexception.cs index 93e9437ad..97c5dcc6b 100644 --- a/mscorlib/system/io/directorynotfoundexception.cs +++ b/mscorlib/system/io/directorynotfoundexception.cs @@ -7,7 +7,7 @@ ** ** Class: DirectoryNotFoundException ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception for accessing a path that doesn't exist. diff --git a/mscorlib/system/io/driveinfo.cs b/mscorlib/system/io/driveinfo.cs index 5f7893387..7dd7a3bc3 100644 --- a/mscorlib/system/io/driveinfo.cs +++ b/mscorlib/system/io/driveinfo.cs @@ -7,7 +7,7 @@ ** ** Class: DriveInfo ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exposes routines for exploring a drive. diff --git a/mscorlib/system/io/drivenotfoundexception.cs b/mscorlib/system/io/drivenotfoundexception.cs index cfc543f30..0361c2908 100644 --- a/mscorlib/system/io/drivenotfoundexception.cs +++ b/mscorlib/system/io/drivenotfoundexception.cs @@ -7,7 +7,7 @@ // // Class: DriveNotFoundException // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Purpose: Exception for accessing a drive that is not available. // diff --git a/mscorlib/system/io/endofstreamexception.cs b/mscorlib/system/io/endofstreamexception.cs index aa07bc4c7..b0cd0d1c9 100644 --- a/mscorlib/system/io/endofstreamexception.cs +++ b/mscorlib/system/io/endofstreamexception.cs @@ -7,7 +7,7 @@ ** ** Class: EndOfStreamException ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception to be thrown when reading past end-of-file. diff --git a/mscorlib/system/io/file.cs b/mscorlib/system/io/file.cs index 8a36be7ee..8bba7c17c 100644 --- a/mscorlib/system/io/file.cs +++ b/mscorlib/system/io/file.cs @@ -7,7 +7,7 @@ ** ** Class: File ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: A collection of methods for manipulating Files. diff --git a/mscorlib/system/io/fileinfo.cs b/mscorlib/system/io/fileinfo.cs index 1148997f4..7296eaaf3 100644 --- a/mscorlib/system/io/fileinfo.cs +++ b/mscorlib/system/io/fileinfo.cs @@ -5,7 +5,7 @@ // ==--== /*============================================================ ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Class: File ** diff --git a/mscorlib/system/io/fileloadexception.cs b/mscorlib/system/io/fileloadexception.cs index 632742dd8..150175d80 100644 --- a/mscorlib/system/io/fileloadexception.cs +++ b/mscorlib/system/io/fileloadexception.cs @@ -7,8 +7,8 @@ ** ** Class: FileLoadException ** -** <OWNER>[....]</OWNER> -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception for failure to load a file that was successfully found. diff --git a/mscorlib/system/io/filenotfoundexception.cs b/mscorlib/system/io/filenotfoundexception.cs index 088ef6117..985d9e1a1 100644 --- a/mscorlib/system/io/filenotfoundexception.cs +++ b/mscorlib/system/io/filenotfoundexception.cs @@ -7,8 +7,8 @@ ** ** Class: FileNotFoundException ** -** <OWNER>[....]</OWNER> -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception for accessing a file that doesn't exist. diff --git a/mscorlib/system/io/filestream.cs b/mscorlib/system/io/filestream.cs index 7e47b8bed..4276a6b2c 100644 --- a/mscorlib/system/io/filestream.cs +++ b/mscorlib/system/io/filestream.cs @@ -7,7 +7,7 @@ ** ** Class: FileStream ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exposes a Stream around a file, with full @@ -39,11 +39,11 @@ /* * FileStream supports different modes of accessing the disk - async mode - * and [....] mode. They are two completely different codepaths in the - * [....] & async methods (ie, Read/Write vs. BeginRead/BeginWrite). File - * handles in NT can be opened in only [....] or overlapped (async) mode, + * and sync mode. They are two completely different codepaths in the + * sync & async methods (ie, Read/Write vs. BeginRead/BeginWrite). File + * handles in NT can be opened in only sync or overlapped (async) mode, * and we have to deal with this pain. Stream has implementations of - * the [....] methods in terms of the async ones, so we'll + * the sync methods in terms of the async ones, so we'll * call through to our base class to get those methods when necessary. * * Also buffering is added into FileStream as well. Folded in the @@ -1226,7 +1226,7 @@ public override long Position { Contract.Assert((_readPos == 0 && _readLen == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLen), "We're either reading or writing, but not both."); - // Verify that internal position is in [....] with the handle + // Verify that internal position is in sync with the handle if (_exposedHandle) VerifyOSHandlePosition(); @@ -1355,7 +1355,7 @@ private void FlushOSBuffer() // Reading is done by blocks from the file, but someone could read // 1 byte from the buffer then write. At that point, the OS's file - // pointer is out of [....] with the stream's position. All write + // pointer is out of sync with the stream's position. All write // functions should call this function to preserve the position in the file. private void FlushRead() { Contract.Assert(_writePos == 0, "FileStream: Write buffer must be empty in FlushRead!"); @@ -1630,7 +1630,7 @@ public override long Seek(long offset, SeekOrigin origin) { offset -= (_readLen - _readPos); } - // Verify that internal position is in [....] with the handle + // Verify that internal position is in sync with the handle if (_exposedHandle) VerifyOSHandlePosition(); @@ -1947,7 +1947,7 @@ private FileStreamAsyncResult BeginReadAsync(byte[] array, int offset, int numBy // (either synchronously or asynchronously) before the first one // returns. This would involve some sort of complex buffer locking // that we probably don't want to get into, at least not in V1. - // If we did a [....] read to fill the buffer, we could avoid the + // If we did a sync read to fill the buffer, we could avoid the // problem, and any async read less than 64K gets turned into a // synchronous read by NT anyways... -- @@ -2515,7 +2515,7 @@ private unsafe int ReadFileNative(SafeFileHandle handle, byte[] bytes, int offse if (r==0) { hr = Marshal.GetLastWin32Error(); - // We should never silently ---- an error here without some + // We should never silently swallow an error here without some // extra work. We must make sure that BeginReadCore won't return an // IAsyncResult that will cause EndRead to block, since the OS won't // call AsyncFSCallback for us. @@ -2572,7 +2572,7 @@ private unsafe int WriteFileNative(SafeFileHandle handle, byte[] bytes, int offs if (r==0) { hr = Marshal.GetLastWin32Error(); - // We should never silently ---- an error here without some + // We should never silently swallow an error here without some // extra work. We must make sure that BeginWriteCore won't return an // IAsyncResult that will cause EndWrite to block, since the OS won't // call AsyncFSCallback for us. diff --git a/mscorlib/system/io/filesystemenumerable.cs b/mscorlib/system/io/filesystemenumerable.cs index 5acaf13e8..562293164 100644 --- a/mscorlib/system/io/filesystemenumerable.cs +++ b/mscorlib/system/io/filesystemenumerable.cs @@ -7,7 +7,7 @@ ** ** Class: FileSystemEnumerable ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Enumerates files and dirs diff --git a/mscorlib/system/io/filesysteminfo.cs b/mscorlib/system/io/filesysteminfo.cs index 557ab1be8..7b7e46e9b 100644 --- a/mscorlib/system/io/filesysteminfo.cs +++ b/mscorlib/system/io/filesysteminfo.cs @@ -7,7 +7,7 @@ ** ** Class: FileSystemInfo ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: @@ -26,18 +26,21 @@ using System.Runtime.Versioning; using System.Diagnostics.Contracts; -namespace System.IO { +namespace System.IO +{ [Serializable] #if !FEATURE_CORECLR [FileIOPermissionAttribute(SecurityAction.InheritanceDemand,Unrestricted=true)] #endif [ComVisible(true)] -#if FEATURE_REMOTING - public abstract class FileSystemInfo : MarshalByRefObject, ISerializable { +#if FEATURE_REMOTING + public abstract class FileSystemInfo : MarshalByRefObject, ISerializable + { #else // FEATURE_REMOTING - public abstract class FileSystemInfo : ISerializable { -#endif //FEATURE_REMOTING - + public abstract class FileSystemInfo : ISerializable + { +#endif //FEATURE_REMOTING + [System.Security.SecurityCritical] // auto-generated internal Win32Native.WIN32_FILE_ATTRIBUTE_DATA _data; // Cache the file information internal int _dataInitialised = -1; // We use this field in conjunction with the Refresh methods, if we succeed @@ -88,37 +91,28 @@ internal void InitializeFrom(Win32Native.WIN32_FIND_DATA findData) } // Full path of the direcory/file - public virtual String FullName { - [System.Security.SecuritySafeCritical] - get + public virtual string FullName + { + [SecuritySafeCritical] + get { - String demandDir; - if (this is DirectoryInfo) - demandDir = Directory.GetDemandDir(FullPath, true); - else - demandDir = FullPath; #if FEATURE_CORECLR - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandDir); + FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, FullPath); sourceState.EnsureState(); #else - FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandDir); + FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, FullPath); #endif return FullPath; } } - internal virtual String UnsafeGetFullName + internal virtual string UnsafeGetFullName { - [System.Security.SecurityCritical] + [SecurityCritical] get { - String demandDir; - if (this is DirectoryInfo) - demandDir = Directory.GetDemandDir(FullPath, true); - else - demandDir = FullPath; #if !FEATURE_CORECLR - FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandDir); + FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, FullPath); #endif return FullPath; } diff --git a/mscorlib/system/io/ioexception.cs b/mscorlib/system/io/ioexception.cs index 699d4f7e7..3301207c6 100644 --- a/mscorlib/system/io/ioexception.cs +++ b/mscorlib/system/io/ioexception.cs @@ -7,7 +7,7 @@ ** ** Class: IOException ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception for a generic IO error. diff --git a/mscorlib/system/io/isolatedstorage/isolatedstorage.cs b/mscorlib/system/io/isolatedstorage/isolatedstorage.cs index 1249595b5..4d384f1d0 100644 --- a/mscorlib/system/io/isolatedstorage/isolatedstorage.cs +++ b/mscorlib/system/io/isolatedstorage/isolatedstorage.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // /*============================================================ @@ -331,7 +331,7 @@ private static bool IsValidName(String s) private static SecurityPermission GetControlEvidencePermission() { - // Don't [....]. OK to create this object more than once. + // Don't sync. OK to create this object more than once. if (s_PermControlEvidence == null) s_PermControlEvidence = new SecurityPermission( SecurityPermissionFlag.ControlEvidence); @@ -341,7 +341,7 @@ private static SecurityPermission GetControlEvidencePermission() private static PermissionSet GetUnrestricted() { - // Don't [....]. OK to create this object more than once. + // Don't sync. OK to create this object more than once. if (s_PermUnrestricted == null) s_PermUnrestricted = new PermissionSet( PermissionState.Unrestricted); diff --git a/mscorlib/system/io/isolatedstorage/isolatedstorageexception.cs b/mscorlib/system/io/isolatedstorage/isolatedstorageexception.cs index e02e83a75..175991615 100644 --- a/mscorlib/system/io/isolatedstorage/isolatedstorageexception.cs +++ b/mscorlib/system/io/isolatedstorage/isolatedstorageexception.cs @@ -7,7 +7,7 @@ * * Class: IsolatedStorageException // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> * * * Purpose: The exceptions in IsolatedStorage diff --git a/mscorlib/system/io/isolatedstorage/isolatedstoragefile.cs b/mscorlib/system/io/isolatedstorage/isolatedstoragefile.cs index 932a4ee9f..739311221 100644 --- a/mscorlib/system/io/isolatedstorage/isolatedstoragefile.cs +++ b/mscorlib/system/io/isolatedstorage/isolatedstoragefile.cs @@ -8,8 +8,8 @@ * * Class: IsolatedStorageFile // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> * * * Purpose: Provides access to Application files and folders @@ -2304,7 +2304,7 @@ internal static FileIOPermission GetGlobalFileIOPerm( { if (IsRoaming(scope)) { - // no [....] needed, ok to create multiple instances. + // no sync needed, ok to create multiple instances. if (s_PermRoaming == null) { s_PermRoaming = new FileIOPermission( @@ -2316,7 +2316,7 @@ internal static FileIOPermission GetGlobalFileIOPerm( if (IsMachine(scope)) { - // no [....] needed, ok to create multiple instances. + // no sync needed, ok to create multiple instances. if (s_PermMachine == null) { s_PermMachine = new FileIOPermission( @@ -2325,7 +2325,7 @@ internal static FileIOPermission GetGlobalFileIOPerm( return s_PermMachine; } - // no [....] needed, ok to create multiple instances. + // no sync needed, ok to create multiple instances. if (s_PermUser == null) { s_PermUser = new FileIOPermission( @@ -2338,7 +2338,7 @@ internal static FileIOPermission GetGlobalFileIOPerm( [System.Security.SecurityCritical] // auto-generated private static void DemandAdminPermission() { - // Ok if more than one instance is created, no need to [....]. + // Ok if more than one instance is created, no need to sync. if (s_PermAdminUser == null) { s_PermAdminUser = new IsolatedStorageFilePermission( diff --git a/mscorlib/system/io/isolatedstorage/isolatedstoragefilestream.cs b/mscorlib/system/io/isolatedstorage/isolatedstoragefilestream.cs index c6d0b5541..caa5cfe5e 100644 --- a/mscorlib/system/io/isolatedstorage/isolatedstoragefilestream.cs +++ b/mscorlib/system/io/isolatedstorage/isolatedstoragefilestream.cs @@ -7,7 +7,7 @@ * * Class: IsolatedStorageFileStream // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> * * * Purpose: Provides access to files using the same interface as FileStream diff --git a/mscorlib/system/io/longpath.cs b/mscorlib/system/io/longpath.cs index 7b863b95c..408048f5e 100644 --- a/mscorlib/system/io/longpath.cs +++ b/mscorlib/system/io/longpath.cs @@ -7,7 +7,7 @@ ** ** Class: File ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Long paths diff --git a/mscorlib/system/io/memorystream.cs b/mscorlib/system/io/memorystream.cs index d91a11621..b3755edac 100644 --- a/mscorlib/system/io/memorystream.cs +++ b/mscorlib/system/io/memorystream.cs @@ -7,7 +7,7 @@ ** ** Class: MemoryStream ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: A Stream whose backing store is memory. Great @@ -422,7 +422,7 @@ public override Task CopyToAsync(Stream destination, Int32 bufferSize, Cancellat // This implementation offers beter performance compared to the base class version. - // The parameter checks must be in [....] with the base version: + // The parameter checks must be in sync with the base version: if (destination == null) throw new ArgumentNullException("destination"); diff --git a/mscorlib/system/io/path.cs b/mscorlib/system/io/path.cs index 3927d52da..26a00f1a3 100644 --- a/mscorlib/system/io/path.cs +++ b/mscorlib/system/io/path.cs @@ -7,7 +7,7 @@ ** ** Class: Path ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: A collection of path manipulation methods. @@ -441,8 +441,26 @@ private static string NewNormalizePathLimitedChecks(string path, int maxPathLeng if (PathInternal.IsPathTooLong(normalized) || PathInternal.AreSegmentsTooLong(normalized)) throw new PathTooLongException(); - if (!PathInternal.IsDevice(normalized) && PathInternal.HasInvalidVolumeSeparator(path)) - throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal")); + // Under old logic certain subsets of paths containing colons were rejected. Some portion of that comes + // indirectly from FileIOPermissions, the rest comes from the section in LegacyNormalizePath below: + // + // // To reject strings like "C:...\foo" and "C :\foo" + // if (firstSegment && currentChar == VolumeSeparatorChar) + // + // The superset of this now is PathInternal.HasInvalidVolumeSeparator(). + // + // Unfortunately a side effect of the old split logic is that some "bad" colon paths slip through when + // fullChecks=false. Notably this means that GetDirectoryName and GetPathRoot would allow URIs (although + // it would mangle them). A user could pass a "file://..." uri to GetDirectoryName(), get "file:\..." back, + // then pass it to Uri which fixes up the bad URI. One particular user code path for this is calling + // Assembly.CodePath and trying to get the directory before passing to the Uri class. + // + // To ease transitioning code forward we'll allow all "bad" colon paths through when we are doing + // limited checks. If we want to add this back (under a quirk perhaps), we would need to conditionalize + // for Device paths as follows: + // + // if (!PathInternal.IsDevice(normalized) && PathInternal.HasInvalidVolumeSeparator(path)) + // throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal")); if (expandShortPaths && normalized.IndexOf('~') != -1) { diff --git a/mscorlib/system/io/pathinternal.cs b/mscorlib/system/io/pathinternal.cs new file mode 100644 index 000000000..1c99959e0 --- /dev/null +++ b/mscorlib/system/io/pathinternal.cs @@ -0,0 +1,645 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Win32; +using System; +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace System.IO +{ + /// <summary>Contains internal path helpers that are shared between many projects.</summary> + internal static class PathInternal + { + internal const string ExtendedPathPrefix = @"\\?\"; + internal const string UncPathPrefix = @"\\"; + internal const string UncExtendedPrefixToInsert = @"?\UNC\"; + internal const string UncExtendedPathPrefix = @"\\?\UNC\"; + internal const string DevicePathPrefix = @"\\.\"; + internal const int DevicePrefixLength = 4; + internal const int MaxShortPath = 260; + internal const int MaxShortDirectoryPath = 248; + + // Windows is limited in long paths by the max size of its internal representation of a unicode string. + // UNICODE_STRING has a max length of USHORT in _bytes_ without a trailing null. + // https://msdn.microsoft.com/en-us/library/windows/hardware/ff564879.aspx + internal const int MaxLongPath = short.MaxValue; + internal static readonly int MaxComponentLength = 255; + + internal static readonly char[] InvalidPathChars = + { + '\"', '<', '>', '|', '\0', + (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10, + (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20, + (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30, + (char)31 + }; + + /// <summary> + /// Validates volume separator only occurs as C: or \\?\C:. This logic is meant to filter out Alternate Data Streams. + /// </summary> + /// <returns>True if the path has an invalid volume separator.</returns> + internal static bool HasInvalidVolumeSeparator(string path) + { + // Toss out paths with colons that aren't a valid drive specifier. + // Cannot start with a colon and can only be of the form "C:" or "\\?\C:". + // (Note that we used to explicitly check "http:" and "file:"- these are caught by this check now.) + + // We don't care about skipping starting space for extended paths. Assume no knowledge of extended paths if we're forcing old path behavior. + bool isExtended = !AppContextSwitches.UseLegacyPathHandling && IsExtended(path); + int startIndex = isExtended ? ExtendedPathPrefix.Length : PathStartSkip(path); + + // If we start with a colon + if ((path.Length > startIndex && path[startIndex] == Path.VolumeSeparatorChar) + // Or have an invalid drive letter and colon + || (path.Length >= startIndex + 2 && path[startIndex + 1] == Path.VolumeSeparatorChar && !IsValidDriveChar(path[startIndex])) + // Or have any colons beyond the drive colon + || (path.Length > startIndex + 2 && path.IndexOf(Path.VolumeSeparatorChar, startIndex + 2) != -1)) + { + return true; + } + + return false; + } + + /// <summary> + /// Returns true if the given StringBuilder starts with the given value. + /// </summary> + /// <param name="value">The string to compare against the start of the StringBuilder.</param> + internal static bool StartsWithOrdinal(StringBuilder builder, string value, bool ignoreCase = false) + { + if (value == null || builder.Length < value.Length) + return false; + + if (ignoreCase) + { + for (int i = 0; i < value.Length; i++) + if (char.ToUpperInvariant(builder[i]) != char.ToUpperInvariant(value[i])) return false; + } + else + { + for (int i = 0; i < value.Length; i++) + if (builder[i] != value[i]) return false; + } + + return true; + } + + /// <summary> + /// Returns true if the given character is a valid drive letter + /// </summary> + internal static bool IsValidDriveChar(char value) + { + return ((value >= 'A' && value <= 'Z') || (value >= 'a' && value <= 'z')); + } + + /// <summary> + /// Returns true if the path is too long + /// </summary> + internal static bool IsPathTooLong(string fullPath) + { + // We'll never know precisely what will fail as paths get changed internally in Windows and + // may grow beyond / shrink below exceed MaxLongPath. + if (AppContextSwitches.BlockLongPaths) + { + // We allow paths of any length if extended (and not in compat mode) + if (AppContextSwitches.UseLegacyPathHandling || !IsExtended(fullPath)) + return fullPath.Length >= MaxShortPath; + } + + return fullPath.Length >= MaxLongPath; + } + + /// <summary> + /// Return true if any path segments are too long + /// </summary> + internal static bool AreSegmentsTooLong(string fullPath) + { + int length = fullPath.Length; + int lastSeparator = 0; + + for (int i = 0; i < length; i++) + { + if (IsDirectorySeparator(fullPath[i])) + { + if (i - lastSeparator > MaxComponentLength) + return true; + lastSeparator = i; + } + } + + if (length - 1 - lastSeparator > MaxComponentLength) + return true; + + return false; + } + + /// <summary> + /// Returns true if the directory is too long + /// </summary> + internal static bool IsDirectoryTooLong(string fullPath) + { + if (AppContextSwitches.BlockLongPaths) + { + // We allow paths of any length if extended (and not in compat mode) + if (AppContextSwitches.UseLegacyPathHandling || !IsExtended(fullPath)) + return (fullPath.Length >= MaxShortDirectoryPath); + } + + return IsPathTooLong(fullPath); + } + + /// <summary> + /// Adds the extended path prefix (\\?\) if not relative or already a device path. + /// </summary> + internal static string EnsureExtendedPrefix(string path) + { + // Putting the extended prefix on the path changes the processing of the path. It won't get normalized, which + // means adding to relative paths will prevent them from getting the appropriate current directory inserted. + + // If it already has some variant of a device path (\??\, \\?\, \\.\, //./, etc.) we don't need to change it + // as it is either correct or we will be changing the behavior. When/if Windows supports long paths implicitly + // in the future we wouldn't want normalization to come back and break existing code. + + // In any case, all internal usages should be hitting normalize path (Path.GetFullPath) before they hit this + // shimming method. (Or making a change that doesn't impact normalization, such as adding a filename to a + // normalized base path.) + if (IsPartiallyQualified(path) || IsDevice(path)) + return path; + + // Given \\server\share in longpath becomes \\?\UNC\server\share + if (path.StartsWith(UncPathPrefix, StringComparison.OrdinalIgnoreCase)) + return path.Insert(2, UncExtendedPrefixToInsert); + + return ExtendedPathPrefix + path; + } + + /// <summary> + /// Removes the extended path prefix (\\?\) if present. + /// </summary> + internal static string RemoveExtendedPrefix(string path) + { + if (!IsExtended(path)) + return path; + + // Given \\?\UNC\server\share we return \\server\share + if (IsExtendedUnc(path)) + return path.Remove(2, 6); + + return path.Substring(DevicePrefixLength); + } + + /// <summary> + /// Removes the extended path prefix (\\?\) if present. + /// </summary> + internal static StringBuilder RemoveExtendedPrefix(StringBuilder path) + { + if (!IsExtended(path)) + return path; + + // Given \\?\UNC\server\share we return \\server\share + if (IsExtendedUnc(path)) + return path.Remove(2, 6); + + return path.Remove(0, DevicePrefixLength); + } + + /// <summary> + /// Returns true if the path uses any of the DOS device path syntaxes. ("\\.\", "\\?\", or "\??\") + /// </summary> + internal static bool IsDevice(string path) + { + // If the path begins with any two separators it will be recognized and normalized and prepped with + // "\??\" for internal usage correctly. "\??\" is recognized and handled, "/??/" is not. + return IsExtended(path) + || + ( + path.Length >= DevicePrefixLength + && IsDirectorySeparator(path[0]) + && IsDirectorySeparator(path[1]) + && (path[2] == '.' || path[2] == '?') + && IsDirectorySeparator(path[3]) + ); + } + + /// <summary> + /// Returns true if the path uses any of the DOS device path syntaxes. ("\\.\", "\\?\", or "\??\") + /// </summary> + internal static bool IsDevice(StringBuffer path) + { + // If the path begins with any two separators it will be recognized and normalized and prepped with + // "\??\" for internal usage correctly. "\??\" is recognized and handled, "/??/" is not. + return IsExtended(path) + || + ( + path.Length >= DevicePrefixLength + && IsDirectorySeparator(path[0]) + && IsDirectorySeparator(path[1]) + && (path[2] == '.' || path[2] == '?') + && IsDirectorySeparator(path[3]) + ); + } + + /// <summary> + /// Returns true if the path uses the canonical form of extended syntax ("\\?\" or "\??\"). If the + /// path matches exactly (cannot use alternate directory separators) Windows will skip normalization + /// and path length checks. + /// </summary> + internal static bool IsExtended(string path) + { + // While paths like "//?/C:/" will work, they're treated the same as "\\.\" paths. + // Skipping of normalization will *only* occur if back slashes ('\') are used. + return path.Length >= DevicePrefixLength + && path[0] == '\\' + && (path[1] == '\\' || path[1] == '?') + && path[2] == '?' + && path[3] == '\\'; + } + + /// <summary> + /// Returns true if the path uses the canonical form of extended syntax ("\\?\" or "\??\"). If the + /// path matches exactly (cannot use alternate directory separators) Windows will skip normalization + /// and path length checks. + /// </summary> + internal static bool IsExtended(StringBuilder path) + { + // While paths like "//?/C:/" will work, they're treated the same as "\\.\" paths. + // Skipping of normalization will *only* occur if back slashes ('\') are used. + return path.Length >= DevicePrefixLength + && path[0] == '\\' + && (path[1] == '\\' || path[1] == '?') + && path[2] == '?' + && path[3] == '\\'; + } + + /// <summary> + /// Returns true if the path uses the canonical form of extended syntax ("\\?\" or "\??\"). If the + /// path matches exactly (cannot use alternate directory separators) Windows will skip normalization + /// and path length checks. + /// </summary> + internal static bool IsExtended(StringBuffer path) + { + // While paths like "//?/C:/" will work, they're treated the same as "\\.\" paths. + // Skipping of normalization will *only* occur if back slashes ('\') are used. + return path.Length >= DevicePrefixLength + && path[0] == '\\' + && (path[1] == '\\' || path[1] == '?') + && path[2] == '?' + && path[3] == '\\'; + } + + /// <summary> + /// Returns true if the path uses the extended UNC syntax (\\?\UNC\ or \??\UNC\) + /// </summary> + internal static bool IsExtendedUnc(string path) + { + return path.Length >= UncExtendedPathPrefix.Length + && IsExtended(path) + && char.ToUpper(path[4]) == 'U' + && char.ToUpper(path[5]) == 'N' + && char.ToUpper(path[6]) == 'C' + && path[7] == '\\'; + } + + /// <summary> + /// Returns true if the path uses the extended UNC syntax (\\?\UNC\ or \??\UNC\) + /// </summary> + internal static bool IsExtendedUnc(StringBuilder path) + { + return path.Length >= UncExtendedPathPrefix.Length + && IsExtended(path) + && char.ToUpper(path[4]) == 'U' + && char.ToUpper(path[5]) == 'N' + && char.ToUpper(path[6]) == 'C' + && path[7] == '\\'; + } + + /// <summary> + /// Returns a value indicating if the given path contains invalid characters (", <, >, | + /// NUL, or any ASCII char whose integer representation is in the range of 1 through 31). + /// Does not check for wild card characters ? and *. + /// + /// Will not check if the path is a device path and not in Legacy mode as many of these + /// characters are valid for devices (pipes for example). + /// </summary> + internal static bool HasIllegalCharacters(string path, bool checkAdditional = false) + { + if (!AppContextSwitches.UseLegacyPathHandling && IsDevice(path)) + { + return false; + } + + return AnyPathHasIllegalCharacters(path, checkAdditional: checkAdditional); + } + + /// <summary> + /// Version of HasIllegalCharacters that checks no AppContextSwitches. Only use if you know you need to skip switches and don't care + /// about proper device path handling. + /// </summary> + internal static bool AnyPathHasIllegalCharacters(string path, bool checkAdditional = false) + { + return path.IndexOfAny(InvalidPathChars) >= 0 || (checkAdditional && AnyPathHasWildCardCharacters(path)); + } + + /// <summary> + /// Check for ? and *. + /// </summary> + internal static bool HasWildCardCharacters(string path) + { + // Question mark is part of some device paths + int startIndex = AppContextSwitches.UseLegacyPathHandling ? 0 : IsDevice(path) ? ExtendedPathPrefix.Length : 0; + return AnyPathHasWildCardCharacters(path, startIndex: startIndex); + } + + /// <summary> + /// Version of HasWildCardCharacters that checks no AppContextSwitches. Only use if you know you need to skip switches and don't care + /// about proper device path handling. + /// </summary> + internal static bool AnyPathHasWildCardCharacters(string path, int startIndex = 0) + { + char currentChar; + for (int i = startIndex; i < path.Length; i++) + { + currentChar = path[i]; + if (currentChar == '*' || currentChar == '?') return true; + } + return false; + } + + /// <summary> + /// Gets the length of the root of the path (drive, share, etc.). + /// </summary> + [System.Security.SecuritySafeCritical] + internal unsafe static int GetRootLength(string path) + { + fixed (char* value = path) + { + return (int)GetRootLength(value, (ulong)path.Length); + } + } + + /// <summary> + /// Gets the length of the root of the path (drive, share, etc.). + /// </summary> + [System.Security.SecuritySafeCritical] + internal unsafe static uint GetRootLength(StringBuffer path) + { + if (path.Length == 0) return 0; + return GetRootLength(path.CharPointer, path.Length); + } + + [System.Security.SecurityCritical] + private unsafe static uint GetRootLength(char* path, ulong pathLength) + { + uint i = 0; + uint volumeSeparatorLength = 2; // Length to the colon "C:" + uint uncRootLength = 2; // Length to the start of the server name "\\" + + bool extendedSyntax = StartsWithOrdinal(path, pathLength, ExtendedPathPrefix); + bool extendedUncSyntax = StartsWithOrdinal(path, pathLength, UncExtendedPathPrefix); + if (extendedSyntax) + { + // Shift the position we look for the root from to account for the extended prefix + if (extendedUncSyntax) + { + // "\\" -> "\\?\UNC\" + uncRootLength = (uint)UncExtendedPathPrefix.Length; + } + else + { + // "C:" -> "\\?\C:" + volumeSeparatorLength += (uint)ExtendedPathPrefix.Length; + } + } + + if ((!extendedSyntax || extendedUncSyntax) && pathLength > 0 && IsDirectorySeparator(path[0])) + { + // UNC or simple rooted path (e.g. "\foo", NOT "\\?\C:\foo") + + i = 1; // Drive rooted (\foo) is one character + if (extendedUncSyntax || (pathLength > 1 && IsDirectorySeparator(path[1]))) + { + // UNC (\\?\UNC\ or \\), scan past the next two directory separators at most + // (e.g. to \\?\UNC\Server\Share or \\Server\Share\) + i = uncRootLength; + int n = 2; // Maximum separators to skip + while (i < pathLength && (!IsDirectorySeparator(path[i]) || --n > 0)) i++; + } + } + else if (pathLength >= volumeSeparatorLength && path[volumeSeparatorLength - 1] == Path.VolumeSeparatorChar) + { + // Path is at least longer than where we expect a colon, and has a colon (\\?\A:, A:) + // If the colon is followed by a directory separator, move past it + i = volumeSeparatorLength; + if (pathLength >= volumeSeparatorLength + 1 && IsDirectorySeparator(path[volumeSeparatorLength])) i++; + } + return i; + } + + [System.Security.SecurityCritical] + private unsafe static bool StartsWithOrdinal(char* source, ulong sourceLength, string value) + { + if (sourceLength < (ulong)value.Length) return false; + for (int i = 0; i < value.Length; i++) + { + if (value[i] != source[i]) return false; + } + return true; + } + + /// <summary> + /// Returns true if the path specified is relative to the current drive or working directory. + /// Returns false if the path is fixed to a specific drive or UNC path. This method does no + /// validation of the path (URIs will be returned as relative as a result). + /// </summary> + /// <remarks> + /// Handles paths that use the alternate directory separator. It is a frequent mistake to + /// assume that rooted paths (Path.IsPathRooted) are not relative. This isn't the case. + /// "C:a" is drive relative- meaning that it will be resolved against the current directory + /// for C: (rooted, but relative). "C:\a" is rooted and not relative (the current directory + /// will not be used to modify the path). + /// </remarks> + internal static bool IsPartiallyQualified(string path) + { + if (path.Length < 2) + { + // It isn't fixed, it must be relative. There is no way to specify a fixed + // path with one character (or less). + return true; + } + + if (IsDirectorySeparator(path[0])) + { + // There is no valid way to specify a relative path with two initial slashes or + // \? as ? isn't valid for drive relative paths and \??\ is equivalent to \\?\ + return !(path[1] == '?' || IsDirectorySeparator(path[1])); + } + + // The only way to specify a fixed path that doesn't begin with two slashes + // is the drive, colon, slash format- i.e. C:\ + return !((path.Length >= 3) + && (path[1] == Path.VolumeSeparatorChar) + && IsDirectorySeparator(path[2]) + // To match old behavior we'll check the drive character for validity as the path is technically + // not qualified if you don't have a valid drive. "=:\" is the "=" file's default data stream. + && IsValidDriveChar(path[0])); + } + + /// <summary> + /// Returns true if the path specified is relative to the current drive or working directory. + /// Returns false if the path is fixed to a specific drive or UNC path. This method does no + /// validation of the path (URIs will be returned as relative as a result). + /// </summary> + /// <remarks> + /// Handles paths that use the alternate directory separator. It is a frequent mistake to + /// assume that rooted paths (Path.IsPathRooted) are not relative. This isn't the case. + /// "C:a" is drive relative- meaning that it will be resolved against the current directory + /// for C: (rooted, but relative). "C:\a" is rooted and not relative (the current directory + /// will not be used to modify the path). + /// </remarks> + internal static bool IsPartiallyQualified(StringBuffer path) + { + if (path.Length < 2) + { + // It isn't fixed, it must be relative. There is no way to specify a fixed + // path with one character (or less). + return true; + } + + if (IsDirectorySeparator(path[0])) + { + // There is no valid way to specify a relative path with two initial slashes or + // \? as ? isn't valid for drive relative paths and \??\ is equivalent to \\?\ + return !(path[1] == '?' || IsDirectorySeparator(path[1])); + } + + // The only way to specify a fixed path that doesn't begin with two slashes + // is the drive, colon, slash format- i.e. C:\ + return !((path.Length >= 3) + && (path[1] == Path.VolumeSeparatorChar) + && IsDirectorySeparator(path[2]) + // To match old behavior we'll check the drive character for validity as the path is technically + // not qualified if you don't have a valid drive. "=:\" is the "=" file's default data stream. + && IsValidDriveChar(path[0])); + } + + /// <summary> + /// Returns the characters to skip at the start of the path if it starts with space(s) and a drive or directory separator. + /// (examples are " C:", " \") + /// This is a legacy behavior of Path.GetFullPath(). + /// </summary> + /// <remarks> + /// Note that this conflicts with IsPathRooted() which doesn't (and never did) such a skip. + /// </remarks> + internal static int PathStartSkip(string path) + { + int startIndex = 0; + while (startIndex < path.Length && path[startIndex] == ' ') startIndex++; + + if (startIndex > 0 && (startIndex < path.Length && IsDirectorySeparator(path[startIndex])) + || (startIndex + 1 < path.Length && path[startIndex + 1] == Path.VolumeSeparatorChar && IsValidDriveChar(path[startIndex]))) + { + // Go ahead and skip spaces as we're either " C:" or " \" + return startIndex; + } + + return 0; + } + + /// <summary> + /// True if the given character is a directory separator. + /// </summary> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsDirectorySeparator(char c) + { + return c == Path.DirectorySeparatorChar || c == Path.AltDirectorySeparatorChar; + } + + /// <summary> + /// Normalize separators in the given path. Converts forward slashes into back slashes and compresses slash runs, keeping initial 2 if present. + /// Also trims initial whitespace in front of "rooted" paths (see PathStartSkip). + /// + /// This effectively replicates the behavior of the legacy NormalizePath when it was called with fullCheck=false and expandShortpaths=false. + /// The current NormalizePath gets directory separator normalization from Win32's GetFullPathName(), which will resolve relative paths and as + /// such can't be used here (and is overkill for our uses). + /// + /// Like the current NormalizePath this will not try and analyze periods/spaces within directory segments. + /// </summary> + /// <remarks> + /// The only callers that used to use Path.Normalize(fullCheck=false) were Path.GetDirectoryName() and Path.GetPathRoot(). Both usages do + /// not need trimming of trailing whitespace here. + /// + /// GetPathRoot() could technically skip normalizing separators after the second segment- consider as a future optimization. + /// + /// For legacy desktop behavior with ExpandShortPaths: + /// - It has no impact on GetPathRoot() so doesn't need consideration. + /// - It could impact GetDirectoryName(), but only if the path isn't relative (C:\ or \\Server\Share). + /// + /// In the case of GetDirectoryName() the ExpandShortPaths behavior was undocumented and provided inconsistent results if the path was + /// fixed/relative. For example: "C:\PROGRA~1\A.TXT" would return "C:\Program Files" while ".\PROGRA~1\A.TXT" would return ".\PROGRA~1". If you + /// ultimately call GetFullPath() this doesn't matter, but if you don't or have any intermediate string handling could easily be tripped up by + /// this undocumented behavior. + /// </remarks> + internal static string NormalizeDirectorySeparators(string path) + { + if (string.IsNullOrEmpty(path)) return path; + + char current; + int start = PathStartSkip(path); + + if (start == 0) + { + // Make a pass to see if we need to normalize so we can potentially skip allocating + bool normalized = true; + + for (int i = 0; i < path.Length; i++) + { + current = path[i]; + if (IsDirectorySeparator(current) + && (current != Path.DirectorySeparatorChar + // Check for sequential separators past the first position (we need to keep initial two for UNC/extended) + || (i > 0 && i + 1 < path.Length && IsDirectorySeparator(path[i + 1])))) + { + normalized = false; + break; + } + } + + if (normalized) return path; + } + + StringBuilder builder = StringBuilderCache.Acquire(path.Length); + + if (IsDirectorySeparator(path[start])) + { + start++; + builder.Append(Path.DirectorySeparatorChar); + } + + for (int i = start; i < path.Length; i++) + { + current = path[i]; + + // If we have a separator + if (IsDirectorySeparator(current)) + { + // If the next is a separator, skip adding this + if (i + 1 < path.Length && IsDirectorySeparator(path[i + 1])) + { + continue; + } + + // Ensure it is the primary separator + current = Path.DirectorySeparatorChar; + } + + builder.Append(current); + } + + return StringBuilderCache.GetStringAndRelease(builder); + } + } +} diff --git a/mscorlib/system/io/pathtoolongexception.cs b/mscorlib/system/io/pathtoolongexception.cs index aebd4c30d..048e734ac 100644 --- a/mscorlib/system/io/pathtoolongexception.cs +++ b/mscorlib/system/io/pathtoolongexception.cs @@ -7,7 +7,7 @@ ** ** Class: PathTooLongException ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception for paths and/or filenames that are diff --git a/mscorlib/system/io/pinnedbuffermemorystream.cs b/mscorlib/system/io/pinnedbuffermemorystream.cs index 7b45756c7..fda409ae8 100644 --- a/mscorlib/system/io/pinnedbuffermemorystream.cs +++ b/mscorlib/system/io/pinnedbuffermemorystream.cs @@ -7,7 +7,7 @@ ** ** Class: PinnedBufferMemoryStream ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Pins a byte[], exposing it as an unmanaged memory diff --git a/mscorlib/system/io/stringreader.cs b/mscorlib/system/io/stringreader.cs index d4d92c05f..1db58849a 100644 --- a/mscorlib/system/io/stringreader.cs +++ b/mscorlib/system/io/stringreader.cs @@ -7,7 +7,7 @@ ** ** Class: StringReader ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: For reading text from strings ** diff --git a/mscorlib/system/io/stringwriter.cs b/mscorlib/system/io/stringwriter.cs index 6f41279ca..f464f5c1a 100644 --- a/mscorlib/system/io/stringwriter.cs +++ b/mscorlib/system/io/stringwriter.cs @@ -7,7 +7,7 @@ ** ** Class: StringWriter ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: For writing text to a string ** diff --git a/mscorlib/system/io/textreader.cs b/mscorlib/system/io/textreader.cs index 5f8e7b98a..4e5bad0c1 100644 --- a/mscorlib/system/io/textreader.cs +++ b/mscorlib/system/io/textreader.cs @@ -7,7 +7,7 @@ ** ** Class: TextReader ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Abstract base class for all Text-only Readers. diff --git a/mscorlib/system/io/textwriter.cs b/mscorlib/system/io/textwriter.cs index 4dbc025fe..1f1987109 100644 --- a/mscorlib/system/io/textwriter.cs +++ b/mscorlib/system/io/textwriter.cs @@ -7,7 +7,7 @@ ** ** Class: TextWriter ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Abstract base class for Text-only Writers. diff --git a/mscorlib/system/io/unmanagedmemoryaccessor.cs b/mscorlib/system/io/unmanagedmemoryaccessor.cs index 70e100c6e..3d4c571bc 100644 --- a/mscorlib/system/io/unmanagedmemoryaccessor.cs +++ b/mscorlib/system/io/unmanagedmemoryaccessor.cs @@ -7,7 +7,7 @@ ** ** Class: UnmanagedMemoryAccessor ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: Provides a fast, AV free, cross-language way of ** accessing unmanaged memory in a random fashion. diff --git a/mscorlib/system/io/unmanagedmemorystream.cs b/mscorlib/system/io/unmanagedmemorystream.cs index c02d6a7d7..2100d3054 100644 --- a/mscorlib/system/io/unmanagedmemorystream.cs +++ b/mscorlib/system/io/unmanagedmemorystream.cs @@ -7,7 +7,7 @@ ** ** Class: UnmanagedMemoryStream ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: Create a stream over unmanaged memory, mostly ** useful for memory-mapped files. @@ -398,7 +398,7 @@ public override int Read([In, Out] byte[] buffer, int offset, int count) { throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (buffer.Length - offset < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); - Contract.EndContractBlock(); // Keep this in [....] with contract validation in ReadAsync + Contract.EndContractBlock(); // Keep this in sync with contract validation in ReadAsync if (!_isOpen) __Error.StreamIsClosed(); if (!CanRead) __Error.ReadNotSupported(); @@ -577,7 +577,7 @@ public override void Write(byte[] buffer, int offset, int count) { throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); if (buffer.Length - offset < count) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); - Contract.EndContractBlock(); // Keep contract validation in [....] with WriteAsync(..) + Contract.EndContractBlock(); // Keep contract validation in sync with WriteAsync(..) if (!_isOpen) __Error.StreamIsClosed(); if (!CanWrite) __Error.WriteNotSupported(); diff --git a/mscorlib/system/io/unmanagedmemorystreamwrapper.cs b/mscorlib/system/io/unmanagedmemorystreamwrapper.cs index 20535e702..613241bab 100644 --- a/mscorlib/system/io/unmanagedmemorystreamwrapper.cs +++ b/mscorlib/system/io/unmanagedmemorystreamwrapper.cs @@ -7,7 +7,7 @@ ** ** Class: UnmanagedMemoryStreamWrapper ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: Create a Memorystream over an UnmanagedMemoryStream ** @@ -152,7 +152,7 @@ public override void SetLength(Int64 value) { public override Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken) { - // The parameter checks must be in [....] with the base version: + // The parameter checks must be in sync with the base version: if (destination == null) throw new ArgumentNullException("destination"); diff --git a/mscorlib/system/object.cs b/mscorlib/system/object.cs index 2d9f91e83..6c27df75d 100644 --- a/mscorlib/system/object.cs +++ b/mscorlib/system/object.cs @@ -86,7 +86,7 @@ public static bool ReferenceEquals (Object objA, Object objB) { // Based on the contents of the object, the hash function will return a suitable // value with a relatively random distribution over the various inputs. // - // The default implementation returns the [....] block index for this instance. + // The default implementation returns the sync block index for this instance. // Calling it on the same object multiple times will return the same value, so // it will technically meet the needs of a hash function, but it's less than ideal. // Objects (& especially value classes) should override this method. diff --git a/mscorlib/system/progress.cs b/mscorlib/system/progress.cs index 6b273c894..a85eeeb73 100644 --- a/mscorlib/system/progress.cs +++ b/mscorlib/system/progress.cs @@ -7,7 +7,7 @@ ** ** Class: Progress<T> ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Event-based implementation of IProgress<T>. @@ -46,8 +46,8 @@ public class Progress<T> : IProgress<T> public Progress() { // Capture the current synchronization context. "current" is determined by CurrentNoFlow, - // which doesn't consider the [....] ctx flown with an ExecutionContext, avoiding - // [....] ctx reference identity issues where the [....] ctx for one thread could be Current on another. + // which doesn't consider the sync ctx flown with an ExecutionContext, avoiding + // sync ctx reference identity issues where the sync ctx for one thread could be Current on another. // If there is no current context, we use a default instance targeting the ThreadPool. m_synchronizationContext = SynchronizationContext.CurrentNoFlow ?? ProgressStatics.DefaultContext; Contract.Assert(m_synchronizationContext != null); @@ -80,14 +80,14 @@ public Progress(Action<T> handler) : this() /// <param name="value">The value of the updated progress.</param> protected virtual void OnReport(T value) { - // If there's no handler, don't bother going through the [....] context. + // If there's no handler, don't bother going through the sync context. // Inside the callback, we'll need to check again, in case // an event handler is removed between now and then. Action<T> handler = m_handler; EventHandler<T> changedEvent = ProgressChanged; if (handler != null || changedEvent != null) { - // Post the processing to the [....] context. + // Post the processing to the sync context. // (If T is a value type, it will get boxed here.) m_synchronizationContext.Post(m_invokeHandlers, value); } diff --git a/mscorlib/system/reflection/Associates.cs b/mscorlib/system/reflection/Associates.cs index 3f9c8e559..e2a1842a4 100644 --- a/mscorlib/system/reflection/Associates.cs +++ b/mscorlib/system/reflection/Associates.cs @@ -3,7 +3,7 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/ConstructorInfo.cs b/mscorlib/system/reflection/ConstructorInfo.cs index 6704bd53f..dfc2d64d8 100644 --- a/mscorlib/system/reflection/ConstructorInfo.cs +++ b/mscorlib/system/reflection/ConstructorInfo.cs @@ -3,7 +3,7 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/__filters.cs b/mscorlib/system/reflection/__filters.cs index 951881c29..b4f925948 100644 --- a/mscorlib/system/reflection/__filters.cs +++ b/mscorlib/system/reflection/__filters.cs @@ -6,7 +6,7 @@ //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // This class defines the delegate methods for the COM+ implemented filters. // This is the reflection version of these. There is also a _Filters class in diff --git a/mscorlib/system/reflection/ambiguousmatchexception.cs b/mscorlib/system/reflection/ambiguousmatchexception.cs index b6f715ae2..cfff77d66 100644 --- a/mscorlib/system/reflection/ambiguousmatchexception.cs +++ b/mscorlib/system/reflection/ambiguousmatchexception.cs @@ -8,7 +8,7 @@ // // AmbiguousMatchException is thrown when binding to a method results in more // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // than one method matching the binding criteria. This exception is thrown in // general when something is Ambiguous. // diff --git a/mscorlib/system/reflection/assembly.cs b/mscorlib/system/reflection/assembly.cs index 24bd73651..2f0a22723 100644 --- a/mscorlib/system/reflection/assembly.cs +++ b/mscorlib/system/reflection/assembly.cs @@ -1146,7 +1146,7 @@ public virtual bool IsDynamic } - // Keep this in [....] with LOADCTX_TYPE defined in fusionpriv.idl + // Keep this in sync with LOADCTX_TYPE defined in fusionpriv.idl internal enum LoadContext { DEFAULT, diff --git a/mscorlib/system/reflection/assemblyattributes.cs b/mscorlib/system/reflection/assemblyattributes.cs index b3fec0ba1..d222ee51a 100644 --- a/mscorlib/system/reflection/assemblyattributes.cs +++ b/mscorlib/system/reflection/assemblyattributes.cs @@ -7,7 +7,7 @@ ** ** File: AssemblyAttributes ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: For Assembly-related custom attributes. diff --git a/mscorlib/system/reflection/assemblyname.cs b/mscorlib/system/reflection/assemblyname.cs index a7e5857d0..802414cc0 100644 --- a/mscorlib/system/reflection/assemblyname.cs +++ b/mscorlib/system/reflection/assemblyname.cs @@ -7,8 +7,8 @@ ** ** File: AssemblyName ** -** <OWNER>[....]</OWNER> -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Used for binding and retrieving info about an assembly diff --git a/mscorlib/system/reflection/assemblynameproxy.cs b/mscorlib/system/reflection/assemblynameproxy.cs index dc844de41..5be9bc495 100644 --- a/mscorlib/system/reflection/assemblynameproxy.cs +++ b/mscorlib/system/reflection/assemblynameproxy.cs @@ -7,8 +7,8 @@ ** ** File: AssemblyNameProxy ** -** <OWNER>[....]</OWNER> -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Remotable version the AssemblyName diff --git a/mscorlib/system/reflection/customattribute.cs b/mscorlib/system/reflection/customattribute.cs index 4dfeb2679..46ee3f08f 100644 --- a/mscorlib/system/reflection/customattribute.cs +++ b/mscorlib/system/reflection/customattribute.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/reflection/customattributeformatexception.cs b/mscorlib/system/reflection/customattributeformatexception.cs index 093314aba..1d158db80 100644 --- a/mscorlib/system/reflection/customattributeformatexception.cs +++ b/mscorlib/system/reflection/customattributeformatexception.cs @@ -8,11 +8,11 @@ // // CustomAttributeFormatException is thrown when the binary format of a // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // custom attribute is invalid. // // <EMAIL>Author: darylo</EMAIL> -// Date: [....] 98 +// Date: Microsoft 98 // namespace System.Reflection { using System; diff --git a/mscorlib/system/reflection/defaultmemberattribute.cs b/mscorlib/system/reflection/defaultmemberattribute.cs index 00d6ab38e..28af33c9d 100644 --- a/mscorlib/system/reflection/defaultmemberattribute.cs +++ b/mscorlib/system/reflection/defaultmemberattribute.cs @@ -8,7 +8,7 @@ // // DefaultMemberAttribute is defines the Member of a Type that is the "default" // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // member used by Type.InvokeMember. The default member is simply a name given // to a type. // diff --git a/mscorlib/system/reflection/emit/aqnbuilder.cs b/mscorlib/system/reflection/emit/aqnbuilder.cs index 35c267da6..e715f5836 100644 --- a/mscorlib/system/reflection/emit/aqnbuilder.cs +++ b/mscorlib/system/reflection/emit/aqnbuilder.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Collections.Generic; using System.Runtime.CompilerServices; diff --git a/mscorlib/system/reflection/emit/assemblybuilder.cs b/mscorlib/system/reflection/emit/assemblybuilder.cs index 221618061..f8099ccd8 100644 --- a/mscorlib/system/reflection/emit/assemblybuilder.cs +++ b/mscorlib/system/reflection/emit/assemblybuilder.cs @@ -23,7 +23,7 @@ // "internal" and "external" ModuleBuilders are similar //************************************************************************************************************* -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Reflection.Emit { using System; @@ -475,7 +475,7 @@ private void InitManifestModule() // The name in the underlying metadata will be set when the // manifest module is created during nCreateDynamicAssembly. - // This name needs to stay in [....] with that used in + // This name needs to stay in sync with that used in // Assembly::Init to call ReflectionModule::Create (in VM) m_manifestModuleBuilder.Init(AssemblyBuilder.MANIFEST_MODULE_NAME, null, 0); diff --git a/mscorlib/system/reflection/emit/assemblybuilderdata.cs b/mscorlib/system/reflection/emit/assemblybuilderdata.cs index cc02531a6..fbce6487b 100644 --- a/mscorlib/system/reflection/emit/assemblybuilderdata.cs +++ b/mscorlib/system/reflection/emit/assemblybuilderdata.cs @@ -5,7 +5,7 @@ // ==--== //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit { diff --git a/mscorlib/system/reflection/emit/constructorbuilder.cs b/mscorlib/system/reflection/emit/constructorbuilder.cs index 3a1435b90..ec850ba4d 100644 --- a/mscorlib/system/reflection/emit/constructorbuilder.cs +++ b/mscorlib/system/reflection/emit/constructorbuilder.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/customattributebuilder.cs b/mscorlib/system/reflection/emit/customattributebuilder.cs index cb0aa8cac..c4cc7d299 100644 --- a/mscorlib/system/reflection/emit/customattributebuilder.cs +++ b/mscorlib/system/reflection/emit/customattributebuilder.cs @@ -5,7 +5,7 @@ // ==--== /*============================================================ ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Class: CustomAttrbuteBuilder ** diff --git a/mscorlib/system/reflection/emit/dynamicilgenerator.cs b/mscorlib/system/reflection/emit/dynamicilgenerator.cs index f26816471..6f86bcd1f 100644 --- a/mscorlib/system/reflection/emit/dynamicilgenerator.cs +++ b/mscorlib/system/reflection/emit/dynamicilgenerator.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit @@ -799,7 +799,7 @@ private class DestroyScout } } - // Keep in [....] with vm/dynamicmethod.h + // Keep in sync with vm/dynamicmethod.h [Flags] internal enum SecurityControlFlags { diff --git a/mscorlib/system/reflection/emit/dynamicmethod.cs b/mscorlib/system/reflection/emit/dynamicmethod.cs index 23a7baa1f..71ee85706 100644 --- a/mscorlib/system/reflection/emit/dynamicmethod.cs +++ b/mscorlib/system/reflection/emit/dynamicmethod.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/enumbuilder.cs b/mscorlib/system/reflection/emit/enumbuilder.cs index 7cea00bdc..f6be53add 100644 --- a/mscorlib/system/reflection/emit/enumbuilder.cs +++ b/mscorlib/system/reflection/emit/enumbuilder.cs @@ -7,7 +7,7 @@ ** ** Class: EnumBuilder ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** EnumBuilder is a helper class to build Enum ( a special type ). diff --git a/mscorlib/system/reflection/emit/eventbuilder.cs b/mscorlib/system/reflection/emit/eventbuilder.cs index 0fea09464..e6bd4327f 100644 --- a/mscorlib/system/reflection/emit/eventbuilder.cs +++ b/mscorlib/system/reflection/emit/eventbuilder.cs @@ -7,7 +7,7 @@ ** ** Class: EventBuilder ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Eventbuilder is for client to define eevnts for a class diff --git a/mscorlib/system/reflection/emit/eventtoken.cs b/mscorlib/system/reflection/emit/eventtoken.cs index a12e442aa..737c95c3d 100644 --- a/mscorlib/system/reflection/emit/eventtoken.cs +++ b/mscorlib/system/reflection/emit/eventtoken.cs @@ -7,7 +7,7 @@ ** ** Class: EventToken ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Propertybuilder is for client to define properties for a class diff --git a/mscorlib/system/reflection/emit/fieldbuilder.cs b/mscorlib/system/reflection/emit/fieldbuilder.cs index c38cc21d3..43cf5cedd 100644 --- a/mscorlib/system/reflection/emit/fieldbuilder.cs +++ b/mscorlib/system/reflection/emit/fieldbuilder.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/fieldtoken.cs b/mscorlib/system/reflection/emit/fieldtoken.cs index 1684ef054..e043c0f7f 100644 --- a/mscorlib/system/reflection/emit/fieldtoken.cs +++ b/mscorlib/system/reflection/emit/fieldtoken.cs @@ -7,7 +7,7 @@ ** ** Class: FieldToken ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Represents a Field to the ILGenerator Class diff --git a/mscorlib/system/reflection/emit/generictypeparameterbuilder.cs b/mscorlib/system/reflection/emit/generictypeparameterbuilder.cs index 8a6f6e540..f9e701e4c 100644 --- a/mscorlib/system/reflection/emit/generictypeparameterbuilder.cs +++ b/mscorlib/system/reflection/emit/generictypeparameterbuilder.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/ilgenerator.cs b/mscorlib/system/reflection/emit/ilgenerator.cs index 475fc3d0f..44f61a5dd 100644 --- a/mscorlib/system/reflection/emit/ilgenerator.cs +++ b/mscorlib/system/reflection/emit/ilgenerator.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/label.cs b/mscorlib/system/reflection/emit/label.cs index 577f1960d..d0ee014f0 100644 --- a/mscorlib/system/reflection/emit/label.cs +++ b/mscorlib/system/reflection/emit/label.cs @@ -7,7 +7,7 @@ ** ** Class: Label ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** diff --git a/mscorlib/system/reflection/emit/localbuilder.cs b/mscorlib/system/reflection/emit/localbuilder.cs index 51f6f15bb..77352947c 100644 --- a/mscorlib/system/reflection/emit/localbuilder.cs +++ b/mscorlib/system/reflection/emit/localbuilder.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Reflection; using System.Security.Permissions; diff --git a/mscorlib/system/reflection/emit/methodbuilder.cs b/mscorlib/system/reflection/emit/methodbuilder.cs index 6cbed85f1..d7bfb9c25 100644 --- a/mscorlib/system/reflection/emit/methodbuilder.cs +++ b/mscorlib/system/reflection/emit/methodbuilder.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit @@ -1404,7 +1404,7 @@ internal virtual void EmitLocalSymInfo(ISymbolWriter symWriter) [ComVisible(false)] public struct ExceptionHandler : IEquatable<ExceptionHandler> { - // Keep in [....] with unmanged structure. + // Keep in sync with unmanged structure. internal readonly int m_exceptionClass; internal readonly int m_tryStartOffset; internal readonly int m_tryEndOffset; diff --git a/mscorlib/system/reflection/emit/methodbuilderinstantiation.cs b/mscorlib/system/reflection/emit/methodbuilderinstantiation.cs index 1a7db5cec..3b73e1b24 100644 --- a/mscorlib/system/reflection/emit/methodbuilderinstantiation.cs +++ b/mscorlib/system/reflection/emit/methodbuilderinstantiation.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/methodrental.cs b/mscorlib/system/reflection/emit/methodrental.cs index e54ffa506..c4e980c95 100644 --- a/mscorlib/system/reflection/emit/methodrental.cs +++ b/mscorlib/system/reflection/emit/methodrental.cs @@ -7,7 +7,7 @@ ** ** Class: MethodRental ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** MethodRental class is to provide a fast way to swap method body implementation diff --git a/mscorlib/system/reflection/emit/methodtoken.cs b/mscorlib/system/reflection/emit/methodtoken.cs index 92d2c9d9f..18c050acc 100644 --- a/mscorlib/system/reflection/emit/methodtoken.cs +++ b/mscorlib/system/reflection/emit/methodtoken.cs @@ -7,7 +7,7 @@ ** ** Class: MethodToken ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Represents a Method to the ILGenerator class. diff --git a/mscorlib/system/reflection/emit/modulebuilder.cs b/mscorlib/system/reflection/emit/modulebuilder.cs index e64bd9bd9..c872fa065 100644 --- a/mscorlib/system/reflection/emit/modulebuilder.cs +++ b/mscorlib/system/reflection/emit/modulebuilder.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/modulebuilderdata.cs b/mscorlib/system/reflection/emit/modulebuilderdata.cs index 36f17022e..0252f9dba 100644 --- a/mscorlib/system/reflection/emit/modulebuilderdata.cs +++ b/mscorlib/system/reflection/emit/modulebuilderdata.cs @@ -5,7 +5,7 @@ // ==--== //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/opcode.cs b/mscorlib/system/reflection/emit/opcode.cs index b0110f5f8..477b3595e 100644 --- a/mscorlib/system/reflection/emit/opcode.cs +++ b/mscorlib/system/reflection/emit/opcode.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Reflection.Emit { using System; using System.Threading; diff --git a/mscorlib/system/reflection/emit/opcodes.cs b/mscorlib/system/reflection/emit/opcodes.cs index f7b85f815..0b0cb66a0 100644 --- a/mscorlib/system/reflection/emit/opcodes.cs +++ b/mscorlib/system/reflection/emit/opcodes.cs @@ -2,7 +2,7 @@ ** **Class: OpCodes ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** **Purpose: Exposes all of the il instructions supported by the runtime. ** diff --git a/mscorlib/system/reflection/emit/parameterbuilder.cs b/mscorlib/system/reflection/emit/parameterbuilder.cs index 840e8bdcb..fbcb9cad9 100644 --- a/mscorlib/system/reflection/emit/parameterbuilder.cs +++ b/mscorlib/system/reflection/emit/parameterbuilder.cs @@ -7,7 +7,7 @@ ** ** Class: ParameterBuilder ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** ParameterBuilder is used to create/associate parameter information diff --git a/mscorlib/system/reflection/emit/parametertoken.cs b/mscorlib/system/reflection/emit/parametertoken.cs index b4fa891db..109641ef2 100644 --- a/mscorlib/system/reflection/emit/parametertoken.cs +++ b/mscorlib/system/reflection/emit/parametertoken.cs @@ -7,7 +7,7 @@ ** ** Class: ParameterToken ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: metadata tokens for a parameter diff --git a/mscorlib/system/reflection/emit/propertybuilder.cs b/mscorlib/system/reflection/emit/propertybuilder.cs index 57cd6df97..b3a73689f 100644 --- a/mscorlib/system/reflection/emit/propertybuilder.cs +++ b/mscorlib/system/reflection/emit/propertybuilder.cs @@ -7,7 +7,7 @@ ** ** Class: PropertyBuilder ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Propertybuilder is for client to define properties for a class diff --git a/mscorlib/system/reflection/emit/propertytoken.cs b/mscorlib/system/reflection/emit/propertytoken.cs index db59f5d80..a29d4c6f4 100644 --- a/mscorlib/system/reflection/emit/propertytoken.cs +++ b/mscorlib/system/reflection/emit/propertytoken.cs @@ -7,7 +7,7 @@ ** ** Class: PropertyToken ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Propertybuilder is for client to define properties for a class diff --git a/mscorlib/system/reflection/emit/signaturehelper.cs b/mscorlib/system/reflection/emit/signaturehelper.cs index 9c61d53dd..05b2d9f40 100644 --- a/mscorlib/system/reflection/emit/signaturehelper.cs +++ b/mscorlib/system/reflection/emit/signaturehelper.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/signaturetoken.cs b/mscorlib/system/reflection/emit/signaturetoken.cs index 2ae4c1eec..a41b2d292 100644 --- a/mscorlib/system/reflection/emit/signaturetoken.cs +++ b/mscorlib/system/reflection/emit/signaturetoken.cs @@ -7,7 +7,7 @@ ** ** Signature: SignatureToken ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Represents a Signature to the ILGenerator signature. diff --git a/mscorlib/system/reflection/emit/stringtoken.cs b/mscorlib/system/reflection/emit/stringtoken.cs index b568cef11..ad7216a46 100644 --- a/mscorlib/system/reflection/emit/stringtoken.cs +++ b/mscorlib/system/reflection/emit/stringtoken.cs @@ -7,7 +7,7 @@ ** ** Class: StringToken ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Represents a String to the ILGenerator class. diff --git a/mscorlib/system/reflection/emit/symbolmethod.cs b/mscorlib/system/reflection/emit/symbolmethod.cs index 136789441..8bca9063d 100644 --- a/mscorlib/system/reflection/emit/symbolmethod.cs +++ b/mscorlib/system/reflection/emit/symbolmethod.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/symboltype.cs b/mscorlib/system/reflection/emit/symboltype.cs index 18f321e7e..f6fb66fc3 100644 --- a/mscorlib/system/reflection/emit/symboltype.cs +++ b/mscorlib/system/reflection/emit/symboltype.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/typebuilder.cs b/mscorlib/system/reflection/emit/typebuilder.cs index 7833c8f6a..9cf13f212 100644 --- a/mscorlib/system/reflection/emit/typebuilder.cs +++ b/mscorlib/system/reflection/emit/typebuilder.cs @@ -4,7 +4,7 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit { diff --git a/mscorlib/system/reflection/emit/typebuilderinstantiation.cs b/mscorlib/system/reflection/emit/typebuilderinstantiation.cs index 0db7978df..61101139e 100644 --- a/mscorlib/system/reflection/emit/typebuilderinstantiation.cs +++ b/mscorlib/system/reflection/emit/typebuilderinstantiation.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/emit/typetoken.cs b/mscorlib/system/reflection/emit/typetoken.cs index bfc3c1611..da4b521d1 100644 --- a/mscorlib/system/reflection/emit/typetoken.cs +++ b/mscorlib/system/reflection/emit/typetoken.cs @@ -7,7 +7,7 @@ ** ** Class: TypeToken ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Represents a Class to the ILGenerator class. diff --git a/mscorlib/system/reflection/emit/unmanagedmarshal.cs b/mscorlib/system/reflection/emit/unmanagedmarshal.cs index 1d2ab1063..5951fc9f5 100644 --- a/mscorlib/system/reflection/emit/unmanagedmarshal.cs +++ b/mscorlib/system/reflection/emit/unmanagedmarshal.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Reflection.Emit { using System.Runtime.InteropServices; diff --git a/mscorlib/system/reflection/emit/xxxontypebuilderinstantiation.cs b/mscorlib/system/reflection/emit/xxxontypebuilderinstantiation.cs index 59ae15e5f..71a3b53dd 100644 --- a/mscorlib/system/reflection/emit/xxxontypebuilderinstantiation.cs +++ b/mscorlib/system/reflection/emit/xxxontypebuilderinstantiation.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection.Emit diff --git a/mscorlib/system/reflection/eventinfo.cs b/mscorlib/system/reflection/eventinfo.cs index c81f87593..34f324199 100644 --- a/mscorlib/system/reflection/eventinfo.cs +++ b/mscorlib/system/reflection/eventinfo.cs @@ -3,7 +3,7 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/fieldinfo.cs b/mscorlib/system/reflection/fieldinfo.cs index 3a7bdfc19..9f7f9494b 100644 --- a/mscorlib/system/reflection/fieldinfo.cs +++ b/mscorlib/system/reflection/fieldinfo.cs @@ -3,7 +3,7 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/introspectionextensions.cs b/mscorlib/system/reflection/introspectionextensions.cs index 4d393c99b..95ba52799 100644 --- a/mscorlib/system/reflection/introspectionextensions.cs +++ b/mscorlib/system/reflection/introspectionextensions.cs @@ -7,7 +7,7 @@ ** ** Class: TypeInfoExtension ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: go from type to type info diff --git a/mscorlib/system/reflection/invalidfiltercriteriaexception.cs b/mscorlib/system/reflection/invalidfiltercriteriaexception.cs index 8c7365319..c7ae1c8a1 100644 --- a/mscorlib/system/reflection/invalidfiltercriteriaexception.cs +++ b/mscorlib/system/reflection/invalidfiltercriteriaexception.cs @@ -8,7 +8,7 @@ // // InvalidFilterCriteriaException is thrown in FindMembers when the // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // filter criteria is not valid for the type of filter being used. // // diff --git a/mscorlib/system/reflection/loaderallocator.cs b/mscorlib/system/reflection/loaderallocator.cs index 4b35f9fdd..d8ff5d79d 100644 --- a/mscorlib/system/reflection/loaderallocator.cs +++ b/mscorlib/system/reflection/loaderallocator.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/reflection/manifestresourceinfo.cs b/mscorlib/system/reflection/manifestresourceinfo.cs index 496012a52..6026f53d8 100644 --- a/mscorlib/system/reflection/manifestresourceinfo.cs +++ b/mscorlib/system/reflection/manifestresourceinfo.cs @@ -7,7 +7,7 @@ ** ** Class: ManifestResourceInfo ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: For info regarding a manifest resource's topology. diff --git a/mscorlib/system/reflection/mdconstant.cs b/mscorlib/system/reflection/mdconstant.cs index f78dc8fb2..3f69c080c 100644 --- a/mscorlib/system/reflection/mdconstant.cs +++ b/mscorlib/system/reflection/mdconstant.cs @@ -3,7 +3,7 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/mdimport.cs b/mscorlib/system/reflection/mdimport.cs index 86d3a25a1..9ff1e3c6c 100644 --- a/mscorlib/system/reflection/mdimport.cs +++ b/mscorlib/system/reflection/mdimport.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; @@ -190,7 +190,7 @@ public byte this[int index] } } - // Keep the definition in [....] with vm\ManagedMdImport.hpp + // Keep the definition in sync with vm\ManagedMdImport.hpp internal int m_length; internal IntPtr m_constArray; } @@ -256,7 +256,7 @@ public static bool IsNullToken(int token) internal unsafe struct MetadataEnumResult { - // Keep the definition in [....] with vm\ManagedMdImport.hpp + // Keep the definition in sync with vm\ManagedMdImport.hpp private int[] largeResult; private int length; private fixed int smallResult[16]; diff --git a/mscorlib/system/reflection/memberinfo.cs b/mscorlib/system/reflection/memberinfo.cs index 33b5c9c7b..ebdb307ba 100644 --- a/mscorlib/system/reflection/memberinfo.cs +++ b/mscorlib/system/reflection/memberinfo.cs @@ -3,7 +3,7 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/memberinfoserializationholder.cs b/mscorlib/system/reflection/memberinfoserializationholder.cs index ee3e0e31b..772cccd6e 100644 --- a/mscorlib/system/reflection/memberinfoserializationholder.cs +++ b/mscorlib/system/reflection/memberinfoserializationholder.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/reflection/methodbase.cs b/mscorlib/system/reflection/methodbase.cs index d36402ddf..f2536f4b7 100644 --- a/mscorlib/system/reflection/methodbase.cs +++ b/mscorlib/system/reflection/methodbase.cs @@ -3,7 +3,7 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/methodbody.cs b/mscorlib/system/reflection/methodbody.cs index 005650ac6..08570cf4b 100644 --- a/mscorlib/system/reflection/methodbody.cs +++ b/mscorlib/system/reflection/methodbody.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/reflection/methodinfo.cs b/mscorlib/system/reflection/methodinfo.cs index 6b8acb771..0987d8225 100644 --- a/mscorlib/system/reflection/methodinfo.cs +++ b/mscorlib/system/reflection/methodinfo.cs @@ -3,7 +3,7 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/missing.cs b/mscorlib/system/reflection/missing.cs index d203d31aa..7b310ebfa 100644 --- a/mscorlib/system/reflection/missing.cs +++ b/mscorlib/system/reflection/missing.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/module.cs b/mscorlib/system/reflection/module.cs index fb10e18a0..b318b3901 100644 --- a/mscorlib/system/reflection/module.cs +++ b/mscorlib/system/reflection/module.cs @@ -4,8 +4,8 @@ // // ==--== //////////////////////////////////////////////////////////////////////////////// -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/obfuscateassemblyattribute.cs b/mscorlib/system/reflection/obfuscateassemblyattribute.cs index 287a19a76..4c38baf4b 100644 --- a/mscorlib/system/reflection/obfuscateassemblyattribute.cs +++ b/mscorlib/system/reflection/obfuscateassemblyattribute.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/reflection/obfuscationattribute.cs b/mscorlib/system/reflection/obfuscationattribute.cs index 3bede5dea..5e9a137cd 100644 --- a/mscorlib/system/reflection/obfuscationattribute.cs +++ b/mscorlib/system/reflection/obfuscationattribute.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/reflection/parameterinfo.cs b/mscorlib/system/reflection/parameterinfo.cs index 8f6739f1d..0494899bc 100644 --- a/mscorlib/system/reflection/parameterinfo.cs +++ b/mscorlib/system/reflection/parameterinfo.cs @@ -3,7 +3,7 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/parametermodifier.cs b/mscorlib/system/reflection/parametermodifier.cs index 545ea83eb..ee168addd 100644 --- a/mscorlib/system/reflection/parametermodifier.cs +++ b/mscorlib/system/reflection/parametermodifier.cs @@ -4,7 +4,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/pointer.cs b/mscorlib/system/reflection/pointer.cs index ec703d95e..636795024 100644 --- a/mscorlib/system/reflection/pointer.cs +++ b/mscorlib/system/reflection/pointer.cs @@ -7,7 +7,7 @@ // // This is a wrapper class for Pointers // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // // diff --git a/mscorlib/system/reflection/propertyinfo.cs b/mscorlib/system/reflection/propertyinfo.cs index f105a9ce3..2ea511c43 100644 --- a/mscorlib/system/reflection/propertyinfo.cs +++ b/mscorlib/system/reflection/propertyinfo.cs @@ -3,7 +3,7 @@ // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Reflection diff --git a/mscorlib/system/reflection/reflectioncontext.cs b/mscorlib/system/reflection/reflectioncontext.cs index d559a661f..3b8539732 100644 --- a/mscorlib/system/reflection/reflectioncontext.cs +++ b/mscorlib/system/reflection/reflectioncontext.cs @@ -7,7 +7,7 @@ ** ** Class: ReflectionContext ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: For Assembly-related stuff. diff --git a/mscorlib/system/reflection/reflectiontypeloadexception.cs b/mscorlib/system/reflection/reflectiontypeloadexception.cs index 07baefda6..df95e64a2 100644 --- a/mscorlib/system/reflection/reflectiontypeloadexception.cs +++ b/mscorlib/system/reflection/reflectiontypeloadexception.cs @@ -8,7 +8,7 @@ // // ReflectionTypeLoadException is thrown when multiple TypeLoadExceptions may occur. // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // Specifically, when you call Module.GetTypes() this causes multiple class loads to occur. // If there are failures, we continue to load classes and build an array of the successfully // loaded classes. We also build an array of the errors that occur. Then we throw this exception diff --git a/mscorlib/system/reflection/strongnamekeypair.cs b/mscorlib/system/reflection/strongnamekeypair.cs index b4a736415..6734a4850 100644 --- a/mscorlib/system/reflection/strongnamekeypair.cs +++ b/mscorlib/system/reflection/strongnamekeypair.cs @@ -7,7 +7,7 @@ ** ** File: StrongNameKeyPair.cs ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Encapsulate access to a public/private key pair diff --git a/mscorlib/system/reflection/targetexception.cs b/mscorlib/system/reflection/targetexception.cs index caba5efd1..c3e51193f 100644 --- a/mscorlib/system/reflection/targetexception.cs +++ b/mscorlib/system/reflection/targetexception.cs @@ -8,7 +8,7 @@ // // TargetException is thrown when the target to an Invoke is invalid. This may // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // occur because the caller doesn't have access to the member, or the target doesn't // define the member, etc. // diff --git a/mscorlib/system/reflection/targetinvocationexception.cs b/mscorlib/system/reflection/targetinvocationexception.cs index 0df1faa9d..dbe11f215 100644 --- a/mscorlib/system/reflection/targetinvocationexception.cs +++ b/mscorlib/system/reflection/targetinvocationexception.cs @@ -8,7 +8,7 @@ // // TargetInvocationException is used to report an exception that was thrown // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // by the target of an invocation. // // diff --git a/mscorlib/system/reflection/targetparametercountexception.cs b/mscorlib/system/reflection/targetparametercountexception.cs index d350a07c2..60007d1cd 100644 --- a/mscorlib/system/reflection/targetparametercountexception.cs +++ b/mscorlib/system/reflection/targetparametercountexception.cs @@ -8,7 +8,7 @@ // // TargetParameterCountException is thrown when the number of parameter to an // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // invocation doesn't match the number expected. // // diff --git a/mscorlib/system/reflection/typedelegator.cs b/mscorlib/system/reflection/typedelegator.cs index 59d567cb2..053c9f58e 100644 --- a/mscorlib/system/reflection/typedelegator.cs +++ b/mscorlib/system/reflection/typedelegator.cs @@ -5,7 +5,7 @@ // ==--== // TypeDelegator // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // This class wraps a Type object and delegates all methods to that Type. namespace System.Reflection { diff --git a/mscorlib/system/reflection/typeinfo.cs b/mscorlib/system/reflection/typeinfo.cs index 842f9e306..098b0add8 100644 --- a/mscorlib/system/reflection/typeinfo.cs +++ b/mscorlib/system/reflection/typeinfo.cs @@ -7,7 +7,7 @@ ** ** Class: TypeInfo ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Notion of a type definition diff --git a/mscorlib/system/resources/__fastresourcecomparer.cs b/mscorlib/system/resources/__fastresourcecomparer.cs index 9b315a100..e04fca6aa 100644 --- a/mscorlib/system/resources/__fastresourcecomparer.cs +++ b/mscorlib/system/resources/__fastresourcecomparer.cs @@ -5,7 +5,7 @@ // ==--== /*============================================================ ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Class: FastResourceComparer ** diff --git a/mscorlib/system/resources/filebasedresourcegroveler.cs b/mscorlib/system/resources/filebasedresourcegroveler.cs index ef75370fe..c1ea5b4f9 100644 --- a/mscorlib/system/resources/filebasedresourcegroveler.cs +++ b/mscorlib/system/resources/filebasedresourcegroveler.cs @@ -7,7 +7,7 @@ ** ** Class: FileBasedResourceGroveler ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Searches for resources on disk, used for file- diff --git a/mscorlib/system/resources/manifestbasedresourcegroveler.cs b/mscorlib/system/resources/manifestbasedresourcegroveler.cs index f834ac321..6cb592a6d 100644 --- a/mscorlib/system/resources/manifestbasedresourcegroveler.cs +++ b/mscorlib/system/resources/manifestbasedresourcegroveler.cs @@ -7,7 +7,7 @@ ** ** Class: ManifestBasedResourceGroveler ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Searches for resources in Assembly manifest, used diff --git a/mscorlib/system/resources/missingmanifestresourceexception.cs b/mscorlib/system/resources/missingmanifestresourceexception.cs index 5230ce273..2baaaf322 100644 --- a/mscorlib/system/resources/missingmanifestresourceexception.cs +++ b/mscorlib/system/resources/missingmanifestresourceexception.cs @@ -7,7 +7,7 @@ ** ** Class: MissingManifestResourceException ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception for a missing assembly-level resource diff --git a/mscorlib/system/resources/missingsatelliteassemblyexception.cs b/mscorlib/system/resources/missingsatelliteassemblyexception.cs index 66de05a64..e9099224a 100644 --- a/mscorlib/system/resources/missingsatelliteassemblyexception.cs +++ b/mscorlib/system/resources/missingsatelliteassemblyexception.cs @@ -7,7 +7,7 @@ ** ** Class: MissingSatelliteAssemblyException ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception for a missing satellite assembly needed diff --git a/mscorlib/system/resources/neutralresourceslanguageattribute.cs b/mscorlib/system/resources/neutralresourceslanguageattribute.cs index 9ab5e027c..e22f68833 100644 --- a/mscorlib/system/resources/neutralresourceslanguageattribute.cs +++ b/mscorlib/system/resources/neutralresourceslanguageattribute.cs @@ -7,7 +7,7 @@ ** ** Class: NeutralResourcesLanguageAttribute ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Tells the ResourceManager what language your main diff --git a/mscorlib/system/resources/resourcefallbackmanager.cs b/mscorlib/system/resources/resourcefallbackmanager.cs index 1b5ce87f6..813909655 100644 --- a/mscorlib/system/resources/resourcefallbackmanager.cs +++ b/mscorlib/system/resources/resourcefallbackmanager.cs @@ -7,7 +7,7 @@ ** ** Class: ResourceFallbackManager ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Encapsulates CultureInfo fallback for resource @@ -67,7 +67,7 @@ IEnumerator IEnumerable.GetEnumerator() return GetEnumerator(); } - // WARING: This function must be kept in [....] with ResourceManager.GetFirstResourceSet() + // WARING: This function must be kept in sync with ResourceManager.GetFirstResourceSet() public IEnumerator<CultureInfo> GetEnumerator() { bool reachedNeutralResourcesCulture = false; diff --git a/mscorlib/system/resources/resourcemanager.cs b/mscorlib/system/resources/resourcemanager.cs index a5f90db3e..0226fb84d 100644 --- a/mscorlib/system/resources/resourcemanager.cs +++ b/mscorlib/system/resources/resourcemanager.cs @@ -66,7 +66,7 @@ public virtual CultureInfo GlobalResourceContextBestFitCultureInfo { } [FriendAccessAllowed] - // [[....] 3/9/2012] This class should be named PRIErrorInfo. + // [Microsoft 3/9/2012] This class should be named PRIErrorInfo. // // During Dev11 CLR RC Ask mode, the Windows Modern Resource Manager // made a breaking change such that ResourceMap.GetSubtree returns null when a subtree is @@ -644,7 +644,7 @@ protected virtual String GetResourceFileName(CultureInfo culture) { return sb.ToString(); } - // WARNING: This function must be kept in [....] with ResourceFallbackManager.GetEnumerator() + // WARNING: This function must be kept in sync with ResourceFallbackManager.GetEnumerator() // Return the first ResourceSet, based on the first culture ResourceFallbackManager would return internal ResourceSet GetFirstResourceSet(CultureInfo culture) { diff --git a/mscorlib/system/resources/resourcereader.cs b/mscorlib/system/resources/resourcereader.cs index ec458846b..c5b438d7d 100644 --- a/mscorlib/system/resources/resourcereader.cs +++ b/mscorlib/system/resources/resourcereader.cs @@ -7,7 +7,7 @@ ** ** Class: ResourceReader ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Default way to read streams of resources on @@ -831,7 +831,7 @@ private Object DeserializeObject(int typeIndex) // types which do demand serialization permission in their // deserialization .cctors will fail. // Also, use a serialization binder to limit bind requests to - // our allowed list of [....] types. + // our allowed list of Microsoft types. _objFormatter.Binder = _typeLimitingBinder; _typeLimitingBinder.ExpectingToDeserialize(type); graph = _objFormatter.UnsafeDeserialize(_store.BaseStream, null); @@ -1005,8 +1005,7 @@ private void _ReadResources() // The hexadecimal E translates to binary 1110 // So, with this & condition we are checking that none of the highest 3 bits are // set before multiplying, as that would cause an overflow. - if ((_numResources & 0xE0000000) != 0){ - + if ((_numResources & 0xE0000000) != 0) { throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); } @@ -1042,7 +1041,7 @@ private void _ReadResources() // The hexadecimal E translates to binary 1110 // So, with this & condition we are checking that none of the highest 3 bits are // set before multiplying, as that would cause an overflow. - if ((_numResources & 0xE0000000) != 0){ + if ((_numResources & 0xE0000000) != 0) { throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted")); } @@ -1137,7 +1136,7 @@ private void InitSafeToDeserializeArray() } else { // Enums should be safe to deserialize, and this helps out - // partially trusted, localized [....] apps. + // partially trusted, localized Microsoft apps. if (resourceType.BaseType == typeof(Enum)) { _safeToDeserialize[i] = true; continue; @@ -1312,7 +1311,7 @@ public override Type BindToType(string assemblyName, string typeName) } } - // [....] types may internally use some enums that aren't + // Microsoft types may internally use some enums that aren't // on our safe to deserialize list, like Font using FontStyle. Type t = ObjectReader.FastBindToType(assemblyName, typeName); if (t.IsEnum) @@ -1323,7 +1322,7 @@ public override Type BindToType(string assemblyName, string typeName) // Throw instead of returning null. // If you're looking at this in a debugger, you've either - // got a hacked .resources file on your hands, or [....] + // got a hacked .resources file on your hands, or Microsoft // types have taken a new dependency on another type. Check // whether assemblyName & typeName refer to a trustworthy type, // & consider adding it to the TypesSafeToDeserialize list. @@ -1409,7 +1408,7 @@ public DictionaryEntry Entry { value = _reader.LoadObject(_dataPosition); // If enumeration and subsequent lookups happen very // frequently in the same process, add a ResourceLocator - // to _resCache here. But [....] enumerates and + // to _resCache here. But Microsoft enumerates and // just about everyone else does lookups. So caching // here may bloat working set. } diff --git a/mscorlib/system/resources/resourceset.cs b/mscorlib/system/resources/resourceset.cs index c722cfb36..0d1234cb6 100644 --- a/mscorlib/system/resources/resourceset.cs +++ b/mscorlib/system/resources/resourceset.cs @@ -7,7 +7,7 @@ ** ** Class: ResourceSet ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Culture-specific collection of resources. diff --git a/mscorlib/system/resources/resourcewriter.cs b/mscorlib/system/resources/resourcewriter.cs index 56b84ac25..b2b8af7cd 100644 --- a/mscorlib/system/resources/resourcewriter.cs +++ b/mscorlib/system/resources/resourcewriter.cs @@ -7,7 +7,7 @@ ** ** Class: ResourceWriter ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Default way to write strings to a CLR resource diff --git a/mscorlib/system/resources/runtimeresourceset.cs b/mscorlib/system/resources/runtimeresourceset.cs index d9cdd07df..0c51f6039 100644 --- a/mscorlib/system/resources/runtimeresourceset.cs +++ b/mscorlib/system/resources/runtimeresourceset.cs @@ -7,7 +7,7 @@ ** ** Class: RuntimeResourceSet ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: CultureInfo-specific collection of resources. diff --git a/mscorlib/system/resources/satellitecontractversionattribute.cs b/mscorlib/system/resources/satellitecontractversionattribute.cs index 4987dc9e6..c0c004568 100644 --- a/mscorlib/system/resources/satellitecontractversionattribute.cs +++ b/mscorlib/system/resources/satellitecontractversionattribute.cs @@ -7,7 +7,7 @@ ** ** Class: SatelliteContractVersionAttribute ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Specifies which version of a satellite assembly diff --git a/mscorlib/system/rttype.cs b/mscorlib/system/rttype.cs index 55238e66b..b2aa5f5d0 100644 --- a/mscorlib/system/rttype.cs +++ b/mscorlib/system/rttype.cs @@ -6,7 +6,7 @@ // // File: RtType.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Implements System.RuntimeType // @@ -50,7 +50,7 @@ namespace System internal delegate void CtorDelegate(Object instance); - // Keep this in [....] with FormatFlags defined in typestring.h + // Keep this in sync with FormatFlags defined in typestring.h internal enum TypeNameFormatFlags { FormatBasic = 0x00000000, // Not a bitmask, simply the tersest flag settings possible @@ -5752,7 +5752,7 @@ private OleAutBinder ForwardCallBinder [Flags] private enum DispatchWrapperType : int { - // This enum must stay in [....] with the DispatchWrapperType enum defined in MLInfo.h + // This enum must stay in sync with the DispatchWrapperType enum defined in MLInfo.h Unknown = 0x00000001, Dispatch = 0x00000002, Record = 0x00000004, diff --git a/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs b/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs index 7e0ed8e89..b2d762d0c 100644 --- a/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs +++ b/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs @@ -7,7 +7,7 @@ // // AsyncMethodBuilder.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Compiler-targeted types that build tasks for use as the return types of asynchronous methods. // @@ -49,7 +49,7 @@ public struct AsyncVoidMethodBuilder /// <returns>The initialized <see cref="AsyncVoidMethodBuilder"/>.</returns> public static AsyncVoidMethodBuilder Create() { - // Capture the current [....] context. If there isn't one, use the dummy s_noContextCaptured + // Capture the current sync context. If there isn't one, use the dummy s_noContextCaptured // instance; this allows us to tell the state of no captured context apart from the state // of an improperly constructed builder instance. SynchronizationContext sc = SynchronizationContext.CurrentNoFlow; diff --git a/mscorlib/system/runtime/compilerservices/ConditionalWeakTable.cs b/mscorlib/system/runtime/compilerservices/ConditionalWeakTable.cs index bae239fea..2f7814328 100644 --- a/mscorlib/system/runtime/compilerservices/ConditionalWeakTable.cs +++ b/mscorlib/system/runtime/compilerservices/ConditionalWeakTable.cs @@ -6,7 +6,7 @@ /*============================================================ ** Class: ConditionalWeakTable ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Description: Compiler support for runtime-generated "object fields." ** diff --git a/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs b/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs index ee78acad6..ec1f77d91 100644 --- a/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs +++ b/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs @@ -7,7 +7,7 @@ // // TaskAwaiter.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Types for awaiting Task and Task<T>. These types are emitted from Task{<T>}.GetAwaiter // and Task{<T>}.ConfigureAwait. They are meant to be used only by the compiler, e.g. diff --git a/mscorlib/system/runtime/compilerservices/YieldAwaitable.cs b/mscorlib/system/runtime/compilerservices/YieldAwaitable.cs index d1ab22fe9..0e04facc0 100644 --- a/mscorlib/system/runtime/compilerservices/YieldAwaitable.cs +++ b/mscorlib/system/runtime/compilerservices/YieldAwaitable.cs @@ -7,7 +7,7 @@ // // YieldAwaitable.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Compiler-targeted type for switching back into the current execution context, e.g. // diff --git a/mscorlib/system/runtime/compilerservices/compilationrelaxations.cs b/mscorlib/system/runtime/compilerservices/compilationrelaxations.cs index 73d602086..cce631b1c 100644 --- a/mscorlib/system/runtime/compilerservices/compilationrelaxations.cs +++ b/mscorlib/system/runtime/compilerservices/compilationrelaxations.cs @@ -11,7 +11,7 @@ namespace System.Runtime.CompilerServices using System; - /// IMPORTANT: Keep this in [....] with corhdr.h + /// IMPORTANT: Keep this in sync with corhdr.h [Serializable] [Flags] [System.Runtime.InteropServices.ComVisible(true)] diff --git a/mscorlib/system/runtime/compilerservices/runtimehelpers.cs b/mscorlib/system/runtime/compilerservices/runtimehelpers.cs index c9cc8f42f..a6d4f8a8a 100644 --- a/mscorlib/system/runtime/compilerservices/runtimehelpers.cs +++ b/mscorlib/system/runtime/compilerservices/runtimehelpers.cs @@ -169,7 +169,7 @@ public static int OffsetToStringData // a String to the first 16-bit character in the String. Skip // over the MethodTable pointer, & String // length. Of course, the String reference points to the memory - // after the [....] block, so don't count that. + // after the sync block, so don't count that. // This property allows C#'s fixed statement to work on Strings. // On 64 bit platforms, this should be 12 (8+4) and on 32 bit 8 (4+4). #if WIN32 diff --git a/mscorlib/system/runtime/exceptionservices/corruptingexceptioncommon.cs b/mscorlib/system/runtime/exceptionservices/corruptingexceptioncommon.cs index 13b30a0f2..7cc021dbd 100644 --- a/mscorlib/system/runtime/exceptionservices/corruptingexceptioncommon.cs +++ b/mscorlib/system/runtime/exceptionservices/corruptingexceptioncommon.cs @@ -13,7 +13,7 @@ ** ** Created: 06/20/2008 ** -** <owner>[....]</owner> +** <owner>Microsoft</owner> ** =============================================================================*/ diff --git a/mscorlib/system/runtime/exceptionservices/exceptionnotification.cs b/mscorlib/system/runtime/exceptionservices/exceptionnotification.cs index acda22b5d..57ea2c178 100644 --- a/mscorlib/system/runtime/exceptionservices/exceptionnotification.cs +++ b/mscorlib/system/runtime/exceptionservices/exceptionnotification.cs @@ -13,7 +13,7 @@ ** ** Created: 10/07/2008 ** -** <owner>[....]</owner> +** <owner>Microsoft</owner> ** =============================================================================*/ diff --git a/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs b/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs index 1b5eb8953..b8050ced0 100644 --- a/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs +++ b/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs @@ -13,7 +13,7 @@ ** ** Created: 11/2/2010 ** -** <owner>[....]</owner> +** <owner>Microsoft</owner> ** =============================================================================*/ diff --git a/mscorlib/system/runtime/interopservices/attributes.cs b/mscorlib/system/runtime/interopservices/attributes.cs index d3c16ca27..956ca4bf0 100644 --- a/mscorlib/system/runtime/interopservices/attributes.cs +++ b/mscorlib/system/runtime/interopservices/attributes.cs @@ -439,7 +439,7 @@ public enum VarEnum [Serializable] [System.Runtime.InteropServices.ComVisible(true)] - // Note that this enum should remain in-[....] with the CorNativeType enum in corhdr.h + // Note that this enum should remain in-sync with the CorNativeType enum in corhdr.h public enum UnmanagedType { Bool = 0x2, // 4 byte boolean value (true != 0, false == 0) @@ -517,6 +517,9 @@ public enum UnmanagedType [System.Runtime.InteropServices.ComVisible(false)] HString = 0x2f, // Windows Runtime HSTRING + + [System.Runtime.InteropServices.ComVisible(false)] + LPUTF8Str = 0x30, // UTF8 string } [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.ReturnValue, Inherited = false)] diff --git a/mscorlib/system/runtime/interopservices/gchandle.cs b/mscorlib/system/runtime/interopservices/gchandle.cs index 5480f22e9..5fcee00f2 100644 --- a/mscorlib/system/runtime/interopservices/gchandle.cs +++ b/mscorlib/system/runtime/interopservices/gchandle.cs @@ -44,7 +44,7 @@ public enum GCHandleType [System.Runtime.InteropServices.ComVisible(true)] public struct GCHandle { - // IMPORTANT: This must be kept in [....] with the GCHandleType enum. + // IMPORTANT: This must be kept in sync with the GCHandleType enum. private const GCHandleType MaxHandleType = GCHandleType.Pinned; #if MDA_SUPPORTED diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/attributes.cs b/mscorlib/system/runtime/interopservices/windowsruntime/attributes.cs index 8be810c56..8dfd4c70c 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/attributes.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/attributes.cs @@ -4,9 +4,9 @@ // // ==--== // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> using System; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/bindablevectortocollectionadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/bindablevectortocollectionadapter.cs index ad818c93a..248643a3c 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/bindablevectortocollectionadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/bindablevectortocollectionadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Runtime; @@ -85,7 +85,7 @@ internal void CopyTo(Array array, int arrayIndex) throw new ArgumentOutOfRangeException("arrayIndex"); // Does the dimension in question have sufficient space to copy the expected number of entries? - // We perform this check before valid index check to ensure the exception message is in [....] with + // We perform this check before valid index check to ensure the exception message is in sync with // the following snippet that uses regular framework code: // // ArrayList list = new ArrayList(); diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/bindablevectortolistadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/bindablevectortolistadapter.cs index f86568feb..e8aa7ecb1 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/bindablevectortolistadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/bindablevectortolistadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Runtime; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/clrikeyvaluepairimpl.cs b/mscorlib/system/runtime/interopservices/windowsruntime/clrikeyvaluepairimpl.cs index 25c318406..44b63f911 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/clrikeyvaluepairimpl.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/clrikeyvaluepairimpl.cs @@ -4,8 +4,8 @@ // // ==--== // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Collections.Generic; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/clripropertyvalueimpl.cs b/mscorlib/system/runtime/interopservices/windowsruntime/clripropertyvalueimpl.cs index c7781abf0..3dc29580b 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/clripropertyvalueimpl.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/clripropertyvalueimpl.cs @@ -4,9 +4,9 @@ // // ==--== // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Diagnostics.Contracts; @@ -475,7 +475,7 @@ private static T CoerceScalarValue<T>(PropertyType type, object value) { return (T)(object)ipv.GetDouble(); } else { - BCLDebug.Assert(false, "T in coersion function wasn't understood as a type that can be coerced - make sure that CoerceScalarValue and NumericScalarTypes are in [....]"); + BCLDebug.Assert(false, "T in coersion function wasn't understood as a type that can be coerced - make sure that CoerceScalarValue and NumericScalarTypes are in sync"); } } diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/clrireferenceimpl.cs b/mscorlib/system/runtime/interopservices/windowsruntime/clrireferenceimpl.cs index edb419c91..8c240e580 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/clrireferenceimpl.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/clrireferenceimpl.cs @@ -4,9 +4,9 @@ // // ==--== // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Collections; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/custompropertyimpl.cs b/mscorlib/system/runtime/interopservices/windowsruntime/custompropertyimpl.cs index 82e901d71..bf762dbef 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/custompropertyimpl.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/custompropertyimpl.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/dictionarytomapadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/dictionarytomapadapter.cs index db7e01476..94a0d9e60 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/dictionarytomapadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/dictionarytomapadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/enumeratortoiteratoradapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/enumeratortoiteratoradapter.cs index a4ee4b1ed..60e229954 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/enumeratortoiteratoradapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/enumeratortoiteratoradapter.cs @@ -4,9 +4,9 @@ // // ==--== // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Collections; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/eventregistrationtoken.cs b/mscorlib/system/runtime/interopservices/windowsruntime/eventregistrationtoken.cs index 5f96a90e7..092e43a2b 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/eventregistrationtoken.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/eventregistrationtoken.cs @@ -4,9 +4,9 @@ // // ==--== // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> using System; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/eventregistrationtokentable.cs b/mscorlib/system/runtime/interopservices/windowsruntime/eventregistrationtokentable.cs index 2de657df7..152e46f34 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/eventregistrationtokentable.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/eventregistrationtokentable.cs @@ -4,9 +4,9 @@ // // ==--== // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Collections.Generic; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/icustompropertyprovider.cs b/mscorlib/system/runtime/interopservices/windowsruntime/icustompropertyprovider.cs index 5ef1d8c06..d505dfac3 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/icustompropertyprovider.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/icustompropertyprovider.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.StubHelpers; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/imapviewtoireadonlydictionaryadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/imapviewtoireadonlydictionaryadapter.cs index 4817cbcf2..40deccb05 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/imapviewtoireadonlydictionaryadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/imapviewtoireadonlydictionaryadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/ireadonlydictionarytoimapviewadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/ireadonlydictionarytoimapviewadapter.cs index 32433c99c..9a9c98ab4 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/ireadonlydictionarytoimapviewadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/ireadonlydictionarytoimapviewadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/ireadonlylisttoivectorviewadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/ireadonlylisttoivectorviewadapter.cs index bec4e3e70..1bf26b164 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/ireadonlylisttoivectorviewadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/ireadonlylisttoivectorviewadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/iteratortoenumeratoradapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/iteratortoenumeratoradapter.cs index 08d11e672..e1460806c 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/iteratortoenumeratoradapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/iteratortoenumeratoradapter.cs @@ -4,8 +4,8 @@ // // ==--== // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Collections; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/ivectorviewtoireadonlylistadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/ivectorviewtoireadonlylistadapter.cs index 2e0631196..14e43b37e 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/ivectorviewtoireadonlylistadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/ivectorviewtoireadonlylistadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/listtobindablevectoradapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/listtobindablevectoradapter.cs index 7212db3e4..fa9e01eb2 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/listtobindablevectoradapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/listtobindablevectoradapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/listtobindablevectorviewadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/listtobindablevectorviewadapter.cs index 80cd46fb6..08e99c526 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/listtobindablevectorviewadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/listtobindablevectorviewadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/listtovectoradapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/listtovectoradapter.cs index 7f5e9cf83..a093837c5 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/listtovectoradapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/listtovectoradapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/managedactivationfactory.cs b/mscorlib/system/runtime/interopservices/windowsruntime/managedactivationfactory.cs index e676a47a5..dd963c54a 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/managedactivationfactory.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/managedactivationfactory.cs @@ -4,9 +4,9 @@ // // ==--== // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Diagnostics.Contracts; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/maptocollectionadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/maptocollectionadapter.cs index ecaedd87b..c04a9a0cf 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/maptocollectionadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/maptocollectionadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/maptodictionaryadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/maptodictionaryadapter.cs index 320397249..8b68eca2b 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/maptodictionaryadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/maptodictionaryadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/mapviewtoreadonlycollectionadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/mapviewtoreadonlycollectionadapter.cs index d9ea83ecb..8854c87e3 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/mapviewtoreadonlycollectionadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/mapviewtoreadonlycollectionadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/vectortocollectionadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/vectortocollectionadapter.cs index af4674c3a..0443ed2d1 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/vectortocollectionadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/vectortocollectionadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/vectortolistadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/vectortolistadapter.cs index edc20f2b6..51858b000 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/vectortolistadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/vectortolistadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/vectorviewtoreadonlycollectionadapter.cs b/mscorlib/system/runtime/interopservices/windowsruntime/vectorviewtoreadonlycollectionadapter.cs index b704460e7..f1e95611b 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/vectorviewtoreadonlycollectionadapter.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/vectorviewtoreadonlycollectionadapter.cs @@ -5,7 +5,7 @@ // ==--== // // <OWNER>GPaperin</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/windowsruntimemarshal.cs b/mscorlib/system/runtime/interopservices/windowsruntime/windowsruntimemarshal.cs index aacf09fdb..c186cf73f 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/windowsruntimemarshal.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/windowsruntimemarshal.cs @@ -4,9 +4,9 @@ // // ==--== // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Collections.Generic; diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/windowsruntimemetadata.cs b/mscorlib/system/runtime/interopservices/windowsruntime/windowsruntimemetadata.cs index 137a190b6..ff320ed95 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/windowsruntimemetadata.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/windowsruntimemetadata.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Runtime.InteropServices.WindowsRuntime { diff --git a/mscorlib/system/runtime/interopservices/windowsruntime/winrtclassactivator.cs b/mscorlib/system/runtime/interopservices/windowsruntime/winrtclassactivator.cs index 3de33410c..0aa99ce42 100644 --- a/mscorlib/system/runtime/interopservices/windowsruntime/winrtclassactivator.cs +++ b/mscorlib/system/runtime/interopservices/windowsruntime/winrtclassactivator.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/runtime/remoting/activationservices.cs b/mscorlib/system/runtime/remoting/activationservices.cs index 74b3c5804..4e57e1e55 100644 --- a/mscorlib/system/runtime/remoting/activationservices.cs +++ b/mscorlib/system/runtime/remoting/activationservices.cs @@ -1745,7 +1745,7 @@ internal void Push(Type typ, Object[] attr) // Need to grow our arrays ... this will be exceedingly rare Object[] newTypes = new Object[activationTypes.Length * 2]; Object[] newAttr = new Object[activationAttributes.Length * 2]; - Contract.Assert(newAttr.Length == newTypes.Length,"These should be in [....]!"); + Contract.Assert(newAttr.Length == newTypes.Length,"These should be in sync!"); Array.Copy(activationTypes, newTypes, activationTypes.Length); Array.Copy(activationAttributes, newAttr, activationAttributes.Length); activationTypes = newTypes; diff --git a/mscorlib/system/runtime/remoting/channelservices.cs b/mscorlib/system/runtime/remoting/channelservices.cs index 0b17b2475..cc38933cf 100644 --- a/mscorlib/system/runtime/remoting/channelservices.cs +++ b/mscorlib/system/runtime/remoting/channelservices.cs @@ -6,7 +6,7 @@ // ==--== //* File: Channel.cs //* -//* <EMAIL>Author: Tarun Anand ([....])</EMAIL> +//* <EMAIL>Author: Tarun Anand (Microsoft)</EMAIL> //* //* Purpose: Defines the general purpose remoting proxy //* diff --git a/mscorlib/system/runtime/remoting/channelsinkstacks.cs b/mscorlib/system/runtime/remoting/channelsinkstacks.cs index 20709a5bd..95d3b542f 100644 --- a/mscorlib/system/runtime/remoting/channelsinkstacks.cs +++ b/mscorlib/system/runtime/remoting/channelsinkstacks.cs @@ -453,7 +453,7 @@ public void ServerCallback(IAsyncResult ar) } // ServerChannelSinkStack - // helper class for transforming [....] message parameter lists into its + // helper class for transforming sync message parameter lists into its // async counterparts internal static class AsyncMessageHelper { diff --git a/mscorlib/system/runtime/remoting/clientsponsor.cs b/mscorlib/system/runtime/remoting/clientsponsor.cs index 07758b177..d20b7b9ef 100644 --- a/mscorlib/system/runtime/remoting/clientsponsor.cs +++ b/mscorlib/system/runtime/remoting/clientsponsor.cs @@ -7,9 +7,9 @@ // // File: ClientSponsor.cs // -// Contents: Agent for keeping Server Object's lifetime in [....] with a client's lifetime +// Contents: Agent for keeping Server Object's lifetime in sync with a client's lifetime // -// History: 8/9/00 <EMAIL>[....]</EMAIL> Created +// History: 8/9/00 <EMAIL>Microsoft</EMAIL> Created // //+---------------------------------------------------------------------------- diff --git a/mscorlib/system/runtime/remoting/configuration.cs b/mscorlib/system/runtime/remoting/configuration.cs index 5eb083130..dc299d089 100644 --- a/mscorlib/system/runtime/remoting/configuration.cs +++ b/mscorlib/system/runtime/remoting/configuration.cs @@ -844,7 +844,7 @@ internal static void RegisterWellKnownServiceType(WellKnownServiceTypeEntry entr lock (Info) { // We make an entry in our config tables so as to keep - // both the file-based and programmatic config in [....]. + // both the file-based and programmatic config in sync. Info.AddWellKnownEntry(entry); } } // RegisterWellKnownServiceType diff --git a/mscorlib/system/runtime/remoting/context.cs b/mscorlib/system/runtime/remoting/context.cs index 91d0bbecf..7ee42e4f6 100644 --- a/mscorlib/system/runtime/remoting/context.cs +++ b/mscorlib/system/runtime/remoting/context.cs @@ -436,7 +436,7 @@ internal virtual IMessageSink GetClientContextChain() } iSink++; } - // now check if we ----d and set appropriately + // now check if we raced and set appropriately lock (this) { if (_clientContextChain==null) diff --git a/mscorlib/system/runtime/remoting/crossappdomainchannel.cs b/mscorlib/system/runtime/remoting/crossappdomainchannel.cs index 010996b9e..a6c628de3 100644 --- a/mscorlib/system/runtime/remoting/crossappdomainchannel.cs +++ b/mscorlib/system/runtime/remoting/crossappdomainchannel.cs @@ -284,7 +284,7 @@ internal static CrossAppDomainSink FindOrCreateSink(CrossAppDomainData xadData) // warning in CrossAppDomainSink::.ctor above // lock(staticSyncObject) { - // Note: keep this in [....] with DomainUnloaded below + // Note: keep this in sync with DomainUnloaded below int key = xadData.DomainID; if (_sinks == null) { @@ -321,7 +321,7 @@ internal static void DomainUnloaded(Int32 domainID) { return; } - // Note: keep this in [....] with FindOrCreateSink + // Note: keep this in sync with FindOrCreateSink int i = 0; int remove = -1; while (_sinks[i] != null) @@ -476,7 +476,7 @@ internal byte[] DoTransitionDispatch( [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { - Message.DebugOut("\n::::::::::::::::::::::::: CrossAppDomain Channel: [....] call starting"); + Message.DebugOut("\n::::::::::::::::::::::::: CrossAppDomain Channel: Sync call starting"); IMessage errMsg = InternalSink.ValidateMessage(reqMsg); if (errMsg != null) { @@ -520,7 +520,7 @@ public virtual IMessage SyncProcessMessage(IMessage reqMsg) // will terminate the security stackwalk caused when // serialization checks for the correct permissions at the // remoting stack frame so the check won't continue on to - // the user and fail. <EMAIL>[from [....]]</EMAIL> + // the user and fail. <EMAIL>[from Microsoft]</EMAIL> // We will hold off from doing this for x-process channels // until the big picture of distributed security is finalized. @@ -560,7 +560,7 @@ public virtual IMessage SyncProcessMessage(IMessage reqMsg) if (responseBytes != null) { retStm = new MemoryStream(responseBytes); - Message.DebugOut("::::::::::::::::::::::::::: CrossAppDomain Channel: [....] call returning!!\n"); + Message.DebugOut("::::::::::::::::::::::::::: CrossAppDomain Channel: Sync call returning!!\n"); //*********************** DESERIALIZE RET-MSG ************** desRetMsg = CrossAppDomainSerializer.DeserializeMessage(retStm, reqMsg as IMethodCallMessage); } diff --git a/mscorlib/system/runtime/remoting/crosscontextchannel.cs b/mscorlib/system/runtime/remoting/crosscontextchannel.cs index 154fc9839..52aaf451e 100644 --- a/mscorlib/system/runtime/remoting/crosscontextchannel.cs +++ b/mscorlib/system/runtime/remoting/crosscontextchannel.cs @@ -133,7 +133,7 @@ public virtual IMessage SyncProcessMessage(IMessage reqMsg) try { - Message.DebugOut("\n::::::::::::::::::::::::: CrossContext Channel: [....] call starting"); + Message.DebugOut("\n::::::::::::::::::::::::: CrossContext Channel: Sync call starting"); IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { @@ -163,7 +163,7 @@ public virtual IMessage SyncProcessMessage(IMessage reqMsg) } } - Message.DebugOut("::::::::::::::::::::::::::: CrossContext Channel: [....] call returning!!\n"); + Message.DebugOut("::::::::::::::::::::::::::: CrossContext Channel: Sync call returning!!\n"); return replyMsg; } diff --git a/mscorlib/system/runtime/remoting/identityholder.cs b/mscorlib/system/runtime/remoting/identityholder.cs index 3e3650d85..6959edaf9 100644 --- a/mscorlib/system/runtime/remoting/identityholder.cs +++ b/mscorlib/system/runtime/remoting/identityholder.cs @@ -449,7 +449,7 @@ internal static Identity FindOrCreateIdentity( if (takeAndRelease) rwlock.AcquireWriterLock(INFINITE); - // SetIdentity will give the correct Id if we ----d + // SetIdentity will give the correct Id if we raced // between the ResolveIdentity call above and now. // (we are unmarshaling, and the server should guarantee // that the uri is unique, so we will use an existing identity diff --git a/mscorlib/system/runtime/remoting/lease.cs b/mscorlib/system/runtime/remoting/lease.cs index a0884ce4e..cafb08d70 100644 --- a/mscorlib/system/runtime/remoting/lease.cs +++ b/mscorlib/system/runtime/remoting/lease.cs @@ -10,7 +10,7 @@ // // Contents: Lease class // -// History: 1/5/00 <EMAIL>[....]</EMAIL> Created +// History: 1/5/00 <EMAIL>Microsoft</EMAIL> Created // //+---------------------------------------------------------------------------- diff --git a/mscorlib/system/runtime/remoting/leasemanager.cs b/mscorlib/system/runtime/remoting/leasemanager.cs index 464f27515..8acbeb049 100644 --- a/mscorlib/system/runtime/remoting/leasemanager.cs +++ b/mscorlib/system/runtime/remoting/leasemanager.cs @@ -10,7 +10,7 @@ // // Contents: Administers the leases in an appdomain // -// History: 1/5/00 <EMAIL>[....]</EMAIL> Created +// History: 1/5/00 <EMAIL>Microsoft</EMAIL> Created // //+---------------------------------------------------------------------------- diff --git a/mscorlib/system/runtime/remoting/message.cs b/mscorlib/system/runtime/remoting/message.cs index 4cba7cf9b..dda57505b 100644 --- a/mscorlib/system/runtime/remoting/message.cs +++ b/mscorlib/system/runtime/remoting/message.cs @@ -48,7 +48,7 @@ internal class Message : IMethodCallMessage, IInternalMessage, ISerializable { // *** NOTE *** - // Keep these in [....] with the flags in Message.h + // Keep these in sync with the flags in Message.h // flags internal const int Sync = 0; // Synchronous call internal const int BeginAsync = 1; // Async Begin call @@ -2018,7 +2018,7 @@ public virtual Object this[Object key] } return null; } - [System.Security.SecuritySafeCritical] // TODO: review - implements transparent public method + [System.Security.SecuritySafeCritical] // set { if (ContainsSpecialKey(key)) @@ -5502,7 +5502,7 @@ internal static void GetParameterMaps(ParameterInfo[] parameters, // // Helper methods for expanding and contracting argument lists - // when translating from async methods to [....] methods and back. + // when translating from async methods to sync methods and back. // internal static Object[] ExpandAsyncEndArgsToSyncArgs(RemotingMethodCachedData syncMethod, diff --git a/mscorlib/system/runtime/remoting/objref.cs b/mscorlib/system/runtime/remoting/objref.cs index a822b3afe..a88d0220a 100644 --- a/mscorlib/system/runtime/remoting/objref.cs +++ b/mscorlib/system/runtime/remoting/objref.cs @@ -642,21 +642,21 @@ private IChannelInfo GetChannelInfoHelper() String urlToBash = bashInfo[0]; String replacementUrl = bashInfo[1]; - // Copy channel info and go [....] urls. + // Copy channel info and go Microsoft urls. ChannelInfo newChInfo = new ChannelInfo(); newChInfo.ChannelData = new Object[oldChannelData.Length]; for (int co = 0; co < oldChannelData.Length; co++) { newChInfo.ChannelData[co] = oldChannelData[co]; - // see if this is one of the ones that we need to [....] + // see if this is one of the ones that we need to Microsoft ChannelDataStore channelDataStore = newChInfo.ChannelData[co] as ChannelDataStore; if (channelDataStore != null) { String[] urls = channelDataStore.ChannelUris; if ((urls != null) && (urls.Length == 1) && urls[0].Equals(urlToBash)) { - // We want to [....] just the url, so we do a shallow copy + // We want to Microsoft just the url, so we do a shallow copy // and replace the url array with the replacementUrl. ChannelDataStore newChannelDataStore = channelDataStore.InternalShallowCopy(); newChannelDataStore.ChannelUris = new String[1]; @@ -1023,7 +1023,7 @@ internal void Init(Object o, Identity idObj, RuntimeType requestedType) Object[] channelData = chan.ChannelData; int channelDataLength = channelData.Length; Object[] newChannelData = new Object[channelDataLength]; - // Clone the data so that we dont [....] the current appdomain data which is stored + // Clone the data so that we dont Microsoft the current appdomain data which is stored // as a static Array.Copy(channelData, newChannelData, channelDataLength); for (int i = 0; i < channelDataLength; i++) diff --git a/mscorlib/system/runtime/remoting/realproxy.cs b/mscorlib/system/runtime/remoting/realproxy.cs index b58d140e2..c574c9327 100644 --- a/mscorlib/system/runtime/remoting/realproxy.cs +++ b/mscorlib/system/runtime/remoting/realproxy.cs @@ -35,7 +35,7 @@ namespace System.Runtime.Remoting.Proxies { using System.Diagnostics.Contracts; - // NOTE: Keep this in [....] with unmanaged enum definition in Remoting.h + // NOTE: Keep this in sync with unmanaged enum definition in Remoting.h [Serializable] internal enum CallType { @@ -52,7 +52,7 @@ internal enum RealProxyFlags Initialized = 0x2 }; - // NOTE: Keep this in [....] with unmanaged struct "messageData" in Remoting.h + // NOTE: Keep this in sync with unmanaged struct "messageData" in Remoting.h [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] internal struct MessageData { @@ -742,7 +742,7 @@ private void PrivateInvoke(ref MessageData msgData, int type) // but the constructormessage hasn't been setup. // so let us just bail out.. // this is currently used by ServicedComponent's for cross appdomain - // pooling: <EMAIL>[....]</EMAIL> + // pooling: <EMAIL>Microsoft</EMAIL> // ctorMsg = new ConstructorCallMessage(null, null, null, (RuntimeType)GetProxiedType()); // Set the constructor frame info in the CCM @@ -834,7 +834,7 @@ private void PrivateInvoke(ref MessageData msgData, int type) { // This was a begin-async on a non-Remoting Proxy. For V-1 they - // cannot support Async and end up doing a [....] call. We need + // cannot support Async and end up doing a Sync call. We need // to fill up here to make the call look like async to // the caller. // Create the async result to return diff --git a/mscorlib/system/runtime/remoting/remotingattributes.cs b/mscorlib/system/runtime/remoting/remotingattributes.cs index 244006ea4..a11ffd983 100644 --- a/mscorlib/system/runtime/remoting/remotingattributes.cs +++ b/mscorlib/system/runtime/remoting/remotingattributes.cs @@ -258,7 +258,7 @@ private enum MethodCacheFlags // parameter maps // NOTE: these fields are all initialized at the same time however access to // the internal property of each field is locked only on that specific field - // having been initialized. - [....] + // having been initialized. - Microsoft private int[] _inRefArgMap = null; // parameter map of input and ref parameters private int[] _outRefArgMap = null; // parameter map of out and ref parameters (exactly all byref parameters) private int[] _outOnlyArgMap = null; // parameter map of only output parameters diff --git a/mscorlib/system/runtime/remoting/remotingproxy.cs b/mscorlib/system/runtime/remoting/remotingproxy.cs index c91d22897..3898b45af 100644 --- a/mscorlib/system/runtime/remoting/remotingproxy.cs +++ b/mscorlib/system/runtime/remoting/remotingproxy.cs @@ -233,7 +233,7 @@ public override IMessage Invoke(IMessage reqMsg) // This is called for all remoted calls on a TP except Ctors - // The method called may be [....], Async or OneWay(special case of Async) + // The method called may be Sync, Async or OneWay(special case of Async) // In the Async case we come here for both BeginInvoke & EndInvoke internal virtual IMessage InternalInvoke( IMethodCallMessage reqMcmMsg, bool useDispatchMessage, int callType) diff --git a/mscorlib/system/runtime/remoting/remotingservices.cs b/mscorlib/system/runtime/remoting/remotingservices.cs index 13b799dbb..679d4eff4 100644 --- a/mscorlib/system/runtime/remoting/remotingservices.cs +++ b/mscorlib/system/runtime/remoting/remotingservices.cs @@ -6,7 +6,7 @@ // // File: RemotingServices.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Author(s): <EMAIL>Gopal Kakivaya (GopalK)</EMAIL> // @@ -616,7 +616,7 @@ internal static ObjRef MarshalInternal(MarshalByRefObject Obj, String ObjURI, Ty { int channelDataLength = channelData.Length; Object[] newChannelData = new Object[channelDataLength]; - // Clone the data so that we dont [....] the current appdomain data which is stored + // Clone the data so that we dont Microsoft the current appdomain data which is stored // as a static Array.Copy(channelData, newChannelData, channelDataLength); for (int i = 0; i < channelDataLength; i++) diff --git a/mscorlib/system/runtime/remoting/soapinteroptypes.cs b/mscorlib/system/runtime/remoting/soapinteroptypes.cs index 07d820acf..21de0d6cd 100644 --- a/mscorlib/system/runtime/remoting/soapinteroptypes.cs +++ b/mscorlib/system/runtime/remoting/soapinteroptypes.cs @@ -231,7 +231,7 @@ public sealed class SoapDuration { // Convert from ISO/xsd TimeDuration to urt TimeSpan // The form of the time duration is PxxYxxDTxxHxxMxx.xxxS or PxxYxxDTxxHxxMxxS - // Keep in [....] with Message.cs + // Keep in sync with Message.cs public static String XsdType diff --git a/mscorlib/system/runtime/remoting/synchronizeddispatch.cs b/mscorlib/system/runtime/remoting/synchronizeddispatch.cs index dc03e3ee7..7ade238a0 100644 --- a/mscorlib/system/runtime/remoting/synchronizeddispatch.cs +++ b/mscorlib/system/runtime/remoting/synchronizeddispatch.cs @@ -271,7 +271,7 @@ internal virtual void InitIfNecessary() /* * Call back function -- executed for each work item that * was enqueued. This is invoked by a thread-pool thread for - * async work items and the caller thread for [....] items. + * async work items and the caller thread for sync items. */ private void DispatcherCallBack(Object stateIgnored, bool ignored) { @@ -356,7 +356,7 @@ internal virtual void HandleWorkCompletion() // See if we found a non-signaled work item at the head. if (bNotify) { - // In both [....] and async cases we just hand off the _locked state to + // In both sync and async cases we just hand off the _locked state to // the next thread which will execute. if (nextWork.IsAsync()) { @@ -366,7 +366,7 @@ internal virtual void HandleWorkCompletion() } else { - // [....]-WorkItem: notify the waiting [....]-thread. + // Sync-WorkItem: notify the waiting sync-thread. lock(nextWork) { Monitor.Pulse(nextWork); @@ -419,7 +419,7 @@ internal virtual void HandleWorkRequest(WorkItem work) } else { - // [....] work is queued only if there are other items + // Sync work is queued only if there are other items // already in the queue. lock(work) { @@ -434,7 +434,7 @@ internal virtual void HandleWorkRequest(WorkItem work) } else { - //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ ENQUEUE [....]!" + (work.IsDummy()?" DUMMY ":" REAL ") + work._thread); + //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ ENQUEUE Sync!" + (work.IsDummy()?" DUMMY ":" REAL ") + work._thread); bQueued = true; work.SetWaiting(); _workItemQueue.Enqueue(work); @@ -514,7 +514,7 @@ internal bool IsNestedCall(IMessage reqMsg) // This returns TRUE only if it is a non-reEntrant context // AND // (the LCID of the reqMsg matches that of - // the top level [....] call lcid associated with the context. + // the top level sync call lcid associated with the context. // OR // it matches one of the async call out lcids) @@ -668,7 +668,7 @@ public IMessageSink NextSink //*************************************** WORK ITEM ********************************// /* - * A work item holds the info about a call to [....] or + * A work item holds the info about a call to Sync or * Async-ProcessMessage. */ internal class WorkItem @@ -681,9 +681,9 @@ internal class WorkItem internal int _flags; internal IMessage _reqMsg; internal IMessageSink _nextSink; - // ReplySink will be null for an [....] work item. + // ReplySink will be null for an sync work item. internal IMessageSink _replySink; - // ReplyMsg is set once the [....] call is completed + // ReplyMsg is set once the sync call is completed internal IMessage _replyMsg; // Context in which the work should execute. @@ -778,14 +778,14 @@ internal static Object ExecuteCallback(Object[] args) } /* - * Execute is called to complete a work item ([....] or async). + * Execute is called to complete a work item (sync or async). * Execute assumes that the context is set correctly and the lock * is taken (i.e. it makes no policy decisions) * * It is called from the following 3 points: * 1. thread pool thread executing the callback for an async item - * 2. calling thread executing the callback for a queued [....] item - * 3. calling thread directly calling Execute for a non-queued [....] item + * 2. calling thread executing the callback for a queued sync item + * 3. calling thread directly calling Execute for a non-queued sync item */ [System.Security.SecurityCritical] // auto-generated internal virtual void Execute() @@ -842,20 +842,20 @@ public virtual IMessage SyncProcessMessage(IMessage reqMsg) // Notify the property that we are leaving _property.HandleThreadExit(); - //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] R: [....] call-out"); + //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] R: Sync call-out"); replyMsg = _nextSink.SyncProcessMessage(reqMsg); // We will just block till we are given permission to re-enter // Notify the property that we wish to re-enter the domain. // This will block the thread here if someone is in the domain. - //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] R: [....] call-out returned, waiting for lock"); + //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] R: Sync call-out returned, waiting for lock"); _property.HandleThreadReEntry(); Contract.Assert(_property.Locked == true,"_property.Locked == true"); } else { // In the non-reentrant case we are just a pass-through sink - //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] NR: [....] call-out (pass through)"); + //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] NR: Sync call-out (pass through)"); // We should mark the domain with our LCID so that call-backs are allowed to enter.. LogicalCallContext cctx = (LogicalCallContext) reqMsg.Properties[Message.CallContextKey]; @@ -868,7 +868,7 @@ public virtual IMessage SyncProcessMessage(IMessage reqMsg) // start of each Invoke. As an optimization we now do it // here in a delayed fashion... since currently only // Synchronization needs it - // Note that for [....]-calls we would just inherit an LCID + // Note that for Sync-calls we would just inherit an LCID // if the call has one, if not we create one. However for // async calls we always generate a new LCID. lcid = Identity.GetNewLogicalCallID(); @@ -896,7 +896,7 @@ public virtual IMessage SyncProcessMessage(IMessage reqMsg) { _property.SyncCallOutLCID = null; - // The [....] callOut is done, we do not need the lcid + // The sync callOut is done, we do not need the lcid // that was associated with the call any more. // (clear it only if we added one to the reqMsg) if (bClear) @@ -914,7 +914,7 @@ public virtual IMessage SyncProcessMessage(IMessage reqMsg) } } - //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] NR: [....] call-out returned"); + //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] NR: Sync call-out returned"); } return replyMsg; } @@ -952,7 +952,7 @@ public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink re Contract.Assert( _property.SyncCallOutLCID == null, - "Cannot handle async call outs when already in a top-level [....] call out"); + "Cannot handle async call outs when already in a top-level sync call out"); //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] NR: Async CallOut: adding to lcidList: " + lcid); _property.AsyncCallOutLCIDList.Add(lcid); } @@ -1012,7 +1012,7 @@ internal AsyncReplySink(IMessageSink nextSink, SynchronizationAttribute prop) public virtual IMessage SyncProcessMessage(IMessage reqMsg) { - // We handle this as a regular new [....] workItem + // We handle this as a regular new Sync workItem // 1. Create a work item WorkItem work = new WorkItem(reqMsg, _nextSink, diff --git a/mscorlib/system/runtime/remoting/urlattribute.cs b/mscorlib/system/runtime/remoting/urlattribute.cs index 37f9d0f7a..d900c5222 100644 --- a/mscorlib/system/runtime/remoting/urlattribute.cs +++ b/mscorlib/system/runtime/remoting/urlattribute.cs @@ -7,12 +7,12 @@ ** ** File: UrlAttribute.cs ** -** <EMAIL>Author: Tarun Anand ([....])</EMAIL> +** <EMAIL>Author: Tarun Anand (Microsoft)</EMAIL> ** ** Purpose: Defines an attribute which can be used at the callsite to ** specify the URL at which the activation will happen. ** -** Date: [....] 30, 2000 +** Date: Microsoft 30, 2000 ** ===========================================================*/ namespace System.Runtime.Remoting.Activation { diff --git a/mscorlib/system/runtime/serialization/formatters/soapfault.cs b/mscorlib/system/runtime/serialization/formatters/soapfault.cs index 849b0644e..c610f69b6 100644 --- a/mscorlib/system/runtime/serialization/formatters/soapfault.cs +++ b/mscorlib/system/runtime/serialization/formatters/soapfault.cs @@ -7,7 +7,7 @@ ** ** Class: SoapFault ** - ** <EMAIL>Author: Peter de Jong ([....])</EMAIL> + ** <EMAIL>Author: Peter de Jong (Microsoft)</EMAIL> ** ** Purpose: Specifies information for a Soap Fault ** diff --git a/mscorlib/system/runtime/serialization/formatterservices.cs b/mscorlib/system/runtime/serialization/formatterservices.cs index d2f39ae63..e3baf2d48 100644 --- a/mscorlib/system/runtime/serialization/formatterservices.cs +++ b/mscorlib/system/runtime/serialization/formatterservices.cs @@ -18,6 +18,7 @@ namespace System.Runtime.Serialization { using System; using System.Reflection; using System.Collections; + using System.Collections.Concurrent; using System.Collections.Generic; using System.Security; using System.Security.Permissions; @@ -34,28 +35,13 @@ namespace System.Runtime.Serialization { [System.Runtime.InteropServices.ComVisible(true)] public static class FormatterServices { #if FEATURE_SERIALIZATION - internal static Dictionary<MemberHolder, MemberInfo[]> m_MemberInfoTable = new Dictionary<MemberHolder, MemberInfo[]>(32); + internal static ConcurrentDictionary<MemberHolder, MemberInfo[]> m_MemberInfoTable = new ConcurrentDictionary<MemberHolder, MemberInfo[]>(); [System.Security.SecurityCritical] private static bool unsafeTypeForwardersIsEnabled = false; [System.Security.SecurityCritical] private static volatile bool unsafeTypeForwardersIsEnabledInitialized = false; - private static Object s_FormatterServicesSyncObject = null; - - private static Object formatterServicesSyncObject - { - get - { - if (s_FormatterServicesSyncObject == null) - { - Object o = new Object(); - Interlocked.CompareExchange<Object>(ref s_FormatterServicesSyncObject, o, null); - } - return s_FormatterServicesSyncObject; - } - } - [SecuritySafeCritical] static FormatterServices() { @@ -197,9 +183,7 @@ public static MemberInfo[] GetSerializableMembers(Type type) { // non-transient, non-static fields. If we are cloning, include the transient fields as well since // we know that we're going to live inside of the same context. [System.Security.SecurityCritical] // auto-generated_required - public static MemberInfo[] GetSerializableMembers(Type type, StreamingContext context) { - MemberInfo[] members; - + public static MemberInfo[] GetSerializableMembers(Type type, StreamingContext context) { if ((object)type==null) { throw new ArgumentNullException("type"); } @@ -210,25 +194,13 @@ public static MemberInfo[] GetSerializableMembers(Type type, StreamingContext co } MemberHolder mh = new MemberHolder(type, context); - - //If we've already gathered the members for this type, just return them. - if (m_MemberInfoTable.ContainsKey(mh)) { - return m_MemberInfoTable[mh]; - } - - lock (formatterServicesSyncObject) { - //If we've already gathered the members for this type, just return them. - if (m_MemberInfoTable.ContainsKey(mh)) { - return m_MemberInfoTable[mh]; - } - - members = InternalGetSerializableMembers((RuntimeType)type); - m_MemberInfoTable[mh] = members; - } - + //If we've already gathered the members for this type, just return them. + MemberInfo[] members = m_MemberInfoTable.GetOrAdd(mh, + _ => InternalGetSerializableMembers((RuntimeType)type)); + return members; - } + } static readonly Type[] advancedTypes = new Type[]{ typeof(System.DelegateSerializationHolder), diff --git a/mscorlib/system/runtime/serialization/safeserializationmanager.cs b/mscorlib/system/runtime/serialization/safeserializationmanager.cs index 8dbe02ab7..5f1b03000 100644 --- a/mscorlib/system/runtime/serialization/safeserializationmanager.cs +++ b/mscorlib/system/runtime/serialization/safeserializationmanager.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Collections; diff --git a/mscorlib/system/runtime/serialization/streamingcontext.cs b/mscorlib/system/runtime/serialization/streamingcontext.cs index 0f223e74b..978d9ce78 100644 --- a/mscorlib/system/runtime/serialization/streamingcontext.cs +++ b/mscorlib/system/runtime/serialization/streamingcontext.cs @@ -56,7 +56,7 @@ public StreamingContextStates State { } // ********************************************************** - // Keep these in [....] with the version in vm\runtimehandles.h + // Keep these in sync with the version in vm\runtimehandles.h // ********************************************************** [Serializable] [Flags] diff --git a/mscorlib/system/runtime/versioning/binarycompatibility.cs b/mscorlib/system/runtime/versioning/binarycompatibility.cs index 441988f30..e9f6817ab 100644 --- a/mscorlib/system/runtime/versioning/binarycompatibility.cs +++ b/mscorlib/system/runtime/versioning/binarycompatibility.cs @@ -7,7 +7,7 @@ ** ** Class: BinaryCompatibility ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: This class is used to determine which binary compatibility diff --git a/mscorlib/system/runtime/versioning/multitargetinghelpers.cs b/mscorlib/system/runtime/versioning/multitargetinghelpers.cs index 51f68edb9..4d6f0b3ff 100644 --- a/mscorlib/system/runtime/versioning/multitargetinghelpers.cs +++ b/mscorlib/system/runtime/versioning/multitargetinghelpers.cs @@ -7,7 +7,7 @@ ** ** Class: MultitargetingHelpers ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Central repository for helpers supporting diff --git a/mscorlib/system/runtimehandles.cs b/mscorlib/system/runtimehandles.cs index 05cecb7b1..5d5818e30 100644 --- a/mscorlib/system/runtimehandles.cs +++ b/mscorlib/system/runtimehandles.cs @@ -2149,7 +2149,7 @@ private extern void GetSignature( #region Private Data Members // - // Keep the layout in [....] with SignatureNative in the VM + // Keep the layout in sync with SignatureNative in the VM // internal RuntimeType[] m_arguments; internal RuntimeType m_declaringType; diff --git a/mscorlib/system/security/accesscontrol/acl.cs b/mscorlib/system/security/accesscontrol/acl.cs index 674cdd485..a32e35b6c 100644 --- a/mscorlib/system/security/accesscontrol/acl.cs +++ b/mscorlib/system/security/accesscontrol/acl.cs @@ -1787,7 +1787,7 @@ private bool CanonicalCheck( bool isDacl ) if ( ace == null ) { // - // <[....]-9/19/2004> Afraid to yank this statement now + // <Microsoft-9/19/2004> Afraid to yank this statement now // for fear of destabilization, so adding an assert instead // diff --git a/mscorlib/system/security/accesscontrol/securitydescriptor.cs b/mscorlib/system/security/accesscontrol/securitydescriptor.cs index 099ebdec1..cf75b4a7d 100644 --- a/mscorlib/system/security/accesscontrol/securitydescriptor.cs +++ b/mscorlib/system/security/accesscontrol/securitydescriptor.cs @@ -913,7 +913,7 @@ private void CreateFromParts( bool isContainer, bool isDS, ControlFlags flags, S ControlFlags actualFlags = flags | ControlFlags.DiscretionaryAclPresent; // - // Keep SACL and the flag bit in [....]. + // Keep SACL and the flag bit in sync. // if (systemAcl == null) @@ -1263,7 +1263,7 @@ internal void UpdateControlFlags(ControlFlags flagsToUpdate, ControlFlags newFla // // These two add/remove method must be called with great care (and thus it is internal) - // The caller is responsible for keeping the SaclPresent and DaclPresent bits in [....] + // The caller is responsible for keeping the SaclPresent and DaclPresent bits in sync // with the actual SACL and DACL. // diff --git a/mscorlib/system/security/attributes.cs b/mscorlib/system/security/attributes.cs index 19e46de5b..d1d5ec45c 100644 --- a/mscorlib/system/security/attributes.cs +++ b/mscorlib/system/security/attributes.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System.Runtime.InteropServices; namespace System.Security diff --git a/mscorlib/system/security/builtinpermissionsets.cs b/mscorlib/system/security/builtinpermissionsets.cs index be1d10fdc..b3f656376 100644 --- a/mscorlib/system/security/builtinpermissionsets.cs +++ b/mscorlib/system/security/builtinpermissionsets.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/security/claims/Claim.cs b/mscorlib/system/security/claims/Claim.cs index decc52ecf..9a49bc497 100644 --- a/mscorlib/system/security/claims/Claim.cs +++ b/mscorlib/system/security/claims/Claim.cs @@ -7,7 +7,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/claims/ClaimsIdentity.cs b/mscorlib/system/security/claims/ClaimsIdentity.cs index 5f3a25e79..172cd7382 100644 --- a/mscorlib/system/security/claims/ClaimsIdentity.cs +++ b/mscorlib/system/security/claims/ClaimsIdentity.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/claims/ClaimsPrincipal.cs b/mscorlib/system/security/claims/ClaimsPrincipal.cs index a8b807d69..3512df9da 100644 --- a/mscorlib/system/security/claims/ClaimsPrincipal.cs +++ b/mscorlib/system/security/claims/ClaimsPrincipal.cs @@ -7,7 +7,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/claims/RoleClaimProvider.cs b/mscorlib/system/security/claims/RoleClaimProvider.cs index 3a061e99c..3664f9142 100644 --- a/mscorlib/system/security/claims/RoleClaimProvider.cs +++ b/mscorlib/system/security/claims/RoleClaimProvider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // // RoleClaimProvider.cs diff --git a/mscorlib/system/security/codeaccesspermission.cs b/mscorlib/system/security/codeaccesspermission.cs index 98fb570b4..e1d1bb12c 100644 --- a/mscorlib/system/security/codeaccesspermission.cs +++ b/mscorlib/system/security/codeaccesspermission.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Security { using System.IO; diff --git a/mscorlib/system/security/codeaccesssecurityengine.cs b/mscorlib/system/security/codeaccesssecurityengine.cs index 45b3eccba..804cc50b1 100644 --- a/mscorlib/system/security/codeaccesssecurityengine.cs +++ b/mscorlib/system/security/codeaccesssecurityengine.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security { @@ -20,7 +20,7 @@ namespace System.Security { using System.Diagnostics.Contracts; // Used in DemandInternal, to remember the result of previous demands - // KEEP IN [....] WITH DEFINITIONS IN SECURITYPOLICY.H + // KEEP IN SYNC WITH DEFINITIONS IN SECURITYPOLICY.H [Serializable] internal enum PermissionType { diff --git a/mscorlib/system/security/cryptography/asymmetricalgorithm.cs b/mscorlib/system/security/cryptography/asymmetricalgorithm.cs index 1e2184537..ec0636390 100644 --- a/mscorlib/system/security/cryptography/asymmetricalgorithm.cs +++ b/mscorlib/system/security/cryptography/asymmetricalgorithm.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/asymmetrickeyexchangedeformatter.cs b/mscorlib/system/security/cryptography/asymmetrickeyexchangedeformatter.cs index f9272ee23..1492e46ba 100644 --- a/mscorlib/system/security/cryptography/asymmetrickeyexchangedeformatter.cs +++ b/mscorlib/system/security/cryptography/asymmetrickeyexchangedeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/asymmetrickeyexchangeformatter.cs b/mscorlib/system/security/cryptography/asymmetrickeyexchangeformatter.cs index 1da8d9b89..5dca811ed 100644 --- a/mscorlib/system/security/cryptography/asymmetrickeyexchangeformatter.cs +++ b/mscorlib/system/security/cryptography/asymmetrickeyexchangeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/asymmetricsignaturedeformatter.cs b/mscorlib/system/security/cryptography/asymmetricsignaturedeformatter.cs index 232e711da..df836d2b0 100644 --- a/mscorlib/system/security/cryptography/asymmetricsignaturedeformatter.cs +++ b/mscorlib/system/security/cryptography/asymmetricsignaturedeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/asymmetricsignatureformatter.cs b/mscorlib/system/security/cryptography/asymmetricsignatureformatter.cs index 6911141f4..37f1d65f6 100644 --- a/mscorlib/system/security/cryptography/asymmetricsignatureformatter.cs +++ b/mscorlib/system/security/cryptography/asymmetricsignatureformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/base64transforms.cs b/mscorlib/system/security/cryptography/base64transforms.cs index 91ffbd4f4..05efe3c3e 100644 --- a/mscorlib/system/security/cryptography/base64transforms.cs +++ b/mscorlib/system/security/cryptography/base64transforms.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/crypto.cs b/mscorlib/system/security/cryptography/crypto.cs index b3868d468..5d2e6a321 100644 --- a/mscorlib/system/security/cryptography/crypto.cs +++ b/mscorlib/system/security/cryptography/crypto.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -20,7 +20,7 @@ namespace System.Security.Cryptography { // and ciphertext-stealing (CTS). Not all implementations will support all modes. [Serializable] [System.Runtime.InteropServices.ComVisible(true)] - public enum CipherMode { // Please keep in [....] with wincrypt.h + public enum CipherMode { // Please keep in sync with wincrypt.h CBC = 1, ECB = 2, OFB = 3, diff --git a/mscorlib/system/security/cryptography/cryptoapitransform.cs b/mscorlib/system/security/cryptography/cryptoapitransform.cs index 5f430f311..6855436bf 100644 --- a/mscorlib/system/security/cryptography/cryptoapitransform.cs +++ b/mscorlib/system/security/cryptography/cryptoapitransform.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/cryptoconfig.cs b/mscorlib/system/security/cryptography/cryptoconfig.cs index 667369d2d..2b790de29 100644 --- a/mscorlib/system/security/cryptography/cryptoconfig.cs +++ b/mscorlib/system/security/cryptography/cryptoconfig.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/cryptostream.cs b/mscorlib/system/security/cryptography/cryptostream.cs index efbe8b773..71cd2fd18 100644 --- a/mscorlib/system/security/cryptography/cryptostream.cs +++ b/mscorlib/system/security/cryptography/cryptostream.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/derivebytes.cs b/mscorlib/system/security/cryptography/derivebytes.cs index c7ed830c8..ee2265e72 100644 --- a/mscorlib/system/security/cryptography/derivebytes.cs +++ b/mscorlib/system/security/cryptography/derivebytes.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/des.cs b/mscorlib/system/security/cryptography/des.cs index 7bd6d2f72..7297ffa3e 100644 --- a/mscorlib/system/security/cryptography/des.cs +++ b/mscorlib/system/security/cryptography/des.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/descryptoserviceprovider.cs b/mscorlib/system/security/cryptography/descryptoserviceprovider.cs index c3a674873..52c51a758 100644 --- a/mscorlib/system/security/cryptography/descryptoserviceprovider.cs +++ b/mscorlib/system/security/cryptography/descryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/dsa.cs b/mscorlib/system/security/cryptography/dsa.cs index a71cf7976..b8aaf9d25 100644 --- a/mscorlib/system/security/cryptography/dsa.cs +++ b/mscorlib/system/security/cryptography/dsa.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/dsacryptoserviceprovider.cs b/mscorlib/system/security/cryptography/dsacryptoserviceprovider.cs index df23a26af..cf1ab5fc2 100644 --- a/mscorlib/system/security/cryptography/dsacryptoserviceprovider.cs +++ b/mscorlib/system/security/cryptography/dsacryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/dsasignaturedeformatter.cs b/mscorlib/system/security/cryptography/dsasignaturedeformatter.cs index 3f8d457d9..bf57d241c 100644 --- a/mscorlib/system/security/cryptography/dsasignaturedeformatter.cs +++ b/mscorlib/system/security/cryptography/dsasignaturedeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/dsasignatureformatter.cs b/mscorlib/system/security/cryptography/dsasignatureformatter.cs index 8bc61b1c3..260113a9e 100644 --- a/mscorlib/system/security/cryptography/dsasignatureformatter.cs +++ b/mscorlib/system/security/cryptography/dsasignatureformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/hashalgorithm.cs b/mscorlib/system/security/cryptography/hashalgorithm.cs index 6d9083317..83d30b64a 100644 --- a/mscorlib/system/security/cryptography/hashalgorithm.cs +++ b/mscorlib/system/security/cryptography/hashalgorithm.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/hmac.cs b/mscorlib/system/security/cryptography/hmac.cs index d87881456..a169beca1 100644 --- a/mscorlib/system/security/cryptography/hmac.cs +++ b/mscorlib/system/security/cryptography/hmac.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/hmacmd5.cs b/mscorlib/system/security/cryptography/hmacmd5.cs index da536c01f..0a3347113 100644 --- a/mscorlib/system/security/cryptography/hmacmd5.cs +++ b/mscorlib/system/security/cryptography/hmacmd5.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/hmacripemd160.cs b/mscorlib/system/security/cryptography/hmacripemd160.cs index 991d877ff..8b2aabebd 100644 --- a/mscorlib/system/security/cryptography/hmacripemd160.cs +++ b/mscorlib/system/security/cryptography/hmacripemd160.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/hmacsha1.cs b/mscorlib/system/security/cryptography/hmacsha1.cs index f58e3cabc..5dd65d6d6 100644 --- a/mscorlib/system/security/cryptography/hmacsha1.cs +++ b/mscorlib/system/security/cryptography/hmacsha1.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/hmacsha256.cs b/mscorlib/system/security/cryptography/hmacsha256.cs index 7a4841100..e4d045278 100644 --- a/mscorlib/system/security/cryptography/hmacsha256.cs +++ b/mscorlib/system/security/cryptography/hmacsha256.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/hmacsha384.cs b/mscorlib/system/security/cryptography/hmacsha384.cs index d01847ba2..068944c0e 100644 --- a/mscorlib/system/security/cryptography/hmacsha384.cs +++ b/mscorlib/system/security/cryptography/hmacsha384.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/hmacsha512.cs b/mscorlib/system/security/cryptography/hmacsha512.cs index e037365e1..886d11bc0 100644 --- a/mscorlib/system/security/cryptography/hmacsha512.cs +++ b/mscorlib/system/security/cryptography/hmacsha512.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/icspasymmetricalgorithm.cs b/mscorlib/system/security/cryptography/icspasymmetricalgorithm.cs index f726d36a0..d5b501ce5 100644 --- a/mscorlib/system/security/cryptography/icspasymmetricalgorithm.cs +++ b/mscorlib/system/security/cryptography/icspasymmetricalgorithm.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/keyedhashalgorithm.cs b/mscorlib/system/security/cryptography/keyedhashalgorithm.cs index a547d240a..ca714da0d 100644 --- a/mscorlib/system/security/cryptography/keyedhashalgorithm.cs +++ b/mscorlib/system/security/cryptography/keyedhashalgorithm.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/mactripledes.cs b/mscorlib/system/security/cryptography/mactripledes.cs index a0d4e7d92..19d8be122 100644 --- a/mscorlib/system/security/cryptography/mactripledes.cs +++ b/mscorlib/system/security/cryptography/mactripledes.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/md5.cs b/mscorlib/system/security/cryptography/md5.cs index 894eeae6a..0d2cbc5ee 100644 --- a/mscorlib/system/security/cryptography/md5.cs +++ b/mscorlib/system/security/cryptography/md5.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/md5cryptoserviceprovider.cs b/mscorlib/system/security/cryptography/md5cryptoserviceprovider.cs index 33c71335e..bbd42c334 100644 --- a/mscorlib/system/security/cryptography/md5cryptoserviceprovider.cs +++ b/mscorlib/system/security/cryptography/md5cryptoserviceprovider.cs @@ -4,7 +4,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/passwordderivebytes.cs b/mscorlib/system/security/cryptography/passwordderivebytes.cs index 23183a883..634cad2bd 100644 --- a/mscorlib/system/security/cryptography/passwordderivebytes.cs +++ b/mscorlib/system/security/cryptography/passwordderivebytes.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/pkcs1maskgenerationmethod.cs b/mscorlib/system/security/cryptography/pkcs1maskgenerationmethod.cs index c48d26cb4..52bea46e8 100644 --- a/mscorlib/system/security/cryptography/pkcs1maskgenerationmethod.cs +++ b/mscorlib/system/security/cryptography/pkcs1maskgenerationmethod.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Cryptography { diff --git a/mscorlib/system/security/cryptography/randomnumbergenerator.cs b/mscorlib/system/security/cryptography/randomnumbergenerator.cs index 1b28257b5..7e4a29475 100644 --- a/mscorlib/system/security/cryptography/randomnumbergenerator.cs +++ b/mscorlib/system/security/cryptography/randomnumbergenerator.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/rc2.cs b/mscorlib/system/security/cryptography/rc2.cs index b4012db86..1089bf030 100644 --- a/mscorlib/system/security/cryptography/rc2.cs +++ b/mscorlib/system/security/cryptography/rc2.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs b/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs index 88f584a51..1b607ef70 100644 --- a/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs +++ b/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/rfc2898derivebytes.cs b/mscorlib/system/security/cryptography/rfc2898derivebytes.cs index 89099cb26..ab8edce48 100644 --- a/mscorlib/system/security/cryptography/rfc2898derivebytes.cs +++ b/mscorlib/system/security/cryptography/rfc2898derivebytes.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/rijndael.cs b/mscorlib/system/security/cryptography/rijndael.cs index 2964bc351..6476b4148 100644 --- a/mscorlib/system/security/cryptography/rijndael.cs +++ b/mscorlib/system/security/cryptography/rijndael.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/rijndaelmanaged.cs b/mscorlib/system/security/cryptography/rijndaelmanaged.cs index b12bdfbec..c394cec04 100644 --- a/mscorlib/system/security/cryptography/rijndaelmanaged.cs +++ b/mscorlib/system/security/cryptography/rijndaelmanaged.cs @@ -4,7 +4,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/rijndaelmanagedtransform.cs b/mscorlib/system/security/cryptography/rijndaelmanagedtransform.cs index 79829fac6..dc93a6317 100644 --- a/mscorlib/system/security/cryptography/rijndaelmanagedtransform.cs +++ b/mscorlib/system/security/cryptography/rijndaelmanagedtransform.cs @@ -4,7 +4,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/ripemd160.cs b/mscorlib/system/security/cryptography/ripemd160.cs index 55edf263f..b78f13433 100644 --- a/mscorlib/system/security/cryptography/ripemd160.cs +++ b/mscorlib/system/security/cryptography/ripemd160.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/ripemd160managed.cs b/mscorlib/system/security/cryptography/ripemd160managed.cs index bf13aabcd..4196bd8de 100644 --- a/mscorlib/system/security/cryptography/ripemd160managed.cs +++ b/mscorlib/system/security/cryptography/ripemd160managed.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/rngcryptoserviceprovider.cs b/mscorlib/system/security/cryptography/rngcryptoserviceprovider.cs index 073f6680f..226632e81 100644 --- a/mscorlib/system/security/cryptography/rngcryptoserviceprovider.cs +++ b/mscorlib/system/security/cryptography/rngcryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/rsa.cs b/mscorlib/system/security/cryptography/rsa.cs index 4a719de5c..dc8a6572d 100644 --- a/mscorlib/system/security/cryptography/rsa.cs +++ b/mscorlib/system/security/cryptography/rsa.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/rsacryptoserviceprovider.cs b/mscorlib/system/security/cryptography/rsacryptoserviceprovider.cs index 0bf87db77..e27577d7a 100644 --- a/mscorlib/system/security/cryptography/rsacryptoserviceprovider.cs +++ b/mscorlib/system/security/cryptography/rsacryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/rsaoaepkeyexchangedeformatter.cs b/mscorlib/system/security/cryptography/rsaoaepkeyexchangedeformatter.cs index 674cdf23f..82e1b3aa1 100644 --- a/mscorlib/system/security/cryptography/rsaoaepkeyexchangedeformatter.cs +++ b/mscorlib/system/security/cryptography/rsaoaepkeyexchangedeformatter.cs @@ -4,7 +4,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Cryptography { diff --git a/mscorlib/system/security/cryptography/rsaoaepkeyexchangeformatter.cs b/mscorlib/system/security/cryptography/rsaoaepkeyexchangeformatter.cs index a931c154c..24b523467 100644 --- a/mscorlib/system/security/cryptography/rsaoaepkeyexchangeformatter.cs +++ b/mscorlib/system/security/cryptography/rsaoaepkeyexchangeformatter.cs @@ -4,7 +4,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Cryptography { diff --git a/mscorlib/system/security/cryptography/rsapkcs1keyexchangedeformatter.cs b/mscorlib/system/security/cryptography/rsapkcs1keyexchangedeformatter.cs index ccd8570ad..fff253e48 100644 --- a/mscorlib/system/security/cryptography/rsapkcs1keyexchangedeformatter.cs +++ b/mscorlib/system/security/cryptography/rsapkcs1keyexchangedeformatter.cs @@ -4,7 +4,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Cryptography { diff --git a/mscorlib/system/security/cryptography/rsapkcs1keyexchangeformatter.cs b/mscorlib/system/security/cryptography/rsapkcs1keyexchangeformatter.cs index 92beef18b..e9e7a296f 100644 --- a/mscorlib/system/security/cryptography/rsapkcs1keyexchangeformatter.cs +++ b/mscorlib/system/security/cryptography/rsapkcs1keyexchangeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Cryptography { diff --git a/mscorlib/system/security/cryptography/rsapkcs1signaturedeformatter.cs b/mscorlib/system/security/cryptography/rsapkcs1signaturedeformatter.cs index 28ee87386..d6bb39143 100644 --- a/mscorlib/system/security/cryptography/rsapkcs1signaturedeformatter.cs +++ b/mscorlib/system/security/cryptography/rsapkcs1signaturedeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/rsapkcs1signatureformatter.cs b/mscorlib/system/security/cryptography/rsapkcs1signatureformatter.cs index 979124256..647d84dbd 100644 --- a/mscorlib/system/security/cryptography/rsapkcs1signatureformatter.cs +++ b/mscorlib/system/security/cryptography/rsapkcs1signatureformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/safecryptohandles.cs b/mscorlib/system/security/cryptography/safecryptohandles.cs index 19b8885de..e7dc76c09 100644 --- a/mscorlib/system/security/cryptography/safecryptohandles.cs +++ b/mscorlib/system/security/cryptography/safecryptohandles.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/sha1.cs b/mscorlib/system/security/cryptography/sha1.cs index e4afdc617..583b16442 100644 --- a/mscorlib/system/security/cryptography/sha1.cs +++ b/mscorlib/system/security/cryptography/sha1.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/sha1cryptoserviceprovider.cs b/mscorlib/system/security/cryptography/sha1cryptoserviceprovider.cs index ed886250f..0b25472e2 100644 --- a/mscorlib/system/security/cryptography/sha1cryptoserviceprovider.cs +++ b/mscorlib/system/security/cryptography/sha1cryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/sha1managed.cs b/mscorlib/system/security/cryptography/sha1managed.cs index ef07a4b17..863cea2e1 100644 --- a/mscorlib/system/security/cryptography/sha1managed.cs +++ b/mscorlib/system/security/cryptography/sha1managed.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/sha256.cs b/mscorlib/system/security/cryptography/sha256.cs index c22be578a..ca193c2d2 100644 --- a/mscorlib/system/security/cryptography/sha256.cs +++ b/mscorlib/system/security/cryptography/sha256.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/sha256managed.cs b/mscorlib/system/security/cryptography/sha256managed.cs index 41711c808..242bfff1b 100644 --- a/mscorlib/system/security/cryptography/sha256managed.cs +++ b/mscorlib/system/security/cryptography/sha256managed.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/sha384.cs b/mscorlib/system/security/cryptography/sha384.cs index 26ed3cb0c..1f6449cb2 100644 --- a/mscorlib/system/security/cryptography/sha384.cs +++ b/mscorlib/system/security/cryptography/sha384.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/sha384managed.cs b/mscorlib/system/security/cryptography/sha384managed.cs index d17eaaa53..c10ab52f6 100644 --- a/mscorlib/system/security/cryptography/sha384managed.cs +++ b/mscorlib/system/security/cryptography/sha384managed.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/sha512.cs b/mscorlib/system/security/cryptography/sha512.cs index cfa001d57..aa1bc2eb9 100644 --- a/mscorlib/system/security/cryptography/sha512.cs +++ b/mscorlib/system/security/cryptography/sha512.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/sha512managed.cs b/mscorlib/system/security/cryptography/sha512managed.cs index 31641440b..20ec6a6b7 100644 --- a/mscorlib/system/security/cryptography/sha512managed.cs +++ b/mscorlib/system/security/cryptography/sha512managed.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/signaturedescription.cs b/mscorlib/system/security/cryptography/signaturedescription.cs index 330a0222f..8a78c9e78 100644 --- a/mscorlib/system/security/cryptography/signaturedescription.cs +++ b/mscorlib/system/security/cryptography/signaturedescription.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/symmetricalgorithm.cs b/mscorlib/system/security/cryptography/symmetricalgorithm.cs index 3d39a2bf3..03a3094af 100644 --- a/mscorlib/system/security/cryptography/symmetricalgorithm.cs +++ b/mscorlib/system/security/cryptography/symmetricalgorithm.cs @@ -4,7 +4,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/tripledes.cs b/mscorlib/system/security/cryptography/tripledes.cs index 9755966c3..366d76260 100644 --- a/mscorlib/system/security/cryptography/tripledes.cs +++ b/mscorlib/system/security/cryptography/tripledes.cs @@ -4,7 +4,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs b/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs index 80dbd5498..65655b56c 100644 --- a/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs +++ b/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/cryptography/utils.cs b/mscorlib/system/security/cryptography/utils.cs index 6f9a9c4e7..31e06487a 100644 --- a/mscorlib/system/security/cryptography/utils.cs +++ b/mscorlib/system/security/cryptography/utils.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -365,8 +365,20 @@ internal static void GetKeyPairHelper (CspAlgorithmType keyType, CspParameters p #if FEATURE_X509_SECURESTRINGS // If the user wanted to specify a PIN or HWND for a smart card CSP, apply those settings now. - if (parameters.ParentWindowHandle != IntPtr.Zero) - SetProviderParameter(TempFetchedProvHandle, parameters.KeyNumber, Constants.CLR_PP_CLIENT_HWND, parameters.ParentWindowHandle); + if (parameters.ParentWindowHandle != IntPtr.Zero) { + // Copy the value onto the stack. + // Then, for versions beyond 4.6.2 take the address of that copy, since &hwnd is what the API wants. + IntPtr parentWindowHandle = parameters.ParentWindowHandle; + IntPtr pHwnd = parentWindowHandle; + + if (!AppContextSwitches.DoNotAddrOfCspParentWindowHandle) { + unsafe { + pHwnd = new IntPtr(&parentWindowHandle); + } + } + + SetProviderParameter(TempFetchedProvHandle, parameters.KeyNumber, Constants.CLR_PP_CLIENT_HWND, pHwnd); + } else if (parameters.KeyPassword != null) { IntPtr szPassword = Marshal.SecureStringToCoTaskMemAnsi(parameters.KeyPassword); try { diff --git a/mscorlib/system/security/framesecuritydescriptor.cs b/mscorlib/system/security/framesecuritydescriptor.cs index 906443274..92f4f22df 100644 --- a/mscorlib/system/security/framesecuritydescriptor.cs +++ b/mscorlib/system/security/framesecuritydescriptor.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Security { using System.Text; using System.Runtime.CompilerServices; diff --git a/mscorlib/system/security/hostprotectionexception.cs b/mscorlib/system/security/hostprotectionexception.cs index 638ddf75b..ee480cb7f 100644 --- a/mscorlib/system/security/hostprotectionexception.cs +++ b/mscorlib/system/security/hostprotectionexception.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // /*============================================================================= diff --git a/mscorlib/system/security/hostsecuritymanager.cs b/mscorlib/system/security/hostsecuritymanager.cs index 113a75e1f..4d90a44fc 100644 --- a/mscorlib/system/security/hostsecuritymanager.cs +++ b/mscorlib/system/security/hostsecuritymanager.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/namedpermissionset.cs b/mscorlib/system/security/namedpermissionset.cs index d2baa4899..24629138d 100644 --- a/mscorlib/system/security/namedpermissionset.cs +++ b/mscorlib/system/security/namedpermissionset.cs @@ -5,7 +5,7 @@ // ==--== // NamedPermissionSet.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Extends PermissionSet to allow an associated name and description // diff --git a/mscorlib/system/security/permissionlistset.cs b/mscorlib/system/security/permissionlistset.cs index fa855d0fa..27cf6cd5a 100644 --- a/mscorlib/system/security/permissionlistset.cs +++ b/mscorlib/system/security/permissionlistset.cs @@ -7,8 +7,8 @@ ** ** Class: PermissionListSet.cs ** -** <OWNER>[....]</OWNER> -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: Holds state about A/G/R permissionsets in a callstack or appdomain ** (Replacement for PermissionListSet) diff --git a/mscorlib/system/security/permissions/environmentpermission.cs b/mscorlib/system/security/permissions/environmentpermission.cs index 5da4d1999..9b86f00aa 100644 --- a/mscorlib/system/security/permissions/environmentpermission.cs +++ b/mscorlib/system/security/permissions/environmentpermission.cs @@ -5,7 +5,7 @@ // ==--== // EnvironmentPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions { diff --git a/mscorlib/system/security/permissions/filedialogpermission.cs b/mscorlib/system/security/permissions/filedialogpermission.cs index a46bc0dc8..55308ce4e 100644 --- a/mscorlib/system/security/permissions/filedialogpermission.cs +++ b/mscorlib/system/security/permissions/filedialogpermission.cs @@ -5,7 +5,7 @@ // ==--== // FileDialogPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions { diff --git a/mscorlib/system/security/permissions/fileiopermission.cs b/mscorlib/system/security/permissions/fileiopermission.cs index db35ac502..6287f3f07 100644 --- a/mscorlib/system/security/permissions/fileiopermission.cs +++ b/mscorlib/system/security/permissions/fileiopermission.cs @@ -5,7 +5,7 @@ // ==--== // FileIOPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions { @@ -210,6 +210,7 @@ internal void AddPathList(FileIOPermissionAccess access, AccessControlActions co { throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); } + Contract.EndContractBlock(); // @ @@ -551,13 +552,10 @@ private static void CheckIllegalCharacters(String[] str, bool onlyCheckExtras) { for (int i = 0; i < str.Length; ++i) { - // FileIOPermission doesn't allow for normalizing across various volume names. This means "C:\" and - // "\\?\C:\" won't be considered correctly. In addition there are many other aliases for the volume - // besides "C:" such as (in one concrete example) "\\?\Harddisk0Partition2\", "\\?\HarddiskVolume6\", - // "\\?\Volume{d1655348-0000-0000-0000-f01500000000}\", etc. - // - // We'll continue to explicitly block extended syntax here by disallowing wildcards no matter where - // they occur in the string (e.g. \\?\ isn't ok) + // Fail out nulls as CheckInvalidPathChars would (to match historical behavior) + if (str[i] == null) throw new ArgumentNullException("path"); + + // Looking for wildcard characters, etc. if (CheckExtraPathCharacters(str[i])) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars")); @@ -570,10 +568,27 @@ private static void CheckIllegalCharacters(String[] str, bool onlyCheckExtras) /// Check for ?,* and null, ignoring extended syntax. /// </summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] + [SecuritySafeCritical] private unsafe static bool CheckExtraPathCharacters(string path) { + // FileIOPermission doesn't allow for normalizing across various volume names. This means "C:\" and + // "\\?\C:\" won't be considered correctly. In addition there are many other aliases for the volume + // besides "C:" such as (in one concrete example) "\\?\Harddisk0Partition2\", "\\?\HarddiskVolume6\", + // "\\?\Volume{d1655348-0000-0000-0000-f01500000000}\", etc. + // + // This was never completely correct due to \\.\ paths. We'll allow \\?\ now if two conditions are met: + // (1) We are in full trust and (2) we _aren't_ under the LegacyPathHandling switch. + + bool skipPrefix = +#if FEATURE_CAS_POLICY + CodeAccessSecurityEngine.QuickCheckForAllDemands() && +#endif + !AppContextSwitches.UseLegacyPathHandling; + + int startIndex = !skipPrefix ? 0 : PathInternal.IsDevice(path) ? PathInternal.DevicePrefixLength : 0; + char currentChar; - for (int i = 0; i < path.Length; i++) + for (int i = startIndex; i < path.Length; i++) { currentChar = path[i]; diff --git a/mscorlib/system/security/permissions/gacidentitypermission.cs b/mscorlib/system/security/permissions/gacidentitypermission.cs index 0f130ad13..df59f63a2 100644 --- a/mscorlib/system/security/permissions/gacidentitypermission.cs +++ b/mscorlib/system/security/permissions/gacidentitypermission.cs @@ -5,7 +5,7 @@ // ==--== // GacIdentityPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissions/hostprotectionpermission.cs b/mscorlib/system/security/permissions/hostprotectionpermission.cs index 8679f29b9..837cac3c1 100644 --- a/mscorlib/system/security/permissions/hostprotectionpermission.cs +++ b/mscorlib/system/security/permissions/hostprotectionpermission.cs @@ -5,7 +5,7 @@ // ==--== // HostProtectionPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions @@ -22,7 +22,7 @@ namespace System.Security.Permissions using System.Globalization; using System.Diagnostics.Contracts; - // Keep this enum in [....] with tools\ngen\ngen.cpp and inc\mscoree.idl + // Keep this enum in sync with tools\ngen\ngen.cpp and inc\mscoree.idl [Serializable] [Flags] diff --git a/mscorlib/system/security/permissions/isolatedstoragefilepermission.cs b/mscorlib/system/security/permissions/isolatedstoragefilepermission.cs index 031cf0983..e52c1caf1 100644 --- a/mscorlib/system/security/permissions/isolatedstoragefilepermission.cs +++ b/mscorlib/system/security/permissions/isolatedstoragefilepermission.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Purpose : This permission is used to controls/administer access to // IsolatedStorageFile diff --git a/mscorlib/system/security/permissions/isolatedstoragepermission.cs b/mscorlib/system/security/permissions/isolatedstoragepermission.cs index 7fad3c55e..69c7f743a 100644 --- a/mscorlib/system/security/permissions/isolatedstoragepermission.cs +++ b/mscorlib/system/security/permissions/isolatedstoragepermission.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions { diff --git a/mscorlib/system/security/permissions/keycontainerpermission.cs b/mscorlib/system/security/permissions/keycontainerpermission.cs index a606bf2ca..0afd60558 100644 --- a/mscorlib/system/security/permissions/keycontainerpermission.cs +++ b/mscorlib/system/security/permissions/keycontainerpermission.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/permissions/permissionattributes.cs b/mscorlib/system/security/permissions/permissionattributes.cs index 09f2ae386..1e36a44ec 100644 --- a/mscorlib/system/security/permissions/permissionattributes.cs +++ b/mscorlib/system/security/permissions/permissionattributes.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Security.Permissions { diff --git a/mscorlib/system/security/permissions/principalpermission.cs b/mscorlib/system/security/permissions/principalpermission.cs index 7598e6286..4ed6ff549 100644 --- a/mscorlib/system/security/permissions/principalpermission.cs +++ b/mscorlib/system/security/permissions/principalpermission.cs @@ -5,7 +5,7 @@ // ==--== // PrincipalPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissions/publisheridentitypermission.cs b/mscorlib/system/security/permissions/publisheridentitypermission.cs index 7c41b3be1..5f78b238d 100644 --- a/mscorlib/system/security/permissions/publisheridentitypermission.cs +++ b/mscorlib/system/security/permissions/publisheridentitypermission.cs @@ -5,7 +5,7 @@ // ==--== // PublisherIdentityPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissions/reflectionpermission.cs b/mscorlib/system/security/permissions/reflectionpermission.cs index 00e79a1ee..7e0d2fd27 100644 --- a/mscorlib/system/security/permissions/reflectionpermission.cs +++ b/mscorlib/system/security/permissions/reflectionpermission.cs @@ -5,7 +5,7 @@ // ==--== // ReflectionPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissions/registrypermission.cs b/mscorlib/system/security/permissions/registrypermission.cs index 0805d55ac..1f7cfddeb 100644 --- a/mscorlib/system/security/permissions/registrypermission.cs +++ b/mscorlib/system/security/permissions/registrypermission.cs @@ -5,7 +5,7 @@ // ==--== // RegistryPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissions/securitypermission.cs b/mscorlib/system/security/permissions/securitypermission.cs index 18b328f88..1e501c599 100644 --- a/mscorlib/system/security/permissions/securitypermission.cs +++ b/mscorlib/system/security/permissions/securitypermission.cs @@ -5,7 +5,7 @@ // ==--== // SecurityPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissions/siteidentitypermission.cs b/mscorlib/system/security/permissions/siteidentitypermission.cs index d08ccce13..a6c530be8 100644 --- a/mscorlib/system/security/permissions/siteidentitypermission.cs +++ b/mscorlib/system/security/permissions/siteidentitypermission.cs @@ -5,7 +5,7 @@ // ==--== // SiteIdentityPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissions/strongnameidentitypermission.cs b/mscorlib/system/security/permissions/strongnameidentitypermission.cs index 31cbc1216..1ab3804bd 100644 --- a/mscorlib/system/security/permissions/strongnameidentitypermission.cs +++ b/mscorlib/system/security/permissions/strongnameidentitypermission.cs @@ -6,7 +6,7 @@ // ==--== // StrongNameIdentityPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissions/strongnamepublickeyblob.cs b/mscorlib/system/security/permissions/strongnamepublickeyblob.cs index 2367f8ba8..ac3cac3e2 100644 --- a/mscorlib/system/security/permissions/strongnamepublickeyblob.cs +++ b/mscorlib/system/security/permissions/strongnamepublickeyblob.cs @@ -5,7 +5,7 @@ // ==--== // StrongNamePublicKeyBlob.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissions/uipermission.cs b/mscorlib/system/security/permissions/uipermission.cs index dea740ad6..6e34b8627 100644 --- a/mscorlib/system/security/permissions/uipermission.cs +++ b/mscorlib/system/security/permissions/uipermission.cs @@ -5,7 +5,7 @@ // ==--== // UIPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissions/urlidentitypermission.cs b/mscorlib/system/security/permissions/urlidentitypermission.cs index ce61fad84..bab282e88 100644 --- a/mscorlib/system/security/permissions/urlidentitypermission.cs +++ b/mscorlib/system/security/permissions/urlidentitypermission.cs @@ -5,7 +5,7 @@ // ==--== // UrlIdentityPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissions/zoneidentitypermission.cs b/mscorlib/system/security/permissions/zoneidentitypermission.cs index 6b3f6c56b..13574f3f2 100644 --- a/mscorlib/system/security/permissions/zoneidentitypermission.cs +++ b/mscorlib/system/security/permissions/zoneidentitypermission.cs @@ -5,7 +5,7 @@ // ==--== // ZoneIdentityPermission.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Permissions diff --git a/mscorlib/system/security/permissionset.cs b/mscorlib/system/security/permissionset.cs index 1edd3c8ad..b71188299 100644 --- a/mscorlib/system/security/permissionset.cs +++ b/mscorlib/system/security/permissionset.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security { diff --git a/mscorlib/system/security/permissionsetenumerator.cs b/mscorlib/system/security/permissionsetenumerator.cs index e65e24d50..c8f041739 100644 --- a/mscorlib/system/security/permissionsetenumerator.cs +++ b/mscorlib/system/security/permissionsetenumerator.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security diff --git a/mscorlib/system/security/permissionsettriple.cs b/mscorlib/system/security/permissionsettriple.cs index f319aa371..170cd2033 100644 --- a/mscorlib/system/security/permissionsettriple.cs +++ b/mscorlib/system/security/permissionsettriple.cs @@ -7,7 +7,7 @@ ** ** Class: PermissionSetTriple ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: Container class for holding an AppDomain's Grantset and Refused sets. ** Also used for CompressedStacks which brings in the third PermissionSet. diff --git a/mscorlib/system/security/permissiontoken.cs b/mscorlib/system/security/permissiontoken.cs index bb328a7e6..92051b8ee 100644 --- a/mscorlib/system/security/permissiontoken.cs +++ b/mscorlib/system/security/permissiontoken.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Security { using System; using System.Security.Util; diff --git a/mscorlib/system/security/policy/allmembershipcondition.cs b/mscorlib/system/security/policy/allmembershipcondition.cs index 9b517b503..e6d327d14 100644 --- a/mscorlib/system/security/policy/allmembershipcondition.cs +++ b/mscorlib/system/security/policy/allmembershipcondition.cs @@ -5,7 +5,7 @@ // ==--== // AllMembershipCondition.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Simple IMembershipCondition implementation that always passes // diff --git a/mscorlib/system/security/policy/applicationdirectory.cs b/mscorlib/system/security/policy/applicationdirectory.cs index b521a618d..3b568460e 100644 --- a/mscorlib/system/security/policy/applicationdirectory.cs +++ b/mscorlib/system/security/policy/applicationdirectory.cs @@ -5,7 +5,7 @@ // ==--== // ApplicationDirectory.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // ApplicationDirectory is an evidence type representing the directory the assembly // was loaded from. diff --git a/mscorlib/system/security/policy/applicationdirectorymembershipcondition.cs b/mscorlib/system/security/policy/applicationdirectorymembershipcondition.cs index 97194d114..5bc3e8dff 100644 --- a/mscorlib/system/security/policy/applicationdirectorymembershipcondition.cs +++ b/mscorlib/system/security/policy/applicationdirectorymembershipcondition.cs @@ -5,7 +5,7 @@ // ==--== // ApplicationDirectoryMembershipCondition.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Implementation of membership condition for "application directories" // diff --git a/mscorlib/system/security/policy/applicationsecurityinfo.cs b/mscorlib/system/security/policy/applicationsecurityinfo.cs index 825d6b027..477b44575 100644 --- a/mscorlib/system/security/policy/applicationsecurityinfo.cs +++ b/mscorlib/system/security/policy/applicationsecurityinfo.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/applicationsecuritymanager.cs b/mscorlib/system/security/policy/applicationsecuritymanager.cs index 07c3d8267..d3bbfbd9c 100644 --- a/mscorlib/system/security/policy/applicationsecuritymanager.cs +++ b/mscorlib/system/security/policy/applicationsecuritymanager.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/applicationtrust.cs b/mscorlib/system/security/policy/applicationtrust.cs index 11092a47e..c93e68a36 100644 --- a/mscorlib/system/security/policy/applicationtrust.cs +++ b/mscorlib/system/security/policy/applicationtrust.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -55,11 +55,11 @@ public sealed class ApplicationTrust : EvidenceBase, ISecurityEncodable private IList<StrongName> m_fullTrustAssemblies; // Permission special flags for the default grant set in this ApplicationTrust. This should be - // updated in [....] with any updates to the default grant set. + // updated in sync with any updates to the default grant set. // // In the general case, these values cannot be trusted - we only store a reference to the // DefaultGrantSet, and return the reference directly, which means that code can update the - // permission set without our knowledge. That would lead to the flags getting out of [....] with the + // permission set without our knowledge. That would lead to the flags getting out of sync with the // grant set. // // However, we only care about these flags when we're creating a homogenous AppDomain, and in that diff --git a/mscorlib/system/security/policy/assemblyevidencefactory.cs b/mscorlib/system/security/policy/assemblyevidencefactory.cs index cdd0434f7..df5f539e8 100644 --- a/mscorlib/system/security/policy/assemblyevidencefactory.cs +++ b/mscorlib/system/security/policy/assemblyevidencefactory.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/security/policy/codegroup.cs b/mscorlib/system/security/policy/codegroup.cs index d7e9a6533..a6439b552 100644 --- a/mscorlib/system/security/policy/codegroup.cs +++ b/mscorlib/system/security/policy/codegroup.cs @@ -5,7 +5,7 @@ // ==--== // CodeGroup.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Representation for code groups used for the policy mechanism // diff --git a/mscorlib/system/security/policy/evidence.cs b/mscorlib/system/security/policy/evidence.cs index 41cc55871..a3e9ab07c 100644 --- a/mscorlib/system/security/policy/evidence.cs +++ b/mscorlib/system/security/policy/evidence.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Policy diff --git a/mscorlib/system/security/policy/evidencebase.cs b/mscorlib/system/security/policy/evidencebase.cs index daf220938..30a8fbee7 100644 --- a/mscorlib/system/security/policy/evidencebase.cs +++ b/mscorlib/system/security/policy/evidencebase.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; @@ -166,7 +166,7 @@ public void Add(EvidenceBase evidence) { Contract.Assert(evidence != null); Contract.Assert(m_legacyEvidenceList.Count == 0 || EvidenceType == evidence.GetType() || (evidence is LegacyEvidenceWrapper && (evidence as LegacyEvidenceWrapper).EvidenceType == EvidenceType), - "LegacyEvidenceList must be ----geonous"); + "LegacyEvidenceList must be homogeonous"); Contract.Assert(evidence.GetType() != typeof(LegacyEvidenceList), "Attempt to add a legacy evidence list to another legacy evidence list"); diff --git a/mscorlib/system/security/policy/evidencetypedescriptor.cs b/mscorlib/system/security/policy/evidencetypedescriptor.cs index b45c54113..ce063253c 100644 --- a/mscorlib/system/security/policy/evidencetypedescriptor.cs +++ b/mscorlib/system/security/policy/evidencetypedescriptor.cs @@ -2,7 +2,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/security/policy/filecodegroup.cs b/mscorlib/system/security/policy/filecodegroup.cs index e3a2bb487..d36c6402a 100644 --- a/mscorlib/system/security/policy/filecodegroup.cs +++ b/mscorlib/system/security/policy/filecodegroup.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/firstmatchcodegroup.cs b/mscorlib/system/security/policy/firstmatchcodegroup.cs index 4700bbbe7..0afbd3c4c 100644 --- a/mscorlib/system/security/policy/firstmatchcodegroup.cs +++ b/mscorlib/system/security/policy/firstmatchcodegroup.cs @@ -5,7 +5,7 @@ // ==--== // FirstMatchCodeGroup.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Representation for code groups used for the policy mechanism // diff --git a/mscorlib/system/security/policy/gac.cs b/mscorlib/system/security/policy/gac.cs index 78f0eea16..a6abea898 100644 --- a/mscorlib/system/security/policy/gac.cs +++ b/mscorlib/system/security/policy/gac.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/gacmembershipcondition.cs b/mscorlib/system/security/policy/gacmembershipcondition.cs index fc9679358..84d65e5e3 100644 --- a/mscorlib/system/security/policy/gacmembershipcondition.cs +++ b/mscorlib/system/security/policy/gacmembershipcondition.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/hash.cs b/mscorlib/system/security/policy/hash.cs index 9bd73cf25..184faec0e 100644 --- a/mscorlib/system/security/policy/hash.cs +++ b/mscorlib/system/security/policy/hash.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/hashmembershipcondition.cs b/mscorlib/system/security/policy/hashmembershipcondition.cs index befd3261f..690034bc6 100644 --- a/mscorlib/system/security/policy/hashmembershipcondition.cs +++ b/mscorlib/system/security/policy/hashmembershipcondition.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/iapplicationtrustmanager.cs b/mscorlib/system/security/policy/iapplicationtrustmanager.cs index 46990db48..194bfbdce 100644 --- a/mscorlib/system/security/policy/iapplicationtrustmanager.cs +++ b/mscorlib/system/security/policy/iapplicationtrustmanager.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/netcodegroup.cs b/mscorlib/system/security/policy/netcodegroup.cs index 17fe906c4..5916875e6 100644 --- a/mscorlib/system/security/policy/netcodegroup.cs +++ b/mscorlib/system/security/policy/netcodegroup.cs @@ -5,7 +5,7 @@ // ==--== // NetCodeGroup.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Representation for code groups used for the policy mechanism // diff --git a/mscorlib/system/security/policy/pefileevidencefactory.cs b/mscorlib/system/security/policy/pefileevidencefactory.cs index 266e7b5f9..b70b1d262 100644 --- a/mscorlib/system/security/policy/pefileevidencefactory.cs +++ b/mscorlib/system/security/policy/pefileevidencefactory.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; @@ -25,7 +25,7 @@ namespace System.Security.Policy { /// <summary> - /// Arguments to the ETW evidence generation event. This enumeration should be kept in [....] with + /// Arguments to the ETW evidence generation event. This enumeration should be kept in sync with /// the VM enumeration EvidenceType in SecurityPolicy.h. /// </summary> internal enum EvidenceTypeGenerated diff --git a/mscorlib/system/security/policy/permissionrequestevidence.cs b/mscorlib/system/security/policy/permissionrequestevidence.cs index e4826330f..ed71bdab1 100644 --- a/mscorlib/system/security/policy/permissionrequestevidence.cs +++ b/mscorlib/system/security/policy/permissionrequestevidence.cs @@ -5,7 +5,7 @@ // ==--== // PermissionRequestEvidence.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Encapsulation of permission request as an evidence type. // diff --git a/mscorlib/system/security/policy/policyexception.cs b/mscorlib/system/security/policy/policyexception.cs index c0716d3c6..11ef230b6 100644 --- a/mscorlib/system/security/policy/policyexception.cs +++ b/mscorlib/system/security/policy/policyexception.cs @@ -5,7 +5,7 @@ // ==--== // PolicyException.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Use this class to throw a PolicyException // diff --git a/mscorlib/system/security/policy/policylevel.cs b/mscorlib/system/security/policy/policylevel.cs index 5a766ce01..10def8e68 100644 --- a/mscorlib/system/security/policy/policylevel.cs +++ b/mscorlib/system/security/policy/policylevel.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/policystatement.cs b/mscorlib/system/security/policy/policystatement.cs index 35e703340..9dbb1239f 100644 --- a/mscorlib/system/security/policy/policystatement.cs +++ b/mscorlib/system/security/policy/policystatement.cs @@ -6,7 +6,7 @@ // ==--== // PolicyStatement.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Represents the policy associated with some piece of evidence // diff --git a/mscorlib/system/security/policy/publisher.cs b/mscorlib/system/security/policy/publisher.cs index b28e9c13b..1234d776c 100644 --- a/mscorlib/system/security/policy/publisher.cs +++ b/mscorlib/system/security/policy/publisher.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/publishermembershipcondition.cs b/mscorlib/system/security/policy/publishermembershipcondition.cs index 3c6dda1f4..c3da15b83 100644 --- a/mscorlib/system/security/policy/publishermembershipcondition.cs +++ b/mscorlib/system/security/policy/publishermembershipcondition.cs @@ -5,7 +5,7 @@ // ==--== // PublisherMembershipCondition.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Implementation of membership condition for X509 certificate based publishers // diff --git a/mscorlib/system/security/policy/site.cs b/mscorlib/system/security/policy/site.cs index 86ef1763a..c18dc2160 100644 --- a/mscorlib/system/security/policy/site.cs +++ b/mscorlib/system/security/policy/site.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/sitemembershipcondition.cs b/mscorlib/system/security/policy/sitemembershipcondition.cs index 4dc9af6f3..067d63f24 100644 --- a/mscorlib/system/security/policy/sitemembershipcondition.cs +++ b/mscorlib/system/security/policy/sitemembershipcondition.cs @@ -6,7 +6,7 @@ // ==--== // SiteMembershipCondition.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Implementation of membership condition for zones // diff --git a/mscorlib/system/security/policy/strongname.cs b/mscorlib/system/security/policy/strongname.cs index 775d5d75d..471482877 100644 --- a/mscorlib/system/security/policy/strongname.cs +++ b/mscorlib/system/security/policy/strongname.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/strongnamemembershipcondition.cs b/mscorlib/system/security/policy/strongnamemembershipcondition.cs index afd302a49..c6470c861 100644 --- a/mscorlib/system/security/policy/strongnamemembershipcondition.cs +++ b/mscorlib/system/security/policy/strongnamemembershipcondition.cs @@ -5,7 +5,7 @@ // ==--== // StrongNameMembershipCondition.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Implementation of membership condition for zones // diff --git a/mscorlib/system/security/policy/unioncodegroup.cs b/mscorlib/system/security/policy/unioncodegroup.cs index 4d6570786..470d0fb8a 100644 --- a/mscorlib/system/security/policy/unioncodegroup.cs +++ b/mscorlib/system/security/policy/unioncodegroup.cs @@ -5,7 +5,7 @@ // ==--== // UnionCodeGroup.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Representation for code groups used for the policy mechanism // diff --git a/mscorlib/system/security/policy/url.cs b/mscorlib/system/security/policy/url.cs index b41f2cfe5..632d2ce3d 100644 --- a/mscorlib/system/security/policy/url.cs +++ b/mscorlib/system/security/policy/url.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/urlmembershipcondition.cs b/mscorlib/system/security/policy/urlmembershipcondition.cs index 2891234f9..a8745a5cb 100644 --- a/mscorlib/system/security/policy/urlmembershipcondition.cs +++ b/mscorlib/system/security/policy/urlmembershipcondition.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/zone.cs b/mscorlib/system/security/policy/zone.cs index 74f60e5ce..9942af9f2 100644 --- a/mscorlib/system/security/policy/zone.cs +++ b/mscorlib/system/security/policy/zone.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/policy/zonemembershipcondition.cs b/mscorlib/system/security/policy/zonemembershipcondition.cs index 329ef5e64..a9afd3033 100644 --- a/mscorlib/system/security/policy/zonemembershipcondition.cs +++ b/mscorlib/system/security/policy/zonemembershipcondition.cs @@ -6,7 +6,7 @@ // ==--== // ZoneMembershipCondition.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Implementation of membership condition for zones // diff --git a/mscorlib/system/security/policymanager.cs b/mscorlib/system/security/policymanager.cs index ff35a450c..814c460ee 100644 --- a/mscorlib/system/security/policymanager.cs +++ b/mscorlib/system/security/policymanager.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -414,7 +414,7 @@ private static QuickCacheEntryType GenerateQuickCache(PolicyLevel level) { if (FullTrustMap == null) { - // This mapping must stay in [....] with the SecurityZone enumeration in SecurityZone.cs + // This mapping must stay in sync with the SecurityZone enumeration in SecurityZone.cs FullTrustMap = new QuickCacheEntryType[] { QuickCacheEntryType.FullTrustZoneMyComputer, diff --git a/mscorlib/system/security/principal/genericidentity.cs b/mscorlib/system/security/principal/genericidentity.cs index 02037c639..b771a7018 100644 --- a/mscorlib/system/security/principal/genericidentity.cs +++ b/mscorlib/system/security/principal/genericidentity.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/principal/genericprincipal.cs b/mscorlib/system/security/principal/genericprincipal.cs index f2f6cacc6..af04dddc4 100644 --- a/mscorlib/system/security/principal/genericprincipal.cs +++ b/mscorlib/system/security/principal/genericprincipal.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/principal/identitynotmappedexception.cs b/mscorlib/system/security/principal/identitynotmappedexception.cs index 8985f087e..f5f9bbabe 100644 --- a/mscorlib/system/security/principal/identitynotmappedexception.cs +++ b/mscorlib/system/security/principal/identitynotmappedexception.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/security/principal/identityreference.cs b/mscorlib/system/security/principal/identityreference.cs index 3be7e0e96..727c8ea73 100644 --- a/mscorlib/system/security/principal/identityreference.cs +++ b/mscorlib/system/security/principal/identityreference.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/security/principal/ircollection.cs b/mscorlib/system/security/principal/ircollection.cs index 979704be5..8c00f1323 100644 --- a/mscorlib/system/security/principal/ircollection.cs +++ b/mscorlib/system/security/principal/ircollection.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Security.Principal { using System; diff --git a/mscorlib/system/security/principal/ntaccount.cs b/mscorlib/system/security/principal/ntaccount.cs index 291d56499..19b7ec764 100644 --- a/mscorlib/system/security/principal/ntaccount.cs +++ b/mscorlib/system/security/principal/ntaccount.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using Microsoft.Win32; diff --git a/mscorlib/system/security/principal/sid.cs b/mscorlib/system/security/principal/sid.cs index bfc99ecf3..e8558b295 100644 --- a/mscorlib/system/security/principal/sid.cs +++ b/mscorlib/system/security/principal/sid.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/security/principal/win32.cs b/mscorlib/system/security/principal/win32.cs index bac02ffb6..2aedb26bc 100644 --- a/mscorlib/system/security/principal/win32.cs +++ b/mscorlib/system/security/principal/win32.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using Microsoft.Win32; diff --git a/mscorlib/system/security/principal/windowsidentity.cs b/mscorlib/system/security/principal/windowsidentity.cs index e045de8e2..ca0b03886 100644 --- a/mscorlib/system/security/principal/windowsidentity.cs +++ b/mscorlib/system/security/principal/windowsidentity.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -46,7 +46,7 @@ public enum WindowsAccountType { Anonymous = 3 } - // Keep in [....] with vm\comprincipal.h + // Keep in sync with vm\comprincipal.h internal enum WinSecurityContext { Thread = 1, // OpenAsSelf = false Process = 2, // OpenAsSelf = true diff --git a/mscorlib/system/security/principal/windowsimpersonationcontext.cs b/mscorlib/system/security/principal/windowsimpersonationcontext.cs index 311c3b3d4..5315ae7ba 100644 --- a/mscorlib/system/security/principal/windowsimpersonationcontext.cs +++ b/mscorlib/system/security/principal/windowsimpersonationcontext.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/principal/windowsprincipal.cs b/mscorlib/system/security/principal/windowsprincipal.cs index d954f9f97..6e60e7de3 100644 --- a/mscorlib/system/security/principal/windowsprincipal.cs +++ b/mscorlib/system/security/principal/windowsprincipal.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/readonlypermissionset.cs b/mscorlib/system/security/readonlypermissionset.cs index 1b9e0ae98..8bb357870 100644 --- a/mscorlib/system/security/readonlypermissionset.cs +++ b/mscorlib/system/security/readonlypermissionset.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // using System; diff --git a/mscorlib/system/security/safesecurityhandles.cs b/mscorlib/system/security/safesecurityhandles.cs index 49adc58c2..460d61994 100644 --- a/mscorlib/system/security/safesecurityhandles.cs +++ b/mscorlib/system/security/safesecurityhandles.cs @@ -1,4 +1,4 @@ -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace Microsoft.Win32.SafeHandles { using System; using System.Runtime.CompilerServices; diff --git a/mscorlib/system/security/securestring.cs b/mscorlib/system/security/securestring.cs index 54d66afce..ca2e8aea6 100644 --- a/mscorlib/system/security/securestring.cs +++ b/mscorlib/system/security/securestring.cs @@ -1,4 +1,4 @@ -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Security { using System.Security.Cryptography; using System.Runtime.InteropServices; diff --git a/mscorlib/system/security/securitycontext.cs b/mscorlib/system/security/securitycontext.cs index 9ee3757ad..d19cdeded 100644 --- a/mscorlib/system/security/securitycontext.cs +++ b/mscorlib/system/security/securitycontext.cs @@ -6,7 +6,7 @@ ** ** Class: SecurityContext ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Capture security context for a thread @@ -32,7 +32,7 @@ namespace System.Security using System.Runtime.Versioning; using System.Diagnostics.Contracts; - // This enum must be kept in [....] with the SecurityContextSource enum in the VM + // This enum must be kept in sync with the SecurityContextSource enum in the VM public enum SecurityContextSource { CurrentAppDomain = 0, diff --git a/mscorlib/system/security/securitydocument.cs b/mscorlib/system/security/securitydocument.cs index 72378d15c..936a9e78b 100644 --- a/mscorlib/system/security/securitydocument.cs +++ b/mscorlib/system/security/securitydocument.cs @@ -7,7 +7,7 @@ // // CLASS: SecurityDocument.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // PURPOSE: Represent an XML document // diff --git a/mscorlib/system/security/securityelement.cs b/mscorlib/system/security/securityelement.cs index 8715f42ce..e238ae5d7 100644 --- a/mscorlib/system/security/securityelement.cs +++ b/mscorlib/system/security/securityelement.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security diff --git a/mscorlib/system/security/securityexception.cs b/mscorlib/system/security/securityexception.cs index 4b3a571a8..d5fe35785 100644 --- a/mscorlib/system/security/securityexception.cs +++ b/mscorlib/system/security/securityexception.cs @@ -7,7 +7,7 @@ ** ** Class: SecurityException ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** Purpose: Exception class for security diff --git a/mscorlib/system/security/securitymanager.cs b/mscorlib/system/security/securitymanager.cs index 1a60f9bc4..777eb6ebf 100644 --- a/mscorlib/system/security/securitymanager.cs +++ b/mscorlib/system/security/securitymanager.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/securityruntime.cs b/mscorlib/system/security/securityruntime.cs index 1c874c243..7989ee4db 100644 --- a/mscorlib/system/security/securityruntime.cs +++ b/mscorlib/system/security/securityruntime.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security { diff --git a/mscorlib/system/security/securitystate.cs b/mscorlib/system/security/securitystate.cs index 3097eb250..067073008 100644 --- a/mscorlib/system/security/securitystate.cs +++ b/mscorlib/system/security/securitystate.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Security; diff --git a/mscorlib/system/security/util/config.cs b/mscorlib/system/security/util/config.cs index 135979dce..3ddf27c3c 100644 --- a/mscorlib/system/security/util/config.cs +++ b/mscorlib/system/security/util/config.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/util/hex.cs b/mscorlib/system/security/util/hex.cs index 9a7d22d4d..c07269852 100644 --- a/mscorlib/system/security/util/hex.cs +++ b/mscorlib/system/security/util/hex.cs @@ -6,7 +6,7 @@ /* * Hex.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> * * Operations to convert to and from Hex * diff --git a/mscorlib/system/security/util/parser.cs b/mscorlib/system/security/util/parser.cs index 10b7aa702..ef53c555f 100644 --- a/mscorlib/system/security/util/parser.cs +++ b/mscorlib/system/security/util/parser.cs @@ -7,7 +7,7 @@ ** ** CLASS: Parser ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** PURPOSE: Parse "Elementary XML", that is, XML without diff --git a/mscorlib/system/security/util/sitestring.cs b/mscorlib/system/security/util/sitestring.cs index 7e705d7cb..f78b85ba7 100644 --- a/mscorlib/system/security/util/sitestring.cs +++ b/mscorlib/system/security/util/sitestring.cs @@ -5,7 +5,7 @@ // ==--== // SiteString // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Util { diff --git a/mscorlib/system/security/util/stringexpressionset.cs b/mscorlib/system/security/util/stringexpressionset.cs index 698f76f02..a67067437 100644 --- a/mscorlib/system/security/util/stringexpressionset.cs +++ b/mscorlib/system/security/util/stringexpressionset.cs @@ -5,7 +5,7 @@ // ==--== // StringExpressionSet // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Util { diff --git a/mscorlib/system/security/util/tokenbasedset.cs b/mscorlib/system/security/util/tokenbasedset.cs index 6f7fe1de2..cbbb43c63 100644 --- a/mscorlib/system/security/util/tokenbasedset.cs +++ b/mscorlib/system/security/util/tokenbasedset.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mscorlib/system/security/util/tokenbasedsetenumerator.cs b/mscorlib/system/security/util/tokenbasedsetenumerator.cs index 4c18c5bce..a9dd114dd 100644 --- a/mscorlib/system/security/util/tokenbasedsetenumerator.cs +++ b/mscorlib/system/security/util/tokenbasedsetenumerator.cs @@ -5,7 +5,7 @@ // ==--== // TokenBasedSetEnumerator.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Util diff --git a/mscorlib/system/security/util/tokenizer.cs b/mscorlib/system/security/util/tokenizer.cs index 3a9ab6694..f942b027c 100644 --- a/mscorlib/system/security/util/tokenizer.cs +++ b/mscorlib/system/security/util/tokenizer.cs @@ -7,7 +7,7 @@ ** ** CLASS: Tokenizer.cs ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** ** PURPOSE: Tokenize "Elementary XML", that is, XML without diff --git a/mscorlib/system/security/util/urlstring.cs b/mscorlib/system/security/util/urlstring.cs index c629fb4f6..9178585f1 100644 --- a/mscorlib/system/security/util/urlstring.cs +++ b/mscorlib/system/security/util/urlstring.cs @@ -5,7 +5,7 @@ // ==--== // URLString // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Implementation of membership condition for zones // diff --git a/mscorlib/system/security/util/xmlutil.cs b/mscorlib/system/security/util/xmlutil.cs index 936eaff9e..ad0a9cb25 100644 --- a/mscorlib/system/security/util/xmlutil.cs +++ b/mscorlib/system/security/util/xmlutil.cs @@ -7,7 +7,7 @@ ** ** CLASS: XMLUtil ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** ** PURPOSE: Helpers for XML input & output ** diff --git a/mscorlib/system/security/verificationexception.cs b/mscorlib/system/security/verificationexception.cs index 2e799519b..90fc2eb72 100644 --- a/mscorlib/system/security/verificationexception.cs +++ b/mscorlib/system/security/verificationexception.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security { diff --git a/mscorlib/system/security/xmlsyntaxexception.cs b/mscorlib/system/security/xmlsyntaxexception.cs index 0ec69646c..2c64008ef 100644 --- a/mscorlib/system/security/xmlsyntaxexception.cs +++ b/mscorlib/system/security/xmlsyntaxexception.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security { diff --git a/mscorlib/system/string.cs b/mscorlib/system/string.cs index 09096a677..5970d643b 100644 --- a/mscorlib/system/string.cs +++ b/mscorlib/system/string.cs @@ -61,7 +61,7 @@ public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable //private static readonly char FmtMsgMarkerChar='%'; //private static readonly char FmtMsgFmtCodeChar='!'; - //These are defined in Com99/src/vm/COMStringCommon.h and must be kept in [....]. + //These are defined in Com99/src/vm/COMStringCommon.h and must be kept in sync. private const int TrimHead = 0; private const int TrimTail = 1; private const int TrimBoth = 2; @@ -1381,6 +1381,16 @@ unsafe static internal String CreateStringFromEncoding( return s; } + [System.Security.SecuritySafeCritical] // auto-generated + unsafe internal int GetBytesFromEncoding(byte* pbNativeBuffer, int cbNativeBuffer,Encoding encoding) + { + // encoding == Encoding.UTF8 + fixed (char* pwzChar = &this.m_firstChar) + { + return encoding.GetBytes(pwzChar, m_stringLength, pbNativeBuffer, cbNativeBuffer); + } + } + [System.Security.SecuritySafeCritical] // auto-generated unsafe internal int ConvertToAnsi(byte *pbNativeBuffer, int cbNativeBuffer, bool fBestFit, bool fThrowOnUnmappableChar) { diff --git a/mscorlib/system/stubhelpers.cs b/mscorlib/system/stubhelpers.cs index 3f6f6fcfb..56a697564 100644 --- a/mscorlib/system/stubhelpers.cs +++ b/mscorlib/system/stubhelpers.cs @@ -126,6 +126,117 @@ static internal void ClearNative(IntPtr pNative) } } // class CSTRMarshaler + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + internal static class UTF8Marshaler + { + const int MAX_UTF8_CHAR_SIZE = 3; + [System.Security.SecurityCritical] + static internal unsafe IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer) + { + if (null == strManaged) + { + return IntPtr.Zero; + } + StubHelpers.CheckStringLength(strManaged.Length); + + int nb; + byte* pbNativeBuffer = (byte*)pNativeBuffer; + + // If we are marshaling into a stack buffer allocated by the ILStub + // we will use a "1-pass" mode where we convert the string directly into the unmanaged buffer. + // else we will allocate the precise native heap memory. + if (pbNativeBuffer != null) + { + // this is the number of bytes allocated by the ILStub. + nb = (strManaged.Length + 1) * MAX_UTF8_CHAR_SIZE; + + // nb is the actual number of bytes written by Encoding.GetBytes. + // use nb to de-limit the string since we are allocating more than + // required on stack + nb = strManaged.GetBytesFromEncoding(pbNativeBuffer, nb, Encoding.UTF8); + } + // required bytes > 260 , allocate required bytes on heap + else + { + nb = Encoding.UTF8.GetByteCount(strManaged); + // + 1 for the null character. + pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 1); + strManaged.GetBytesFromEncoding(pbNativeBuffer, nb, Encoding.UTF8); + } + pbNativeBuffer[nb] = 0x0; + return (IntPtr)pbNativeBuffer; + } + + [System.Security.SecurityCritical] + static internal unsafe string ConvertToManaged(IntPtr cstr) + { + if (IntPtr.Zero == cstr) + return null; + int nbBytes = StubHelpers.strlen((sbyte*)cstr); + return String.CreateStringFromEncoding((byte*)cstr, nbBytes, Encoding.UTF8); + } + + [System.Security.SecurityCritical] + static internal void ClearNative(IntPtr pNative) + { + if (pNative != IntPtr.Zero) + { + Win32Native.CoTaskMemFree(pNative); + } + } + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + internal static class UTF8BufferMarshaler + { + [System.Security.SecurityCritical] + static internal unsafe IntPtr ConvertToNative(StringBuilder sb, IntPtr pNativeBuffer, int flags) + { + if (null == sb) + { + return IntPtr.Zero; + } + + // Convert to string first + string strManaged = sb.ToString(); + + // Get byte count + int nb = Encoding.UTF8.GetByteCount(strManaged); + + // EmitConvertSpaceCLRToNative allocates memory + byte* pbNativeBuffer = (byte*)pNativeBuffer; + nb = strManaged.GetBytesFromEncoding(pbNativeBuffer, nb, Encoding.UTF8); + + pbNativeBuffer[nb] = 0x0; + return (IntPtr)pbNativeBuffer; + } + + [System.Security.SecurityCritical] + static internal unsafe void ConvertToManaged(StringBuilder sb, IntPtr pNative) + { + if (pNative == null) + return; + + int nbBytes = StubHelpers.strlen((sbyte*)pNative); + int numChar = Encoding.UTF8.GetCharCount((byte*)pNative, nbBytes); + + // +1 GetCharCount return 0 if the pNative points to a + // an empty buffer.We still need to allocate an empty + // buffer with a '\0' to distingiush it from null. + // Note that pinning on (char *pinned = new char[0]) + // return null and Encoding.UTF8.GetChars do not like + // null argument. + char[] cCharBuffer = new char[numChar + 1]; + cCharBuffer[numChar] = '\0'; + fixed (char* pBuffer = cCharBuffer) + { + numChar = Encoding.UTF8.GetChars((byte*)pNative, nbBytes, pBuffer, numChar); + // replace string builder internal buffer + sb.ReplaceBufferInternal(pBuffer, numChar); + } + } + } + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal static class BSTRMarshaler { @@ -147,7 +258,7 @@ static internal unsafe IntPtr ConvertToNative(string strManaged, IntPtr pNativeB if (hasTrailByte) { - // this is an odd-sized string with a trailing byte stored in its [....] block + // this is an odd-sized string with a trailing byte stored in its sync block lengthInBytes++; } @@ -231,7 +342,7 @@ static internal unsafe string ConvertToManaged(IntPtr bstr) if ((length & 1) == 1) { - // odd-sized strings need to have the trailing byte saved in their [....] block + // odd-sized strings need to have the trailing byte saved in their sync block ret.SetTrailByte(((byte *)bstr.ToPointer())[length - 1]); } diff --git a/mscorlib/system/text/asciiencoding.cs b/mscorlib/system/text/asciiencoding.cs index 471635e01..9c6e96720 100644 --- a/mscorlib/system/text/asciiencoding.cs +++ b/mscorlib/system/text/asciiencoding.cs @@ -44,7 +44,7 @@ internal override void SetDefaultFallbacks() // // The following methods are copied from EncodingNLS.cs. // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here. - // These should be kept in [....] for the following classes: + // These should be kept in sync for the following classes: // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding // diff --git a/mscorlib/system/text/encoding.cs b/mscorlib/system/text/encoding.cs index bd8805d81..ae16176c2 100644 --- a/mscorlib/system/text/encoding.cs +++ b/mscorlib/system/text/encoding.cs @@ -107,7 +107,7 @@ public abstract class Encoding : ICloneable // // The following values are from mlang.idl. These values - // should be in [....] with those in mlang.idl. + // should be in sync with those in mlang.idl. // private const int MIMECONTF_MAILNEWS = 0x00000001; private const int MIMECONTF_BROWSER = 0x00000002; diff --git a/mscorlib/system/text/iso2022encoding.cs b/mscorlib/system/text/iso2022encoding.cs index 6443a665f..39c6e68ba 100644 --- a/mscorlib/system/text/iso2022encoding.cs +++ b/mscorlib/system/text/iso2022encoding.cs @@ -11,7 +11,7 @@ // Abstract: // // Managed implimentation of ISO 2022 code pages, ported from the implimentation in c_is2022.dll -// This code should be kept in [....] with the other implimentations +// This code should be kept in sync with the other implimentations // This encoding wraps the basic encodings in code that adds the shift in/out wrapper methods // // Notes: diff --git a/mscorlib/system/text/unicodeencoding.cs b/mscorlib/system/text/unicodeencoding.cs index 80d5e2d34..3cd2b0f6b 100644 --- a/mscorlib/system/text/unicodeencoding.cs +++ b/mscorlib/system/text/unicodeencoding.cs @@ -81,7 +81,7 @@ internal override void SetDefaultFallbacks() // // The following methods are copied from EncodingNLS.cs. // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here. - // These should be kept in [....] for the following classes: + // These should be kept in sync for the following classes: // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding // diff --git a/mscorlib/system/text/utf32encoding.cs b/mscorlib/system/text/utf32encoding.cs index 6b6eaa06a..3a80fa65d 100644 --- a/mscorlib/system/text/utf32encoding.cs +++ b/mscorlib/system/text/utf32encoding.cs @@ -85,7 +85,7 @@ internal override void SetDefaultFallbacks() // // The following methods are copied from EncodingNLS.cs. // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here. - // These should be kept in [....] for the following classes: + // These should be kept in sync for the following classes: // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding // diff --git a/mscorlib/system/text/utf7encoding.cs b/mscorlib/system/text/utf7encoding.cs index 9da1fcb52..b8d6403c2 100644 --- a/mscorlib/system/text/utf7encoding.cs +++ b/mscorlib/system/text/utf7encoding.cs @@ -149,7 +149,7 @@ public override int GetHashCode() // // The following methods are copied from EncodingNLS.cs. // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here. - // These should be kept in [....] for the following classes: + // These should be kept in sync for the following classes: // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding // diff --git a/mscorlib/system/text/utf8encoding.cs b/mscorlib/system/text/utf8encoding.cs index b548523db..7994224b2 100644 --- a/mscorlib/system/text/utf8encoding.cs +++ b/mscorlib/system/text/utf8encoding.cs @@ -107,7 +107,7 @@ internal override void SetDefaultFallbacks() // // The following methods are copied from EncodingNLS.cs. // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here. - // These should be kept in [....] for the following classes: + // These should be kept in sync for the following classes: // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding // diff --git a/mscorlib/system/threading/CDSsyncETWBCLProvider.cs b/mscorlib/system/threading/CDSsyncETWBCLProvider.cs index c6ec27a13..6038171c5 100644 --- a/mscorlib/system/threading/CDSsyncETWBCLProvider.cs +++ b/mscorlib/system/threading/CDSsyncETWBCLProvider.cs @@ -7,12 +7,12 @@ // // CdsSyncEtwBCLProvider.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A helper class for firing ETW events related to the Coordination Data Structure -// [....] primitives. This provider is used by CDS [....] primitives in both mscorlib.dll +// sync primitives. This provider is used by CDS sync primitives in both mscorlib.dll // and system.dll. The purpose of sharing the provider class is to be able to enable -// ETW tracing on all CDS [....] types with a single ETW provider GUID, and to minimize +// ETW tracing on all CDS sync types with a single ETW provider GUID, and to minimize // the number of providers in use. // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -36,8 +36,8 @@ namespace System.Threading internal sealed class CdsSyncEtwBCLProvider : EventSource { /// <summary> - /// Defines the singleton instance for the CDS [....] ETW provider. - /// The CDS [....] Event provider GUID is {EC631D38-466B-4290-9306-834971BA0217}. + /// Defines the singleton instance for the CDS Sync ETW provider. + /// The CDS Sync Event provider GUID is {EC631D38-466B-4290-9306-834971BA0217}. /// </summary> public static CdsSyncEtwBCLProvider Log = new CdsSyncEtwBCLProvider(); /// <summary>Prevent external instantiation. All logging should go through the Log instance.</summary> diff --git a/mscorlib/system/threading/CancellationToken.cs b/mscorlib/system/threading/CancellationToken.cs index 565577f0b..5367d15d3 100644 --- a/mscorlib/system/threading/CancellationToken.cs +++ b/mscorlib/system/threading/CancellationToken.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> //////////////////////////////////////////////////////////////////////////////// #pragma warning disable 0420 // turn off 'a reference to a volatile field will not be treated as volatile' during CAS. @@ -334,8 +334,8 @@ private CancellationTokenRegistration Register(Action<Object> callback, Object s return new CancellationTokenRegistration(); // nothing to do for tokens than can never reach the canceled state. Give them a dummy registration. } - // Capture [....]/execution contexts if required. - // Note: Only capture [....]/execution contexts if IsCancellationRequested = false + // Capture sync/execution contexts if required. + // Note: Only capture sync/execution contexts if IsCancellationRequested = false // as we know that if it is true that the callback will just be called synchronously. SynchronizationContext capturedSyncContext = null; diff --git a/mscorlib/system/threading/CancellationTokenRegistration.cs b/mscorlib/system/threading/CancellationTokenRegistration.cs index a340d721c..11dbf0bd3 100644 --- a/mscorlib/system/threading/CancellationTokenRegistration.cs +++ b/mscorlib/system/threading/CancellationTokenRegistration.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> //////////////////////////////////////////////////////////////////////////////// using System.Diagnostics.Contracts; diff --git a/mscorlib/system/threading/CancellationTokenSource.cs b/mscorlib/system/threading/CancellationTokenSource.cs index b656f560a..c53db2050 100644 --- a/mscorlib/system/threading/CancellationTokenSource.cs +++ b/mscorlib/system/threading/CancellationTokenSource.cs @@ -5,7 +5,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> //////////////////////////////////////////////////////////////////////////////// using System; @@ -789,7 +789,7 @@ private void ExecuteCallbackHandlers(bool throwOnFirstException) m_executingCallback = currArrayFragment[i]; if (m_executingCallback != null) { - //Transition to the target [....] context (if necessary), and continue our work there. + //Transition to the target sync context (if necessary), and continue our work there. CancellationCallbackCoreWorkArguments args = new CancellationCallbackCoreWorkArguments(currArrayFragment, i); // marshal exceptions: either aggregate or perform an immediate rethrow @@ -855,7 +855,7 @@ private void CancellationCallbackCoreWork(CancellationCallbackCoreWorkArguments { if (callback.TargetExecutionContext != null) { - // we are running via a custom [....] context, so update the executing threadID + // we are running via a custom sync context, so update the executing threadID callback.CancellationTokenSource.ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId; } callback.ExecuteCallback(); @@ -951,7 +951,7 @@ internal void WaitForCallbackToComplete(CancellationCallbackInfo callbackInfo) // ---------------------------------------------------------- // -- CancellationCallbackCoreWorkArguments -- // ---------------------------------------------------------- - // Helper struct for passing data to the target [....] context + // Helper struct for passing data to the target sync context internal struct CancellationCallbackCoreWorkArguments { internal SparselyPopulatedArrayFragment<CancellationCallbackInfo> m_currArrayFragment; diff --git a/mscorlib/system/threading/CountdownEvent.cs b/mscorlib/system/threading/CountdownEvent.cs index 4e1addf98..1f1e95ee3 100644 --- a/mscorlib/system/threading/CountdownEvent.cs +++ b/mscorlib/system/threading/CountdownEvent.cs @@ -7,7 +7,7 @@ // // CountdownEvent.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A simple coordination data structure that we use for fork/join style parallelism. // @@ -115,7 +115,7 @@ public bool IsSet // The latch is "completed" if its current count has reached 0. Note that this is NOT // the same thing is checking the event's IsCompleted property. There is a tiny window // of time, after the final decrement of the current count to 0 and before setting the - // event, where the two values are out of [....]. + // event, where the two values are out of sync. return (m_currentCount <= 0); } } diff --git a/mscorlib/system/threading/LazyInitializer.cs b/mscorlib/system/threading/LazyInitializer.cs index 7be5f6a1a..f34e183d0 100644 --- a/mscorlib/system/threading/LazyInitializer.cs +++ b/mscorlib/system/threading/LazyInitializer.cs @@ -7,7 +7,7 @@ // // LazyInitializer.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // a set of lightweight static helpers for lazy initialization. // diff --git a/mscorlib/system/threading/ManualResetEventSlim.cs b/mscorlib/system/threading/ManualResetEventSlim.cs index 7d9e15d10..2d1278ab9 100644 --- a/mscorlib/system/threading/ManualResetEventSlim.cs +++ b/mscorlib/system/threading/ManualResetEventSlim.cs @@ -8,7 +8,7 @@ // // SlimManualResetEvent.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // An manual-reset event that mixes a little spinning with a true Win32 event. // @@ -281,7 +281,7 @@ private bool LazyInitializeEvent() // guarantee only one event is actually stored in this field. if (Interlocked.CompareExchange(ref m_eventObj, newEventObj, null) != null) { - // We ----d with someone else and lost. Destroy the garbage event. + // We raced with someone else and lost. Destroy the garbage event. newEventObj.Close(); return false; diff --git a/mscorlib/system/threading/SemaphoreSlim.cs b/mscorlib/system/threading/SemaphoreSlim.cs index f97d1ccc8..ddda17187 100644 --- a/mscorlib/system/threading/SemaphoreSlim.cs +++ b/mscorlib/system/threading/SemaphoreSlim.cs @@ -7,7 +7,7 @@ // // SemaphoreSlim.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A lightweight semahore class that contains the basic semaphore functions plus some useful functions like interrupt // and wait handle exposing to allow waiting on multiple semaphores. diff --git a/mscorlib/system/threading/SpinLock.cs b/mscorlib/system/threading/SpinLock.cs index 6dd635a31..78e7968eb 100644 --- a/mscorlib/system/threading/SpinLock.cs +++ b/mscorlib/system/threading/SpinLock.cs @@ -11,7 +11,7 @@ // repeatedly checking until the lock becomes available. As the thread remains active performing a non-useful task, // the use of such a lock is a kind of busy waiting and consumes CPU resources without performing real work. // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System; diff --git a/mscorlib/system/threading/SpinWait.cs b/mscorlib/system/threading/SpinWait.cs index 3fb4a1fdc..596f9885a 100644 --- a/mscorlib/system/threading/SpinWait.cs +++ b/mscorlib/system/threading/SpinWait.cs @@ -7,7 +7,7 @@ // // SpinWait.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Central spin logic used across the entire code-base. // diff --git a/mscorlib/system/threading/Tasks/BeginEndAwaitableAdapter.cs b/mscorlib/system/threading/Tasks/BeginEndAwaitableAdapter.cs index 68b89d53a..73d21b566 100644 --- a/mscorlib/system/threading/Tasks/BeginEndAwaitableAdapter.cs +++ b/mscorlib/system/threading/Tasks/BeginEndAwaitableAdapter.cs @@ -3,7 +3,7 @@ /// Copyright (c) Microsoft Corporation. All rights reserved. /// </copyright> /// -/// <owner>[....]</owner> +/// <owner>Microsoft</owner> /// <owner>gpaperin</owner> ///----------- ----------- ----------- ----------- ----------- ----------- diff --git a/mscorlib/system/threading/Tasks/ConcurrentExclusiveSchedulerPair.cs b/mscorlib/system/threading/Tasks/ConcurrentExclusiveSchedulerPair.cs index 50e9a8122..ec8b1be4c 100644 --- a/mscorlib/system/threading/Tasks/ConcurrentExclusiveSchedulerPair.cs +++ b/mscorlib/system/threading/Tasks/ConcurrentExclusiveSchedulerPair.cs @@ -7,7 +7,7 @@ // // ConcurrentExclusiveSchedulerPair.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A pair of schedulers that together support concurrent (reader) / exclusive (writer) // task scheduling. Using just the exclusive scheduler can be used to simulate a serial @@ -70,7 +70,7 @@ public class ConcurrentExclusiveSchedulerPair /// <summary>Default MaxConcurrencyLevel is the processor count if not otherwise specified.</summary> private static Int32 DefaultMaxConcurrencyLevel { get { return Environment.ProcessorCount; } } - /// <summary>Gets the [....] obj used to protect all state on this instance.</summary> + /// <summary>Gets the sync obj used to protect all state on this instance.</summary> private object ValueLock { get { return m_threadProcessingMapping; } } /// <summary> @@ -763,7 +763,7 @@ internal static void ContractAssertMonitorStatus(object syncObj, bool held) /// <param name="isReplacementReplica">If this task is being created to replace another.</param> /// <remarks> /// These options should be used for all tasks that have the potential to run user code or - /// that are repeatedly spawned and thus need a modi---- of fair treatment. + /// that are repeatedly spawned and thus need a modicum of fair treatment. /// </remarks> /// <returns>The options to use.</returns> internal static TaskCreationOptions GetCreationOptionsForTask(bool isReplacementReplica = false) diff --git a/mscorlib/system/threading/Tasks/Future.cs b/mscorlib/system/threading/Tasks/Future.cs index f8011808b..b04813409 100644 --- a/mscorlib/system/threading/Tasks/Future.cs +++ b/mscorlib/system/threading/Tasks/Future.cs @@ -7,7 +7,7 @@ // // Future.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A task that produces a value. // diff --git a/mscorlib/system/threading/Tasks/FutureFactory.cs b/mscorlib/system/threading/Tasks/FutureFactory.cs index cd3bc163a..44f6ac04d 100644 --- a/mscorlib/system/threading/Tasks/FutureFactory.cs +++ b/mscorlib/system/threading/Tasks/FutureFactory.cs @@ -7,7 +7,7 @@ // // FutureFactory.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // As with TaskFactory, TaskFactory<TResult> encodes common factory patterns into helper methods. // diff --git a/mscorlib/system/threading/Tasks/Parallel.cs b/mscorlib/system/threading/Tasks/Parallel.cs index 55aa15974..515967981 100644 --- a/mscorlib/system/threading/Tasks/Parallel.cs +++ b/mscorlib/system/threading/Tasks/Parallel.cs @@ -7,7 +7,7 @@ // // Parallel.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A helper class that contains parallel versions of various looping constructs. This // internally uses the task parallel library, but takes care to expose very little diff --git a/mscorlib/system/threading/Tasks/ParallelLoopState.cs b/mscorlib/system/threading/Tasks/ParallelLoopState.cs index 2ae0c8790..4fd15a87a 100644 --- a/mscorlib/system/threading/Tasks/ParallelLoopState.cs +++ b/mscorlib/system/threading/Tasks/ParallelLoopState.cs @@ -7,7 +7,7 @@ // // ParallelState.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A non-generic and generic parallel state class, used by the Parallel helper class // for parallel loop management. diff --git a/mscorlib/system/threading/Tasks/ParallelRangeManager.cs b/mscorlib/system/threading/Tasks/ParallelRangeManager.cs index 89d3b65b4..7c625cf22 100644 --- a/mscorlib/system/threading/Tasks/ParallelRangeManager.cs +++ b/mscorlib/system/threading/Tasks/ParallelRangeManager.cs @@ -7,7 +7,7 @@ // // ParallelRangeManager.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Implements the algorithm for distributing loop indices to parallel loop workers // diff --git a/mscorlib/system/threading/Tasks/ProducerConsumerQueues.cs b/mscorlib/system/threading/Tasks/ProducerConsumerQueues.cs index 50febfcbc..b0b8db284 100644 --- a/mscorlib/system/threading/Tasks/ProducerConsumerQueues.cs +++ b/mscorlib/system/threading/Tasks/ProducerConsumerQueues.cs @@ -7,7 +7,7 @@ // // ProducerConsumerQueues.cs // -// <OWNER>[....], [....]</OWNER> +// <OWNER>Microsoft, Microsoft</OWNER> // // Specialized producer/consumer queues. // @@ -58,7 +58,7 @@ internal interface IProducerConsumerQueue<T> : IEnumerable<T> int Count { get; } /// <summary>A thread-safe way to get the number of items in the collection. May synchronize access by locking the provided synchronization object.</summary> - /// <param name="syncObj">The [....] object used to lock</param> + /// <param name="syncObj">The sync object used to lock</param> /// <returns>The collection count</returns> int GetCountSafe(object syncObj); } diff --git a/mscorlib/system/threading/Tasks/TPLETWProvider.cs b/mscorlib/system/threading/Tasks/TPLETWProvider.cs index aed9c00a5..005e7d385 100644 --- a/mscorlib/system/threading/Tasks/TPLETWProvider.cs +++ b/mscorlib/system/threading/Tasks/TPLETWProvider.cs @@ -7,7 +7,7 @@ // // TplEtwProvider.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // EventSource for TPL. // diff --git a/mscorlib/system/threading/Tasks/Task.cs b/mscorlib/system/threading/Tasks/Task.cs index 948fa8af9..f64243ce0 100644 --- a/mscorlib/system/threading/Tasks/Task.cs +++ b/mscorlib/system/threading/Tasks/Task.cs @@ -7,7 +7,7 @@ // // Task.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A schedulable unit of work. // diff --git a/mscorlib/system/threading/Tasks/TaskCanceledException.cs b/mscorlib/system/threading/Tasks/TaskCanceledException.cs index fe647cdb3..256bd0294 100644 --- a/mscorlib/system/threading/Tasks/TaskCanceledException.cs +++ b/mscorlib/system/threading/Tasks/TaskCanceledException.cs @@ -7,7 +7,7 @@ // // TaskCanceledException.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // An exception for task cancellations. // diff --git a/mscorlib/system/threading/Tasks/TaskCompletionSource.cs b/mscorlib/system/threading/Tasks/TaskCompletionSource.cs index 8c5edf097..7d1487a7c 100644 --- a/mscorlib/system/threading/Tasks/TaskCompletionSource.cs +++ b/mscorlib/system/threading/Tasks/TaskCompletionSource.cs @@ -7,7 +7,7 @@ // // TaskCompletionSource.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // TaskCompletionSource<TResult> is the producer end of an unbound future. Its // Task member may be distributed as the consumer end of the future. diff --git a/mscorlib/system/threading/Tasks/TaskContinuation.cs b/mscorlib/system/threading/Tasks/TaskContinuation.cs index eb106a785..eecbd9e12 100644 --- a/mscorlib/system/threading/Tasks/TaskContinuation.cs +++ b/mscorlib/system/threading/Tasks/TaskContinuation.cs @@ -7,7 +7,7 @@ // // TaskContinuation.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Implementation of task continuations, TaskContinuation, and its descendants. // @@ -223,7 +223,7 @@ internal override void InnerInvoke() // - StandardTaskContinuation: wraps a task,options,and scheduler, and overrides Run to process the task with that configuration // - AwaitTaskContinuation: base for continuations created through TaskAwaiter; targets default scheduler by default // - TaskSchedulerAwaitTaskContinuation: awaiting with a non-default TaskScheduler - // - SynchronizationContextAwaitTaskContinuation: awaiting with a "current" [....] ctx + // - SynchronizationContextAwaitTaskContinuation: awaiting with a "current" sync ctx /// <summary>Represents a continuation.</summary> internal abstract class TaskContinuation diff --git a/mscorlib/system/threading/Tasks/TaskExceptionHolder.cs b/mscorlib/system/threading/Tasks/TaskExceptionHolder.cs index 32d121d16..3ba61491b 100644 --- a/mscorlib/system/threading/Tasks/TaskExceptionHolder.cs +++ b/mscorlib/system/threading/Tasks/TaskExceptionHolder.cs @@ -7,7 +7,7 @@ // // TaskExceptionHolder.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // An abstraction for holding and aggregating exceptions. // diff --git a/mscorlib/system/threading/Tasks/TaskFactory.cs b/mscorlib/system/threading/Tasks/TaskFactory.cs index 3c8e798e0..b15df277a 100644 --- a/mscorlib/system/threading/Tasks/TaskFactory.cs +++ b/mscorlib/system/threading/Tasks/TaskFactory.cs @@ -7,7 +7,7 @@ // // TaskFactory.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // There are a plethora of common patterns for which Tasks are created. TaskFactory encodes // these patterns into helper methods. These helpers also pick up default configuration settings diff --git a/mscorlib/system/threading/Tasks/TaskScheduler.cs b/mscorlib/system/threading/Tasks/TaskScheduler.cs index 3b27ed26d..644c8809b 100644 --- a/mscorlib/system/threading/Tasks/TaskScheduler.cs +++ b/mscorlib/system/threading/Tasks/TaskScheduler.cs @@ -7,7 +7,7 @@ // // TaskScheduler.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // This file contains the primary interface and management of tasks and queues. // @@ -281,8 +281,8 @@ internal void InternalQueueTask(Task task) // Member variables // - // The global container that keeps track of TaskScheduler instances. s_activeTaskSchedulers must be initialized before s_defaultTaskScheduler. - private static readonly ConditionalWeakTable<TaskScheduler, object> s_activeTaskSchedulers = new ConditionalWeakTable<TaskScheduler,object>(); + // The global container that keeps track of TaskScheduler instances for debugging purposes. + private static ConditionalWeakTable<TaskScheduler, object> s_activeTaskSchedulers; // An AppDomain-wide default manager. private static readonly TaskScheduler s_defaultTaskScheduler = new ThreadPoolTaskScheduler(); @@ -299,16 +299,32 @@ internal void InternalQueueTask(Task task) // // Constructors and public properties // - + /// <summary> /// Initializes the <see cref="System.Threading.Tasks.TaskScheduler"/>. /// </summary> protected TaskScheduler() { - // Protected constructor. It's here to ensure all user implemented TaskSchedulers will be - // registered in the active schedulers list. - Contract.Assert(s_activeTaskSchedulers != null, "Expected non-null s_activeTaskSchedulers"); - s_activeTaskSchedulers.Add(this, null); + // Register the scheduler in the active scheduler list. This is only relevant when debugging, + // so we only pay the cost if the debugger is attached when the scheduler is created. This + // means that the internal TaskScheduler.GetTaskSchedulersForDebugger() will only include + // schedulers created while the debugger is attached. + if (Debugger.IsAttached) + { + AddToActiveTaskSchedulers(); + } + } + + /// <summary>Adds this scheduler ot the active schedulers tracking collection for debugging purposes.</summary> + private void AddToActiveTaskSchedulers() + { + ConditionalWeakTable<TaskScheduler, object> activeTaskSchedulers = s_activeTaskSchedulers; + if (activeTaskSchedulers == null) + { + Interlocked.CompareExchange(ref s_activeTaskSchedulers, new ConditionalWeakTable<TaskScheduler, object>(), null); + activeTaskSchedulers = s_activeTaskSchedulers; + } + activeTaskSchedulers.Add(this, null); } /// <summary> @@ -558,9 +574,20 @@ internal Task[] GetScheduledTasksForDebugger() [SecurityCritical] internal static TaskScheduler[] GetTaskSchedulersForDebugger() { - Contract.Assert(s_activeTaskSchedulers != null, "Expected non-null s_activeTaskSchedulers"); + if (s_activeTaskSchedulers == null) + { + // No schedulers were tracked. Just give back the default. + return new TaskScheduler[] { s_defaultTaskScheduler }; + } ICollection<TaskScheduler> schedulers = s_activeTaskSchedulers.Keys; + if (!schedulers.Contains(s_defaultTaskScheduler)) + { + // Make sure the default is included, in case the debugger attached + // after it was created. + schedulers.Add(s_defaultTaskScheduler); + } + var arr = new TaskScheduler[schedulers.Count]; schedulers.CopyTo(arr, 0); foreach (var scheduler in arr) @@ -582,13 +609,13 @@ public SystemThreadingTasks_TaskSchedulerDebugView(TaskScheduler scheduler) m_taskScheduler = scheduler; } - // returns the scheduler’s Id + // returns the scheduler’s Id public Int32 Id { get { return m_taskScheduler.Id; } } - // returns the scheduler’s GetScheduledTasks + // returns the scheduler’s GetScheduledTasks public IEnumerable<Task> ScheduledTasks { [SecurityCritical] diff --git a/mscorlib/system/threading/Tasks/TaskSchedulerException.cs b/mscorlib/system/threading/Tasks/TaskSchedulerException.cs index 61b75ea7f..5d2f9ad79 100644 --- a/mscorlib/system/threading/Tasks/TaskSchedulerException.cs +++ b/mscorlib/system/threading/Tasks/TaskSchedulerException.cs @@ -7,7 +7,7 @@ // // TaskSchedulerException.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // An exception for task schedulers. // diff --git a/mscorlib/system/threading/Tasks/TaskToApm.cs b/mscorlib/system/threading/Tasks/TaskToApm.cs index 952d539a7..e518055ee 100644 --- a/mscorlib/system/threading/Tasks/TaskToApm.cs +++ b/mscorlib/system/threading/Tasks/TaskToApm.cs @@ -7,7 +7,7 @@ // // TaskToApm.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Helper methods for using Tasks to implement the APM pattern. // diff --git a/mscorlib/system/threading/Tasks/ThreadPoolTaskScheduler.cs b/mscorlib/system/threading/Tasks/ThreadPoolTaskScheduler.cs index 0da781819..bf5b063df 100644 --- a/mscorlib/system/threading/Tasks/ThreadPoolTaskScheduler.cs +++ b/mscorlib/system/threading/Tasks/ThreadPoolTaskScheduler.cs @@ -1,4 +1,4 @@ -// ==++== +// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // @@ -7,7 +7,7 @@ // // TaskScheduler.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // This file contains the primary interface and management of tasks and queues. // @@ -34,6 +34,7 @@ internal sealed class ThreadPoolTaskScheduler: TaskScheduler /// </summary> internal ThreadPoolTaskScheduler() { + int id = base.Id; // force ID creation of the default scheduler } // static delegate for threads allocated to handle LongRunning tasks. diff --git a/mscorlib/system/threading/ThreadLocal.cs b/mscorlib/system/threading/ThreadLocal.cs index 544b0cdb6..aa8425fd9 100644 --- a/mscorlib/system/threading/ThreadLocal.cs +++ b/mscorlib/system/threading/ThreadLocal.cs @@ -8,7 +8,7 @@ // // ThreadLocal.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // A class that provides a simple, lightweight implementation of thread-local lazy-initialization, where a value is initialized once per accessing // thread; this provides an alternative to using a ThreadStatic static variable and having diff --git a/mscorlib/system/threading/abandonedmutexexception.cs b/mscorlib/system/threading/abandonedmutexexception.cs index d32f45303..593f215f1 100644 --- a/mscorlib/system/threading/abandonedmutexexception.cs +++ b/mscorlib/system/threading/abandonedmutexexception.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // AbandonedMutexException // Thrown when a wait completes because one or more mutexes was abandoned. diff --git a/mscorlib/system/threading/asynclocal.cs b/mscorlib/system/threading/asynclocal.cs index 600a4b0ee..3e1f5f9f6 100644 --- a/mscorlib/system/threading/asynclocal.cs +++ b/mscorlib/system/threading/asynclocal.cs @@ -2,7 +2,7 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Collections.Generic; diff --git a/mscorlib/system/threading/autoresetevent.cs b/mscorlib/system/threading/autoresetevent.cs index e7506554e..1ed58d271 100644 --- a/mscorlib/system/threading/autoresetevent.cs +++ b/mscorlib/system/threading/autoresetevent.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: AutoResetEvent diff --git a/mscorlib/system/threading/compressedstack.cs b/mscorlib/system/threading/compressedstack.cs index d6c584d82..5c18afbbb 100644 --- a/mscorlib/system/threading/compressedstack.cs +++ b/mscorlib/system/threading/compressedstack.cs @@ -7,8 +7,8 @@ ** ** Class: CompressedStack ** -** <OWNER>[....]</OWNER> -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> +** <OWNER>Microsoft</OWNER> ** ** Purpose: Managed wrapper for the security stack compression implementation ** diff --git a/mscorlib/system/threading/eventwaithandle.cs b/mscorlib/system/threading/eventwaithandle.cs index 08426b232..65151cff7 100644 --- a/mscorlib/system/threading/eventwaithandle.cs +++ b/mscorlib/system/threading/eventwaithandle.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: EventWaitHandle diff --git a/mscorlib/system/threading/executioncontext.cs b/mscorlib/system/threading/executioncontext.cs index b5564b99e..0f93e1626 100644 --- a/mscorlib/system/threading/executioncontext.cs +++ b/mscorlib/system/threading/executioncontext.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================ ** ** Class: ExecutionContext @@ -447,7 +447,7 @@ public void Undo() public override int GetHashCode() { - // review - [....] + // review - Microsoft return _thread == null ? ToString().GetHashCode() : _thread.GetHashCode(); } @@ -1234,7 +1234,7 @@ static internal ExecutionContext Capture(ref StackCrawlMark stackMark, CaptureOp if (!ecCurrent.IsNull) { - // capture the [....] context + // capture the sync context if (0 == (options & CaptureOptions.IgnoreSyncCtx)) syncCtxNew = (ecCurrent.SynchronizationContext == null) ? null : ecCurrent.SynchronizationContext.CreateCopy(); diff --git a/mscorlib/system/threading/hostexecutioncontextmanager.cs b/mscorlib/system/threading/hostexecutioncontextmanager.cs index 981b2889b..2f5ccc667 100644 --- a/mscorlib/system/threading/hostexecutioncontextmanager.cs +++ b/mscorlib/system/threading/hostexecutioncontextmanager.cs @@ -4,7 +4,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================ ** ** Class: ExecutionContext diff --git a/mscorlib/system/threading/interlocked.cs b/mscorlib/system/threading/interlocked.cs index fad5b4625..441460b70 100644 --- a/mscorlib/system/threading/interlocked.cs +++ b/mscorlib/system/threading/interlocked.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Threading { using System; diff --git a/mscorlib/system/threading/lockcookie.cs b/mscorlib/system/threading/lockcookie.cs index 86f818222..32c976097 100644 --- a/mscorlib/system/threading/lockcookie.cs +++ b/mscorlib/system/threading/lockcookie.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================ ** ** Class: LockCookie @@ -29,7 +29,7 @@ public struct LockCookie public override int GetHashCode() { - // review - [....]! + // review - Microsoft! return _dwFlags + _dwWriterSeqNum + _wReaderAndWriterLevel + _dwThreadID; } diff --git a/mscorlib/system/threading/lockrecursionexception.cs b/mscorlib/system/threading/lockrecursionexception.cs index 5598d810b..a8391a001 100644 --- a/mscorlib/system/threading/lockrecursionexception.cs +++ b/mscorlib/system/threading/lockrecursionexception.cs @@ -13,8 +13,8 @@ // acquire a lock, because the particular lock kind doesn't // support it in its current state. // -// <OWNER>[....]</OWNER> -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> +// <OWNER>Microsoft</OWNER> // ============================================================*/ diff --git a/mscorlib/system/threading/manualresetevent.cs b/mscorlib/system/threading/manualresetevent.cs index 40db6655c..1586fb44a 100644 --- a/mscorlib/system/threading/manualresetevent.cs +++ b/mscorlib/system/threading/manualresetevent.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: ManualResetEvent diff --git a/mscorlib/system/threading/monitor.cs b/mscorlib/system/threading/monitor.cs index 923223080..9ceade566 100644 --- a/mscorlib/system/threading/monitor.cs +++ b/mscorlib/system/threading/monitor.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: Monitor diff --git a/mscorlib/system/threading/mutex.cs b/mscorlib/system/threading/mutex.cs index bfd5458ca..9e403c08a 100644 --- a/mscorlib/system/threading/mutex.cs +++ b/mscorlib/system/threading/mutex.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: Mutex diff --git a/mscorlib/system/threading/overlapped.cs b/mscorlib/system/threading/overlapped.cs index eb22b0a8c..2a19f42f0 100644 --- a/mscorlib/system/threading/overlapped.cs +++ b/mscorlib/system/threading/overlapped.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /* * This files defines the following types: diff --git a/mscorlib/system/threading/readerwriterlock.cs b/mscorlib/system/threading/readerwriterlock.cs index cc5a736be..50f61b25f 100644 --- a/mscorlib/system/threading/readerwriterlock.cs +++ b/mscorlib/system/threading/readerwriterlock.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================ ** ** Class: RWLock diff --git a/mscorlib/system/threading/semaphorefullexception.cs b/mscorlib/system/threading/semaphorefullexception.cs index 19b0632ca..5a61c8f79 100644 --- a/mscorlib/system/threading/semaphorefullexception.cs +++ b/mscorlib/system/threading/semaphorefullexception.cs @@ -7,7 +7,7 @@ ** ** Class: SemaphoreFullException ** -** <OWNER>[....]</OWNER> +** <OWNER>Microsoft</OWNER> ** =============================================================================*/ namespace System.Threading { diff --git a/mscorlib/system/threading/synchronizationcontext.cs b/mscorlib/system/threading/synchronizationcontext.cs index 47036f1b1..9afc55b5b 100644 --- a/mscorlib/system/threading/synchronizationcontext.cs +++ b/mscorlib/system/threading/synchronizationcontext.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================ ** ** Class: SynchronizationContext @@ -79,7 +79,7 @@ public SynchronizationContext() static Type s_cachedPreparedType4; static Type s_cachedPreparedType5; - // protected so that only the derived [....] context class can enable these flags + // protected so that only the derived sync context class can enable these flags [System.Security.SecuritySafeCritical] // auto-generated [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "We never dereference s_cachedPreparedType*, so ordering is unimportant")] protected void SetWaitNotificationRequired() @@ -93,7 +93,7 @@ protected void SetWaitNotificationRequired() // So we keep track of a few types we've already prepared in this AD. It is uncommon to have more than // a few SynchronizationContext implementations, so we only cache the first five we encounter; this lets // our cache be much faster than a more general cache might be. This is important, because this - // is a *very* hot code path for many WPF and [....] apps. + // is a *very* hot code path for many WPF and Microsoft apps. // Type type = this.GetType(); if (s_cachedPreparedType1 != type && diff --git a/mscorlib/system/threading/synchronizationlockexception.cs b/mscorlib/system/threading/synchronizationlockexception.cs index 884005d21..91d4ac363 100644 --- a/mscorlib/system/threading/synchronizationlockexception.cs +++ b/mscorlib/system/threading/synchronizationlockexception.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: SynchronizationLockException diff --git a/mscorlib/system/threading/thread.cs b/mscorlib/system/threading/thread.cs index b98798c48..487f81d00 100644 --- a/mscorlib/system/threading/thread.cs +++ b/mscorlib/system/threading/thread.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: Thread diff --git a/mscorlib/system/threading/threadabortexception.cs b/mscorlib/system/threading/threadabortexception.cs index c3adf9ac2..657f41103 100644 --- a/mscorlib/system/threading/threadabortexception.cs +++ b/mscorlib/system/threading/threadabortexception.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: ThreadAbortException diff --git a/mscorlib/system/threading/threadinterruptedexception.cs b/mscorlib/system/threading/threadinterruptedexception.cs index 28e1eed10..af9a03dc3 100644 --- a/mscorlib/system/threading/threadinterruptedexception.cs +++ b/mscorlib/system/threading/threadinterruptedexception.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: ThreadInterruptedException diff --git a/mscorlib/system/threading/threadpool.cs b/mscorlib/system/threading/threadpool.cs index b58432102..d3e28d1e6 100644 --- a/mscorlib/system/threading/threadpool.cs +++ b/mscorlib/system/threading/threadpool.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: ThreadPool @@ -101,7 +101,7 @@ internal int Add(T e) } else if (i == array.Length - 1) { - // Must resize. If we ----d and lost, we start over again. + // Must resize. If we raced and lost, we start over again. if (array != m_array) continue; diff --git a/mscorlib/system/threading/threadstartexception.cs b/mscorlib/system/threading/threadstartexception.cs index a04134946..99163d89b 100644 --- a/mscorlib/system/threading/threadstartexception.cs +++ b/mscorlib/system/threading/threadstartexception.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Threading { diff --git a/mscorlib/system/threading/threadstateexception.cs b/mscorlib/system/threading/threadstateexception.cs index 3fa634c23..fecd34441 100644 --- a/mscorlib/system/threading/threadstateexception.cs +++ b/mscorlib/system/threading/threadstateexception.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: ThreadStateException diff --git a/mscorlib/system/threading/timeout.cs b/mscorlib/system/threading/timeout.cs index bf070e1d3..9b7d3562a 100644 --- a/mscorlib/system/threading/timeout.cs +++ b/mscorlib/system/threading/timeout.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Threading { using System.Threading; diff --git a/mscorlib/system/threading/timer.cs b/mscorlib/system/threading/timer.cs index 5e7368331..02e1d5ba1 100644 --- a/mscorlib/system/threading/timer.cs +++ b/mscorlib/system/threading/timer.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Threading { @@ -71,7 +71,7 @@ private TimerQueue() // We need to keep our notion of time synchronized with the calls to SleepEx that drive // the underlying native timer. In Win8, SleepEx does not count the time the machine spends // sleeping/hibernating. Environment.TickCount (GetTickCount) *does* count that time, - // so we will get out of [....] with SleepEx if we use that method. + // so we will get out of sync with SleepEx if we use that method. // // So, on Win8, we use QueryUnbiasedInterruptTime instead; this does not count time spent // in sleep/hibernate mode. diff --git a/mscorlib/system/threading/volatile.cs b/mscorlib/system/threading/volatile.cs index abf6cb7cc..5682b2973 100644 --- a/mscorlib/system/threading/volatile.cs +++ b/mscorlib/system/threading/volatile.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/mscorlib/system/threading/waithandle.cs b/mscorlib/system/threading/waithandle.cs index 026d7c6a3..e85d72f3c 100644 --- a/mscorlib/system/threading/waithandle.cs +++ b/mscorlib/system/threading/waithandle.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> /*============================================================================= ** ** Class: WaitHandle (this name is NOT definitive) @@ -106,7 +106,7 @@ public virtual IntPtr Handle // ideally do these things: // *) Expose a settable SafeHandle property on WaitHandle. // *) Expose a settable OwnsHandle property on SafeHandle. - // We're looking into this. -- [....] + // We're looking into this. -- Microsoft if (safeWaitHandle != null) { safeWaitHandle.SetHandleAsInvalid(); diff --git a/mscorlib/system/threading/waithandlecannotbeopenedexception.cs b/mscorlib/system/threading/waithandlecannotbeopenedexception.cs index b7b80e060..06c941d6e 100644 --- a/mscorlib/system/threading/waithandlecannotbeopenedexception.cs +++ b/mscorlib/system/threading/waithandlecannotbeopenedexception.cs @@ -4,7 +4,7 @@ // // ==--== // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> namespace System.Threading { using System; diff --git a/mscorlib/system/type.cs b/mscorlib/system/type.cs index 0f605083d..4eada4a29 100644 --- a/mscorlib/system/type.cs +++ b/mscorlib/system/type.cs @@ -6,7 +6,7 @@ // // File: Type.cs // -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // Implements System.Type //