LibreOffice Module sd (master) 1
buttonset.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <com/sun/star/embed/ElementModes.hpp>
23#include <com/sun/star/embed/XStorage.hpp>
24#include <com/sun/star/graphic/GraphicProvider.hpp>
25#include <com/sun/star/graphic/XGraphicProvider.hpp>
26#include <com/sun/star/io/XStream.hpp>
27
28#include <o3tl/safeint.hxx>
29#include <osl/file.hxx>
34#include <vcl/graph.hxx>
35#include <vcl/virdev.hxx>
36#include <vcl/image.hxx>
39
40#include <memory>
41
42#include "buttonset.hxx"
43
44using namespace ::com::sun::star::uno;
45using namespace ::com::sun::star::graphic;
46using namespace ::com::sun::star::embed;
47using namespace ::com::sun::star::io;
48using namespace ::com::sun::star::beans;
49using namespace ::com::sun::star::lang;
50
51namespace {
52
53class ButtonsImpl
54{
55public:
56 explicit ButtonsImpl( const OUString& rURL );
57
58 Reference< XInputStream > getInputStream( const OUString& rName );
59
60 bool getGraphic( const Reference< XGraphicProvider >& xGraphicProvider, const OUString& rName, Graphic& rGraphic );
61
62 bool copyGraphic( const OUString& rName, const OUString& rPath );
63
64private:
65 Reference< XStorage > mxStorage;
66};
67
68}
69
70ButtonsImpl::ButtonsImpl( const OUString& rURL )
71{
72 try
73 {
74 mxStorage = comphelper::OStorageHelper::GetStorageOfFormatFromURL( ZIP_STORAGE_FORMAT_STRING, rURL, ElementModes::READ );
75 }
76 catch( Exception& )
77 {
78 TOOLS_WARN_EXCEPTION( "sd", "sd::ButtonsImpl::ButtonsImpl()" );
79 }
80}
81
82Reference< XInputStream > ButtonsImpl::getInputStream( const OUString& rName )
83{
84 Reference< XInputStream > xInputStream;
85 if( mxStorage.is() ) try
86 {
87 Reference< XStream > xStream( mxStorage->openStreamElement( rName, ElementModes::READ ) );
88 if( xStream.is() )
89 xInputStream = xStream->getInputStream();
90 }
91 catch( Exception& )
92 {
93 TOOLS_WARN_EXCEPTION( "sd", "sd::ButtonsImpl::getInputStream()" );
94 }
95 return xInputStream;
96}
97
98bool ButtonsImpl::getGraphic( const Reference< XGraphicProvider >& xGraphicProvider, const OUString& rName, Graphic& rGraphic )
99{
100 Reference< XInputStream > xInputStream( getInputStream( rName ) );
101 if( xInputStream.is() && xGraphicProvider.is() ) try
102 {
103 Sequence< PropertyValue > aMediaProperties{ comphelper::makePropertyValue(
104 "InputStream", xInputStream) };
105 Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties ) );
106
107 if( xGraphic.is() )
108 {
109 rGraphic = Graphic( xGraphic );
110 return true;
111 }
112 }
113 catch( Exception& )
114 {
115 TOOLS_WARN_EXCEPTION( "sd", "sd::ButtonsImpl::getGraphic()" );
116 }
117 return false;
118}
119
120bool ButtonsImpl::copyGraphic( const OUString& rName, const OUString& rPath )
121{
122 Reference< XInputStream > xInput( getInputStream( rName ) );
123 if( xInput.is() ) try
124 {
125 osl::File::remove( rPath );
126 osl::File aOutputFile( rPath );
127 if( aOutputFile.open( osl_File_OpenFlag_Write|osl_File_OpenFlag_Create ) == osl::FileBase::E_None )
128 {
129 Reference< XOutputStream > xOutput( new comphelper::OSLOutputStreamWrapper( aOutputFile ) );
131 return true;
132 }
133 }
134 catch( Exception& )
135 {
136 TOOLS_WARN_EXCEPTION( "sd", "sd::ButtonsImpl::copyGraphic()" );
137 }
138
139 return false;
140}
141
143{
144public:
146
147 int getCount() const;
148
149 bool getPreview( int nSet, const std::vector< OUString >& rButtons, Image& rImage );
150 bool exportButton( int nSet, const OUString& rPath, const OUString& rName );
151
152 void scanForButtonSets( const OUString& rPath );
153
154 Reference< XGraphicProvider > const & getGraphicProvider();
155
156 std::vector< std::shared_ptr< ButtonsImpl > > maButtons;
157 Reference< XGraphicProvider > mxGraphicProvider;
158};
159
161{
162 static const char sSubPath[] = "/wizard/web/buttons" ;
163
164 OUString sSharePath = SvtPathOptions().GetConfigPath() +
165 sSubPath;
166 scanForButtonSets( sSharePath );
167
168 OUString sUserPath = SvtPathOptions().GetUserConfigPath() +
169 sSubPath;
170 scanForButtonSets( sUserPath );
171}
172
173void ButtonSetImpl::scanForButtonSets( const OUString& rPath )
174{
175 osl::Directory aDirectory( rPath );
176 if( aDirectory.open() != osl::FileBase::E_None )
177 return;
178
179 osl::DirectoryItem aItem;
180 while( aDirectory.getNextItem( aItem, 2211 ) == osl::FileBase::E_None )
181 {
182 osl::FileStatus aStatus( osl_FileStatus_Mask_FileName|osl_FileStatus_Mask_FileURL );
183 if( aItem.getFileStatus( aStatus ) == osl::FileBase::E_None )
184 {
185 OUString sFileName( aStatus.getFileName() );
186 if( sFileName.endsWithIgnoreAsciiCase( ".zip" ) )
187 maButtons.push_back( std::make_shared< ButtonsImpl >( aStatus.getFileURL() ) );
188 }
189 }
190}
191
193{
194 return maButtons.size();
195}
196
197bool ButtonSetImpl::getPreview( int nSet, const std::vector< OUString >& rButtons, Image& rImage )
198{
199 if( (nSet >= 0) && (o3tl::make_unsigned(nSet) < maButtons.size()))
200 {
201 ButtonsImpl& rSet = *maButtons[nSet];
202
203 std::vector< Graphic > aGraphics;
204
206 pDev->SetMapMode(MapMode(MapUnit::MapPixel));
207
208 Size aSize;
209 std::vector< 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( pDev ) );
219 aSize.AdjustWidth(aGraphicSize.Width() );
220
221 if( aSize.Height() < aGraphicSize.Height() )
222 aSize.setHeight( aGraphicSize.Height() );
223
224 if( aIter != rButtons.end() )
225 aSize.AdjustWidth(3 );
226 }
227
228 pDev->SetOutputSizePixel( aSize );
229
230 Point aPos;
231
232 for( const Graphic& aGraphic : aGraphics )
233 {
234 aGraphic.Draw(*pDev, aPos);
235
236 aPos.AdjustX(aGraphic.GetSizePixel().Width() + 3 );
237 }
238
239 rImage = Image( pDev->GetBitmapEx( Point(), aSize ) );
240 return true;
241 }
242 return false;
243}
244
245bool ButtonSetImpl::exportButton( int nSet, const OUString& rPath, const OUString& rName )
246{
247 if( (nSet >= 0) && (o3tl::make_unsigned(nSet) < maButtons.size()))
248 {
249 ButtonsImpl& rSet = *maButtons[nSet];
250
251 return rSet.copyGraphic( rName, rPath );
252 }
253 return false;
254}
255
256Reference< XGraphicProvider > const & ButtonSetImpl::getGraphicProvider()
257{
258 if( !mxGraphicProvider.is() )
259 {
260 Reference< XComponentContext > xComponentContext = ::comphelper::getProcessComponentContext();
261 mxGraphicProvider = GraphicProvider::create(xComponentContext);
262 }
263 return mxGraphicProvider;
264}
265
267: mpImpl( new ButtonSetImpl() )
268{
269}
270
272{
273}
274
276{
277 return mpImpl->getCount();
278}
279
280bool ButtonSet::getPreview( int nSet, const std::vector< OUString >& rButtons, Image& rImage )
281{
282 return mpImpl->getPreview( nSet, rButtons, rImage );
283}
284
285bool ButtonSet::exportButton( int nSet, const OUString& rPath, const OUString& rName )
286{
287 return mpImpl->exportButton( nSet, rPath, rName );
288}
289
290/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XInputStream > xStream
int getCount() const
Definition: buttonset.cxx:192
void scanForButtonSets(const OUString &rPath)
Definition: buttonset.cxx:173
bool exportButton(int nSet, const OUString &rPath, const OUString &rName)
Definition: buttonset.cxx:245
bool getPreview(int nSet, const std::vector< OUString > &rButtons, Image &rImage)
Definition: buttonset.cxx:197
std::vector< std::shared_ptr< ButtonsImpl > > maButtons
Definition: buttonset.cxx:156
Reference< XGraphicProvider > const & getGraphicProvider()
Definition: buttonset.cxx:256
Reference< XGraphicProvider > mxGraphicProvider
Definition: buttonset.cxx:157
bool exportButton(int nSet, const OUString &rPath, const OUString &rName)
Definition: buttonset.cxx:285
bool getPreview(int nSet, const std::vector< OUString > &rButtons, Image &rImage)
Definition: buttonset.cxx:280
std::unique_ptr< ButtonSetImpl > mpImpl
Definition: buttonset.hxx:43
int getCount() const
Definition: buttonset.cxx:275
Size GetSizePixel(const OutputDevice *pRefDevice=nullptr) const
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long Height() const
tools::Long AdjustWidth(tools::Long n)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
const OUString & GetConfigPath() const
const OUString & GetUserConfigPath() const
static void CopyInputToOutput(const css::uno::Reference< css::io::XInputStream > &xInput, const css::uno::Reference< css::io::XOutputStream > &xOutput)
static css::uno::Reference< css::embed::XStorage > GetStorageOfFormatFromURL(const OUString &aFormat, const OUString &aURL, sal_Int32 nStorageMode, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
#define TOOLS_WARN_EXCEPTION(area, stream)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
Reference< XNameContainer > mxStorage
static SfxItemSet & rSet