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 #include "oox/ole/axcontrolfragment.hxx"
25 
26 #include "oox/core/xmlfilterbase.hxx"
27 #include "oox/helper/binaryinputstream.hxx"
28 #include "oox/helper/binaryoutputstream.hxx"
29 #include "oox/ole/axcontrol.hxx"
30 #include "oox/ole/olehelper.hxx"
31 #include "oox/ole/olestorage.hxx"
32 
33 namespace oox {
34 namespace ole {
35 
36 // ============================================================================
37 
38 using namespace ::com::sun::star::io;
39 using namespace ::com::sun::star::uno;
40 
41 using ::oox::core::ContextHandler2;
42 using ::oox::core::ContextHandlerRef;
43 using ::oox::core::FragmentHandler2;
44 using ::oox::core::XmlFilterBase;
45 using ::rtl::OUString;
46 
47 // ============================================================================
48 
AxControlPropertyContext(FragmentHandler2 & rFragment,ControlModelBase & rModel)49 AxControlPropertyContext::AxControlPropertyContext( FragmentHandler2& rFragment, ControlModelBase& rModel ) :
50     ContextHandler2( rFragment ),
51     mrModel( rModel ),
52     mnPropId( XML_TOKEN_INVALID )
53 {
54 }
55 
onCreateContext(sal_Int32 nElement,const AttributeList & rAttribs)56 ContextHandlerRef AxControlPropertyContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
57 {
58     switch( getCurrentElement() )
59     {
60         case AX_TOKEN( ocx ):
61             if( nElement == AX_TOKEN( ocxPr ) )
62             {
63                 mnPropId = rAttribs.getToken( AX_TOKEN( name ), XML_TOKEN_INVALID );
64                 switch( mnPropId )
65                 {
66                     case XML_TOKEN_INVALID:
67                         return 0;
68                     case XML_Picture:
69                     case XML_MouseIcon:
70                         return this;        // import picture path from ax:picture child element
71                     default:
72                         mrModel.importProperty( mnPropId, rAttribs.getString( AX_TOKEN( value ), OUString() ) );
73                 }
74             }
75         break;
76 
77         case AX_TOKEN( ocxPr ):
78             if( nElement == AX_TOKEN( picture ) )
79             {
80                 OUString aPicturePath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
81                 if( aPicturePath.getLength() > 0 )
82                 {
83                     BinaryXInputStream aInStrm( getFilter().openInputStream( aPicturePath ), true );
84                     mrModel.importPictureData( mnPropId, aInStrm );
85                 }
86             }
87         break;
88     }
89     return 0;
90 }
91 
92 // ============================================================================
93 
AxControlFragment(XmlFilterBase & rFilter,const OUString & rFragmentPath,EmbeddedControl & rControl)94 AxControlFragment::AxControlFragment( XmlFilterBase& rFilter, const OUString& rFragmentPath, EmbeddedControl& rControl ) :
95     FragmentHandler2( rFilter, rFragmentPath, true ),
96     mrControl( rControl )
97 {
98 }
99 
onCreateContext(sal_Int32 nElement,const AttributeList & rAttribs)100 ContextHandlerRef AxControlFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
101 {
102     if( isRootElement() && (nElement == AX_TOKEN( ocx )) )
103     {
104         OUString aClassId = rAttribs.getString( AX_TOKEN( classid ), OUString() );
105         switch( rAttribs.getToken( AX_TOKEN( persistence ), XML_TOKEN_INVALID ) )
106         {
107             case XML_persistPropertyBag:
108                 if( ControlModelBase* pModel = mrControl.createModelFromGuid( aClassId ) )
109                     return new AxControlPropertyContext( *this, *pModel );
110             break;
111 
112             case XML_persistStreamInit:
113             {
114                 OUString aFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
115                 if( aFragmentPath.getLength() > 0 )
116                 {
117                     BinaryXInputStream aInStrm( getFilter().openInputStream( aFragmentPath ), true );
118                     if( !aInStrm.isEof() )
119                     {
120                         // binary stream contains a copy of the class ID, must be equal to attribute value
121                         OUString aStrmClassId = OleHelper::importGuid( aInStrm );
122                         OSL_ENSURE( aClassId.equalsIgnoreAsciiCase( aStrmClassId ),
123                             "AxControlFragment::importBinaryControl - form control class ID mismatch" );
124                         if( ControlModelBase* pModel = mrControl.createModelFromGuid( aStrmClassId ) )
125                             pModel->importBinaryModel( aInStrm );
126                     }
127                 }
128             }
129             break;
130 
131             case XML_persistStorage:
132             {
133                 OUString aFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
134                 if( aFragmentPath.getLength() > 0 )
135                 {
136                     Reference< XInputStream > xStrgStrm = getFilter().openInputStream( aFragmentPath );
137                     if( xStrgStrm.is() )
138                     {
139                         OleStorage aStorage( getFilter().getComponentContext(), xStrgStrm, false );
140                         BinaryXInputStream aInStrm( aStorage.openInputStream( CREATE_OUSTRING( "f" ) ), true );
141                         if( !aInStrm.isEof() )
142                             if( AxContainerModelBase* pModel = dynamic_cast< AxContainerModelBase* >( mrControl.createModelFromGuid( aClassId ) ) )
143                                 pModel->importBinaryModel( aInStrm );
144                     }
145                 }
146             }
147             break;
148         }
149     }
150     return 0;
151 }
152 
153 // ============================================================================
154 
155 } // namespace ole
156 } // namespace oox
157