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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26
27 #include <com/sun/star/embed/ElementModes.hpp>
28 #include <com/sun/star/graphic/XGraphicProvider.hpp>
29
30 #include <osl/file.hxx>
31 #include <comphelper/storagehelper.hxx>
32 #include <comphelper/oslfile2streamwrap.hxx>
33 #include <comphelper/processfactory.hxx>
34 #include <tools/debug.hxx>
35 #include <vcl/graph.hxx>
36 #include <vcl/virdev.hxx>
37 #include <vcl/image.hxx>
38 #include <unotools/pathoptions.hxx>
39
40 #include <boost/shared_ptr.hpp>
41
42 #include "buttonset.hxx"
43
44 using ::rtl::OUString;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::graphic;
47 using namespace ::com::sun::star::embed;
48 using namespace ::com::sun::star::io;
49 using namespace ::com::sun::star::beans;
50 using namespace ::com::sun::star::lang;
51
52 class ButtonsImpl
53 {
54 public:
55 ButtonsImpl( const OUString& rURL );
56
57 Reference< XInputStream > getInputStream( const OUString& rName );
58
59 bool getGraphic( const Reference< XGraphicProvider >& xGraphicProvider, const OUString& rName, Graphic& rGraphic );
60
61 bool copyGraphic( const OUString& rName, const OUString& rPath );
62
63 private:
64 Reference< XStorage > mxStorage;
65 };
66
ButtonsImpl(const OUString & rURL)67 ButtonsImpl::ButtonsImpl( const OUString& rURL )
68 {
69 try
70 {
71 mxStorage = comphelper::OStorageHelper::GetStorageOfFormatFromURL( ZIP_STORAGE_FORMAT_STRING, rURL, ElementModes::READ );
72 }
73 catch( Exception& )
74 {
75 DBG_ERROR("sd::ButtonsImpl::ButtonsImpl(), exception caught!" );
76 }
77 }
78
getInputStream(const OUString & rName)79 Reference< XInputStream > ButtonsImpl::getInputStream( const OUString& rName )
80 {
81 Reference< XInputStream > xInputStream;
82 if( mxStorage.is() ) try
83 {
84 Reference< XStream > xStream( mxStorage->openStreamElement( rName, ElementModes::READ ) );
85 if( xStream.is() )
86 xInputStream = xStream->getInputStream();
87 }
88 catch( Exception& )
89 {
90 DBG_ERROR( "sd::ButtonsImpl::getInputStream(), exception caught!" );
91 }
92 return xInputStream;
93 }
94
getGraphic(const Reference<XGraphicProvider> & xGraphicProvider,const rtl::OUString & rName,Graphic & rGraphic)95 bool ButtonsImpl::getGraphic( const Reference< XGraphicProvider >& xGraphicProvider, const rtl::OUString& rName, Graphic& rGraphic )
96 {
97 Reference< XInputStream > xInputStream( getInputStream( rName ) );
98 if( xInputStream.is() && xGraphicProvider.is() ) try
99 {
100 Sequence< PropertyValue > aMediaProperties( 1 );
101 aMediaProperties[0].Name = ::rtl::OUString::createFromAscii( "InputStream" );
102 aMediaProperties[0].Value <<= xInputStream;
103 Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties ) );
104
105 if( xGraphic.is() )
106 {
107 rGraphic = Graphic( xGraphic );
108 return true;
109 }
110 }
111 catch( Exception& )
112 {
113 DBG_ERROR( "sd::ButtonsImpl::getGraphic(), exception caught!" );
114 }
115 return false;
116 }
117
copyGraphic(const OUString & rName,const OUString & rPath)118 bool ButtonsImpl::copyGraphic( const OUString& rName, const OUString& rPath )
119 {
120 Reference< XInputStream > xInput( getInputStream( rName ) );
121 if( xInput.is() ) try
122 {
123 osl::File::remove( rPath );
124 osl::File aOutputFile( rPath );
125 if( aOutputFile.open( OpenFlag_Write|OpenFlag_Create ) == osl::FileBase::E_None )
126 {
127 Reference< XOutputStream > xOutput( new comphelper::OSLOutputStreamWrapper( aOutputFile ) );
128 comphelper::OStorageHelper::CopyInputToOutput( xInput, xOutput );
129 return true;
130 }
131 }
132 catch( Exception& )
133 {
134 DBG_ERROR( "sd::ButtonsImpl::copyGraphic(), exception caught!" );
135 }
136
137 return false;
138 }
139
140 typedef std::vector< boost::shared_ptr< ButtonsImpl > > ButtonVector;
141 class ButtonSetImpl
142 {
143 public:
144 ButtonSetImpl();
145
146 int getCount() const;
147
148 bool getPreview( int nSet, const std::vector< rtl::OUString >& rButtons, Image& rImage );
149 bool exportButton( int nSet, const rtl::OUString& rPath, const rtl::OUString& rName );
150
151 void scanForButtonSets( const OUString& rPath );
152
153 Reference< XGraphicProvider > getGraphicProvider();
154
155 ButtonVector maButtons;
156 Reference< XGraphicProvider > mxGraphicProvider;
157 };
158
ButtonSetImpl()159 ButtonSetImpl::ButtonSetImpl()
160 {
161 const OUString sSubPath( RTL_CONSTASCII_USTRINGPARAM( "/wizard/web/buttons" ) );
162
163 OUString sSharePath( SvtPathOptions().GetConfigPath() );
164 sSharePath += sSubPath;
165 scanForButtonSets( sSharePath );
166
167 OUString sUserPath( SvtPathOptions().GetUserConfigPath() );
168 sUserPath += sSubPath;
169 scanForButtonSets( sUserPath );
170 }
171
scanForButtonSets(const OUString & rPath)172 void ButtonSetImpl::scanForButtonSets( const OUString& rPath )
173 {
174 OUString aSystemPath;
175 osl::Directory aDirectory( rPath );
176 if( aDirectory.open() == osl::FileBase::E_None )
177 {
178 osl::DirectoryItem aItem;
179 while( aDirectory.getNextItem( aItem, 2211 ) == osl::FileBase::E_None )
180 {
181 osl::FileStatus aStatus( FileStatusMask_FileName|FileStatusMask_FileURL );
182 if( aItem.getFileStatus( aStatus ) == osl::FileBase::E_None )
183 {
184 OUString sFileName( aStatus.getFileName() );
185 if( sFileName.endsWithIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM(".zip" ) ) )
186 maButtons.push_back( boost::shared_ptr< ButtonsImpl >( new ButtonsImpl( aStatus.getFileURL() ) ) );
187 }
188 }
189 }
190 }
191
getCount() const192 int ButtonSetImpl::getCount() const
193 {
194 return maButtons.size();
195 }
196
getPreview(int nSet,const std::vector<rtl::OUString> & rButtons,Image & rImage)197 bool ButtonSetImpl::getPreview( int nSet, const std::vector< rtl::OUString >& rButtons, Image& rImage )
198 {
199 if( (nSet >= 0) && (nSet < static_cast<int>(maButtons.size())))
200 {
201 ButtonsImpl& rSet = *maButtons[nSet].get();
202
203 std::vector< Graphic > aGraphics;
204
205 VirtualDevice aDev;
206 aDev.SetMapMode(MapMode(MAP_PIXEL));
207
208 Size aSize;
209 std::vector< rtl::OUString >::const_iterator aIter( rButtons.begin() );
210 while( aIter != rButtons.end() )
211 {
212 Graphic aGraphic;
213 if( !rSet.getGraphic( getGraphicProvider(), (*aIter++), aGraphic ) )
214 return false;
215
216 aGraphics.push_back(aGraphic);
217
218 Size aGraphicSize( aGraphic.GetSizePixel( &aDev ) );
219 aSize.Width() += aGraphicSize.Width();
220
221 if( aSize.Height() < aGraphicSize.Height() )
222 aSize.Height() = aGraphicSize.Height();
223
224 if( aIter != rButtons.end() )
225 aSize.Width() += 3;
226 }
227
228 aDev.SetOutputSizePixel( aSize );
229
230 Point aPos;
231
232 std::vector< Graphic >::iterator aGraphIter( aGraphics.begin() );
233 while( aGraphIter != aGraphics.end() )
234 {
235 Graphic aGraphic( (*aGraphIter++) );
236
237 aGraphic.Draw( &aDev, aPos );
238
239 aPos.X() += aGraphic.GetSizePixel().Width() + 3;
240 }
241
242 rImage = Image( aDev.GetBitmapEx( Point(), aSize ) );
243 return true;
244 }
245 return false;
246 }
247
exportButton(int nSet,const rtl::OUString & rPath,const rtl::OUString & rName)248 bool ButtonSetImpl::exportButton( int nSet, const rtl::OUString& rPath, const rtl::OUString& rName )
249 {
250 if( (nSet >= 0) && (nSet < static_cast<int>(maButtons.size())))
251 {
252 ButtonsImpl& rSet = *maButtons[nSet].get();
253
254 return rSet.copyGraphic( rName, rPath );
255 }
256 return false;
257 }
258
getGraphicProvider()259 Reference< XGraphicProvider > ButtonSetImpl::getGraphicProvider()
260 {
261 if( !mxGraphicProvider.is() )
262 {
263 Reference< XMultiServiceFactory > xServiceManager( ::comphelper::getProcessServiceFactory() );
264 if( xServiceManager.is() ) try
265 {
266 Reference< XGraphicProvider > xGraphProvider(
267 xServiceManager->createInstance(
268 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ), UNO_QUERY_THROW );
269
270 mxGraphicProvider = xGraphProvider;
271 }
272 catch( Exception& )
273 {
274 DBG_ERROR("sd::ButtonSetImpl::getGraphicProvider(), could not get graphic provider!");
275 }
276 }
277 return mxGraphicProvider;
278 }
279
280
ButtonSet()281 ButtonSet::ButtonSet()
282 : mpImpl( new ButtonSetImpl() )
283 {
284 }
285
~ButtonSet()286 ButtonSet::~ButtonSet()
287 {
288 delete mpImpl;
289 }
290
getCount() const291 int ButtonSet::getCount() const
292 {
293 return mpImpl->getCount();
294 }
295
getPreview(int nSet,const std::vector<rtl::OUString> & rButtons,Image & rImage)296 bool ButtonSet::getPreview( int nSet, const std::vector< rtl::OUString >& rButtons, Image& rImage )
297 {
298 return mpImpl->getPreview( nSet, rButtons, rImage );
299 }
300
exportButton(int nSet,const rtl::OUString & rPath,const rtl::OUString & rName)301 bool ButtonSet::exportButton( int nSet, const rtl::OUString& rPath, const rtl::OUString& rName )
302 {
303 return mpImpl->exportButton( nSet, rPath, rName );
304 }
305
306