xref: /trunk/main/sd/source/filter/html/buttonset.cxx (revision 79aad27f)
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