| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sc.hxx" |
| |
| // ============================================================================ |
| #include "xltracer.hxx" |
| #include <filter/msfilter/msfiltertracer.hxx> |
| #include "address.hxx" |
| |
| using ::rtl::OUString; |
| using ::com::sun::star::uno::Sequence; |
| using ::com::sun::star::beans::PropertyValue; |
| |
| // ============================================================================ |
| |
| // Trace Table details are grouped by functionality using the context entry. |
| // Each separate context starts at the next 1000 interval. New entries should |
| // be added to their appropriate context. New contexts should be added onto |
| // the end. Any gaps in the 1000 sequence or within the 1000 are the result |
| // of trace events no longer present. |
| static const XclTracerDetails pTracerDetails[] = |
| { |
| { eUnKnown, 0, "UNKNOWN", "UNKNOWN", "Unknown trace property." }, |
| { eRowLimitExceeded, 1000, "Limits", "Sheet", "Row limit exceeded." }, |
| { eTabLimitExceeded, 1001, "Limits", "Sheet", "Sheet limit exceeded." }, |
| { ePassword, 2000, "Protection", "Password", "Document is password protected." }, |
| { ePrintRange, 3000, "Print", "Print Range", "Print Range present." }, |
| { eShortDate, 4000, "CellFormatting", "Short Dates", "Possible Date format issue." }, |
| { eBorderLineStyle, 4004, "CellFormatting", "Border", "Line style not supported.", }, |
| { eFillPattern, 4005, "CellFormatting", "Pattern", "Fill Pattern not supported.", }, |
| { eInvisibleGrid, 5000, "Properties", "Grid Invisible", "Grid invisible on first sheet." }, |
| { eFormattedNote, 6000, "Notes", "Formatting", "Text may be formatted." }, |
| { eFormulaExtName, 7000, "Formula", "External Name", "External names not supported." }, |
| { eFormulaMissingArg, 7001, "Formula", "Missing Argument","Parameter missing." }, |
| { ePivotDataSource, 8000, "Chart", "Pivot", "External data source not supported."}, |
| { ePivotChartExists, 8001, "Chart", "Pivot", "Pivot Chart not supported."}, |
| { eChartUnKnownType, 8002, "Chart", "Type", "Chart Type not supported."}, |
| { eChartTrendLines, 8003, "Chart", "Type", "Chart trendlines not supported."}, |
| { eChartOnlySheet, 8004, "Chart", "Type", "Chart only sheet not supported."}, |
| { eChartRange, 8005, "Chart", "Source Data", "Chart source ranges too complex."}, |
| { eChartDSName, 8006, "Chart", "Source Data", "Series titles not linked to cells."}, |
| { eChartDataTable, 8007, "Chart", "Legend", "Data table not supported."}, |
| { eChartLegendPosition, 8008, "Chart", "Legend", "Position not guaranteed."}, |
| { eChartTextFormatting, 8009, "Chart", "Formatting", "Text formatting present."}, |
| { eChartEmbeddedObj, 8010, "Chart", "Area", "Object inside chart."}, |
| { eChartAxisAuto, 8012, "Chart", "Axis", "Axis interval is automatic."}, |
| { eChartInvalidXY, 8013, "Chart", "Scatter", "Unsupported or invalid data range for XY chart."}, |
| { eChartErrorBars, 8014, "Chart", "Type", "Chart error bars not supported."}, |
| { eChartAxisManual, 8015, "Chart", "Axis", "Manual axis crossing point adjusted."}, |
| { eUnsupportedObject, 9000, "Object", "Type", "Limited Object support."}, |
| { eObjectNotPrintable, 9001, "Object", "Print", "Object not printable."}, |
| { eDVType, 10000, "DataValidation", "Type", "Custom type present."} |
| }; |
| |
| XclTracer::XclTracer( const String& rDocUrl, const OUString& rConfigPath ) : |
| maFirstTimes(eTraceLength,true) |
| { |
| Sequence< PropertyValue > aConfigData( 1 ); |
| aConfigData[ 0 ].Name = CREATE_OUSTRING( "DocumentURL" ); |
| aConfigData[ 0 ].Value <<= OUString( rDocUrl ); |
| mpTracer.reset( new MSFilterTracer( rConfigPath, &aConfigData ) ); |
| mpTracer->StartTracing(); |
| mbEnabled = mpTracer->IsEnabled(); |
| } |
| |
| XclTracer::~XclTracer() |
| { |
| mpTracer->EndTracing(); |
| } |
| |
| void XclTracer::AddAttribute( const OUString& rName, const OUString& rValue ) |
| { |
| if( mbEnabled ) |
| mpTracer->AddAttribute( rName, rValue ); |
| } |
| |
| void XclTracer::Trace( const OUString& rElementID, const OUString& rMessage ) |
| { |
| if( mbEnabled ) |
| { |
| mpTracer->Trace( rElementID, rMessage ); |
| mpTracer->ClearAttributes(); |
| } |
| } |
| |
| void XclTracer::TraceLog( XclTracerId eProblem, sal_Int32 nValue ) |
| { |
| if( mbEnabled ) |
| { |
| OUString sID( CREATE_STRING( "SC" ) ); |
| sID += OUString::valueOf( static_cast< sal_Int32 >( pTracerDetails[ eProblem ].mnID ) ); |
| OUString sProblem = OUString::createFromAscii( pTracerDetails[ eProblem ].mpProblem ); |
| |
| switch (eProblem) |
| { |
| case eRowLimitExceeded: |
| Context(eProblem,static_cast<SCTAB>(nValue)); |
| break; |
| case eTabLimitExceeded: |
| Context(eProblem,static_cast<SCTAB>(nValue)); |
| break; |
| default: |
| Context(eProblem); |
| break; |
| } |
| Trace(sID, sProblem); |
| } |
| } |
| |
| void XclTracer::Context( XclTracerId eProblem, SCTAB nTab ) |
| { |
| OUString sContext = OUString::createFromAscii( pTracerDetails[ eProblem ].mpContext ); |
| OUString sDetail = OUString::createFromAscii( pTracerDetails[ eProblem ].mpDetail ); |
| |
| switch (eProblem) |
| { |
| case eRowLimitExceeded: |
| case eTabLimitExceeded: |
| sDetail += OUString::valueOf( static_cast< sal_Int32 >( nTab + 1 ) ); |
| break; |
| default: |
| break; |
| } |
| AddAttribute(sContext, sDetail); |
| } |
| |
| void XclTracer::ProcessTraceOnce(XclTracerId eProblem, SCTAB nTab) |
| { |
| if( mbEnabled && maFirstTimes[eProblem]) |
| { |
| TraceLog(pTracerDetails[eProblem].meProblemId, nTab); |
| maFirstTimes[eProblem] = false; |
| } |
| } |
| |
| void XclTracer::TraceInvalidAddress( const ScAddress& rPos, const ScAddress& rMaxPos ) |
| { |
| TraceInvalidRow(rPos.Tab(), rPos.Row(), rMaxPos.Row()); |
| TraceInvalidTab(rPos.Tab(), rMaxPos.Tab()); |
| } |
| |
| void XclTracer::TraceInvalidRow( SCTAB nTab, sal_uInt32 nRow, sal_uInt32 nMaxRow ) |
| { |
| if(nRow > nMaxRow) |
| ProcessTraceOnce(eRowLimitExceeded, nTab); |
| } |
| |
| void XclTracer::TraceInvalidTab( SCTAB nTab, SCTAB nMaxTab ) |
| { |
| if(nTab > nMaxTab) |
| ProcessTraceOnce(eTabLimitExceeded, nTab); |
| } |
| |
| void XclTracer::TracePrintRange() |
| { |
| ProcessTraceOnce( ePrintRange); |
| } |
| |
| void XclTracer::TraceDates( sal_uInt16 nNumFmt) |
| { |
| // Short Date = 14 and Short Date+Time = 22 |
| if(nNumFmt == 14 || nNumFmt == 22) |
| ProcessTraceOnce(eShortDate); |
| } |
| |
| void XclTracer::TraceBorderLineStyle( bool bBorderLineStyle) |
| { |
| if(bBorderLineStyle) |
| ProcessTraceOnce(eBorderLineStyle); |
| } |
| |
| void XclTracer::TraceFillPattern( bool bFillPattern) |
| { |
| if(bFillPattern) |
| ProcessTraceOnce(eFillPattern); |
| } |
| |
| void XclTracer::TraceFormulaMissingArg() |
| { |
| // missing parameter in Formula record |
| ProcessTraceOnce(eFormulaMissingArg); |
| } |
| |
| void XclTracer::TracePivotDataSource( bool bExternal) |
| { |
| if(bExternal) |
| ProcessTraceOnce(ePivotDataSource); |
| } |
| |
| void XclTracer::TracePivotChartExists() |
| { |
| // Pivot Charts not currently displayed. |
| ProcessTraceOnce(ePivotChartExists); |
| } |
| |
| void XclTracer::TraceChartUnKnownType() |
| { |
| ProcessTraceOnce(eChartUnKnownType); |
| } |
| |
| void XclTracer::TraceChartOnlySheet() |
| { |
| ProcessTraceOnce(eChartOnlySheet); |
| } |
| |
| void XclTracer::TraceChartDataTable() |
| { |
| // Data table is not supported. |
| ProcessTraceOnce(eChartDataTable); |
| } |
| |
| void XclTracer::TraceChartLegendPosition() |
| { |
| // If position is set to "not docked or inside the plot area" then |
| // we cannot guarantee the legend position. |
| ProcessTraceOnce(eChartLegendPosition); |
| } |
| |
| void XclTracer::TraceChartEmbeddedObj() |
| { |
| // drawing objects e.g. text boxes etc not supported inside charts |
| ProcessTraceOnce(eChartEmbeddedObj); |
| } |
| |
| void XclTracer::TraceUnsupportedObjects() |
| { |
| // Called from Excel 5.0 - limited Graphical object support. |
| ProcessTraceOnce(eUnsupportedObject); |
| } |
| |
| void XclTracer::TraceObjectNotPrintable() |
| { |
| ProcessTraceOnce(eObjectNotPrintable); |
| } |
| |
| void XclTracer::TraceDVType( bool bType) |
| { |
| // Custom types work if 'Data->validity dialog' is not OKed. |
| if(bType) |
| ProcessTraceOnce(eDVType); |
| } |
| |
| // ============================================================================ |
| |