1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef OOX_XLS_EXTERNALLINKBUFFER_HXX 25 #define OOX_XLS_EXTERNALLINKBUFFER_HXX 26 27 #include <com/sun/star/sheet/ExternalLinkInfo.hpp> 28 #include "oox/helper/containerhelper.hxx" 29 #include "oox/xls/defnamesbuffer.hxx" 30 31 namespace com { namespace sun { namespace star { 32 namespace sheet { struct DDEItemInfo; } 33 namespace sheet { class XDDELink; } 34 namespace sheet { class XExternalDocLink; } 35 namespace sheet { class XExternalSheetCache; } 36 } } } 37 38 namespace oox { namespace core { 39 class Relations; 40 } } 41 42 namespace oox { 43 namespace xls { 44 45 // ============================================================================ 46 47 struct ExternalNameModel 48 { 49 bool mbBuiltIn; /// Name is a built-in name. 50 bool mbNotify; /// Notify application on data change. 51 bool mbPreferPic; /// Picture link. 52 bool mbStdDocName; /// Name is the StdDocumentName for DDE. 53 bool mbOleObj; /// Name is an OLE object. 54 bool mbIconified; /// Iconified object link. 55 56 explicit ExternalNameModel(); 57 }; 58 59 // ============================================================================ 60 61 class ExternalLink; 62 63 class ExternalName : public DefinedNameBase 64 { 65 public: 66 explicit ExternalName( const ExternalLink& rParentLink ); 67 68 /** Appends the passed value to the result set. */ 69 template< typename Type > appendResultValue(const Type & rValue)70 inline void appendResultValue( const Type& rValue ) 71 { if( maCurrIt != maResults.end() ) (*maCurrIt++) <<= rValue; } 72 73 /** Imports the definedName element. */ 74 void importDefinedName( const AttributeList& rAttribs ); 75 /** Imports the ddeItem element describing an item of a DDE link. */ 76 void importDdeItem( const AttributeList& rAttribs ); 77 /** Imports the values element containing the size of the DDE result matrix. */ 78 void importValues( const AttributeList& rAttribs ); 79 /** Imports the oleItem element describing an object of an OLE link. */ 80 void importOleItem( const AttributeList& rAttribs ); 81 82 /** Imports the EXTERNALNAME record containing the name (only). */ 83 void importExternalName( SequenceInputStream& rStrm ); 84 /** Imports the EXTERNALNAMEFLAGS record containing the settings of an external name. */ 85 void importExternalNameFlags( SequenceInputStream& rStrm ); 86 /** Imports the DDEITEMVALUES record containing the size of the DDE result matrix. */ 87 void importDdeItemValues( SequenceInputStream& rStrm ); 88 /** Imports the DDEITEM_BOOL record containing a boolean value in a link result. */ 89 void importDdeItemBool( SequenceInputStream& rStrm ); 90 /** Imports the DDEITEM_DOUBLE record containing a double value in a link result. */ 91 void importDdeItemDouble( SequenceInputStream& rStrm ); 92 /** Imports the DDEITEM_ERROR record containing an error code in a link result. */ 93 void importDdeItemError( SequenceInputStream& rStrm ); 94 /** Imports the DDEITEM_STRING record containing a string in a link result. */ 95 void importDdeItemString( SequenceInputStream& rStrm ); 96 97 /** Imports the EXTERNALNAME record from the passed stream. */ 98 void importExternalName( BiffInputStream& rStrm ); 99 100 /** Returns true, if the name refers to an OLE object. */ isOleObject() const101 inline bool isOleObject() const { return maExtNameModel.mbOleObj; } 102 103 #if 0 104 /** Returns the sheet cache index if this is a sheet-local external name. */ 105 sal_Int32 getSheetCacheIndex() const; 106 #endif 107 108 /** Returns the DDE item info needed by the XML formula parser. */ 109 bool getDdeItemInfo( 110 ::com::sun::star::sheet::DDEItemInfo& orItemInfo ) const; 111 112 /** Returns the complete DDE link data of this DDE item. */ 113 bool getDdeLinkData( 114 ::rtl::OUString& orDdeServer, 115 ::rtl::OUString& orDdeTopic, 116 ::rtl::OUString& orDdeItem ); 117 118 private: 119 /** Tries to convert the passed token sequence to an ExternalReference. */ 120 void extractExternalReference( const ApiTokenSequence& rTokens ); 121 /** Sets the size of the result matrix. */ 122 void setResultSize( sal_Int32 nColumns, sal_Int32 nRows ); 123 124 private: 125 typedef Matrix< ::com::sun::star::uno::Any > ResultMatrix; 126 127 const ExternalLink& mrParentLink; /// External link this name belongs to. 128 ExternalNameModel maExtNameModel; /// Additional name data. 129 ResultMatrix maResults; /// DDE/OLE link results. 130 ResultMatrix::iterator maCurrIt; /// Current position in result matrix. 131 sal_uInt32 mnStorageId; /// OLE storage identifier (BIFF). 132 ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XDDELink > 133 mxDdeLink; /// Interface of a DDE link. 134 bool mbDdeLinkCreated; /// True = already tried to create the DDE link. 135 }; 136 137 typedef ::boost::shared_ptr< ExternalName > ExternalNameRef; 138 139 // ============================================================================ 140 141 /** Contains indexes for a range of sheets in the spreadsheet document. */ 142 class LinkSheetRange 143 { 144 public: LinkSheetRange()145 inline explicit LinkSheetRange() { setDeleted(); } LinkSheetRange(sal_Int32 nFirst,sal_Int32 nLast)146 inline explicit LinkSheetRange( sal_Int32 nFirst, sal_Int32 nLast ) { setRange( nFirst, nLast ); } LinkSheetRange(sal_Int32 nDocLink,sal_Int32 nFirst,sal_Int32 nLast)147 inline explicit LinkSheetRange( sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast ) { setExternalRange( nDocLink, nFirst, nLast ); } 148 149 /** Sets this struct to deleted state. */ 150 void setDeleted(); 151 /** Sets this struct to "use current sheet" state. */ 152 void setSameSheet(); 153 /** Sets the passed absolute sheet range to the members of this struct. */ 154 void setRange( sal_Int32 nFirst, sal_Int32 nLast ); 155 /** Sets the passed external sheet cache range to the members of this struct. */ 156 void setExternalRange( sal_Int32 nDocLink, sal_Int32 nFirst, sal_Int32 nLast ); 157 158 /** Returns true, if the sheet indexes are valid and different. */ isDeleted() const159 inline bool isDeleted() const { return mnFirst < 0; } 160 /** Returns true, if the sheet range points to an external document. */ isExternal() const161 inline bool isExternal() const { return !isDeleted() && (meType == LINKSHEETRANGE_EXTERNAL); } 162 /** Returns true, if the sheet indexes are valid and different. */ isSameSheet() const163 inline bool isSameSheet() const { return meType == LINKSHEETRANGE_SAMESHEET; } 164 /** Returns true, if the sheet indexes are valid and different. */ is3dRange() const165 inline bool is3dRange() const { return (0 <= mnFirst) && (mnFirst < mnLast); } 166 getDocLinkIndex() const167 inline sal_Int32 getDocLinkIndex() const { return mnDocLink; } getFirstSheet() const168 inline sal_Int32 getFirstSheet() const { return mnFirst; } getLastSheet() const169 inline sal_Int32 getLastSheet() const { return mnLast; } 170 171 private: 172 enum LinkSheetRangeType 173 { 174 LINKSHEETRANGE_INTERNAL, /// Sheet range in the own document. 175 LINKSHEETRANGE_EXTERNAL, /// Sheet range in an external document. 176 LINKSHEETRANGE_SAMESHEET /// Current sheet depending on context. 177 }; 178 179 LinkSheetRangeType meType; /// Link sheet range type. 180 sal_Int32 mnDocLink; /// Document link token index for external links. 181 sal_Int32 mnFirst; /// Index of the first sheet or index of first external sheet cache. 182 sal_Int32 mnLast; /// Index of the last sheet or index of last external sheet cache. 183 }; 184 185 // ============================================================================ 186 187 enum ExternalLinkType 188 { 189 LINKTYPE_SELF, /// Link refers to the current workbook. 190 LINKTYPE_SAME, /// Link refers to the current sheet. 191 LINKTYPE_INTERNAL, /// Link refers to a sheet in the own workbook. 192 LINKTYPE_EXTERNAL, /// Link refers to an external spreadsheet document. 193 LINKTYPE_ANALYSIS, /// Link refers to the Analysis add-in. 194 LINKTYPE_LIBRARY, /// Link refers to an external add-in. 195 LINKTYPE_DDE, /// DDE link. 196 LINKTYPE_OLE, /// OLE link. 197 LINKTYPE_MAYBE_DDE_OLE, /// Could be DDE or OLE link (BIFF only). 198 LINKTYPE_UNKNOWN /// Unknown or unsupported link type. 199 }; 200 201 // ---------------------------------------------------------------------------- 202 203 class ExternalLink : public WorkbookHelper 204 { 205 public: 206 explicit ExternalLink( const WorkbookHelper& rHelper ); 207 208 /** Imports the externalReference element containing the relation identifier. */ 209 void importExternalReference( const AttributeList& rAttribs ); 210 /** Imports the externalBook element describing an externally linked document. */ 211 void importExternalBook( const ::oox::core::Relations& rRelations, const AttributeList& rAttribs ); 212 /** Imports the sheetName element containing the sheet name in an externally linked document. */ 213 void importSheetName( const AttributeList& rAttribs ); 214 /** Imports the definedName element describing an external name. */ 215 void importDefinedName( const AttributeList& rAttribs ); 216 /** Imports the ddeLink element describing a DDE link. */ 217 void importDdeLink( const AttributeList& rAttribs ); 218 /** Imports the ddeItem element describing an item of a DDE link. */ 219 ExternalNameRef importDdeItem( const AttributeList& rAttribs ); 220 /** Imports the oleLink element describing an OLE link. */ 221 void importOleLink( const ::oox::core::Relations& rRelations, const AttributeList& rAttribs ); 222 /** Imports the oleItem element describing an object of an OLE link. */ 223 ExternalNameRef importOleItem( const AttributeList& rAttribs ); 224 225 /** Imports the EXTERNALBOOK record describing an externally linked document, DDE link, or OLE link. */ 226 void importExternalBook( const ::oox::core::Relations& rRelations, SequenceInputStream& rStrm ); 227 /** Imports the EXTSHEETNAMES record containing the sheet names in an externally linked document. */ 228 void importExtSheetNames( SequenceInputStream& rStrm ); 229 /** Imports the EXTERNALNAME record describing an external name. */ 230 ExternalNameRef importExternalName( SequenceInputStream& rStrm ); 231 /** Imports the EXTERNALREF record from the passed stream. */ 232 void importExternalRef( SequenceInputStream& rStrm ); 233 /** Imports the EXTERNALSELF record from the passed stream. */ 234 void importExternalSelf( SequenceInputStream& rStrm ); 235 /** Imports the EXTERNALSAME record from the passed stream. */ 236 void importExternalSame( SequenceInputStream& rStrm ); 237 /** Imports the EXTERNALADDIN record from the passed stream. */ 238 void importExternalAddin( SequenceInputStream& rStrm ); 239 240 /** Imports the EXTERNSHEET record from the passed stream. */ 241 void importExternSheet( BiffInputStream& rStrm ); 242 /** Imports the EXTERNALBOOK record from the passed stream. */ 243 void importExternalBook( BiffInputStream& rStrm ); 244 /** Imports the EXTERNALNAME record from the passed stream. */ 245 void importExternalName( BiffInputStream& rStrm ); 246 247 /** Sets the link type to 'self reference'. */ setSelfLinkType()248 inline void setSelfLinkType() { meLinkType = LINKTYPE_SELF; } 249 250 /** Returns the type of this external link. */ getLinkType() const251 inline ExternalLinkType getLinkType() const { return meLinkType; } 252 /** Returns true, if the link refers to the current workbook. */ isInternalLink() const253 inline bool isInternalLink() const { return (meLinkType == LINKTYPE_SELF) || (meLinkType == LINKTYPE_INTERNAL); } 254 255 /** Returns the relation identifier for the external link fragment. */ getRelId() const256 inline const ::rtl::OUString& getRelId() const { return maRelId; } 257 /** Returns the class name of this external link. */ getClassName() const258 inline const ::rtl::OUString& getClassName() const { return maClassName; } 259 /** Returns the target URL of this external link. */ getTargetUrl() const260 inline const ::rtl::OUString& getTargetUrl() const { return maTargetUrl; } 261 /** Returns the link info needed by the XML formula parser. */ 262 ::com::sun::star::sheet::ExternalLinkInfo getLinkInfo() const; 263 264 /** Returns the type of the external library if this is a library link. */ 265 FunctionLibraryType getFuncLibraryType() const; 266 267 /** Returns the internal Calc sheet index or for the passed sheet. */ 268 sal_Int16 getCalcSheetIndex( sal_Int32 nTabId = 0 ) const; 269 270 /** Returns the token index of the external document. */ 271 sal_Int32 getDocumentLinkIndex() const; 272 /** Returns the external sheet cache index or for the passed sheet. */ 273 sal_Int32 getSheetCacheIndex( sal_Int32 nTabId = 0 ) const; 274 /** Returns the sheet cache of the external sheet with the passed index. */ 275 ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalSheetCache > 276 getSheetCache( sal_Int32 nTabId ) const; 277 278 /** Returns the internal sheet range or range of external sheet caches for the passed sheet range (BIFF only). */ 279 void getSheetRange( LinkSheetRange& orSheetRange, sal_Int32 nTabId1, sal_Int32 nTabId2 ) const; 280 281 /** Returns the external name with the passed zero-based index. */ 282 ExternalNameRef getNameByIndex( sal_Int32 nIndex ) const; 283 284 private: 285 void setExternalTargetUrl( const ::rtl::OUString& rTargetUrl, const ::rtl::OUString& rTargetType ); 286 void setDdeOleTargetUrl( const ::rtl::OUString& rClassName, const ::rtl::OUString& rTargetUrl, ExternalLinkType eLinkType ); 287 void parseExternalReference( const ::oox::core::Relations& rRelations, const ::rtl::OUString& rRelId ); 288 ::rtl::OUString parseBiffTargetUrl( const ::rtl::OUString& rBiffTargetUrl ); 289 290 /** Creates an external locument link and the sheet cache for the passed sheet name. */ 291 void insertExternalSheet( const ::rtl::OUString& rSheetName ); 292 293 ExternalNameRef createExternalName(); 294 295 private: 296 typedef ::std::vector< sal_Int16 > Int16Vector; 297 typedef ::std::vector< sal_Int32 > Int32Vector; 298 typedef RefVector< ExternalName > ExternalNameVector; 299 300 ExternalLinkType meLinkType; /// Type of this link object. 301 FunctionLibraryType meFuncLibType; /// Type of the function library, if link type is LINKTYPE_LIBRARY. 302 ::rtl::OUString maRelId; /// Relation identifier for the external link fragment. 303 ::rtl::OUString maClassName; /// DDE service, OLE class name. 304 ::rtl::OUString maTargetUrl; /// Target link, DDE topic, OLE target. 305 ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalDocLink > 306 mxDocLink; /// Interface for an external document. 307 Int16Vector maCalcSheets; /// Internal sheet indexes. 308 Int32Vector maSheetCaches; /// External sheet cache indexes. 309 ExternalNameVector maExtNames; /// Defined names in external document. 310 }; 311 312 typedef ::boost::shared_ptr< ExternalLink > ExternalLinkRef; 313 314 // ============================================================================ 315 316 /** Represents a REF entry in the BIFF12 EXTERNALSHEETS or in the BIFF8 317 EXTERNSHEET record. 318 319 This struct is used to map ref identifiers to external books (BIFF12: 320 EXTERNALREF records, BIFF8: EXTERNALBOOK records), and provides sheet 321 indexes into the sheet list of the external document. 322 */ 323 struct RefSheetsModel 324 { 325 sal_Int32 mnExtRefId; /// Zero-based index into list of external documents. 326 sal_Int32 mnTabId1; /// Zero-based index to first sheet in external document. 327 sal_Int32 mnTabId2; /// Zero-based index to last sheet in external document. 328 329 explicit RefSheetsModel(); 330 331 void readBiff12Data( SequenceInputStream& rStrm ); 332 void readBiff8Data( BiffInputStream& rStrm ); 333 }; 334 335 // ---------------------------------------------------------------------------- 336 337 class ExternalLinkBuffer : public WorkbookHelper 338 { 339 public: 340 explicit ExternalLinkBuffer( const WorkbookHelper& rHelper ); 341 342 /** Imports the externalReference element containing . */ 343 ExternalLinkRef importExternalReference( const AttributeList& rAttribs ); 344 345 /** Imports the EXTERNALREF record from the passed stream. */ 346 ExternalLinkRef importExternalRef( SequenceInputStream& rStrm ); 347 /** Imports the EXTERNALSELF record from the passed stream. */ 348 void importExternalSelf( SequenceInputStream& rStrm ); 349 /** Imports the EXTERNALSAME record from the passed stream. */ 350 void importExternalSame( SequenceInputStream& rStrm ); 351 /** Imports the EXTERNALADDIN record from the passed stream. */ 352 void importExternalAddin( SequenceInputStream& rStrm ); 353 /** Imports the EXTERNALSHEETS record from the passed stream. */ 354 void importExternalSheets( SequenceInputStream& rStrm ); 355 356 /** Imports the EXTERNSHEET record from the passed stream. */ 357 ExternalLinkRef importExternSheet( BiffInputStream& rStrm ); 358 /** Imports the EXTERNALBOOK record from the passed stream. */ 359 ExternalLinkRef importExternalBook( BiffInputStream& rStrm ); 360 /** Imports the EXTERNALNAME record from the passed stream. */ 361 void importExternalName( BiffInputStream& rStrm ); 362 /** Imports the BIFF8 EXTERNSHEET record from the passed stream. */ 363 void importExternSheet8( BiffInputStream& rStrm ); 364 365 /** Returns the sequence of link infos needed by the XML formula parser. */ 366 ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::ExternalLinkInfo > 367 getLinkInfos() const; 368 369 /** Returns the external link for the passed reference identifier. */ 370 ExternalLinkRef getExternalLink( sal_Int32 nRefId, bool bUseRefSheets = true ) const; 371 372 /** Returns the sheet range for the specified reference (BIFF2-BIFF5 only). */ 373 LinkSheetRange getSheetRange( sal_Int32 nRefId, sal_Int16 nTabId1, sal_Int16 nTabId2 ) const; 374 /** Returns the sheet range for the specified reference (BIFF8 only). */ 375 LinkSheetRange getSheetRange( sal_Int32 nRefId ) const; 376 377 private: 378 /** Creates a new external link and inserts it into the list of links. */ 379 ExternalLinkRef createExternalLink(); 380 381 /** Returns the specified sheet indexes for a reference identifier. */ 382 const RefSheetsModel* getRefSheets( sal_Int32 nRefId ) const; 383 384 private: 385 typedef RefVector< ExternalLink > ExternalLinkVec; 386 typedef ::std::vector< RefSheetsModel > RefSheetsModelVec; 387 388 ExternalLinkRef mxSelfRef; /// Implicit self reference at index 0. 389 ExternalLinkVec maLinks; /// List of link structures for all kinds of links. 390 ExternalLinkVec maExtLinks; /// Real external links needed for formula parser. 391 RefSheetsModelVec maRefSheets; /// Sheet indexes for reference ids. 392 bool mbUseRefSheets; /// True = use maRefSheets list (BIFF12 only). 393 }; 394 395 // ============================================================================ 396 397 } // namespace xls 398 } // namespace oox 399 400 #endif 401